aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/intel
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/intel')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/cfg/22000.c104
-rw-r--r--drivers/net/wireless/intel/iwlwifi/cfg/9000.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/agn.h9
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c47
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/main.c19
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/rx.c6
-rw-r--r--drivers/net/wireless/intel/iwlwifi/dvm/scan.c3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/acpi.c32
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/acpi.h22
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/alive.h48
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/commands.h5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h180
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/location.h191
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h27
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/power.h24
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/scan.h6
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/tx.h18
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/dbg.c1110
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/dbg.h85
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/debugfs.c11
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/debugfs.h9
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/error-dump.h95
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/file.h25
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/img.h31
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/init.c3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/runtime.h23
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-config.h52
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-csr.h5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c23
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-debug.h5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-drv.c77
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c47
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-io.c79
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-io.h44
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c31
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-prph.h7
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-trans.h41
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/Makefile1
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/coex.c7
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/constants.h7
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/d3.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c138
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c654
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c244
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/fw.c141
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/led.c3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c124
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c292
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mvm.h61
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/ops.c63
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c1
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/power.c23
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rs.c30
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rx.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c103
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/scan.c20
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.c152
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.h3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/time-event.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/tx.c27
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/utils.c31
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c16
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c6
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/drv.c115
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/internal.h30
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/rx.c118
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c28
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/trans.c213
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c8
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/tx.c30
71 files changed, 4090 insertions, 1154 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
index eb93711d474b..fdc56f821b5a 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
@@ -6,7 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2015-2017 Intel Deutschland GmbH 8 * Copyright(c) 2015-2017 Intel Deutschland GmbH
9 * Copyright (C) 2018 Intel Corporation 9 * Copyright (C) 2018-2019 Intel Corporation
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 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 12 * it under the terms of version 2 of the GNU General Public License as
@@ -20,7 +20,7 @@
20 * BSD LICENSE 20 * BSD LICENSE
21 * 21 *
22 * Copyright(c) 2015-2017 Intel Deutschland GmbH 22 * Copyright(c) 2015-2017 Intel Deutschland GmbH
23 * Copyright (C) 2018 Intel Corporation 23 * Copyright (C) 2018-2019 Intel Corporation
24 * All rights reserved. 24 * All rights reserved.
25 * 25 *
26 * Redistribution and use in source and binary forms, with or without 26 * Redistribution and use in source and binary forms, with or without
@@ -56,7 +56,7 @@
56#include "iwl-config.h" 56#include "iwl-config.h"
57 57
58/* Highest firmware API version supported */ 58/* Highest firmware API version supported */
59#define IWL_22000_UCODE_API_MAX 43 59#define IWL_22000_UCODE_API_MAX 46
60 60
61/* Lowest firmware API version supported */ 61/* Lowest firmware API version supported */
62#define IWL_22000_UCODE_API_MIN 39 62#define IWL_22000_UCODE_API_MIN 39
@@ -79,11 +79,15 @@
79#define IWL_22000_HR_B_F0_FW_PRE "iwlwifi-Qu-b0-hr-b0-" 79#define IWL_22000_HR_B_F0_FW_PRE "iwlwifi-Qu-b0-hr-b0-"
80#define IWL_22000_QU_B_HR_B_FW_PRE "iwlwifi-Qu-b0-hr-b0-" 80#define IWL_22000_QU_B_HR_B_FW_PRE "iwlwifi-Qu-b0-hr-b0-"
81#define IWL_22000_HR_B_FW_PRE "iwlwifi-QuQnj-b0-hr-b0-" 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#define IWL_22000_HR_A0_FW_PRE "iwlwifi-QuQnj-a0-hr-a0-" 82#define IWL_22000_HR_A0_FW_PRE "iwlwifi-QuQnj-a0-hr-a0-"
84#define IWL_22000_SU_Z0_FW_PRE "iwlwifi-su-z0-" 83#define IWL_22000_SU_Z0_FW_PRE "iwlwifi-su-z0-"
85#define IWL_QU_B_JF_B_FW_PRE "iwlwifi-Qu-b0-jf-b0-" 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#define IWL_CC_A_FW_PRE "iwlwifi-cc-a0-" 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#define IWL_22000_HR_MODULE_FIRMWARE(api) \ 92#define IWL_22000_HR_MODULE_FIRMWARE(api) \
89 IWL_22000_HR_FW_PRE __stringify(api) ".ucode" 93 IWL_22000_HR_FW_PRE __stringify(api) ".ucode"
@@ -97,16 +101,26 @@
97 IWL_22000_QU_B_HR_B_FW_PRE __stringify(api) ".ucode" 101 IWL_22000_QU_B_HR_B_FW_PRE __stringify(api) ".ucode"
98#define IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(api) \ 102#define IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(api) \
99 IWL_22000_HR_B_FW_PRE __stringify(api) ".ucode" 103 IWL_22000_HR_B_FW_PRE __stringify(api) ".ucode"
100#define IWL_22000_JF_B0_QNJ_MODULE_FIRMWARE(api) \
101 IWL_22000_JF_B0_FW_PRE __stringify(api) ".ucode"
102#define IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(api) \ 104#define IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(api) \
103 IWL_22000_HR_A0_FW_PRE __stringify(api) ".ucode" 105 IWL_22000_HR_A0_FW_PRE __stringify(api) ".ucode"
104#define IWL_22000_SU_Z0_MODULE_FIRMWARE(api) \ 106#define IWL_22000_SU_Z0_MODULE_FIRMWARE(api) \
105 IWL_22000_SU_Z0_FW_PRE __stringify(api) ".ucode" 107 IWL_22000_SU_Z0_FW_PRE __stringify(api) ".ucode"
106#define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \ 108#define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \
107 IWL_QU_B_JF_B_FW_PRE __stringify(api) ".ucode" 109 IWL_QU_B_JF_B_FW_PRE __stringify(api) ".ucode"
108#define IWL_CC_A_MODULE_FIRMWARE(api) \ 110#define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \
111 IWL_QU_B_JF_B_FW_PRE __stringify(api) ".ucode"
112#define IWL_QNJ_B_JF_B_MODULE_FIRMWARE(api) \
113 IWL_QNJ_B_JF_B_FW_PRE __stringify(api) ".ucode"
114#define IWL_CC_A_MODULE_FIRMWARE(api) \
109 IWL_CC_A_FW_PRE __stringify(api) ".ucode" 115 IWL_CC_A_FW_PRE __stringify(api) ".ucode"
116#define IWL_22000_SO_A_JF_B_MODULE_FIRMWARE(api) \
117 IWL_22000_SO_A_JF_B_FW_PRE __stringify(api) ".ucode"
118#define IWL_22000_SO_A_HR_B_MODULE_FIRMWARE(api) \
119 IWL_22000_SO_A_HR_B_FW_PRE __stringify(api) ".ucode"
120#define IWL_22000_SO_A_GF_A_MODULE_FIRMWARE(api) \
121 IWL_22000_SO_A_GF_A_FW_PRE __stringify(api) ".ucode"
122#define IWL_22000_TY_A_GF_A_MODULE_FIRMWARE(api) \
123 IWL_22000_TY_A_GF_A_FW_PRE __stringify(api) ".ucode"
110 124
111static const struct iwl_base_params iwl_22000_base_params = { 125static const struct iwl_base_params iwl_22000_base_params = {
112 .eeprom_size = OTP_LOW_IMAGE_SIZE_32K, 126 .eeprom_size = OTP_LOW_IMAGE_SIZE_32K,
@@ -167,6 +181,10 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
167 .d3_debug_data_base_addr = 0x401000, \ 181 .d3_debug_data_base_addr = 0x401000, \
168 .d3_debug_data_length = 60 * 1024 182 .d3_debug_data_length = 60 * 1024
169 183
184#define IWL_DEVICE_AX200_COMMON \
185 IWL_DEVICE_22000_COMMON, \
186 .umac_prph_offset = 0x300000
187
170#define IWL_DEVICE_22500 \ 188#define IWL_DEVICE_22500 \
171 IWL_DEVICE_22000_COMMON, \ 189 IWL_DEVICE_22000_COMMON, \
172 .device_family = IWL_DEVICE_FAMILY_22000, \ 190 .device_family = IWL_DEVICE_FAMILY_22000, \
@@ -179,6 +197,13 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
179 .base_params = &iwl_22560_base_params, \ 197 .base_params = &iwl_22560_base_params, \
180 .csr = &iwl_csr_v2 198 .csr = &iwl_csr_v2
181 199
200#define IWL_DEVICE_AX210 \
201 IWL_DEVICE_AX200_COMMON, \
202 .device_family = IWL_DEVICE_FAMILY_AX210, \
203 .base_params = &iwl_22000_base_params, \
204 .csr = &iwl_csr_v1, \
205 .min_txq_size = 128
206
182const struct iwl_cfg iwl22000_2ac_cfg_hr = { 207const struct iwl_cfg iwl22000_2ac_cfg_hr = {
183 .name = "Intel(R) Dual Band Wireless AC 22000", 208 .name = "Intel(R) Dual Band Wireless AC 22000",
184 .fw_name_pre = IWL_22000_HR_FW_PRE, 209 .fw_name_pre = IWL_22000_HR_FW_PRE,
@@ -198,8 +223,8 @@ const struct iwl_cfg iwl22000_2ac_cfg_jf = {
198 IWL_DEVICE_22500, 223 IWL_DEVICE_22500,
199}; 224};
200 225
201const struct iwl_cfg iwl22560_2ax_cfg_hr = { 226const struct iwl_cfg iwl_ax101_cfg_qu_hr = {
202 .name = "Intel(R) Wireless-AX 22560", 227 .name = "Intel(R) Wi-Fi 6 AX101",
203 .fw_name_pre = IWL_22000_QU_B_HR_B_FW_PRE, 228 .fw_name_pre = IWL_22000_QU_B_HR_B_FW_PRE,
204 IWL_DEVICE_22500, 229 IWL_DEVICE_22500,
205 /* 230 /*
@@ -220,10 +245,11 @@ const struct iwl_cfg iwl22260_2ax_cfg = {
220 * HT size; mac80211 would otherwise pick the HE max (256) by default. 245 * HT size; mac80211 would otherwise pick the HE max (256) by default.
221 */ 246 */
222 .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, 247 .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
248 .bisr_workaround = 1,
223}; 249};
224 250
225const struct iwl_cfg killer1650x_2ax_cfg = { 251const struct iwl_cfg killer1650x_2ax_cfg = {
226 .name = "Killer(R) Wireless-AX 1650x Wireless Network Adapter (22260NGW)", 252 .name = "Killer(R) Wireless-AX 1650x Wireless Network Adapter (200NGW)",
227 .fw_name_pre = IWL_CC_A_FW_PRE, 253 .fw_name_pre = IWL_CC_A_FW_PRE,
228 IWL_DEVICE_22500, 254 IWL_DEVICE_22500,
229 /* 255 /*
@@ -232,10 +258,11 @@ const struct iwl_cfg killer1650x_2ax_cfg = {
232 * HT size; mac80211 would otherwise pick the HE max (256) by default. 258 * HT size; mac80211 would otherwise pick the HE max (256) by default.
233 */ 259 */
234 .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, 260 .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
261 .bisr_workaround = 1,
235}; 262};
236 263
237const struct iwl_cfg killer1650w_2ax_cfg = { 264const struct iwl_cfg killer1650w_2ax_cfg = {
238 .name = "Killer(R) Wireless-AX 1650w Wireless Network Adapter (22260D2W)", 265 .name = "Killer(R) Wireless-AX 1650w Wireless Network Adapter (200D2W)",
239 .fw_name_pre = IWL_CC_A_FW_PRE, 266 .fw_name_pre = IWL_CC_A_FW_PRE,
240 IWL_DEVICE_22500, 267 IWL_DEVICE_22500,
241 /* 268 /*
@@ -244,6 +271,7 @@ const struct iwl_cfg killer1650w_2ax_cfg = {
244 * HT size; mac80211 would otherwise pick the HE max (256) by default. 271 * HT size; mac80211 would otherwise pick the HE max (256) by default.
245 */ 272 */
246 .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, 273 .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
274 .bisr_workaround = 1,
247}; 275};
248 276
249/* 277/*
@@ -275,6 +303,18 @@ const struct iwl_cfg iwl9560_2ac_160_cfg_qu_b0_jf_b0 = {
275 IWL_DEVICE_22500, 303 IWL_DEVICE_22500,
276}; 304};
277 305
306const struct iwl_cfg iwl9560_2ac_cfg_qnj_jf_b0 = {
307 .name = "Intel(R) Wireless-AC 9560 160MHz",
308 .fw_name_pre = IWL_QNJ_B_JF_B_FW_PRE,
309 IWL_DEVICE_22500,
310 /*
311 * This device doesn't support receiving BlockAck with a large bitmap
312 * so we need to restrict the size of transmitted aggregation to the
313 * HT size; mac80211 would otherwise pick the HE max (256) by default.
314 */
315 .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
316};
317
278const struct iwl_cfg killer1550i_2ac_cfg_qu_b0_jf_b0 = { 318const struct iwl_cfg killer1550i_2ac_cfg_qu_b0_jf_b0 = {
279 .name = "Killer (R) Wireless-AC 1550i Wireless Network Adapter (9560NGW)", 319 .name = "Killer (R) Wireless-AC 1550i Wireless Network Adapter (9560NGW)",
280 .fw_name_pre = IWL_QU_B_JF_B_FW_PRE, 320 .fw_name_pre = IWL_QU_B_JF_B_FW_PRE,
@@ -347,18 +387,6 @@ const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0 = {
347 .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, 387 .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
348}; 388};
349 389
350const struct iwl_cfg iwl22000_2ax_cfg_qnj_jf_b0 = {
351 .name = "Intel(R) Dual Band Wireless AX 22000",
352 .fw_name_pre = IWL_22000_JF_B0_FW_PRE,
353 IWL_DEVICE_22500,
354 /*
355 * This device doesn't support receiving BlockAck with a large bitmap
356 * so we need to restrict the size of transmitted aggregation to the
357 * HT size; mac80211 would otherwise pick the HE max (256) by default.
358 */
359 .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
360};
361
362const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0 = { 390const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0 = {
363 .name = "Intel(R) Dual Band Wireless AX 22000", 391 .name = "Intel(R) Dual Band Wireless AX 22000",
364 .fw_name_pre = IWL_22000_HR_A0_FW_PRE, 392 .fw_name_pre = IWL_22000_HR_A0_FW_PRE,
@@ -384,13 +412,41 @@ const struct iwl_cfg iwl22560_2ax_cfg_su_cdb = {
384 .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT, 412 .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
385}; 413};
386 414
415const struct iwl_cfg iwlax210_2ax_cfg_so_jf_a0 = {
416 .name = "Intel(R) Wireless-AC 9560 160MHz",
417 .fw_name_pre = IWL_22000_SO_A_JF_B_FW_PRE,
418 IWL_DEVICE_AX210,
419};
420
421const struct iwl_cfg iwlax210_2ax_cfg_so_hr_a0 = {
422 .name = "Intel(R) Wi-Fi 6 AX201 160MHz",
423 .fw_name_pre = IWL_22000_SO_A_HR_B_FW_PRE,
424 IWL_DEVICE_AX210,
425};
426
427const struct iwl_cfg iwlax210_2ax_cfg_so_gf_a0 = {
428 .name = "Intel(R) Wi-Fi 7 AX211 160MHz",
429 .fw_name_pre = IWL_22000_SO_A_GF_A_FW_PRE,
430 IWL_DEVICE_AX210,
431};
432
433const struct iwl_cfg iwlax210_2ax_cfg_ty_gf_a0 = {
434 .name = "Intel(R) Wi-Fi 7 AX210 160MHz",
435 .fw_name_pre = IWL_22000_TY_A_GF_A_FW_PRE,
436 IWL_DEVICE_AX210,
437};
438
387MODULE_FIRMWARE(IWL_22000_HR_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 439MODULE_FIRMWARE(IWL_22000_HR_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
388MODULE_FIRMWARE(IWL_22000_JF_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 440MODULE_FIRMWARE(IWL_22000_JF_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
389MODULE_FIRMWARE(IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 441MODULE_FIRMWARE(IWL_22000_HR_A_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
390MODULE_FIRMWARE(IWL_22000_HR_B_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 442MODULE_FIRMWARE(IWL_22000_HR_B_F0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
391MODULE_FIRMWARE(IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 443MODULE_FIRMWARE(IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
392MODULE_FIRMWARE(IWL_22000_JF_B0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
393MODULE_FIRMWARE(IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 444MODULE_FIRMWARE(IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
394MODULE_FIRMWARE(IWL_22000_SU_Z0_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 445MODULE_FIRMWARE(IWL_22000_SU_Z0_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
395MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 446MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
447MODULE_FIRMWARE(IWL_QNJ_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
396MODULE_FIRMWARE(IWL_CC_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 448MODULE_FIRMWARE(IWL_CC_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
449MODULE_FIRMWARE(IWL_22000_SO_A_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
450MODULE_FIRMWARE(IWL_22000_SO_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
451MODULE_FIRMWARE(IWL_22000_SO_A_GF_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
452MODULE_FIRMWARE(IWL_22000_TY_A_GF_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
index 113bcf7735a0..3225b64eb845 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
@@ -57,7 +57,7 @@
57#include "fw/file.h" 57#include "fw/file.h"
58 58
59/* Highest firmware API version supported */ 59/* Highest firmware API version supported */
60#define IWL9000_UCODE_API_MAX 43 60#define IWL9000_UCODE_API_MAX 46
61 61
62/* Lowest firmware API version supported */ 62/* Lowest firmware API version supported */
63#define IWL9000_UCODE_API_MIN 30 63#define IWL9000_UCODE_API_MIN 30
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/agn.h b/drivers/net/wireless/intel/iwlwifi/dvm/agn.h
index 431e13c6ee35..254a5ce52456 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/agn.h
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/agn.h
@@ -439,13 +439,10 @@ static inline void iwl_dvm_set_pmi(struct iwl_priv *priv, bool state)
439} 439}
440 440
441#ifdef CONFIG_IWLWIFI_DEBUGFS 441#ifdef CONFIG_IWLWIFI_DEBUGFS
442int iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir); 442void iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir);
443#else 443#else
444static inline int iwl_dbgfs_register(struct iwl_priv *priv, 444static inline void iwl_dbgfs_register(struct iwl_priv *priv,
445 struct dentry *dbgfs_dir) 445 struct dentry *dbgfs_dir) { }
446{
447 return 0;
448}
449#endif /* CONFIG_IWLWIFI_DEBUGFS */ 446#endif /* CONFIG_IWLWIFI_DEBUGFS */
450 447
451#ifdef CONFIG_IWLWIFI_DEBUG 448#ifdef CONFIG_IWLWIFI_DEBUG
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c
index 3d2e44a642de..d4b19673b06a 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c
@@ -3,6 +3,7 @@
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
6 * Copyright (C) 2018 Intel Corporation
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 9 * it under the terms of version 2 of the GNU General Public License as
@@ -36,31 +37,8 @@
36 37
37/* create and remove of files */ 38/* create and remove of files */
38#define DEBUGFS_ADD_FILE(name, parent, mode) do { \ 39#define DEBUGFS_ADD_FILE(name, parent, mode) do { \
39 if (!debugfs_create_file(#name, mode, parent, priv, \ 40 debugfs_create_file(#name, mode, parent, priv, \
40 &iwl_dbgfs_##name##_ops)) \ 41 &iwl_dbgfs_##name##_ops); \
41 goto err; \
42} while (0)
43
44#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \
45 struct dentry *__tmp; \
46 __tmp = debugfs_create_bool(#name, 0600, parent, ptr); \
47 if (IS_ERR(__tmp) || !__tmp) \
48 goto err; \
49} while (0)
50
51#define DEBUGFS_ADD_X32(name, parent, ptr) do { \
52 struct dentry *__tmp; \
53 __tmp = debugfs_create_x32(#name, 0600, parent, ptr); \
54 if (IS_ERR(__tmp) || !__tmp) \
55 goto err; \
56} while (0)
57
58#define DEBUGFS_ADD_U32(name, parent, ptr, mode) do { \
59 struct dentry *__tmp; \
60 __tmp = debugfs_create_u32(#name, mode, \
61 parent, ptr); \
62 if (IS_ERR(__tmp) || !__tmp) \
63 goto err; \
64} while (0) 42} while (0)
65 43
66/* file operation */ 44/* file operation */
@@ -2238,7 +2216,7 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file,
2238 buf_size = min(count, sizeof(buf) - 1); 2216 buf_size = min(count, sizeof(buf) - 1);
2239 if (copy_from_user(buf, user_buf, buf_size)) 2217 if (copy_from_user(buf, user_buf, buf_size))
2240 return -EFAULT; 2218 return -EFAULT;
2241 if (sscanf(buf, "%d", &event_log_flag) != 1) 2219 if (sscanf(buf, "%u", &event_log_flag) != 1)
2242 return -EFAULT; 2220 return -EFAULT;
2243 if (event_log_flag == 1) 2221 if (event_log_flag == 1)
2244 iwl_dump_nic_event_log(priv, true, NULL); 2222 iwl_dump_nic_event_log(priv, true, NULL);
@@ -2347,21 +2325,15 @@ DEBUGFS_READ_WRITE_FILE_OPS(calib_disabled);
2347 * Create the debugfs files and directories 2325 * Create the debugfs files and directories
2348 * 2326 *
2349 */ 2327 */
2350int iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir) 2328void iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir)
2351{ 2329{
2352 struct dentry *dir_data, *dir_rf, *dir_debug; 2330 struct dentry *dir_data, *dir_rf, *dir_debug;
2353 2331
2354 priv->debugfs_dir = dbgfs_dir; 2332 priv->debugfs_dir = dbgfs_dir;
2355 2333
2356 dir_data = debugfs_create_dir("data", dbgfs_dir); 2334 dir_data = debugfs_create_dir("data", dbgfs_dir);
2357 if (!dir_data)
2358 goto err;
2359 dir_rf = debugfs_create_dir("rf", dbgfs_dir); 2335 dir_rf = debugfs_create_dir("rf", dbgfs_dir);
2360 if (!dir_rf)
2361 goto err;
2362 dir_debug = debugfs_create_dir("debug", dbgfs_dir); 2336 dir_debug = debugfs_create_dir("debug", dbgfs_dir);
2363 if (!dir_debug)
2364 goto err;
2365 2337
2366 DEBUGFS_ADD_FILE(nvm, dir_data, 0400); 2338 DEBUGFS_ADD_FILE(nvm, dir_data, 0400);
2367 DEBUGFS_ADD_FILE(sram, dir_data, 0600); 2339 DEBUGFS_ADD_FILE(sram, dir_data, 0600);
@@ -2421,13 +2393,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir)
2421 2393
2422 snprintf(buf, 100, "../../%pd2", dev_dir); 2394 snprintf(buf, 100, "../../%pd2", dev_dir);
2423 2395
2424 if (!debugfs_create_symlink("iwlwifi", mac80211_dir, buf)) 2396 debugfs_create_symlink("iwlwifi", mac80211_dir, buf);
2425 goto err;
2426 } 2397 }
2427
2428 return 0;
2429
2430err:
2431 IWL_ERR(priv, "failed to create the dvm debugfs entries\n");
2432 return -ENOMEM;
2433} 2398}
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
index bd3c3b921d4c..7c68a86ed9e1 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c
@@ -1509,13 +1509,10 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1509 if (iwlagn_mac_setup_register(priv, &fw->ucode_capa)) 1509 if (iwlagn_mac_setup_register(priv, &fw->ucode_capa))
1510 goto out_destroy_workqueue; 1510 goto out_destroy_workqueue;
1511 1511
1512 if (iwl_dbgfs_register(priv, dbgfs_dir)) 1512 iwl_dbgfs_register(priv, dbgfs_dir);
1513 goto out_mac80211_unregister;
1514 1513
1515 return op_mode; 1514 return op_mode;
1516 1515
1517out_mac80211_unregister:
1518 iwlagn_mac_unregister(priv);
1519out_destroy_workqueue: 1516out_destroy_workqueue:
1520 iwl_tt_exit(priv); 1517 iwl_tt_exit(priv);
1521 iwl_cancel_deferred_work(priv); 1518 iwl_cancel_deferred_work(priv);
@@ -1881,7 +1878,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
1881 return pos; 1878 return pos;
1882 } 1879 }
1883 1880
1884 if (!(iwl_have_debug_level(IWL_DL_FW_ERRORS)) && !full_log) 1881 if (!(iwl_have_debug_level(IWL_DL_FW)) && !full_log)
1885 size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) 1882 size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES)
1886 ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size; 1883 ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size;
1887 IWL_ERR(priv, "Start IWL Event Log Dump: display last %u entries\n", 1884 IWL_ERR(priv, "Start IWL Event Log Dump: display last %u entries\n",
@@ -1897,7 +1894,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
1897 if (!*buf) 1894 if (!*buf)
1898 return -ENOMEM; 1895 return -ENOMEM;
1899 } 1896 }
1900 if (iwl_have_debug_level(IWL_DL_FW_ERRORS) || full_log) { 1897 if (iwl_have_debug_level(IWL_DL_FW) || full_log) {
1901 /* 1898 /*
1902 * if uCode has wrapped back to top of log, 1899 * if uCode has wrapped back to top of log,
1903 * start at the oldest entry, 1900 * start at the oldest entry,
@@ -1927,7 +1924,7 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
1927 unsigned int reload_msec; 1924 unsigned int reload_msec;
1928 unsigned long reload_jiffies; 1925 unsigned long reload_jiffies;
1929 1926
1930 if (iwl_have_debug_level(IWL_DL_FW_ERRORS)) 1927 if (iwl_have_debug_level(IWL_DL_FW))
1931 iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS); 1928 iwl_print_rx_config_cmd(priv, IWL_RXON_CTX_BSS);
1932 1929
1933 /* uCode is no longer loaded. */ 1930 /* uCode is no longer loaded. */
@@ -1965,12 +1962,12 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
1965 1962
1966 if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { 1963 if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
1967 if (iwlwifi_mod_params.fw_restart) { 1964 if (iwlwifi_mod_params.fw_restart) {
1968 IWL_DEBUG_FW_ERRORS(priv, 1965 IWL_DEBUG_FW(priv,
1969 "Restarting adapter due to uCode error.\n"); 1966 "Restarting adapter due to uCode error.\n");
1970 queue_work(priv->workqueue, &priv->restart); 1967 queue_work(priv->workqueue, &priv->restart);
1971 } else 1968 } else
1972 IWL_DEBUG_FW_ERRORS(priv, 1969 IWL_DEBUG_FW(priv,
1973 "Detected FW error, but not restarting\n"); 1970 "Detected FW error, but not restarting\n");
1974 } 1971 }
1975} 1972}
1976 1973
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rx.c b/drivers/net/wireless/intel/iwlwifi/dvm/rx.c
index 6f17a5e24e82..e224b23f0ba8 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/rx.c
@@ -2,6 +2,7 @@
2 * 2 *
3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * Copyright(c) 2015 Intel Deutschland GmbH 4 * Copyright(c) 2015 Intel Deutschland GmbH
5 * Copyright(c) 2018 Intel Corporation
5 * 6 *
6 * Portions of this file are derived from the ipw3945 project, as well 7 * Portions of this file are derived from the ipw3945 project, as well
7 * as portionhelp of the ieee80211 subsystem header files. 8 * as portionhelp of the ieee80211 subsystem header files.
@@ -592,7 +593,7 @@ static int iwlagn_set_decrypted_flag(struct iwl_priv *priv,
592 if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == 593 if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
593 RX_RES_STATUS_BAD_KEY_TTAK) 594 RX_RES_STATUS_BAD_KEY_TTAK)
594 break; 595 break;
595 596 /* fall through */
596 case RX_RES_STATUS_SEC_TYPE_WEP: 597 case RX_RES_STATUS_SEC_TYPE_WEP:
597 if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == 598 if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
598 RX_RES_STATUS_BAD_ICV_MIC) { 599 RX_RES_STATUS_BAD_ICV_MIC) {
@@ -601,6 +602,7 @@ static int iwlagn_set_decrypted_flag(struct iwl_priv *priv,
601 IWL_DEBUG_RX(priv, "Packet destroyed\n"); 602 IWL_DEBUG_RX(priv, "Packet destroyed\n");
602 return -1; 603 return -1;
603 } 604 }
605 /* fall through */
604 case RX_RES_STATUS_SEC_TYPE_CCMP: 606 case RX_RES_STATUS_SEC_TYPE_CCMP:
605 if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) == 607 if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
606 RX_RES_STATUS_DECRYPT_OK) { 608 RX_RES_STATUS_DECRYPT_OK) {
@@ -729,7 +731,7 @@ static u32 iwlagn_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
729 decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK; 731 decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK;
730 break; 732 break;
731 } 733 }
732 /* fall through if TTAK OK */ 734 /* fall through */
733 default: 735 default:
734 if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK)) 736 if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK))
735 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC; 737 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/scan.c b/drivers/net/wireless/intel/iwlwifi/dvm/scan.c
index 8d7aafb4d9e9..f190f7beb3a8 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/scan.c
@@ -3,6 +3,7 @@
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
6 * Copyright(c) 2018 Intel Corporation
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 9 * it under the terms of version 2 of the GNU General Public License as
@@ -418,7 +419,7 @@ static u16 iwl_limit_dwell(struct iwl_priv *priv, u16 dwell_time)
418 limit = (limits[1] * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; 419 limit = (limits[1] * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
419 limit /= 2; 420 limit /= 2;
420 dwell_time = min(limit, dwell_time); 421 dwell_time = min(limit, dwell_time);
421 /* fall through to limit further */ 422 /* fall through */
422 case 1: 423 case 1:
423 limit = (limits[0] * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; 424 limit = (limits[0] * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
424 limit /= n_active; 425 limit /= n_active;
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
index 32d000cffe9f..405038ce98d6 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2017 Intel Deutschland GmbH 8 * Copyright(c) 2017 Intel Deutschland GmbH
9 * Copyright (C) 2019 Intel Corporation
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 12 * it under the terms of version 2 of the GNU General Public License as
@@ -26,6 +27,7 @@
26 * BSD LICENSE 27 * BSD LICENSE
27 * 28 *
28 * Copyright(c) 2017 Intel Deutschland GmbH 29 * Copyright(c) 2017 Intel Deutschland GmbH
30 * Copyright (C) 2019 Intel Corporation
29 * All rights reserved. 31 * All rights reserved.
30 * 32 *
31 * Redistribution and use in source and binary forms, with or without 33 * Redistribution and use in source and binary forms, with or without
@@ -205,3 +207,33 @@ out:
205 return dflt_pwr_limit; 207 return dflt_pwr_limit;
206} 208}
207IWL_EXPORT_SYMBOL(iwl_acpi_get_pwr_limit); 209IWL_EXPORT_SYMBOL(iwl_acpi_get_pwr_limit);
210
211int iwl_acpi_get_eckv(struct device *dev, u32 *extl_clk)
212{
213 union acpi_object *wifi_pkg, *data;
214 int ret;
215
216 data = iwl_acpi_get_object(dev, ACPI_ECKV_METHOD);
217 if (IS_ERR(data))
218 return PTR_ERR(data);
219
220 wifi_pkg = iwl_acpi_get_wifi_pkg(dev, data, ACPI_ECKV_WIFI_DATA_SIZE);
221 if (IS_ERR(wifi_pkg)) {
222 ret = PTR_ERR(wifi_pkg);
223 goto out_free;
224 }
225
226 if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) {
227 ret = -EINVAL;
228 goto out_free;
229 }
230
231 *extl_clk = wifi_pkg->package.elements[1].integer.value;
232
233 ret = 0;
234
235out_free:
236 kfree(data);
237 return ret;
238}
239IWL_EXPORT_SYMBOL(iwl_acpi_get_eckv);
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
index 7492dfb6729b..f5704e16643f 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
@@ -6,7 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2017 Intel Deutschland GmbH 8 * Copyright(c) 2017 Intel Deutschland GmbH
9 * Copyright(c) 2018 Intel Corporation 9 * Copyright(c) 2018 - 2019 Intel Corporation
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 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 12 * it under the terms of version 2 of the GNU General Public License as
@@ -27,7 +27,7 @@
27 * BSD LICENSE 27 * BSD LICENSE
28 * 28 *
29 * Copyright(c) 2017 Intel Deutschland GmbH 29 * Copyright(c) 2017 Intel Deutschland GmbH
30 * Copyright(c) 2018 Intel Corporation 30 * Copyright(c) 2018 - 2019 Intel Corporation
31 * All rights reserved. 31 * All rights reserved.
32 * 32 *
33 * Redistribution and use in source and binary forms, with or without 33 * Redistribution and use in source and binary forms, with or without
@@ -67,6 +67,7 @@
67#define ACPI_WGDS_METHOD "WGDS" 67#define ACPI_WGDS_METHOD "WGDS"
68#define ACPI_WRDD_METHOD "WRDD" 68#define ACPI_WRDD_METHOD "WRDD"
69#define ACPI_SPLC_METHOD "SPLC" 69#define ACPI_SPLC_METHOD "SPLC"
70#define ACPI_ECKV_METHOD "ECKV"
70 71
71#define ACPI_WIFI_DOMAIN (0x07) 72#define ACPI_WIFI_DOMAIN (0x07)
72 73
@@ -86,6 +87,7 @@
86#define ACPI_WGDS_WIFI_DATA_SIZE 19 87#define ACPI_WGDS_WIFI_DATA_SIZE 19
87#define ACPI_WRDD_WIFI_DATA_SIZE 2 88#define ACPI_WRDD_WIFI_DATA_SIZE 2
88#define ACPI_SPLC_WIFI_DATA_SIZE 2 89#define ACPI_SPLC_WIFI_DATA_SIZE 2
90#define ACPI_ECKV_WIFI_DATA_SIZE 2
89 91
90#define ACPI_WGDS_NUM_BANDS 2 92#define ACPI_WGDS_NUM_BANDS 2
91#define ACPI_WGDS_TABLE_SIZE 3 93#define ACPI_WGDS_TABLE_SIZE 3
@@ -109,6 +111,17 @@ int iwl_acpi_get_mcc(struct device *dev, char *mcc);
109 111
110u64 iwl_acpi_get_pwr_limit(struct device *dev); 112u64 iwl_acpi_get_pwr_limit(struct device *dev);
111 113
114/*
115 * iwl_acpi_get_eckv - read external clock validation from ACPI, if available
116 *
117 * @dev: the struct device
118 * @extl_clk: output var (2 bytes) that will get the clk indication.
119 *
120 * This function tries to read the external clock indication
121 * from ACPI if available.
122 */
123int iwl_acpi_get_eckv(struct device *dev, u32 *extl_clk);
124
112#else /* CONFIG_ACPI */ 125#else /* CONFIG_ACPI */
113 126
114static inline void *iwl_acpi_get_object(struct device *dev, acpi_string method) 127static inline void *iwl_acpi_get_object(struct device *dev, acpi_string method)
@@ -133,5 +146,10 @@ static inline u64 iwl_acpi_get_pwr_limit(struct device *dev)
133 return 0; 146 return 0;
134} 147}
135 148
149static inline int iwl_acpi_get_eckv(struct device *dev, u32 *extl_clk)
150{
151 return -ENOENT;
152}
153
136#endif /* CONFIG_ACPI */ 154#endif /* CONFIG_ACPI */
137#endif /* __iwl_fw_acpi__ */ 155#endif /* __iwl_fw_acpi__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h b/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h
index 08d3d8a190f6..df1bd0d2450e 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/alive.h
@@ -96,14 +96,7 @@ enum {
96 96
97#define IWL_ALIVE_FLG_RFKILL BIT(0) 97#define IWL_ALIVE_FLG_RFKILL BIT(0)
98 98
99struct iwl_lmac_alive { 99struct iwl_lmac_debug_addrs {
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;
107 __le32 error_event_table_ptr; /* SRAM address for error log */ 100 __le32 error_event_table_ptr; /* SRAM address for error log */
108 __le32 log_event_table_ptr; /* SRAM address for LMAC event log */ 101 __le32 log_event_table_ptr; /* SRAM address for LMAC event log */
109 __le32 cpu_register_ptr; 102 __le32 cpu_register_ptr;
@@ -112,13 +105,28 @@ struct iwl_lmac_alive {
112 __le32 scd_base_ptr; /* SRAM address for SCD */ 105 __le32 scd_base_ptr; /* SRAM address for SCD */
113 __le32 st_fwrd_addr; /* pointer to Store and forward */ 106 __le32 st_fwrd_addr; /* pointer to Store and forward */
114 __le32 st_fwrd_size; 107 __le32 st_fwrd_size;
108} __packed; /* UCODE_DEBUG_ADDRS_API_S_VER_2 */
109
110struct iwl_lmac_alive {
111 __le32 ucode_major;
112 __le32 ucode_minor;
113 u8 ver_subtype;
114 u8 ver_type;
115 u8 mac;
116 u8 opt;
117 __le32 timestamp;
118 struct iwl_lmac_debug_addrs dbg_ptrs;
115} __packed; /* UCODE_ALIVE_NTFY_API_S_VER_3 */ 119} __packed; /* UCODE_ALIVE_NTFY_API_S_VER_3 */
116 120
121struct iwl_umac_debug_addrs {
122 __le32 error_info_addr; /* SRAM address for UMAC error log */
123 __le32 dbg_print_buff_addr;
124} __packed; /* UMAC_DEBUG_ADDRS_API_S_VER_1 */
125
117struct iwl_umac_alive { 126struct iwl_umac_alive {
118 __le32 umac_major; /* UMAC version: major */ 127 __le32 umac_major; /* UMAC version: major */
119 __le32 umac_minor; /* UMAC version: minor */ 128 __le32 umac_minor; /* UMAC version: minor */
120 __le32 error_info_addr; /* SRAM address for UMAC error log */ 129 struct iwl_umac_debug_addrs dbg_ptrs;
121 __le32 dbg_print_buff_addr;
122} __packed; /* UMAC_ALIVE_DATA_API_S_VER_2 */ 130} __packed; /* UMAC_ALIVE_DATA_API_S_VER_2 */
123 131
124struct mvm_alive_resp_v3 { 132struct mvm_alive_resp_v3 {
@@ -189,4 +197,24 @@ struct iwl_card_state_notif {
189 __le32 flags; 197 __le32 flags;
190} __packed; /* CARD_STATE_NTFY_API_S_VER_1 */ 198} __packed; /* CARD_STATE_NTFY_API_S_VER_1 */
191 199
200/**
201 * enum iwl_error_recovery_flags - flags for error recovery cmd
202 * @ERROR_RECOVERY_UPDATE_DB: update db from blob sent
203 * @ERROR_RECOVERY_END_OF_RECOVERY: end of recovery
204 */
205enum iwl_error_recovery_flags {
206 ERROR_RECOVERY_UPDATE_DB = BIT(0),
207 ERROR_RECOVERY_END_OF_RECOVERY = BIT(1),
208};
209
210/**
211 * struct iwl_fw_error_recovery_cmd - recovery cmd sent upon assert
212 * @flags: &enum iwl_error_recovery_flags
213 * @buf_size: db buffer size in bytes
214 */
215struct iwl_fw_error_recovery_cmd {
216 __le32 flags;
217 __le32 buf_size;
218} __packed; /* ERROR_RECOVERY_CMD_HDR_API_S_VER_1 */
219
192#endif /* __iwl_fw_api_alive_h__ */ 220#endif /* __iwl_fw_api_alive_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
index 0290b333d860..4d2274bcc0b5 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
@@ -643,6 +643,11 @@ enum iwl_system_subcmd_ids {
643 * @INIT_EXTENDED_CFG_CMD: &struct iwl_init_extended_cfg_cmd 643 * @INIT_EXTENDED_CFG_CMD: &struct iwl_init_extended_cfg_cmd
644 */ 644 */
645 INIT_EXTENDED_CFG_CMD = 0x03, 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#endif /* __iwl_fw_api_commands_h__ */ 653#endif /* __iwl_fw_api_commands_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
index ab82b7a67967..33858787817b 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/dbg-tlv.h
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright (C) 2018 Intel Corporation 8 * Copyright (C) 2018 - 2019 Intel Corporation
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -25,7 +25,7 @@
25 * 25 *
26 * BSD LICENSE 26 * BSD LICENSE
27 * 27 *
28 * Copyright (C) 2018 Intel Corporation 28 * Copyright (C) 2018 - 2019 Intel Corporation
29 * All rights reserved. 29 * All rights reserved.
30 * 30 *
31 * Redistribution and use in source and binary forms, with or without 31 * Redistribution and use in source and binary forms, with or without
@@ -70,7 +70,7 @@ struct iwl_fw_ini_header {
70 __le32 tlv_version; 70 __le32 tlv_version;
71 __le32 apply_point; 71 __le32 apply_point;
72 u8 data[]; 72 u8 data[];
73} __packed; /* FW_INI_HEADER_TLV_S */ 73} __packed; /* FW_DEBUG_TLV_HEADER_S */
74 74
75/** 75/**
76 * struct iwl_fw_ini_allocation_tlv - (IWL_FW_INI_TLV_TYPE_BUFFER_ALLOCATION) 76 * struct iwl_fw_ini_allocation_tlv - (IWL_FW_INI_TLV_TYPE_BUFFER_ALLOCATION)
@@ -92,7 +92,7 @@ struct iwl_fw_ini_allocation_tlv {
92 __le32 size; 92 __le32 size;
93 __le32 max_fragments; 93 __le32 max_fragments;
94 __le32 min_frag_size; 94 __le32 min_frag_size;
95} __packed; /* FW_INI_BUFFER_ALLOCATION_TLV_S_VER_1 */ 95} __packed; /* FW_DEBUG_TLV_BUFFER_ALLOCATION_TLV_S_VER_1 */
96 96
97/** 97/**
98 * struct iwl_fw_ini_hcmd (IWL_FW_INI_TLV_TYPE_HCMD) 98 * struct iwl_fw_ini_hcmd (IWL_FW_INI_TLV_TYPE_HCMD)
@@ -108,7 +108,7 @@ struct iwl_fw_ini_hcmd {
108 u8 group; 108 u8 group;
109 __le16 padding; 109 __le16 padding;
110 u8 data[0]; 110 u8 data[0];
111} __packed; /* FW_INI_HCMD_S */ 111} __packed; /* FW_DEBUG_TLV_HCMD_DATA_S */
112 112
113/** 113/**
114 * struct iwl_fw_ini_hcmd_tlv 114 * struct iwl_fw_ini_hcmd_tlv
@@ -118,7 +118,7 @@ struct iwl_fw_ini_hcmd {
118struct iwl_fw_ini_hcmd_tlv { 118struct iwl_fw_ini_hcmd_tlv {
119 struct iwl_fw_ini_header header; 119 struct iwl_fw_ini_header header;
120 struct iwl_fw_ini_hcmd hcmd; 120 struct iwl_fw_ini_hcmd hcmd;
121} __packed; /* FW_INI_HCMD_TLV_S_VER_1 */ 121} __packed; /* FW_DEBUG_TLV_HCMD_S_VER_1 */
122 122
123/* 123/*
124 * struct iwl_fw_ini_debug_flow_tlv (IWL_FW_INI_TLV_TYPE_DEBUG_FLOW) 124 * struct iwl_fw_ini_debug_flow_tlv (IWL_FW_INI_TLV_TYPE_DEBUG_FLOW)
@@ -129,20 +129,50 @@ struct iwl_fw_ini_hcmd_tlv {
129struct iwl_fw_ini_debug_flow_tlv { 129struct iwl_fw_ini_debug_flow_tlv {
130 struct iwl_fw_ini_header header; 130 struct iwl_fw_ini_header header;
131 __le32 debug_flow_cfg; 131 __le32 debug_flow_cfg;
132} __packed; /* FW_INI_DEBUG_FLOW_TLV_S_VER_1 */ 132} __packed; /* FW_DEBUG_TLV_FLOW_TLV_S_VER_1 */
133 133
134#define IWL_FW_INI_MAX_REGION_ID 20 134#define IWL_FW_INI_MAX_REGION_ID 64
135#define IWL_FW_INI_MAX_NAME 32 135#define IWL_FW_INI_MAX_NAME 32
136
137/**
138 * struct iwl_fw_ini_region_cfg_internal - meta data of internal memory region
139 * @num_of_range: the amount of ranges in the region
140 * @range_data_size: size of the data to read per range, in bytes.
141 */
142struct iwl_fw_ini_region_cfg_internal {
143 __le32 num_of_ranges;
144 __le32 range_data_size;
145} __packed; /* FW_DEBUG_TLV_REGION_NIC_INTERNAL_RANGES_S */
146
147/**
148 * struct iwl_fw_ini_region_cfg_fifos - meta data of fifos region
149 * @fid1: fifo id 1 - bitmap of lmac tx/rx fifos to include in the region
150 * @fid2: fifo id 2 - bitmap of umac rx fifos to include in the region.
151 * It is unused for tx.
152 * @num_of_registers: number of prph registers in the region, each register is
153 * 4 bytes size.
154 * @header_only: none zero value indicates that this region does not include
155 * fifo data and includes only the given registers.
156 */
157struct iwl_fw_ini_region_cfg_fifos {
158 __le32 fid1;
159 __le32 fid2;
160 __le32 num_of_registers;
161 __le32 header_only;
162} __packed; /* FW_DEBUG_TLV_REGION_FIFOS_S */
163
136/** 164/**
137 * struct iwl_fw_ini_region_cfg 165 * struct iwl_fw_ini_region_cfg
138 * @region_id: ID of this dump configuration 166 * @region_id: ID of this dump configuration
139 * @region_type: &enum iwl_fw_ini_region_type 167 * @region_type: &enum iwl_fw_ini_region_type
140 * @num_regions: amount of regions in the address array. 168 * @num_regions: amount of regions in the address array.
141 * @allocation_id: For DRAM type field substitutes for allocation_id.
142 * @name_len: name length 169 * @name_len: name length
143 * @name: file name to use for this region 170 * @name: file name to use for this region
144 * @size: size of the data, in bytes.(unused for IWL_FW_INI_REGION_DRAM_BUFFER) 171 * @internal: used in case the region uses internal memory.
145 * @start_addr: array of addresses. (unused for IWL_FW_INI_REGION_DRAM_BUFFER) 172 * @allocation_id: For DRAM type field substitutes for allocation_id
173 * @fifos: used in case of fifos region.
174 * @offset: offset to use for each memory base address
175 * @start_addr: array of addresses.
146 */ 176 */
147struct iwl_fw_ini_region_cfg { 177struct iwl_fw_ini_region_cfg {
148 __le32 region_id; 178 __le32 region_id;
@@ -150,32 +180,38 @@ struct iwl_fw_ini_region_cfg {
150 __le32 name_len; 180 __le32 name_len;
151 u8 name[IWL_FW_INI_MAX_NAME]; 181 u8 name[IWL_FW_INI_MAX_NAME];
152 union { 182 union {
153 __le32 num_regions; 183 struct iwl_fw_ini_region_cfg_internal internal;
154 __le32 allocation_id; 184 __le32 allocation_id;
185 struct iwl_fw_ini_region_cfg_fifos fifos;
155 }; 186 };
156 __le32 size; 187 __le32 offset;
157 __le32 start_addr[]; 188 __le32 start_addr[];
158} __packed; /* FW_INI_REGION_CONFIG_S */ 189} __packed; /* FW_DEBUG_TLV_REGION_CONFIG_S */
159 190
160/** 191/**
161 * struct iwl_fw_ini_region_tlv - (IWL_FW_INI_TLV_TYPE_REGION_CFG) 192 * struct iwl_fw_ini_region_tlv - (IWL_FW_INI_TLV_TYPE_REGION_CFG)
162 * DUMP sections define IDs and triggers that use those IDs TLV 193 * DUMP sections define IDs and triggers that use those IDs TLV
163 * @header: header 194 * @header: header
164 * @num_regions: how many different region section and IDs are coming next 195 * @num_regions: how many different region section and IDs are coming next
165 * @iwl_fw_ini_dump dump_config: list of dump configurations 196 * @region_config: list of dump configurations
166 */ 197 */
167struct iwl_fw_ini_region_tlv { 198struct iwl_fw_ini_region_tlv {
168 struct iwl_fw_ini_header header; 199 struct iwl_fw_ini_header header;
169 __le32 num_regions; 200 __le32 num_regions;
170 struct iwl_fw_ini_region_cfg region_config[]; 201 struct iwl_fw_ini_region_cfg region_config[];
171} __packed; /* FW_INI_REGION_CFG_S */ 202} __packed; /* FW_DEBUG_TLV_REGIONS_S_VER_1 */
172 203
173/** 204/**
174 * struct iwl_fw_ini_trigger - (IWL_FW_INI_TLV_TYPE_DUMP_CFG) 205 * struct iwl_fw_ini_trigger - (IWL_FW_INI_TLV_TYPE_DUMP_CFG)
175 * Region sections define IDs and triggers that use those IDs TLV 206 * Region sections define IDs and triggers that use those IDs TLV
176 * 207 *
177 * @trigger_id: enum &iwl_fw_ini_tigger_id 208 * @trigger_id: enum &iwl_fw_ini_tigger_id
178 * @ignore_default: override FW TLV with binary TLV 209 * @override_trig: determines how apply trigger in case a trigger with the
210 * same id is already in use. Using the first 2 bytes:
211 * Byte 0: if 0, override trigger configuration, otherwise use the
212 * existing configuration.
213 * Byte 1: if 0, override trigger regions, otherwise append regions to
214 * existing trigger.
179 * @dump_delay: delay from trigger fire to dump, in usec 215 * @dump_delay: delay from trigger fire to dump, in usec
180 * @occurrences: max amount of times to be fired 216 * @occurrences: max amount of times to be fired
181 * @ignore_consec: ignore consecutive triggers, in usec 217 * @ignore_consec: ignore consecutive triggers, in usec
@@ -187,7 +223,7 @@ struct iwl_fw_ini_region_tlv {
187 */ 223 */
188struct iwl_fw_ini_trigger { 224struct iwl_fw_ini_trigger {
189 __le32 trigger_id; 225 __le32 trigger_id;
190 __le32 ignore_default; 226 __le32 override_trig;
191 __le32 dump_delay; 227 __le32 dump_delay;
192 __le32 occurrences; 228 __le32 occurrences;
193 __le32 ignore_consec; 229 __le32 ignore_consec;
@@ -196,7 +232,7 @@ struct iwl_fw_ini_trigger {
196 __le32 trigger_data; 232 __le32 trigger_data;
197 __le32 num_regions; 233 __le32 num_regions;
198 __le32 data[]; 234 __le32 data[];
199} __packed; /* FW_INI_TRIGGER_CONFIG_S */ 235} __packed; /* FW_TLV_DEBUG_TRIGGER_CONFIG_S */
200 236
201/** 237/**
202 * struct iwl_fw_ini_trigger_tlv - (IWL_FW_INI_TLV_TYPE_TRIGGERS_CFG) 238 * struct iwl_fw_ini_trigger_tlv - (IWL_FW_INI_TLV_TYPE_TRIGGERS_CFG)
@@ -210,20 +246,17 @@ struct iwl_fw_ini_trigger_tlv {
210 struct iwl_fw_ini_header header; 246 struct iwl_fw_ini_header header;
211 __le32 num_triggers; 247 __le32 num_triggers;
212 struct iwl_fw_ini_trigger trigger_config[]; 248 struct iwl_fw_ini_trigger trigger_config[];
213} __packed; /* FW_INI_TRIGGER_CFG_S */ 249} __packed; /* FW_TLV_DEBUG_TRIGGERS_S_VER_1 */
214 250
215/** 251/**
216 * enum iwl_fw_ini_trigger_id 252 * enum iwl_fw_ini_trigger_id
217 * @IWL_FW_TRIGGER_ID_FW_ASSERT: FW assert 253 * @IWL_FW_TRIGGER_ID_FW_ASSERT: FW assert
218 * @IWL_FW_TRIGGER_ID_FW_TFD_Q_HANG: TFD queue hang
219 * @IWL_FW_TRIGGER_ID_FW_HW_ERROR: HW assert 254 * @IWL_FW_TRIGGER_ID_FW_HW_ERROR: HW assert
220 * @IWL_FW_TRIGGER_ID_FW_TRIGGER_ERROR: FW error notification 255 * @IWL_FW_TRIGGER_ID_FW_TFD_Q_HANG: TFD queue hang
221 * @IWL_FW_TRIGGER_ID_FW_TRIGGER_WARNING: FW warning notification 256 * @IWL_FW_TRIGGER_ID_FW_DEBUG_HOST_TRIGGER: FW debug notification
222 * @IWL_FW_TRIGGER_ID_FW_TRIGGER_INFO: FW info notification 257 * @IWL_FW_TRIGGER_ID_FW_GENERIC_NOTIFOCATION: FW generic notification
223 * @IWL_FW_TRIGGER_ID_FW_TRIGGER_DEBUG: FW debug notification
224 * @IWL_FW_TRIGGER_ID_USER_TRIGGER: User trigger 258 * @IWL_FW_TRIGGER_ID_USER_TRIGGER: User trigger
225 * @IWL_FW_TRIGGER_ID_HOST_PEER_CLIENT_INACTIVITY: peer inactivity 259 * @IWL_FW_TRIGGER_ID_HOST_PEER_CLIENT_INACTIVITY: peer inactivity
226 * @FW_DEBUG_TLV_TRIGGER_ID_HOST_DID_INITIATED_EVENT: undefined
227 * @IWL_FW_TRIGGER_ID_HOST_TX_LATENCY_THRESHOLD_CROSSED: TX latency 260 * @IWL_FW_TRIGGER_ID_HOST_TX_LATENCY_THRESHOLD_CROSSED: TX latency
228 * threshold was crossed 261 * threshold was crossed
229 * @IWL_FW_TRIGGER_ID_HOST_TX_RESPONSE_STATUS_FAILED: TX failed 262 * @IWL_FW_TRIGGER_ID_HOST_TX_RESPONSE_STATUS_FAILED: TX failed
@@ -257,50 +290,53 @@ struct iwl_fw_ini_trigger_tlv {
257 * @IWL_FW_TRIGGER_ID_NUM: number of trigger IDs 290 * @IWL_FW_TRIGGER_ID_NUM: number of trigger IDs
258 */ 291 */
259enum iwl_fw_ini_trigger_id { 292enum iwl_fw_ini_trigger_id {
293 IWL_FW_TRIGGER_ID_INVALID = 0,
294
260 /* Errors triggers */ 295 /* Errors triggers */
261 IWL_FW_TRIGGER_ID_FW_ASSERT = 1, 296 IWL_FW_TRIGGER_ID_FW_ASSERT = 1,
262 IWL_FW_TRIGGER_ID_FW_TFD_Q_HANG = 2, 297 IWL_FW_TRIGGER_ID_FW_HW_ERROR = 2,
263 IWL_FW_TRIGGER_ID_FW_HW_ERROR = 3, 298 IWL_FW_TRIGGER_ID_FW_TFD_Q_HANG = 3,
264 /* Generic triggers */ 299
265 IWL_FW_TRIGGER_ID_FW_TRIGGER_ERROR = 4, 300 /* FW triggers */
266 IWL_FW_TRIGGER_ID_FW_TRIGGER_WARNING = 5, 301 IWL_FW_TRIGGER_ID_FW_DEBUG_HOST_TRIGGER = 4,
267 IWL_FW_TRIGGER_ID_FW_TRIGGER_INFO = 6, 302 IWL_FW_TRIGGER_ID_FW_GENERIC_NOTIFOCATION = 5,
268 IWL_FW_TRIGGER_ID_FW_TRIGGER_DEBUG = 7, 303
269 /* User Trigger */ 304 /* User trigger */
270 IWL_FW_TRIGGER_ID_USER_TRIGGER = 8, 305 IWL_FW_TRIGGER_ID_USER_TRIGGER = 6,
306
271 /* Host triggers */ 307 /* Host triggers */
272 IWL_FW_TRIGGER_ID_HOST_PEER_CLIENT_INACTIVITY = 9, 308 IWL_FW_TRIGGER_ID_HOST_PEER_CLIENT_INACTIVITY = 7,
273 IWL_FW_TRIGGER_ID_HOST_DID_INITIATED_EVENT = 10, 309 IWL_FW_TRIGGER_ID_HOST_TX_LATENCY_THRESHOLD_CROSSED = 8,
274 IWL_FW_TRIGGER_ID_HOST_TX_LATENCY_THRESHOLD_CROSSED = 11, 310 IWL_FW_TRIGGER_ID_HOST_TX_RESPONSE_STATUS_FAILED = 9,
275 IWL_FW_TRIGGER_ID_HOST_TX_RESPONSE_STATUS_FAILED = 12, 311 IWL_FW_TRIGGER_ID_HOST_OS_REQ_DEAUTH_PEER = 10,
276 IWL_FW_TRIGGER_ID_HOST_OS_REQ_DEAUTH_PEER = 13, 312 IWL_FW_TRIGGER_ID_HOST_STOP_GO_REQUEST = 11,
277 IWL_FW_TRIGGER_ID_HOST_STOP_GO_REQUEST = 14, 313 IWL_FW_TRIGGER_ID_HOST_START_GO_REQUEST = 12,
278 IWL_FW_TRIGGER_ID_HOST_START_GO_REQUEST = 15, 314 IWL_FW_TRIGGER_ID_HOST_JOIN_GROUP_REQUEST = 13,
279 IWL_FW_TRIGGER_ID_HOST_JOIN_GROUP_REQUEST = 16, 315 IWL_FW_TRIGGER_ID_HOST_SCAN_START = 14,
280 IWL_FW_TRIGGER_ID_HOST_SCAN_START = 17, 316 IWL_FW_TRIGGER_ID_HOST_SCAN_SUBMITTED = 15,
281 IWL_FW_TRIGGER_ID_HOST_SCAN_SUBITTED = 18, 317 IWL_FW_TRIGGER_ID_HOST_SCAN_PARAMS = 16,
282 IWL_FW_TRIGGER_ID_HOST_SCAN_PARAMS = 19, 318 IWL_FW_TRIGGER_ID_HOST_CHECK_FOR_HANG = 17,
283 IWL_FW_TRIGGER_ID_HOST_CHECK_FOR_HANG = 20, 319 IWL_FW_TRIGGER_ID_HOST_BAR_RECEIVED = 18,
284 IWL_FW_TRIGGER_ID_HOST_BAR_RECEIVED = 21, 320 IWL_FW_TRIGGER_ID_HOST_AGG_TX_RESPONSE_STATUS_FAILED = 19,
285 IWL_FW_TRIGGER_ID_HOST_AGG_TX_RESPONSE_STATUS_FAILED = 22, 321 IWL_FW_TRIGGER_ID_HOST_EAPOL_TX_RESPONSE_FAILED = 20,
286 IWL_FW_TRIGGER_ID_HOST_EAPOL_TX_RESPONSE_FAILED = 23, 322 IWL_FW_TRIGGER_ID_HOST_FAKE_TX_RESPONSE_SUSPECTED = 21,
287 IWL_FW_TRIGGER_ID_HOST_FAKE_TX_RESPONSE_SUSPECTED = 24, 323 IWL_FW_TRIGGER_ID_HOST_AUTH_REQ_FROM_ASSOC_CLIENT = 22,
288 IWL_FW_TRIGGER_ID_HOST_AUTH_REQ_FROM_ASSOC_CLIENT = 25, 324 IWL_FW_TRIGGER_ID_HOST_ROAM_COMPLETE = 23,
289 IWL_FW_TRIGGER_ID_HOST_ROAM_COMPLETE = 26, 325 IWL_FW_TRIGGER_ID_HOST_AUTH_ASSOC_FAST_FAILED = 24,
290 IWL_FW_TRIGGER_ID_HOST_AUTH_ASSOC_FAST_FAILED = 27, 326 IWL_FW_TRIGGER_ID_HOST_D3_START = 25,
291 IWL_FW_TRIGGER_ID_HOST_D3_START = 28, 327 IWL_FW_TRIGGER_ID_HOST_D3_END = 26,
292 IWL_FW_TRIGGER_ID_HOST_D3_END = 29, 328 IWL_FW_TRIGGER_ID_HOST_BSS_MISSED_BEACONS = 27,
293 IWL_FW_TRIGGER_ID_HOST_BSS_MISSED_BEACONS = 30, 329 IWL_FW_TRIGGER_ID_HOST_P2P_CLIENT_MISSED_BEACONS = 28,
294 IWL_FW_TRIGGER_ID_HOST_P2P_CLIENT_MISSED_BEACONS = 31, 330 IWL_FW_TRIGGER_ID_HOST_PEER_CLIENT_TX_FAILURES = 29,
295 IWL_FW_TRIGGER_ID_HOST_PEER_CLIENT_TX_FAILURES = 32, 331 IWL_FW_TRIGGER_ID_HOST_TX_WFD_ACTION_FRAME_FAILED = 30,
296 IWL_FW_TRIGGER_ID_HOST_TX_WFD_ACTION_FRAME_FAILED = 33, 332 IWL_FW_TRIGGER_ID_HOST_AUTH_ASSOC_FAILED = 31,
297 IWL_FW_TRIGGER_ID_HOST_AUTH_ASSOC_FAILED = 34, 333 IWL_FW_TRIGGER_ID_HOST_SCAN_COMPLETE = 32,
298 IWL_FW_TRIGGER_ID_HOST_SCAN_COMPLETE = 35, 334 IWL_FW_TRIGGER_ID_HOST_SCAN_ABORT = 33,
299 IWL_FW_TRIGGER_ID_HOST_SCAN_ABORT = 36, 335 IWL_FW_TRIGGER_ID_HOST_NIC_ALIVE = 34,
300 IWL_FW_TRIGGER_ID_HOST_NIC_ALIVE = 37, 336 IWL_FW_TRIGGER_ID_HOST_CHANNEL_SWITCH_COMPLETE = 35,
301 IWL_FW_TRIGGER_ID_HOST_CHANNEL_SWITCH_COMPLETE = 38, 337
302 IWL_FW_TRIGGER_ID_NUM, 338 IWL_FW_TRIGGER_ID_NUM,
303}; /* FW_INI_TRIGGER_ID_E_VER_1 */ 339}; /* FW_DEBUG_TLV_TRIGGER_ID_E_VER_1 */
304 340
305/** 341/**
306 * enum iwl_fw_ini_apply_point 342 * enum iwl_fw_ini_apply_point
@@ -320,7 +356,7 @@ enum iwl_fw_ini_apply_point {
320 IWL_FW_INI_APPLY_MISSED_BEACONS, 356 IWL_FW_INI_APPLY_MISSED_BEACONS,
321 IWL_FW_INI_APPLY_SCAN_COMPLETE, 357 IWL_FW_INI_APPLY_SCAN_COMPLETE,
322 IWL_FW_INI_APPLY_NUM, 358 IWL_FW_INI_APPLY_NUM,
323}; /* FW_INI_APPLY_POINT_E_VER_1 */ 359}; /* FW_DEBUG_TLV_APPLY_POINT_E_VER_1 */
324 360
325/** 361/**
326 * enum iwl_fw_ini_allocation_id 362 * enum iwl_fw_ini_allocation_id
@@ -340,7 +376,7 @@ enum iwl_fw_ini_allocation_id {
340 IWL_FW_INI_ALLOCATION_ID_SDFX, 376 IWL_FW_INI_ALLOCATION_ID_SDFX,
341 IWL_FW_INI_ALLOCATION_ID_FW_DUMP, 377 IWL_FW_INI_ALLOCATION_ID_FW_DUMP,
342 IWL_FW_INI_ALLOCATION_ID_USER_DEFINED, 378 IWL_FW_INI_ALLOCATION_ID_USER_DEFINED,
343}; /* FW_INI_ALLOCATION_ID_E_VER_1 */ 379}; /* FW_DEBUG_TLV_ALLOCATION_ID_E_VER_1 */
344 380
345/** 381/**
346 * enum iwl_fw_ini_buffer_location 382 * enum iwl_fw_ini_buffer_location
@@ -349,10 +385,10 @@ enum iwl_fw_ini_allocation_id {
349 * @IWL_FW_INI_LOCATION_DRAM_PATH: DRAM location 385 * @IWL_FW_INI_LOCATION_DRAM_PATH: DRAM location
350 */ 386 */
351enum iwl_fw_ini_buffer_location { 387enum iwl_fw_ini_buffer_location {
352 IWL_FW_INI_LOCATION_SRAM_INVALID, 388 IWL_FW_INI_LOCATION_INVALID,
353 IWL_FW_INI_LOCATION_SRAM_PATH, 389 IWL_FW_INI_LOCATION_SRAM_PATH,
354 IWL_FW_INI_LOCATION_DRAM_PATH, 390 IWL_FW_INI_LOCATION_DRAM_PATH,
355}; /* FW_INI_BUFFER_LOCATION_E_VER_1 */ 391}; /* FW_DEBUG_TLV_BUFFER_LOCATION_E_VER_1 */
356 392
357/** 393/**
358 * enum iwl_fw_ini_debug_flow 394 * enum iwl_fw_ini_debug_flow
@@ -364,7 +400,7 @@ enum iwl_fw_ini_debug_flow {
364 IWL_FW_INI_DEBUG_INVALID, 400 IWL_FW_INI_DEBUG_INVALID,
365 IWL_FW_INI_DEBUG_DBTR_FLOW, 401 IWL_FW_INI_DEBUG_DBTR_FLOW,
366 IWL_FW_INI_DEBUG_TB2DTF_FLOW, 402 IWL_FW_INI_DEBUG_TB2DTF_FLOW,
367}; /* FW_INI_DEBUG_FLOW_E_VER_1 */ 403}; /* FW_DEBUG_TLV_FLOW_E_VER_1 */
368 404
369/** 405/**
370 * enum iwl_fw_ini_region_type 406 * enum iwl_fw_ini_region_type
@@ -396,6 +432,6 @@ enum iwl_fw_ini_region_type {
396 IWL_FW_INI_REGION_PAGING, 432 IWL_FW_INI_REGION_PAGING,
397 IWL_FW_INI_REGION_CSR, 433 IWL_FW_INI_REGION_CSR,
398 IWL_FW_INI_REGION_NUM 434 IWL_FW_INI_REGION_NUM
399}; /* FW_INI_REGION_TYPE_E_VER_1*/ 435}; /* FW_DEBUG_TLV_REGION_TYPE_E_VER_1 */
400 436
401#endif 437#endif
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h
index 6da91ec0df55..5dddb21c1c4d 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/location.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/location.h
@@ -7,6 +7,7 @@
7 * 7 *
8 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 8 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
9 * Copyright (C) 2018 Intel Corporation 9 * Copyright (C) 2018 Intel Corporation
10 * Copyright (C) 2019 Intel Corporation
10 * 11 *
11 * This program is free software; you can redistribute it and/or modify 12 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -28,6 +29,7 @@
28 * 29 *
29 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 30 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
30 * Copyright (C) 2018 Intel Corporation 31 * Copyright (C) 2018 Intel Corporation
32 * Copyright (C) 2019 Intel Corporation
31 * All rights reserved. 33 * All rights reserved.
32 * 34 *
33 * Redistribution and use in source and binary forms, with or without 35 * Redistribution and use in source and binary forms, with or without
@@ -322,7 +324,7 @@ enum iwl_tof_location_query {
322}; 324};
323 325
324 /** 326 /**
325 * struct iwl_tof_range_req_ap_entry - AP configuration parameters 327 * struct iwl_tof_range_req_ap_entry_v2 - AP configuration parameters
326 * @channel_num: Current AP Channel 328 * @channel_num: Current AP Channel
327 * @bandwidth: Current AP Bandwidth. One of iwl_tof_bandwidth. 329 * @bandwidth: Current AP Bandwidth. One of iwl_tof_bandwidth.
328 * @tsf_delta_direction: TSF relatively to the subject AP 330 * @tsf_delta_direction: TSF relatively to the subject AP
@@ -355,7 +357,7 @@ enum iwl_tof_location_query {
355 * @notify_mcsi: &enum iwl_tof_mcsi_ntfy. 357 * @notify_mcsi: &enum iwl_tof_mcsi_ntfy.
356 * @reserved: For alignment and future use 358 * @reserved: For alignment and future use
357 */ 359 */
358struct iwl_tof_range_req_ap_entry { 360struct iwl_tof_range_req_ap_entry_v2 {
359 u8 channel_num; 361 u8 channel_num;
360 u8 bandwidth; 362 u8 bandwidth;
361 u8 tsf_delta_direction; 363 u8 tsf_delta_direction;
@@ -374,6 +376,62 @@ struct iwl_tof_range_req_ap_entry {
374 u8 algo_type; 376 u8 algo_type;
375 u8 notify_mcsi; 377 u8 notify_mcsi;
376 __le16 reserved; 378 __le16 reserved;
379} __packed; /* LOCATION_RANGE_REQ_AP_ENTRY_CMD_API_S_VER_2 */
380
381/**
382 * enum iwl_initiator_ap_flags - per responder FTM configuration flags
383 * @IWL_INITIATOR_AP_FLAGS_ASAP: Request for ASAP measurement.
384 * @IWL_INITIATOR_AP_FLAGS_LCI_REQUEST: Request for LCI information
385 * @IWL_INITIATOR_AP_FLAGS_CIVIC_REQUEST: Request for CIVIC information
386 * @IWL_INITIATOR_AP_FLAGS_DYN_ACK: Send HT/VHT ack for FTM frames. If not set,
387 * 20Mhz dup acks will be sent.
388 * @IWL_INITIATOR_AP_FLAGS_ALGO_LR: Use LR algo type for rtt calculation.
389 * Default algo type is ML.
390 * @IWL_INITIATOR_AP_FLAGS_ALGO_FFT: Use FFT algo type for rtt calculation.
391 * Default algo type is ML.
392 * @IWL_INITIATOR_AP_FLAGS_MCSI_REPORT: Send the MCSI for each FTM frame to the
393 * driver.
394 */
395enum iwl_initiator_ap_flags {
396 IWL_INITIATOR_AP_FLAGS_ASAP = BIT(1),
397 IWL_INITIATOR_AP_FLAGS_LCI_REQUEST = BIT(2),
398 IWL_INITIATOR_AP_FLAGS_CIVIC_REQUEST = BIT(3),
399 IWL_INITIATOR_AP_FLAGS_DYN_ACK = BIT(4),
400 IWL_INITIATOR_AP_FLAGS_ALGO_LR = BIT(5),
401 IWL_INITIATOR_AP_FLAGS_ALGO_FFT = BIT(6),
402 IWL_INITIATOR_AP_FLAGS_MCSI_REPORT = BIT(8),
403};
404
405/**
406 * struct iwl_tof_range_req_ap_entry - AP configuration parameters
407 * @initiator_ap_flags: see &enum iwl_initiator_ap_flags.
408 * @channel_num: AP Channel number
409 * @bandwidth: AP bandwidth. One of iwl_tof_bandwidth.
410 * @ctrl_ch_position: Coding of the control channel position relative to the
411 * center frequency, see iwl_mvm_get_ctrl_pos().
412 * @ftmr_max_retries: Max number of retries to send the FTMR in case of no
413 * reply from the AP.
414 * @bssid: AP's BSSID
415 * @burst_period: Recommended value to be sent to the AP. Measurement
416 * periodicity In units of 100ms. ignored if num_of_bursts_exp = 0
417 * @samples_per_burst: the number of FTMs pairs in single Burst (1-31);
418 * @num_of_bursts: Recommended value to be sent to the AP. 2s Exponent of
419 * the number of measurement iterations (min 2^0 = 1, max 2^14)
420 * @reserved: For alignment and future use
421 * @tsf_delta: not in use
422 */
423struct iwl_tof_range_req_ap_entry {
424 __le32 initiator_ap_flags;
425 u8 channel_num;
426 u8 bandwidth;
427 u8 ctrl_ch_position;
428 u8 ftmr_max_retries;
429 u8 bssid[ETH_ALEN];
430 __le16 burst_period;
431 u8 samples_per_burst;
432 u8 num_of_bursts;
433 __le16 reserved;
434 __le32 tsf_delta;
377} __packed; /* LOCATION_RANGE_REQ_AP_ENTRY_CMD_API_S_VER_3 */ 435} __packed; /* LOCATION_RANGE_REQ_AP_ENTRY_CMD_API_S_VER_3 */
378 436
379/** 437/**
@@ -403,7 +461,12 @@ enum iwl_tof_response_mode {
403 * @IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_A: use antenna A fo TX ACKs during FTM 461 * @IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_A: use antenna A fo TX ACKs during FTM
404 * @IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_B: use antenna B fo TX ACKs during FTM 462 * @IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_B: use antenna B fo TX ACKs during FTM
405 * @IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_C: use antenna C fo TX ACKs during FTM 463 * @IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_C: use antenna C fo TX ACKs during FTM
406 * @IWL_TOF_INITIATOR_FLAGS_MINDELTA_NO_PREF: no preference for minDeltaFTM 464 * @IWL_TOF_INITIATOR_FLAGS_MACADDR_RANDOM: use random mac address for FTM
465 * @IWL_TOF_INITIATOR_FLAGS_SPECIFIC_CALIB: use the specific calib value from
466 * the range request command
467 * @IWL_TOF_INITIATOR_FLAGS_COMMON_CALIB: use the common calib value from the
468 * ragne request command
469 * @IWL_TOF_INITIATOR_FLAGS_NON_ASAP_SUPPORT: support non-asap measurements
407 */ 470 */
408enum iwl_tof_initiator_flags { 471enum iwl_tof_initiator_flags {
409 IWL_TOF_INITIATOR_FLAGS_FAST_ALGO_DISABLED = BIT(0), 472 IWL_TOF_INITIATOR_FLAGS_FAST_ALGO_DISABLED = BIT(0),
@@ -413,14 +476,17 @@ enum iwl_tof_initiator_flags {
413 IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_A = BIT(4), 476 IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_A = BIT(4),
414 IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_B = BIT(5), 477 IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_B = BIT(5),
415 IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_C = BIT(6), 478 IWL_TOF_INITIATOR_FLAGS_TX_CHAIN_SEL_C = BIT(6),
416 IWL_TOF_INITIATOR_FLAGS_MINDELTA_NO_PREF = BIT(7), 479 IWL_TOF_INITIATOR_FLAGS_MACADDR_RANDOM = BIT(7),
480 IWL_TOF_INITIATOR_FLAGS_SPECIFIC_CALIB = BIT(15),
481 IWL_TOF_INITIATOR_FLAGS_COMMON_CALIB = BIT(16),
482 IWL_TOF_INITIATOR_FLAGS_NON_ASAP_SUPPORT = BIT(20),
417}; /* LOCATION_RANGE_REQ_CMD_API_S_VER_5 */ 483}; /* LOCATION_RANGE_REQ_CMD_API_S_VER_5 */
418 484
419#define IWL_MVM_TOF_MAX_APS 5 485#define IWL_MVM_TOF_MAX_APS 5
420#define IWL_MVM_TOF_MAX_TWO_SIDED_APS 5 486#define IWL_MVM_TOF_MAX_TWO_SIDED_APS 5
421 487
422/** 488/**
423 * struct iwl_tof_range_req_cmd - start measurement cmd 489 * struct iwl_tof_range_req_cmd_v5 - start measurement cmd
424 * @initiator_flags: see flags @ iwl_tof_initiator_flags 490 * @initiator_flags: see flags @ iwl_tof_initiator_flags
425 * @request_id: A Token incremented per request. The same Token will be 491 * @request_id: A Token incremented per request. The same Token will be
426 * sent back in the range response 492 * sent back in the range response
@@ -448,7 +514,7 @@ enum iwl_tof_initiator_flags {
448 * @specific_calib: The specific calib value to inject to this measurement calc 514 * @specific_calib: The specific calib value to inject to this measurement calc
449 * @ap: per-AP request data 515 * @ap: per-AP request data
450 */ 516 */
451struct iwl_tof_range_req_cmd { 517struct iwl_tof_range_req_cmd_v5 {
452 __le32 initiator_flags; 518 __le32 initiator_flags;
453 u8 request_id; 519 u8 request_id;
454 u8 initiator; 520 u8 initiator;
@@ -465,10 +531,42 @@ struct iwl_tof_range_req_cmd {
465 u8 ftm_tx_chains; 531 u8 ftm_tx_chains;
466 __le16 common_calib; 532 __le16 common_calib;
467 __le16 specific_calib; 533 __le16 specific_calib;
468 struct iwl_tof_range_req_ap_entry ap[IWL_MVM_TOF_MAX_APS]; 534 struct iwl_tof_range_req_ap_entry_v2 ap[IWL_MVM_TOF_MAX_APS];
469} __packed; 535} __packed;
470/* LOCATION_RANGE_REQ_CMD_API_S_VER_5 */ 536/* LOCATION_RANGE_REQ_CMD_API_S_VER_5 */
471 537
538/**
539 * struct iwl_tof_range_req_cmd - start measurement cmd
540 * @initiator_flags: see flags @ iwl_tof_initiator_flags
541 * @request_id: A Token incremented per request. The same Token will be
542 * sent back in the range response
543 * @num_of_ap: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS)
544 * @range_req_bssid: ranging request BSSID
545 * @macaddr_mask: Bits set to 0 shall be copied from the MAC address template.
546 * Bits set to 1 shall be randomized by the UMAC
547 * @macaddr_template: MAC address template to use for non-randomized bits
548 * @req_timeout_ms: Requested timeout of the response in units of milliseconds.
549 * This is the session time for completing the measurement.
550 * @tsf_mac_id: report the measurement start time for each ap in terms of the
551 * TSF of this mac id. 0xff to disable TSF reporting.
552 * @common_calib: The common calib value to inject to this measurement calc
553 * @specific_calib: The specific calib value to inject to this measurement calc
554 * @ap: per-AP request data, see &struct iwl_tof_range_req_ap_entry_v2.
555 */
556struct iwl_tof_range_req_cmd {
557 __le32 initiator_flags;
558 u8 request_id;
559 u8 num_of_ap;
560 u8 range_req_bssid[ETH_ALEN];
561 u8 macaddr_mask[ETH_ALEN];
562 u8 macaddr_template[ETH_ALEN];
563 __le32 req_timeout_ms;
564 __le32 tsf_mac_id;
565 __le16 common_calib;
566 __le16 specific_calib;
567 struct iwl_tof_range_req_ap_entry ap[IWL_MVM_TOF_MAX_APS];
568} __packed; /* LOCATION_RANGE_REQ_CMD_API_S_VER_7 */
569
472/* 570/*
473 * enum iwl_tof_range_request_status - status of the sent request 571 * enum iwl_tof_range_request_status - status of the sent request
474 * @IWL_TOF_RANGE_REQUEST_STATUS_SUCCESSFUL - FW successfully received the 572 * @IWL_TOF_RANGE_REQUEST_STATUS_SUCCESSFUL - FW successfully received the
@@ -528,7 +626,7 @@ enum iwl_tof_entry_status {
528}; /* LOCATION_RANGE_RSP_AP_ENTRY_NTFY_API_S_VER_2 */ 626}; /* LOCATION_RANGE_RSP_AP_ENTRY_NTFY_API_S_VER_2 */
529 627
530/** 628/**
531 * struct iwl_tof_range_rsp_ap_entry_ntfy - AP parameters (response) 629 * struct iwl_tof_range_rsp_ap_entry_ntfy_v3 - AP parameters (response)
532 * @bssid: BSSID of the AP 630 * @bssid: BSSID of the AP
533 * @measure_status: current APs measurement status, one of 631 * @measure_status: current APs measurement status, one of
534 * &enum iwl_tof_entry_status. 632 * &enum iwl_tof_entry_status.
@@ -555,7 +653,7 @@ enum iwl_tof_entry_status {
555 * @papd_calib_output: The result of the tof papd calibration that was injected 653 * @papd_calib_output: The result of the tof papd calibration that was injected
556 * into the algorithm. 654 * into the algorithm.
557 */ 655 */
558struct iwl_tof_range_rsp_ap_entry_ntfy { 656struct iwl_tof_range_rsp_ap_entry_ntfy_v3 {
559 u8 bssid[ETH_ALEN]; 657 u8 bssid[ETH_ALEN];
560 u8 measure_status; 658 u8 measure_status;
561 u8 measure_bw; 659 u8 measure_bw;
@@ -577,6 +675,59 @@ struct iwl_tof_range_rsp_ap_entry_ntfy {
577} __packed; /* LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_3 */ 675} __packed; /* LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_3 */
578 676
579/** 677/**
678 * struct iwl_tof_range_rsp_ap_entry_ntfy - AP parameters (response)
679 * @bssid: BSSID of the AP
680 * @measure_status: current APs measurement status, one of
681 * &enum iwl_tof_entry_status.
682 * @measure_bw: Current AP Bandwidth: 0 20MHz, 1 40MHz, 2 80MHz
683 * @rtt: The Round Trip Time that took for the last measurement for
684 * current AP [pSec]
685 * @rtt_variance: The Variance of the RTT values measured for current AP
686 * @rtt_spread: The Difference between the maximum and the minimum RTT
687 * values measured for current AP in the current session [pSec]
688 * @rssi: RSSI as uploaded in the Channel Estimation notification
689 * @rssi_spread: The Difference between the maximum and the minimum RSSI values
690 * measured for current AP in the current session
691 * @last_burst: 1 if no more FTM sessions are scheduled for this responder
692 * @refusal_period: refusal period in case of
693 * @IWL_TOF_ENTRY_RESPONDER_CANNOT_COLABORATE [sec]
694 * @timestamp: The GP2 Clock [usec] where Channel Estimation notification was
695 * uploaded by the LMAC
696 * @start_tsf: measurement start time in TSF of the mac specified in the range
697 * request
698 * @rx_rate_n_flags: rate and flags of the last FTM frame received from this
699 * responder
700 * @tx_rate_n_flags: rate and flags of the last ack sent to this responder
701 * @t2t3_initiator: as calculated from the algo in the initiator
702 * @t1t4_responder: as calculated from the algo in the responder
703 * @common_calib: Calib val that was used in for this AP measurement
704 * @specific_calib: val that was used in for this AP measurement
705 * @papd_calib_output: The result of the tof papd calibration that was injected
706 * into the algorithm.
707 */
708struct iwl_tof_range_rsp_ap_entry_ntfy {
709 u8 bssid[ETH_ALEN];
710 u8 measure_status;
711 u8 measure_bw;
712 __le32 rtt;
713 __le32 rtt_variance;
714 __le32 rtt_spread;
715 s8 rssi;
716 u8 rssi_spread;
717 u8 last_burst;
718 u8 refusal_period;
719 __le32 timestamp;
720 __le32 start_tsf;
721 __le32 rx_rate_n_flags;
722 __le32 tx_rate_n_flags;
723 __le32 t2t3_initiator;
724 __le32 t1t4_responder;
725 __le16 common_calib;
726 __le16 specific_calib;
727 __le32 papd_calib_output;
728} __packed; /* LOCATION_RANGE_RSP_AP_ETRY_NTFY_API_S_VER_4 */
729
730/**
580 * enum iwl_tof_response_status - tof response status 731 * enum iwl_tof_response_status - tof response status
581 * 732 *
582 * @IWL_TOF_RESPONSE_SUCCESS: successful range. 733 * @IWL_TOF_RESPONSE_SUCCESS: successful range.
@@ -593,7 +744,7 @@ enum iwl_tof_response_status {
593}; /* LOCATION_RNG_RSP_STATUS */ 744}; /* LOCATION_RNG_RSP_STATUS */
594 745
595/** 746/**
596 * struct iwl_tof_range_rsp_ntfy - ranging response notification 747 * struct iwl_tof_range_rsp_ntfy_v5 - ranging response notification
597 * @request_id: A Token ID of the corresponding Range request 748 * @request_id: A Token ID of the corresponding Range request
598 * @request_status: status of current measurement session, one of 749 * @request_status: status of current measurement session, one of
599 * &enum iwl_tof_response_status. 750 * &enum iwl_tof_response_status.
@@ -601,13 +752,29 @@ enum iwl_tof_response_status {
601 * @num_of_aps: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS) 752 * @num_of_aps: Number of APs to measure (error if > IWL_MVM_TOF_MAX_APS)
602 * @ap: per-AP data 753 * @ap: per-AP data
603 */ 754 */
604struct iwl_tof_range_rsp_ntfy { 755struct iwl_tof_range_rsp_ntfy_v5 {
605 u8 request_id; 756 u8 request_id;
606 u8 request_status; 757 u8 request_status;
607 u8 last_in_batch; 758 u8 last_in_batch;
608 u8 num_of_aps; 759 u8 num_of_aps;
760 struct iwl_tof_range_rsp_ap_entry_ntfy_v3 ap[IWL_MVM_TOF_MAX_APS];
761} __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_5 */
762
763/**
764 * struct iwl_tof_range_rsp_ntfy - ranging response notification
765 * @request_id: A Token ID of the corresponding Range request
766 * @num_of_aps: Number of APs results
767 * @last_report: 1 if no more FTM sessions are scheduled, 0 otherwise.
768 * @reserved: reserved
769 * @ap: per-AP data
770 */
771struct iwl_tof_range_rsp_ntfy {
772 u8 request_id;
773 u8 num_of_aps;
774 u8 last_report;
775 u8 reserved;
609 struct iwl_tof_range_rsp_ap_entry_ntfy ap[IWL_MVM_TOF_MAX_APS]; 776 struct iwl_tof_range_rsp_ap_entry_ntfy ap[IWL_MVM_TOF_MAX_APS];
610} __packed; 777} __packed; /* LOCATION_RANGE_RSP_NTFY_API_S_VER_6 */
611 778
612#define IWL_MVM_TOF_MCSI_BUF_SIZE (245) 779#define IWL_MVM_TOF_MCSI_BUF_SIZE (245)
613/** 780/**
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h
index ca49db786ed6..6b4d59daacd6 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/mac-cfg.h
@@ -74,6 +74,10 @@ enum iwl_mac_conf_subcmd_ids {
74 */ 74 */
75 LOW_LATENCY_CMD = 0x3, 75 LOW_LATENCY_CMD = 0x3,
76 /** 76 /**
77 * @CHANNEL_SWITCH_TIME_EVENT_CMD: &struct iwl_chan_switch_te_cmd
78 */
79 CHANNEL_SWITCH_TIME_EVENT_CMD = 0x4,
80 /**
77 * @PROBE_RESPONSE_DATA_NOTIF: &struct iwl_probe_resp_data_notif 81 * @PROBE_RESPONSE_DATA_NOTIF: &struct iwl_probe_resp_data_notif
78 */ 82 */
79 PROBE_RESPONSE_DATA_NOTIF = 0xFC, 83 PROBE_RESPONSE_DATA_NOTIF = 0xFC,
@@ -136,6 +140,29 @@ struct iwl_channel_switch_noa_notif {
136} __packed; /* CHANNEL_SWITCH_START_NTFY_API_S_VER_1 */ 140} __packed; /* CHANNEL_SWITCH_START_NTFY_API_S_VER_1 */
137 141
138/** 142/**
143 * struct iwl_chan_switch_te_cmd - Channel Switch Time Event command
144 *
145 * @mac_id: MAC ID for channel switch
146 * @action: action to perform, one of FW_CTXT_ACTION_*
147 * @tsf: beacon tsf
148 * @cs_count: channel switch count from CSA/eCSA IE
149 * @cs_delayed_bcn_count: if set to N (!= 0) GO/AP can delay N beacon intervals
150 * at the new channel after the channel switch, otherwise (N == 0) expect
151 * beacon right after the channel switch.
152 * @cs_mode: 1 - quiet, 0 - otherwise
153 * @reserved: reserved for alignment purposes
154 */
155struct iwl_chan_switch_te_cmd {
156 __le32 mac_id;
157 __le32 action;
158 __le32 tsf;
159 u8 cs_count;
160 u8 cs_delayed_bcn_count;
161 u8 cs_mode;
162 u8 reserved;
163} __packed; /* MAC_CHANNEL_SWITCH_TIME_EVENT_S_VER_2 */
164
165/**
139 * struct iwl_mac_low_latency_cmd - set/clear mac to 'low-latency mode' 166 * struct iwl_mac_low_latency_cmd - set/clear mac to 'low-latency mode'
140 * 167 *
141 * @mac_id: MAC ID to whom to apply the low-latency configurations 168 * @mac_id: MAC ID to whom to apply the low-latency configurations
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
index 286a22da232d..01f003c6cff9 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
@@ -8,7 +8,7 @@
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
10 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 10 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
11 * Copyright (C) 2018 Intel Corporation 11 * Copyright (C) 2018 - 2019 Intel Corporation
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of version 2 of the GNU General Public License as 14 * it under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
32 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
33 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 33 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
34 * Copyright (C) 2018 Intel Corporation 34 * Copyright (C) 2018 - 2019 Intel Corporation
35 * All rights reserved. 35 * All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -200,9 +200,16 @@ struct iwl_powertable_cmd {
200 * @DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK: 200 * @DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK:
201 * '1' Allow to save power by turning off 201 * '1' Allow to save power by turning off
202 * receiver and transmitter. '0' - does not allow. 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*/
204enum iwl_device_power_flags { 209enum 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/**
@@ -470,6 +477,13 @@ struct iwl_geo_tx_power_profiles_resp {
470 * @ba_escape_timer: Fully receive and parse beacon if no beacons were passed 477 * @ba_escape_timer: Fully receive and parse beacon if no beacons were passed
471 * for a longer period of time then this escape-timeout. Units: Beacons. 478 * for a longer period of time then this escape-timeout. Units: Beacons.
472 * @ba_enable_beacon_abort: 1, beacon abort is enabled; 0, disabled. 479 * @ba_enable_beacon_abort: 1, beacon abort is enabled; 0, disabled.
480 * @bf_threshold_absolute_low: See below.
481 * @bf_threshold_absolute_high: Send Beacon to driver if Energy value calculated
482 * for this beacon crossed this absolute threshold. For the 'Increase'
483 * direction the bf_energy_absolute_low[i] is used. For the 'Decrease'
484 * direction the bf_energy_absolute_high[i] is used. Zero value means
485 * that this specific threshold is ignored for beacon filtering, and
486 * beacon will not be forced to be sent to driver due to this setting.
473 */ 487 */
474struct iwl_beacon_filter_cmd { 488struct iwl_beacon_filter_cmd {
475 __le32 bf_energy_delta; 489 __le32 bf_energy_delta;
@@ -483,7 +497,9 @@ struct iwl_beacon_filter_cmd {
483 __le32 bf_escape_timer; 497 __le32 bf_escape_timer;
484 __le32 ba_escape_timer; 498 __le32 ba_escape_timer;
485 __le32 ba_enable_beacon_abort; 499 __le32 ba_enable_beacon_abort;
486} __packed; 500 __le32 bf_threshold_absolute_low[2];
501 __le32 bf_threshold_absolute_high[2];
502} __packed; /* BEACON_FILTER_CONFIG_API_S_VER_4 */
487 503
488/* Beacon filtering and beacon abort */ 504/* Beacon filtering and beacon abort */
489#define IWL_BF_ENERGY_DELTA_DEFAULT 5 505#define IWL_BF_ENERGY_DELTA_DEFAULT 5
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h
index 18741889ec30..890a939c463d 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/scan.h
@@ -8,7 +8,7 @@
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11 * Copyright(c) 2018 Intel Corporation 11 * Copyright(c) 2018 - 2019 Intel Corporation
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of version 2 of the GNU General Public License as 14 * it under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
34 * Copyright(c) 2018 Intel Corporation 34 * Copyright(c) 2018 - 2019 Intel Corporation
35 * All rights reserved. 35 * All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -434,7 +434,7 @@ struct iwl_periodic_scan_complete {
434/* The maximum of either of these cannot exceed 8, because we use an 434/* The maximum of either of these cannot exceed 8, because we use an
435 * 8-bit mask (see IWL_MVM_SCAN_MASK in mvm.h). 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#define IWL_MVM_MAX_LMAC_SCANS 1 438#define IWL_MVM_MAX_LMAC_SCANS 1
439 439
440enum scan_config_flags { 440enum scan_config_flags {
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
index 358bdf051e83..8511e735c374 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/tx.h
@@ -847,13 +847,13 @@ struct iwl_beacon_notif {
847} __packed; 847} __packed;
848 848
849/** 849/**
850 * struct iwl_extended_beacon_notif - notifies about beacon transmission 850 * struct iwl_extended_beacon_notif_v5 - notifies about beacon transmission
851 * @beacon_notify_hdr: tx response command associated with the beacon 851 * @beacon_notify_hdr: tx response command associated with the beacon
852 * @tsf: last beacon tsf 852 * @tsf: last beacon tsf
853 * @ibss_mgr_status: whether IBSS is manager 853 * @ibss_mgr_status: whether IBSS is manager
854 * @gp2: last beacon time in gp2 854 * @gp2: last beacon time in gp2
855 */ 855 */
856struct iwl_extended_beacon_notif { 856struct iwl_extended_beacon_notif_v5 {
857 struct iwl_mvm_tx_resp beacon_notify_hdr; 857 struct iwl_mvm_tx_resp beacon_notify_hdr;
858 __le64 tsf; 858 __le64 tsf;
859 __le32 ibss_mgr_status; 859 __le32 ibss_mgr_status;
@@ -861,6 +861,20 @@ struct iwl_extended_beacon_notif {
861} __packed; /* BEACON_NTFY_API_S_VER_5 */ 861} __packed; /* BEACON_NTFY_API_S_VER_5 */
862 862
863/** 863/**
864 * struct iwl_extended_beacon_notif - notifies about beacon transmission
865 * @status: the status of the Tx response of the beacon
866 * @tsf: last beacon tsf
867 * @ibss_mgr_status: whether IBSS is manager
868 * @gp2: last beacon time in gp2
869 */
870struct iwl_extended_beacon_notif {
871 __le32 status;
872 __le64 tsf;
873 __le32 ibss_mgr_status;
874 __le32 gp2;
875} __packed; /* BEACON_NTFY_API_S_VER_6_ */
876
877/**
864 * enum iwl_dump_control - dump (flush) control flags 878 * enum iwl_dump_control - dump (flush) control flags
865 * @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty 879 * @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty
866 * and the TFD queues are empty. 880 * and the TFD queues are empty.
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 22efd94da6d3..f119c49cd39c 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -8,7 +8,7 @@
8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 10 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
11 * Copyright(c) 2018 Intel Corporation 11 * Copyright(c) 2018 - 2019 Intel Corporation
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of version 2 of the GNU General Public License as 14 * it under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
31 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 31 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
33 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 33 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
34 * Copyright(c) 2018 Intel Corporation 34 * Copyright(c) 2018 - 2019 Intel Corporation
35 * All rights reserved. 35 * All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -242,7 +242,8 @@ static void iwl_fw_dump_rxf(struct iwl_fw_runtime *fwrt,
242 cfg->lmac[0].rxfifo1_size, 0, 0); 242 cfg->lmac[0].rxfifo1_size, 0, 0);
243 /* Pull RXF2 */ 243 /* Pull RXF2 */
244 iwl_fwrt_dump_rxf(fwrt, dump_data, cfg->rxfifo2_size, 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 /* Pull LMAC2 RXF1 */ 247 /* Pull LMAC2 RXF1 */
247 if (fwrt->smem_cfg.num_lmacs > 1) 248 if (fwrt->smem_cfg.num_lmacs > 1)
248 iwl_fwrt_dump_rxf(fwrt, dump_data, 249 iwl_fwrt_dump_rxf(fwrt, dump_data,
@@ -673,7 +674,9 @@ static void iwl_fw_prph_handler(struct iwl_fw_runtime *fwrt, void *ptr,
673{ 674{
674 u32 range_len; 675 u32 range_len;
675 676
676 if (fwrt->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000) { 677 if (fwrt->trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210) {
678 /* TODO */
679 } else if (fwrt->trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000) {
677 range_len = ARRAY_SIZE(iwl_prph_dump_addr_22000); 680 range_len = ARRAY_SIZE(iwl_prph_dump_addr_22000);
678 handler(fwrt, iwl_prph_dump_addr_22000, range_len, ptr); 681 handler(fwrt, iwl_prph_dump_addr_22000, range_len, ptr);
679 } else { 682 } else {
@@ -707,28 +710,6 @@ static void iwl_fw_dump_mem(struct iwl_fw_runtime *fwrt,
707 IWL_DEBUG_INFO(fwrt, "WRT memory dump. Type=%u\n", dump_mem->type); 710 IWL_DEBUG_INFO(fwrt, "WRT memory dump. Type=%u\n", dump_mem->type);
708} 711}
709 712
710static void iwl_fw_dump_named_mem(struct iwl_fw_runtime *fwrt,
711 struct iwl_fw_error_dump_data **dump_data,
712 u32 len, u32 ofs, u8 *name, u8 name_len)
713{
714 struct iwl_fw_error_dump_named_mem *dump_mem;
715
716 if (!len)
717 return;
718
719 (*dump_data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
720 (*dump_data)->len = cpu_to_le32(len + sizeof(*dump_mem));
721 dump_mem = (void *)(*dump_data)->data;
722 dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_NAMED_MEM);
723 dump_mem->offset = cpu_to_le32(ofs);
724 dump_mem->name_len = name_len;
725 memcpy(dump_mem->name, name, name_len);
726 iwl_trans_read_mem_bytes(fwrt->trans, ofs, dump_mem->data, len);
727 *dump_data = iwl_fw_error_next_data(*dump_data);
728
729 IWL_DEBUG_INFO(fwrt, "WRT memory dump. Type=%u\n", dump_mem->type);
730}
731
732#define ADD_LEN(len, item_len, const_len) \ 713#define ADD_LEN(len, item_len, const_len) \
733 do {size_t item = item_len; len += (!!item) * const_len + item; } \ 714 do {size_t item = item_len; len += (!!item) * const_len + item; } \
734 while (0) 715 while (0)
@@ -815,6 +796,9 @@ static void iwl_dump_paging(struct iwl_fw_runtime *fwrt,
815 DMA_BIDIRECTIONAL); 796 DMA_BIDIRECTIONAL);
816 memcpy(paging->data, page_address(pages), 797 memcpy(paging->data, page_address(pages),
817 PAGING_BLOCK_SIZE); 798 PAGING_BLOCK_SIZE);
799 dma_sync_single_for_device(fwrt->trans->dev, addr,
800 PAGING_BLOCK_SIZE,
801 DMA_BIDIRECTIONAL);
818 (*data) = iwl_fw_error_next_data(*data); 802 (*data) = iwl_fw_error_next_data(*data);
819 } 803 }
820} 804}
@@ -1059,117 +1043,645 @@ out:
1059 return dump_file; 1043 return dump_file;
1060} 1044}
1061 1045
1062static void iwl_dump_prph_ini(struct iwl_trans *trans, 1046static int iwl_dump_ini_prph_iter(struct iwl_fw_runtime *fwrt,
1063 struct iwl_fw_error_dump_data **data, 1047 struct iwl_fw_ini_region_cfg *reg,
1064 struct iwl_fw_ini_region_cfg *reg) 1048 void *range_ptr, int idx)
1065{ 1049{
1066 struct iwl_fw_error_dump_prph *prph; 1050 struct iwl_fw_ini_error_dump_range *range = range_ptr;
1051 __le32 *val = range->data;
1052 u32 addr, prph_val, offset = le32_to_cpu(reg->offset);
1053 int i;
1054
1055 range->start_addr = reg->start_addr[idx];
1056 range->range_data_size = reg->internal.range_data_size;
1057 for (i = 0; i < le32_to_cpu(reg->internal.range_data_size); i += 4) {
1058 addr = le32_to_cpu(range->start_addr) + i;
1059 prph_val = iwl_read_prph(fwrt->trans, addr + offset);
1060 if (prph_val == 0x5a5a5a5a)
1061 return -EBUSY;
1062 *val++ = cpu_to_le32(prph_val);
1063 }
1064
1065 return sizeof(*range) + le32_to_cpu(range->range_data_size);
1066}
1067
1068static int iwl_dump_ini_csr_iter(struct iwl_fw_runtime *fwrt,
1069 struct iwl_fw_ini_region_cfg *reg,
1070 void *range_ptr, int idx)
1071{
1072 struct iwl_fw_ini_error_dump_range *range = range_ptr;
1073 __le32 *val = range->data;
1074 u32 addr, offset = le32_to_cpu(reg->offset);
1075 int i;
1076
1077 range->start_addr = reg->start_addr[idx];
1078 range->range_data_size = reg->internal.range_data_size;
1079 for (i = 0; i < le32_to_cpu(reg->internal.range_data_size); i += 4) {
1080 addr = le32_to_cpu(range->start_addr) + i;
1081 *val++ = cpu_to_le32(iwl_trans_read32(fwrt->trans,
1082 addr + offset));
1083 }
1084
1085 return sizeof(*range) + le32_to_cpu(range->range_data_size);
1086}
1087
1088static int iwl_dump_ini_dev_mem_iter(struct iwl_fw_runtime *fwrt,
1089 struct iwl_fw_ini_region_cfg *reg,
1090 void *range_ptr, int idx)
1091{
1092 struct iwl_fw_ini_error_dump_range *range = range_ptr;
1093 u32 addr = le32_to_cpu(range->start_addr);
1094 u32 offset = le32_to_cpu(reg->offset);
1095
1096 range->start_addr = reg->start_addr[idx];
1097 range->range_data_size = reg->internal.range_data_size;
1098 iwl_trans_read_mem_bytes(fwrt->trans, addr + offset, range->data,
1099 le32_to_cpu(reg->internal.range_data_size));
1100
1101 return sizeof(*range) + le32_to_cpu(range->range_data_size);
1102}
1103
1104static int
1105iwl_dump_ini_paging_gen2_iter(struct iwl_fw_runtime *fwrt,
1106 struct iwl_fw_ini_region_cfg *reg,
1107 void *range_ptr, int idx)
1108{
1109 struct iwl_fw_ini_error_dump_range *range = range_ptr;
1110 u32 page_size = fwrt->trans->init_dram.paging[idx].size;
1111
1112 range->start_addr = cpu_to_le32(idx);
1113 range->range_data_size = cpu_to_le32(page_size);
1114 memcpy(range->data, fwrt->trans->init_dram.paging[idx].block,
1115 page_size);
1116
1117 return sizeof(*range) + le32_to_cpu(range->range_data_size);
1118}
1119
1120static int iwl_dump_ini_paging_iter(struct iwl_fw_runtime *fwrt,
1121 struct iwl_fw_ini_region_cfg *reg,
1122 void *range_ptr, int idx)
1123{
1124 /* increase idx by 1 since the pages are from 1 to
1125 * fwrt->num_of_paging_blk + 1
1126 */
1127 struct page *page = fwrt->fw_paging_db[++idx].fw_paging_block;
1128 struct iwl_fw_ini_error_dump_range *range = range_ptr;
1129 dma_addr_t addr = fwrt->fw_paging_db[idx].fw_paging_phys;
1130 u32 page_size = fwrt->fw_paging_db[idx].fw_paging_size;
1131
1132 range->start_addr = cpu_to_le32(idx);
1133 range->range_data_size = cpu_to_le32(page_size);
1134 dma_sync_single_for_cpu(fwrt->trans->dev, addr, page_size,
1135 DMA_BIDIRECTIONAL);
1136 memcpy(range->data, page_address(page), page_size);
1137 dma_sync_single_for_device(fwrt->trans->dev, addr, page_size,
1138 DMA_BIDIRECTIONAL);
1139
1140 return sizeof(*range) + le32_to_cpu(range->range_data_size);
1141}
1142
1143static int
1144iwl_dump_ini_mon_dram_iter(struct iwl_fw_runtime *fwrt,
1145 struct iwl_fw_ini_region_cfg *reg, void *range_ptr,
1146 int idx)
1147{
1148 struct iwl_fw_ini_error_dump_range *range = range_ptr;
1149 u32 start_addr = iwl_read_umac_prph(fwrt->trans,
1150 MON_BUFF_BASE_ADDR_VER2);
1151
1152 if (start_addr == 0x5a5a5a5a)
1153 return -EBUSY;
1154
1155 range->start_addr = cpu_to_le32(start_addr);
1156 range->range_data_size = cpu_to_le32(fwrt->trans->fw_mon[idx].size);
1157
1158 memcpy(range->data, fwrt->trans->fw_mon[idx].block,
1159 fwrt->trans->fw_mon[idx].size);
1160
1161 return sizeof(*range) + le32_to_cpu(range->range_data_size);
1162}
1163
1164struct iwl_ini_txf_iter_data {
1165 int fifo;
1166 int lmac;
1167 u32 fifo_size;
1168 bool internal_txf;
1169 bool init;
1170};
1171
1172static bool iwl_ini_txf_iter(struct iwl_fw_runtime *fwrt,
1173 struct iwl_fw_ini_region_cfg *reg)
1174{
1175 struct iwl_ini_txf_iter_data *iter = fwrt->dump.fifo_iter;
1176 struct iwl_fwrt_shared_mem_cfg *cfg = &fwrt->smem_cfg;
1177 int txf_num = cfg->num_txfifo_entries;
1178 int int_txf_num = ARRAY_SIZE(cfg->internal_txfifo_size);
1179 u32 lmac_bitmap = le32_to_cpu(reg->fifos.fid1);
1180
1181 if (!iter)
1182 return false;
1183
1184 if (iter->init) {
1185 if (le32_to_cpu(reg->offset) &&
1186 WARN_ONCE(cfg->num_lmacs == 1,
1187 "Invalid lmac offset: 0x%x\n",
1188 le32_to_cpu(reg->offset)))
1189 return false;
1190
1191 iter->init = false;
1192 iter->internal_txf = false;
1193 iter->fifo_size = 0;
1194 iter->fifo = -1;
1195 if (le32_to_cpu(reg->offset))
1196 iter->lmac = 1;
1197 else
1198 iter->lmac = 0;
1199 }
1200
1201 if (!iter->internal_txf)
1202 for (iter->fifo++; iter->fifo < txf_num; iter->fifo++) {
1203 iter->fifo_size =
1204 cfg->lmac[iter->lmac].txfifo_size[iter->fifo];
1205 if (iter->fifo_size && (lmac_bitmap & BIT(iter->fifo)))
1206 return true;
1207 }
1208
1209 iter->internal_txf = true;
1210
1211 if (!fw_has_capa(&fwrt->fw->ucode_capa,
1212 IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG))
1213 return false;
1214
1215 for (iter->fifo++; iter->fifo < int_txf_num + txf_num; iter->fifo++) {
1216 iter->fifo_size =
1217 cfg->internal_txfifo_size[iter->fifo - txf_num];
1218 if (iter->fifo_size && (lmac_bitmap & BIT(iter->fifo)))
1219 return true;
1220 }
1221
1222 return false;
1223}
1224
1225static int iwl_dump_ini_txf_iter(struct iwl_fw_runtime *fwrt,
1226 struct iwl_fw_ini_region_cfg *reg,
1227 void *range_ptr, int idx)
1228{
1229 struct iwl_fw_ini_fifo_error_dump_range *range = range_ptr;
1230 struct iwl_ini_txf_iter_data *iter;
1231 u32 offs = le32_to_cpu(reg->offset), addr;
1232 u32 registers_size =
1233 le32_to_cpu(reg->fifos.num_of_registers) * sizeof(__le32);
1234 __le32 *val = range->data;
1067 unsigned long flags; 1235 unsigned long flags;
1068 u32 i, size = le32_to_cpu(reg->num_regions); 1236 int i;
1069 1237
1070 IWL_DEBUG_INFO(trans, "WRT PRPH dump\n"); 1238 if (!iwl_ini_txf_iter(fwrt, reg))
1239 return -EIO;
1071 1240
1072 if (!iwl_trans_grab_nic_access(trans, &flags)) 1241 if (!iwl_trans_grab_nic_access(fwrt->trans, &flags))
1242 return -EBUSY;
1243
1244 iter = fwrt->dump.fifo_iter;
1245
1246 range->fifo_num = cpu_to_le32(iter->fifo);
1247 range->num_of_registers = reg->fifos.num_of_registers;
1248 range->range_data_size = cpu_to_le32(iter->fifo_size + registers_size);
1249
1250 iwl_write_prph_no_grab(fwrt->trans, TXF_LARC_NUM + offs, iter->fifo);
1251
1252 /* read txf registers */
1253 for (i = 0; i < le32_to_cpu(reg->fifos.num_of_registers); i++) {
1254 addr = le32_to_cpu(reg->start_addr[i]) + offs;
1255
1256 *val++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr));
1257 }
1258
1259 if (reg->fifos.header_only) {
1260 range->range_data_size = cpu_to_le32(registers_size);
1261 goto out;
1262 }
1263
1264 /* Set the TXF_READ_MODIFY_ADDR to TXF_WR_PTR */
1265 iwl_write_prph_no_grab(fwrt->trans, TXF_READ_MODIFY_ADDR + offs,
1266 TXF_WR_PTR + offs);
1267
1268 /* Dummy-read to advance the read pointer to the head */
1269 iwl_read_prph_no_grab(fwrt->trans, TXF_READ_MODIFY_DATA + offs);
1270
1271 /* Read FIFO */
1272 addr = TXF_READ_MODIFY_DATA + offs;
1273 for (i = 0; i < iter->fifo_size; i += sizeof(__le32))
1274 *val++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr));
1275
1276out:
1277 iwl_trans_release_nic_access(fwrt->trans, &flags);
1278
1279 return sizeof(*range) + le32_to_cpu(range->range_data_size);
1280}
1281
1282struct iwl_ini_rxf_data {
1283 u32 fifo_num;
1284 u32 size;
1285 u32 offset;
1286};
1287
1288static void iwl_ini_get_rxf_data(struct iwl_fw_runtime *fwrt,
1289 struct iwl_fw_ini_region_cfg *reg,
1290 struct iwl_ini_rxf_data *data)
1291{
1292 u32 fid1 = le32_to_cpu(reg->fifos.fid1);
1293 u32 fid2 = le32_to_cpu(reg->fifos.fid2);
1294 u32 fifo_idx;
1295
1296 if (!data)
1073 return; 1297 return;
1074 1298
1075 for (i = 0; i < size; i++) { 1299 memset(data, 0, sizeof(*data));
1076 (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PRPH); 1300
1077 (*data)->len = cpu_to_le32(le32_to_cpu(reg->size) + 1301 if (WARN_ON_ONCE((fid1 && fid2) || (!fid1 && !fid2)))
1078 sizeof(*prph)); 1302 return;
1079 prph = (void *)(*data)->data; 1303
1080 prph->prph_start = reg->start_addr[i]; 1304 fifo_idx = ffs(fid1) - 1;
1081 prph->data[0] = cpu_to_le32(iwl_read_prph_no_grab(trans, 1305 if (fid1 && !WARN_ON_ONCE((~BIT(fifo_idx) & fid1) ||
1082 le32_to_cpu(prph->prph_start))); 1306 fifo_idx >= MAX_NUM_LMAC)) {
1083 *data = iwl_fw_error_next_data(*data); 1307 data->size = fwrt->smem_cfg.lmac[fifo_idx].rxfifo1_size;
1308 data->fifo_num = fifo_idx;
1309 return;
1310 }
1311
1312 fifo_idx = ffs(fid2) - 1;
1313 if (fid2 && !WARN_ON_ONCE(fifo_idx != 0)) {
1314 data->size = fwrt->smem_cfg.rxfifo2_size;
1315 data->offset = RXF_DIFF_FROM_PREV;
1316 /* use bit 31 to distinguish between umac and lmac rxf while
1317 * parsing the dump
1318 */
1319 data->fifo_num = fifo_idx | IWL_RXF_UMAC_BIT;
1320 return;
1084 } 1321 }
1085 iwl_trans_release_nic_access(trans, &flags);
1086} 1322}
1087 1323
1088static void iwl_dump_csr_ini(struct iwl_trans *trans, 1324static int iwl_dump_ini_rxf_iter(struct iwl_fw_runtime *fwrt,
1089 struct iwl_fw_error_dump_data **data, 1325 struct iwl_fw_ini_region_cfg *reg,
1090 struct iwl_fw_ini_region_cfg *reg) 1326 void *range_ptr, int idx)
1091{ 1327{
1092 int i, num = le32_to_cpu(reg->num_regions); 1328 struct iwl_fw_ini_fifo_error_dump_range *range = range_ptr;
1093 u32 size = le32_to_cpu(reg->size); 1329 struct iwl_ini_rxf_data rxf_data;
1330 u32 offs = le32_to_cpu(reg->offset), addr;
1331 u32 registers_size =
1332 le32_to_cpu(reg->fifos.num_of_registers) * sizeof(__le32);
1333 __le32 *val = range->data;
1334 unsigned long flags;
1335 int i;
1336
1337 iwl_ini_get_rxf_data(fwrt, reg, &rxf_data);
1338 if (!rxf_data.size)
1339 return -EIO;
1094 1340
1095 IWL_DEBUG_INFO(trans, "WRT CSR dump\n"); 1341 if (!iwl_trans_grab_nic_access(fwrt->trans, &flags))
1342 return -EBUSY;
1096 1343
1097 for (i = 0; i < num; i++) { 1344 offs += rxf_data.offset;
1098 u32 add = le32_to_cpu(reg->start_addr[i]);
1099 __le32 *val;
1100 int j;
1101 1345
1102 (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_CSR); 1346 range->fifo_num = cpu_to_le32(rxf_data.fifo_num);
1103 (*data)->len = cpu_to_le32(size); 1347 range->num_of_registers = reg->fifos.num_of_registers;
1104 val = (void *)(*data)->data; 1348 range->range_data_size = cpu_to_le32(rxf_data.size + registers_size);
1105 1349
1106 for (j = 0; j < size; j += 4) 1350 /* read rxf registers */
1107 *val++ = cpu_to_le32(iwl_trans_read32(trans, j + add)); 1351 for (i = 0; i < le32_to_cpu(reg->fifos.num_of_registers); i++) {
1352 addr = le32_to_cpu(reg->start_addr[i]) + offs;
1108 1353
1109 *data = iwl_fw_error_next_data(*data); 1354 *val++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr));
1355 }
1356
1357 if (reg->fifos.header_only) {
1358 range->range_data_size = cpu_to_le32(registers_size);
1359 goto out;
1360 }
1361
1362 /* Lock fence */
1363 iwl_write_prph_no_grab(fwrt->trans, RXF_SET_FENCE_MODE + offs, 0x1);
1364 /* Set fence pointer to the same place like WR pointer */
1365 iwl_write_prph_no_grab(fwrt->trans, RXF_LD_WR2FENCE + offs, 0x1);
1366 /* Set fence offset */
1367 iwl_write_prph_no_grab(fwrt->trans, RXF_LD_FENCE_OFFSET_ADDR + offs,
1368 0x0);
1369
1370 /* Read FIFO */
1371 addr = RXF_FIFO_RD_FENCE_INC + offs;
1372 for (i = 0; i < rxf_data.size; i += sizeof(__le32))
1373 *val++ = cpu_to_le32(iwl_read_prph_no_grab(fwrt->trans, addr));
1374
1375out:
1376 iwl_trans_release_nic_access(fwrt->trans, &flags);
1377
1378 return sizeof(*range) + le32_to_cpu(range->range_data_size);
1379}
1380
1381static void *iwl_dump_ini_mem_fill_header(struct iwl_fw_runtime *fwrt,
1382 struct iwl_fw_ini_region_cfg *reg,
1383 void *data)
1384{
1385 struct iwl_fw_ini_error_dump *dump = data;
1386
1387 return dump->ranges;
1388}
1389
1390static void
1391*iwl_dump_ini_mon_dram_fill_header(struct iwl_fw_runtime *fwrt,
1392 struct iwl_fw_ini_region_cfg *reg,
1393 void *data)
1394{
1395 struct iwl_fw_ini_monitor_dram_dump *mon_dump = (void *)data;
1396 u32 write_ptr, cycle_cnt;
1397 unsigned long flags;
1398
1399 if (!iwl_trans_grab_nic_access(fwrt->trans, &flags)) {
1400 IWL_ERR(fwrt, "Failed to get DRAM monitor header\n");
1401 return NULL;
1110 } 1402 }
1403 write_ptr = iwl_read_umac_prph_no_grab(fwrt->trans,
1404 MON_BUFF_WRPTR_VER2);
1405 cycle_cnt = iwl_read_umac_prph_no_grab(fwrt->trans,
1406 MON_BUFF_CYCLE_CNT_VER2);
1407 iwl_trans_release_nic_access(fwrt->trans, &flags);
1408
1409 mon_dump->write_ptr = cpu_to_le32(write_ptr);
1410 mon_dump->cycle_cnt = cpu_to_le32(cycle_cnt);
1411
1412 return mon_dump->ranges;
1413}
1414
1415static void *iwl_dump_ini_fifo_fill_header(struct iwl_fw_runtime *fwrt,
1416 struct iwl_fw_ini_region_cfg *reg,
1417 void *data)
1418{
1419 struct iwl_fw_ini_fifo_error_dump *dump = data;
1420
1421 return dump->ranges;
1422}
1423
1424static u32 iwl_dump_ini_mem_ranges(struct iwl_fw_runtime *fwrt,
1425 struct iwl_fw_ini_region_cfg *reg)
1426{
1427 return le32_to_cpu(reg->internal.num_of_ranges);
1428}
1429
1430static u32 iwl_dump_ini_paging_gen2_ranges(struct iwl_fw_runtime *fwrt,
1431 struct iwl_fw_ini_region_cfg *reg)
1432{
1433 return fwrt->trans->init_dram.paging_cnt;
1434}
1435
1436static u32 iwl_dump_ini_paging_ranges(struct iwl_fw_runtime *fwrt,
1437 struct iwl_fw_ini_region_cfg *reg)
1438{
1439 return fwrt->num_of_paging_blk;
1440}
1441
1442static u32 iwl_dump_ini_mon_dram_ranges(struct iwl_fw_runtime *fwrt,
1443 struct iwl_fw_ini_region_cfg *reg)
1444{
1445 return 1;
1446}
1447
1448static u32 iwl_dump_ini_txf_ranges(struct iwl_fw_runtime *fwrt,
1449 struct iwl_fw_ini_region_cfg *reg)
1450{
1451 struct iwl_ini_txf_iter_data iter = { .init = true };
1452 void *fifo_iter = fwrt->dump.fifo_iter;
1453 u32 num_of_fifos = 0;
1454
1455 fwrt->dump.fifo_iter = &iter;
1456 while (iwl_ini_txf_iter(fwrt, reg))
1457 num_of_fifos++;
1458
1459 fwrt->dump.fifo_iter = fifo_iter;
1460
1461 return num_of_fifos;
1462}
1463
1464static u32 iwl_dump_ini_rxf_ranges(struct iwl_fw_runtime *fwrt,
1465 struct iwl_fw_ini_region_cfg *reg)
1466{
1467 /* Each Rx fifo needs a different offset and therefore, it's
1468 * region can contain only one fifo, i.e. 1 memory range.
1469 */
1470 return 1;
1471}
1472
1473static u32 iwl_dump_ini_mem_get_size(struct iwl_fw_runtime *fwrt,
1474 struct iwl_fw_ini_region_cfg *reg)
1475{
1476 return sizeof(struct iwl_fw_ini_error_dump) +
1477 iwl_dump_ini_mem_ranges(fwrt, reg) *
1478 (sizeof(struct iwl_fw_ini_error_dump_range) +
1479 le32_to_cpu(reg->internal.range_data_size));
1480}
1481
1482static u32 iwl_dump_ini_paging_gen2_get_size(struct iwl_fw_runtime *fwrt,
1483 struct iwl_fw_ini_region_cfg *reg)
1484{
1485 int i;
1486 u32 range_header_len = sizeof(struct iwl_fw_ini_error_dump_range);
1487 u32 size = sizeof(struct iwl_fw_ini_error_dump);
1488
1489 for (i = 0; i < iwl_dump_ini_paging_gen2_ranges(fwrt, reg); i++)
1490 size += range_header_len +
1491 fwrt->trans->init_dram.paging[i].size;
1492
1493 return size;
1494}
1495
1496static u32 iwl_dump_ini_paging_get_size(struct iwl_fw_runtime *fwrt,
1497 struct iwl_fw_ini_region_cfg *reg)
1498{
1499 int i;
1500 u32 range_header_len = sizeof(struct iwl_fw_ini_error_dump_range);
1501 u32 size = sizeof(struct iwl_fw_ini_error_dump);
1502
1503 for (i = 1; i <= iwl_dump_ini_paging_ranges(fwrt, reg); i++)
1504 size += range_header_len + fwrt->fw_paging_db[i].fw_paging_size;
1505
1506 return size;
1507}
1508
1509static u32 iwl_dump_ini_mon_dram_get_size(struct iwl_fw_runtime *fwrt,
1510 struct iwl_fw_ini_region_cfg *reg)
1511{
1512 u32 size = sizeof(struct iwl_fw_ini_monitor_dram_dump);
1513
1514 if (fwrt->trans->num_blocks)
1515 size += fwrt->trans->fw_mon[0].size;
1516
1517 return size;
1518}
1519
1520static u32 iwl_dump_ini_txf_get_size(struct iwl_fw_runtime *fwrt,
1521 struct iwl_fw_ini_region_cfg *reg)
1522{
1523 struct iwl_ini_txf_iter_data iter = { .init = true };
1524 void *fifo_iter = fwrt->dump.fifo_iter;
1525 u32 size = 0;
1526 u32 fifo_hdr = sizeof(struct iwl_fw_ini_fifo_error_dump_range) +
1527 le32_to_cpu(reg->fifos.num_of_registers) * sizeof(__le32);
1528
1529 fwrt->dump.fifo_iter = &iter;
1530 while (iwl_ini_txf_iter(fwrt, reg)) {
1531 size += fifo_hdr;
1532 if (!reg->fifos.header_only)
1533 size += iter.fifo_size;
1534 }
1535
1536 if (size)
1537 size += sizeof(struct iwl_fw_ini_fifo_error_dump);
1538
1539 fwrt->dump.fifo_iter = fifo_iter;
1540
1541 return size;
1542}
1543
1544static u32 iwl_dump_ini_rxf_get_size(struct iwl_fw_runtime *fwrt,
1545 struct iwl_fw_ini_region_cfg *reg)
1546{
1547 struct iwl_ini_rxf_data rx_data;
1548 u32 size = sizeof(struct iwl_fw_ini_fifo_error_dump) +
1549 sizeof(struct iwl_fw_ini_fifo_error_dump_range) +
1550 le32_to_cpu(reg->fifos.num_of_registers) * sizeof(__le32);
1551
1552 if (reg->fifos.header_only)
1553 return size;
1554
1555 iwl_ini_get_rxf_data(fwrt, reg, &rx_data);
1556 size += rx_data.size;
1557
1558 return size;
1559}
1560
1561/**
1562 * struct iwl_dump_ini_mem_ops - ini memory dump operations
1563 * @get_num_of_ranges: returns the number of memory ranges in the region.
1564 * @get_size: returns the total size of the region.
1565 * @fill_mem_hdr: fills region type specific headers and returns pointer to
1566 * the first range or NULL if failed to fill headers.
1567 * @fill_range: copies a given memory range into the dump.
1568 * Returns the size of the range or negative error value otherwise.
1569 */
1570struct iwl_dump_ini_mem_ops {
1571 u32 (*get_num_of_ranges)(struct iwl_fw_runtime *fwrt,
1572 struct iwl_fw_ini_region_cfg *reg);
1573 u32 (*get_size)(struct iwl_fw_runtime *fwrt,
1574 struct iwl_fw_ini_region_cfg *reg);
1575 void *(*fill_mem_hdr)(struct iwl_fw_runtime *fwrt,
1576 struct iwl_fw_ini_region_cfg *reg, void *data);
1577 int (*fill_range)(struct iwl_fw_runtime *fwrt,
1578 struct iwl_fw_ini_region_cfg *reg, void *range,
1579 int idx);
1580};
1581
1582/**
1583 * iwl_dump_ini_mem - copy a memory region into the dump
1584 * @fwrt: fw runtime struct.
1585 * @data: dump memory data.
1586 * @reg: region to copy to the dump.
1587 */
1588static void
1589iwl_dump_ini_mem(struct iwl_fw_runtime *fwrt,
1590 enum iwl_fw_ini_region_type type,
1591 struct iwl_fw_error_dump_data **data,
1592 struct iwl_fw_ini_region_cfg *reg,
1593 struct iwl_dump_ini_mem_ops *ops)
1594{
1595 struct iwl_fw_ini_error_dump_header *header = (void *)(*data)->data;
1596 void *range;
1597 u32 num_of_ranges, i;
1598
1599 if (WARN_ON(!ops || !ops->get_num_of_ranges || !ops->get_size ||
1600 !ops->fill_mem_hdr || !ops->fill_range))
1601 return;
1602
1603 num_of_ranges = ops->get_num_of_ranges(fwrt, reg);
1604
1605 (*data)->type = cpu_to_le32(type | INI_DUMP_BIT);
1606 (*data)->len = cpu_to_le32(ops->get_size(fwrt, reg));
1607
1608 header->num_of_ranges = cpu_to_le32(num_of_ranges);
1609 header->name_len = cpu_to_le32(min_t(int, IWL_FW_INI_MAX_NAME,
1610 le32_to_cpu(reg->name_len)));
1611 memcpy(header->name, reg->name, le32_to_cpu(header->name_len));
1612
1613 range = ops->fill_mem_hdr(fwrt, reg, header);
1614 if (!range) {
1615 IWL_ERR(fwrt, "Failed to fill region header: id=%d, type=%d\n",
1616 le32_to_cpu(reg->region_id), type);
1617 return;
1618 }
1619
1620 for (i = 0; i < num_of_ranges; i++) {
1621 int range_size = ops->fill_range(fwrt, reg, range, i);
1622
1623 if (range_size < 0) {
1624 IWL_ERR(fwrt, "Failed to dump region: id=%d, type=%d\n",
1625 le32_to_cpu(reg->region_id), type);
1626 return;
1627 }
1628 range = range + range_size;
1629 }
1630 *data = iwl_fw_error_next_data(*data);
1111} 1631}
1112 1632
1113static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt, 1633static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt,
1114 struct iwl_fw_ini_trigger *trigger) 1634 struct iwl_fw_ini_trigger *trigger)
1115{ 1635{
1116 int i, num, size = 0, hdr_len = sizeof(struct iwl_fw_error_dump_data); 1636 int i, size = 0, hdr_len = sizeof(struct iwl_fw_error_dump_data);
1117 1637
1118 if (!trigger || !trigger->num_regions) 1638 if (!trigger || !trigger->num_regions)
1119 return 0; 1639 return 0;
1120 1640
1121 num = le32_to_cpu(trigger->num_regions); 1641 for (i = 0; i < le32_to_cpu(trigger->num_regions); i++) {
1122 for (i = 0; i < num; i++) {
1123 u32 reg_id = le32_to_cpu(trigger->data[i]); 1642 u32 reg_id = le32_to_cpu(trigger->data[i]);
1124 struct iwl_fw_ini_region_cfg *reg; 1643 struct iwl_fw_ini_region_cfg *reg;
1125 enum iwl_fw_ini_region_type type; 1644 enum iwl_fw_ini_region_type type;
1126 u32 num_entries;
1127 1645
1128 if (WARN_ON(reg_id >= ARRAY_SIZE(fwrt->dump.active_regs))) 1646 if (WARN_ON(reg_id >= ARRAY_SIZE(fwrt->dump.active_regs)))
1129 continue; 1647 continue;
1130 1648
1131 reg = fwrt->dump.active_regs[reg_id].reg; 1649 reg = fwrt->dump.active_regs[reg_id];
1132 if (WARN(!reg, "Unassigned region %d\n", reg_id)) 1650 if (WARN(!reg, "Unassigned region %d\n", reg_id))
1133 continue; 1651 continue;
1134 1652
1135 type = le32_to_cpu(reg->region_type); 1653 type = le32_to_cpu(reg->region_type);
1136 num_entries = le32_to_cpu(reg->num_regions);
1137
1138 switch (type) { 1654 switch (type) {
1139 case IWL_FW_INI_REGION_DEVICE_MEMORY: 1655 case IWL_FW_INI_REGION_DEVICE_MEMORY:
1140 size += hdr_len +
1141 sizeof(struct iwl_fw_error_dump_named_mem) +
1142 le32_to_cpu(reg->size);
1143 break;
1144 case IWL_FW_INI_REGION_PERIPHERY_MAC: 1656 case IWL_FW_INI_REGION_PERIPHERY_MAC:
1145 case IWL_FW_INI_REGION_PERIPHERY_PHY: 1657 case IWL_FW_INI_REGION_PERIPHERY_PHY:
1146 case IWL_FW_INI_REGION_PERIPHERY_AUX: 1658 case IWL_FW_INI_REGION_PERIPHERY_AUX:
1147 size += num_entries * 1659 case IWL_FW_INI_REGION_INTERNAL_BUFFER:
1148 (hdr_len + 1660 case IWL_FW_INI_REGION_CSR:
1149 sizeof(struct iwl_fw_error_dump_prph) + 1661 size += hdr_len + iwl_dump_ini_mem_get_size(fwrt, reg);
1150 sizeof(u32));
1151 break; 1662 break;
1152 case IWL_FW_INI_REGION_TXF: 1663 case IWL_FW_INI_REGION_TXF:
1153 size += iwl_fw_txf_len(fwrt, &fwrt->smem_cfg); 1664 size += hdr_len + iwl_dump_ini_txf_get_size(fwrt, reg);
1154 break; 1665 break;
1155 case IWL_FW_INI_REGION_RXF: 1666 case IWL_FW_INI_REGION_RXF:
1156 size += iwl_fw_rxf_len(fwrt, &fwrt->smem_cfg); 1667 size += hdr_len + iwl_dump_ini_rxf_get_size(fwrt, reg);
1157 break; 1668 break;
1158 case IWL_FW_INI_REGION_PAGING: 1669 case IWL_FW_INI_REGION_PAGING: {
1159 if (!iwl_fw_dbg_is_paging_enabled(fwrt)) 1670 size += hdr_len;
1160 break; 1671 if (iwl_fw_dbg_is_paging_enabled(fwrt)) {
1161 size += fwrt->num_of_paging_blk * 1672 size += iwl_dump_ini_paging_get_size(fwrt, reg);
1162 (hdr_len + 1673 } else {
1163 sizeof(struct iwl_fw_error_dump_paging) + 1674 size += iwl_dump_ini_paging_gen2_get_size(fwrt,
1164 PAGING_BLOCK_SIZE); 1675 reg);
1165 break; 1676 }
1166 case IWL_FW_INI_REGION_CSR:
1167 size += num_entries *
1168 (hdr_len + le32_to_cpu(reg->size));
1169 break; 1677 break;
1678 }
1170 case IWL_FW_INI_REGION_DRAM_BUFFER: 1679 case IWL_FW_INI_REGION_DRAM_BUFFER:
1171 /* Transport takes care of DRAM dumping */ 1680 if (!fwrt->trans->num_blocks)
1172 case IWL_FW_INI_REGION_INTERNAL_BUFFER: 1681 break;
1682 size += hdr_len +
1683 iwl_dump_ini_mon_dram_get_size(fwrt, reg);
1684 break;
1173 case IWL_FW_INI_REGION_DRAM_IMR: 1685 case IWL_FW_INI_REGION_DRAM_IMR:
1174 /* Undefined yet */ 1686 /* Undefined yet */
1175 default: 1687 default:
@@ -1181,8 +1693,7 @@ static int iwl_fw_ini_get_trigger_len(struct iwl_fw_runtime *fwrt,
1181 1693
1182static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt, 1694static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
1183 struct iwl_fw_ini_trigger *trigger, 1695 struct iwl_fw_ini_trigger *trigger,
1184 struct iwl_fw_error_dump_data **data, 1696 struct iwl_fw_error_dump_data **data)
1185 u32 *dump_mask)
1186{ 1697{
1187 int i, num = le32_to_cpu(trigger->num_regions); 1698 int i, num = le32_to_cpu(trigger->num_regions);
1188 1699
@@ -1190,11 +1701,12 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
1190 u32 reg_id = le32_to_cpu(trigger->data[i]); 1701 u32 reg_id = le32_to_cpu(trigger->data[i]);
1191 enum iwl_fw_ini_region_type type; 1702 enum iwl_fw_ini_region_type type;
1192 struct iwl_fw_ini_region_cfg *reg; 1703 struct iwl_fw_ini_region_cfg *reg;
1704 struct iwl_dump_ini_mem_ops ops;
1193 1705
1194 if (reg_id >= ARRAY_SIZE(fwrt->dump.active_regs)) 1706 if (reg_id >= ARRAY_SIZE(fwrt->dump.active_regs))
1195 continue; 1707 continue;
1196 1708
1197 reg = fwrt->dump.active_regs[reg_id].reg; 1709 reg = fwrt->dump.active_regs[reg_id];
1198 /* Don't warn, get_trigger_len already warned */ 1710 /* Don't warn, get_trigger_len already warned */
1199 if (!reg) 1711 if (!reg)
1200 continue; 1712 continue;
@@ -1202,39 +1714,75 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
1202 type = le32_to_cpu(reg->region_type); 1714 type = le32_to_cpu(reg->region_type);
1203 switch (type) { 1715 switch (type) {
1204 case IWL_FW_INI_REGION_DEVICE_MEMORY: 1716 case IWL_FW_INI_REGION_DEVICE_MEMORY:
1205 if (WARN_ON(le32_to_cpu(reg->num_regions) > 1)) 1717 case IWL_FW_INI_REGION_INTERNAL_BUFFER:
1206 continue; 1718 ops.get_num_of_ranges = iwl_dump_ini_mem_ranges;
1207 iwl_fw_dump_named_mem(fwrt, data, 1719 ops.get_size = iwl_dump_ini_mem_get_size;
1208 le32_to_cpu(reg->size), 1720 ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
1209 le32_to_cpu(reg->start_addr[0]), 1721 ops.fill_range = iwl_dump_ini_dev_mem_iter;
1210 reg->name, 1722 iwl_dump_ini_mem(fwrt, type, data, reg, &ops);
1211 le32_to_cpu(reg->name_len));
1212 break; 1723 break;
1213 case IWL_FW_INI_REGION_PERIPHERY_MAC: 1724 case IWL_FW_INI_REGION_PERIPHERY_MAC:
1214 case IWL_FW_INI_REGION_PERIPHERY_PHY: 1725 case IWL_FW_INI_REGION_PERIPHERY_PHY:
1215 case IWL_FW_INI_REGION_PERIPHERY_AUX: 1726 case IWL_FW_INI_REGION_PERIPHERY_AUX:
1216 iwl_dump_prph_ini(fwrt->trans, data, reg); 1727 ops.get_num_of_ranges = iwl_dump_ini_mem_ranges;
1728 ops.get_size = iwl_dump_ini_mem_get_size;
1729 ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
1730 ops.fill_range = iwl_dump_ini_prph_iter;
1731 iwl_dump_ini_mem(fwrt, type, data, reg, &ops);
1217 break; 1732 break;
1218 case IWL_FW_INI_REGION_DRAM_BUFFER: 1733 case IWL_FW_INI_REGION_DRAM_BUFFER:
1219 *dump_mask |= BIT(IWL_FW_ERROR_DUMP_FW_MONITOR); 1734 ops.get_num_of_ranges = iwl_dump_ini_mon_dram_ranges;
1735 ops.get_size = iwl_dump_ini_mon_dram_get_size;
1736 ops.fill_mem_hdr = iwl_dump_ini_mon_dram_fill_header;
1737 ops.fill_range = iwl_dump_ini_mon_dram_iter;
1738 iwl_dump_ini_mem(fwrt, type, data, reg, &ops);
1220 break; 1739 break;
1221 case IWL_FW_INI_REGION_PAGING: 1740 case IWL_FW_INI_REGION_PAGING: {
1222 if (iwl_fw_dbg_is_paging_enabled(fwrt)) 1741 ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
1223 iwl_dump_paging(fwrt, data); 1742 if (iwl_fw_dbg_is_paging_enabled(fwrt)) {
1224 else 1743 ops.get_num_of_ranges =
1225 *dump_mask |= BIT(IWL_FW_ERROR_DUMP_PAGING); 1744 iwl_dump_ini_paging_ranges;
1745 ops.get_size = iwl_dump_ini_paging_get_size;
1746 ops.fill_range = iwl_dump_ini_paging_iter;
1747 } else {
1748 ops.get_num_of_ranges =
1749 iwl_dump_ini_paging_gen2_ranges;
1750 ops.get_size =
1751 iwl_dump_ini_paging_gen2_get_size;
1752 ops.fill_range = iwl_dump_ini_paging_gen2_iter;
1753 }
1754
1755 iwl_dump_ini_mem(fwrt, type, data, reg, &ops);
1226 break; 1756 break;
1227 case IWL_FW_INI_REGION_TXF: 1757 }
1228 iwl_fw_dump_txf(fwrt, data); 1758 case IWL_FW_INI_REGION_TXF: {
1759 struct iwl_ini_txf_iter_data iter = { .init = true };
1760 void *fifo_iter = fwrt->dump.fifo_iter;
1761
1762 fwrt->dump.fifo_iter = &iter;
1763 ops.get_num_of_ranges = iwl_dump_ini_txf_ranges;
1764 ops.get_size = iwl_dump_ini_txf_get_size;
1765 ops.fill_mem_hdr = iwl_dump_ini_fifo_fill_header;
1766 ops.fill_range = iwl_dump_ini_txf_iter;
1767 iwl_dump_ini_mem(fwrt, type, data, reg, &ops);
1768 fwrt->dump.fifo_iter = fifo_iter;
1229 break; 1769 break;
1770 }
1230 case IWL_FW_INI_REGION_RXF: 1771 case IWL_FW_INI_REGION_RXF:
1231 iwl_fw_dump_rxf(fwrt, data); 1772 ops.get_num_of_ranges = iwl_dump_ini_rxf_ranges;
1773 ops.get_size = iwl_dump_ini_rxf_get_size;
1774 ops.fill_mem_hdr = iwl_dump_ini_fifo_fill_header;
1775 ops.fill_range = iwl_dump_ini_rxf_iter;
1776 iwl_dump_ini_mem(fwrt, type, data, reg, &ops);
1232 break; 1777 break;
1233 case IWL_FW_INI_REGION_CSR: 1778 case IWL_FW_INI_REGION_CSR:
1234 iwl_dump_csr_ini(fwrt->trans, data, reg); 1779 ops.get_num_of_ranges = iwl_dump_ini_mem_ranges;
1780 ops.get_size = iwl_dump_ini_mem_get_size;
1781 ops.fill_mem_hdr = iwl_dump_ini_mem_fill_header;
1782 ops.fill_range = iwl_dump_ini_csr_iter;
1783 iwl_dump_ini_mem(fwrt, type, data, reg, &ops);
1235 break; 1784 break;
1236 case IWL_FW_INI_REGION_DRAM_IMR: 1785 case IWL_FW_INI_REGION_DRAM_IMR:
1237 case IWL_FW_INI_REGION_INTERNAL_BUFFER:
1238 /* This is undefined yet */ 1786 /* This is undefined yet */
1239 default: 1787 default:
1240 break; 1788 break;
@@ -1244,26 +1792,23 @@ static void iwl_fw_ini_dump_trigger(struct iwl_fw_runtime *fwrt,
1244 1792
1245static struct iwl_fw_error_dump_file * 1793static struct iwl_fw_error_dump_file *
1246_iwl_fw_error_ini_dump(struct iwl_fw_runtime *fwrt, 1794_iwl_fw_error_ini_dump(struct iwl_fw_runtime *fwrt,
1247 struct iwl_fw_dump_ptrs *fw_error_dump, 1795 struct iwl_fw_dump_ptrs *fw_error_dump)
1248 u32 *dump_mask)
1249{ 1796{
1250 int size, id = le32_to_cpu(fwrt->dump.desc->trig_desc.type); 1797 int size, id = le32_to_cpu(fwrt->dump.desc->trig_desc.type);
1251 struct iwl_fw_error_dump_data *dump_data; 1798 struct iwl_fw_error_dump_data *dump_data;
1252 struct iwl_fw_error_dump_file *dump_file; 1799 struct iwl_fw_error_dump_file *dump_file;
1253 struct iwl_fw_ini_trigger *trigger, *ext; 1800 struct iwl_fw_ini_trigger *trigger;
1254 1801
1255 if (id == FW_DBG_TRIGGER_FW_ASSERT) 1802 if (id == FW_DBG_TRIGGER_FW_ASSERT)
1256 id = IWL_FW_TRIGGER_ID_FW_ASSERT; 1803 id = IWL_FW_TRIGGER_ID_FW_ASSERT;
1257 1804
1258 if (WARN_ON(id >= ARRAY_SIZE(fwrt->dump.active_trigs))) 1805 if (!iwl_fw_ini_trigger_on(fwrt, id))
1259 return NULL; 1806 return NULL;
1260 1807
1261 trigger = fwrt->dump.active_trigs[id].conf; 1808 trigger = fwrt->dump.active_trigs[id].trig;
1262 ext = fwrt->dump.active_trigs[id].conf_ext;
1263 1809
1264 size = sizeof(*dump_file); 1810 size = sizeof(*dump_file);
1265 size += iwl_fw_ini_get_trigger_len(fwrt, trigger); 1811 size += iwl_fw_ini_get_trigger_len(fwrt, trigger);
1266 size += iwl_fw_ini_get_trigger_len(fwrt, ext);
1267 1812
1268 if (!size) 1813 if (!size)
1269 return NULL; 1814 return NULL;
@@ -1278,11 +1823,7 @@ _iwl_fw_error_ini_dump(struct iwl_fw_runtime *fwrt,
1278 dump_data = (void *)dump_file->data; 1823 dump_data = (void *)dump_file->data;
1279 dump_file->file_len = cpu_to_le32(size); 1824 dump_file->file_len = cpu_to_le32(size);
1280 1825
1281 *dump_mask = 0; 1826 iwl_fw_ini_dump_trigger(fwrt, trigger, &dump_data);
1282 if (trigger)
1283 iwl_fw_ini_dump_trigger(fwrt, trigger, &dump_data, dump_mask);
1284 if (ext)
1285 iwl_fw_ini_dump_trigger(fwrt, ext, &dump_data, dump_mask);
1286 1827
1287 return dump_file; 1828 return dump_file;
1288} 1829}
@@ -1308,8 +1849,7 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
1308 goto out; 1849 goto out;
1309 1850
1310 if (fwrt->trans->ini_valid) 1851 if (fwrt->trans->ini_valid)
1311 dump_file = _iwl_fw_error_ini_dump(fwrt, fw_error_dump, 1852 dump_file = _iwl_fw_error_ini_dump(fwrt, fw_error_dump);
1312 &dump_mask);
1313 else 1853 else
1314 dump_file = _iwl_fw_error_dump(fwrt, fw_error_dump); 1854 dump_file = _iwl_fw_error_dump(fwrt, fw_error_dump);
1315 1855
@@ -1321,7 +1861,10 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
1321 if (!fwrt->trans->ini_valid && fwrt->dump.monitor_only) 1861 if (!fwrt->trans->ini_valid && fwrt->dump.monitor_only)
1322 dump_mask &= IWL_FW_ERROR_DUMP_FW_MONITOR; 1862 dump_mask &= IWL_FW_ERROR_DUMP_FW_MONITOR;
1323 1863
1324 fw_error_dump->trans_ptr = iwl_trans_dump_data(fwrt->trans, dump_mask); 1864 if (!fwrt->trans->ini_valid)
1865 fw_error_dump->trans_ptr =
1866 iwl_trans_dump_data(fwrt->trans, dump_mask);
1867
1325 file_len = le32_to_cpu(dump_file->file_len); 1868 file_len = le32_to_cpu(dump_file->file_len);
1326 fw_error_dump->fwrt_len = file_len; 1869 fw_error_dump->fwrt_len = file_len;
1327 if (fw_error_dump->trans_ptr) { 1870 if (fw_error_dump->trans_ptr) {
@@ -1362,61 +1905,12 @@ const struct iwl_fw_dump_desc iwl_dump_desc_assert = {
1362}; 1905};
1363IWL_EXPORT_SYMBOL(iwl_dump_desc_assert); 1906IWL_EXPORT_SYMBOL(iwl_dump_desc_assert);
1364 1907
1365void iwl_fw_assert_error_dump(struct iwl_fw_runtime *fwrt)
1366{
1367 IWL_INFO(fwrt, "error dump due to fw assert\n");
1368 fwrt->dump.desc = &iwl_dump_desc_assert;
1369 iwl_fw_error_dump(fwrt);
1370}
1371IWL_EXPORT_SYMBOL(iwl_fw_assert_error_dump);
1372
1373void iwl_fw_alive_error_dump(struct iwl_fw_runtime *fwrt)
1374{
1375 struct iwl_fw_dump_desc *iwl_dump_desc_no_alive =
1376 kmalloc(sizeof(*iwl_dump_desc_no_alive), GFP_KERNEL);
1377
1378 if (!iwl_dump_desc_no_alive)
1379 return;
1380
1381 iwl_dump_desc_no_alive->trig_desc.type =
1382 cpu_to_le32(FW_DBG_TRIGGER_NO_ALIVE);
1383 iwl_dump_desc_no_alive->len = 0;
1384
1385 if (WARN_ON(fwrt->dump.desc))
1386 iwl_fw_free_dump_desc(fwrt);
1387
1388 IWL_WARN(fwrt, "Collecting data: trigger %d fired.\n",
1389 FW_DBG_TRIGGER_NO_ALIVE);
1390
1391 fwrt->dump.desc = iwl_dump_desc_no_alive;
1392 iwl_fw_error_dump(fwrt);
1393 clear_bit(IWL_FWRT_STATUS_WAIT_ALIVE, &fwrt->status);
1394}
1395IWL_EXPORT_SYMBOL(iwl_fw_alive_error_dump);
1396
1397int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt, 1908int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
1398 const struct iwl_fw_dump_desc *desc, 1909 const struct iwl_fw_dump_desc *desc,
1399 bool monitor_only, 1910 bool monitor_only,
1400 unsigned int delay) 1911 unsigned int delay)
1401{ 1912{
1402 /* 1913 if (test_and_set_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status))
1403 * If the loading of the FW completed successfully, the next step is to
1404 * get the SMEM config data. Thus, if fwrt->smem_cfg.num_lmacs is non
1405 * zero, the FW was already loaded successully. If the state is "NO_FW"
1406 * in such a case - exit, since FW may be dead. Otherwise, we
1407 * can try to collect the data, since FW might just not be fully
1408 * loaded (no "ALIVE" yet), and the debug data is accessible.
1409 *
1410 * Corner case: got the FW alive but crashed before getting the SMEM
1411 * config. In such a case, due to HW access problems, we might
1412 * collect garbage.
1413 */
1414 if (fwrt->trans->state == IWL_TRANS_NO_FW &&
1415 fwrt->smem_cfg.num_lmacs)
1416 return -EIO;
1417
1418 if (test_and_set_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status) ||
1419 test_bit(IWL_FWRT_STATUS_WAIT_ALIVE, &fwrt->status))
1420 return -EBUSY; 1914 return -EBUSY;
1421 1915
1422 if (WARN_ON(fwrt->dump.desc)) 1916 if (WARN_ON(fwrt->dump.desc))
@@ -1428,12 +1922,39 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
1428 fwrt->dump.desc = desc; 1922 fwrt->dump.desc = desc;
1429 fwrt->dump.monitor_only = monitor_only; 1923 fwrt->dump.monitor_only = monitor_only;
1430 1924
1431 schedule_delayed_work(&fwrt->dump.wk, delay); 1925 schedule_delayed_work(&fwrt->dump.wk, usecs_to_jiffies(delay));
1432 1926
1433 return 0; 1927 return 0;
1434} 1928}
1435IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect_desc); 1929IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect_desc);
1436 1930
1931int iwl_fw_dbg_error_collect(struct iwl_fw_runtime *fwrt,
1932 enum iwl_fw_dbg_trigger trig_type)
1933{
1934 int ret;
1935 struct iwl_fw_dump_desc *iwl_dump_error_desc =
1936 kmalloc(sizeof(*iwl_dump_error_desc), GFP_KERNEL);
1937
1938 if (!iwl_dump_error_desc)
1939 return -ENOMEM;
1940
1941 iwl_dump_error_desc->trig_desc.type = cpu_to_le32(trig_type);
1942 iwl_dump_error_desc->len = 0;
1943
1944 ret = iwl_fw_dbg_collect_desc(fwrt, iwl_dump_error_desc, false, 0);
1945 if (ret) {
1946 kfree(iwl_dump_error_desc);
1947 } else {
1948 set_bit(STATUS_FW_WAIT_DUMP, &fwrt->trans->status);
1949
1950 /* trigger nmi to halt the fw */
1951 iwl_force_nmi(fwrt->trans);
1952 }
1953
1954 return ret;
1955}
1956IWL_EXPORT_SYMBOL(iwl_fw_dbg_error_collect);
1957
1437int _iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt, 1958int _iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
1438 enum iwl_fw_dbg_trigger trig, 1959 enum iwl_fw_dbg_trigger trig,
1439 const char *str, size_t len, 1960 const char *str, size_t len,
@@ -1457,8 +1978,10 @@ int _iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
1457 } 1978 }
1458 1979
1459 trigger->occurrences = cpu_to_le16(occurrences); 1980 trigger->occurrences = cpu_to_le16(occurrences);
1460 delay = le16_to_cpu(trigger->trig_dis_ms);
1461 monitor_only = trigger->mode & IWL_FW_DBG_TRIGGER_MONITOR_ONLY; 1981 monitor_only = trigger->mode & IWL_FW_DBG_TRIGGER_MONITOR_ONLY;
1982
1983 /* convert msec to usec */
1984 delay = le32_to_cpu(trigger->stop_delay) * USEC_PER_MSEC;
1462 } 1985 }
1463 1986
1464 desc = kzalloc(sizeof(*desc) + len, GFP_ATOMIC); 1987 desc = kzalloc(sizeof(*desc) + len, GFP_ATOMIC);
@@ -1478,6 +2001,7 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
1478 u32 id, const char *str, size_t len) 2001 u32 id, const char *str, size_t len)
1479{ 2002{
1480 struct iwl_fw_dump_desc *desc; 2003 struct iwl_fw_dump_desc *desc;
2004 struct iwl_fw_ini_active_triggers *active;
1481 u32 occur, delay; 2005 u32 occur, delay;
1482 2006
1483 if (!fwrt->trans->ini_valid) 2007 if (!fwrt->trans->ini_valid)
@@ -1486,15 +2010,17 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
1486 if (id == FW_DBG_TRIGGER_USER) 2010 if (id == FW_DBG_TRIGGER_USER)
1487 id = IWL_FW_TRIGGER_ID_USER_TRIGGER; 2011 id = IWL_FW_TRIGGER_ID_USER_TRIGGER;
1488 2012
1489 if (WARN_ON(!fwrt->dump.active_trigs[id].active)) 2013 active = &fwrt->dump.active_trigs[id];
2014
2015 if (WARN_ON(!active->active))
1490 return -EINVAL; 2016 return -EINVAL;
1491 2017
1492 delay = le32_to_cpu(fwrt->dump.active_trigs[id].conf->dump_delay); 2018 delay = le32_to_cpu(active->trig->dump_delay);
1493 occur = le32_to_cpu(fwrt->dump.active_trigs[id].conf->occurrences); 2019 occur = le32_to_cpu(active->trig->occurrences);
1494 if (!occur) 2020 if (!occur)
1495 return 0; 2021 return 0;
1496 2022
1497 if (le32_to_cpu(fwrt->dump.active_trigs[id].conf->force_restart)) { 2023 if (le32_to_cpu(active->trig->force_restart)) {
1498 IWL_WARN(fwrt, "Force restart: trigger %d fired.\n", id); 2024 IWL_WARN(fwrt, "Force restart: trigger %d fired.\n", id);
1499 iwl_force_nmi(fwrt->trans); 2025 iwl_force_nmi(fwrt->trans);
1500 return 0; 2026 return 0;
@@ -1504,8 +2030,7 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
1504 if (!desc) 2030 if (!desc)
1505 return -ENOMEM; 2031 return -ENOMEM;
1506 2032
1507 occur--; 2033 active->trig->occurrences = cpu_to_le32(--occur);
1508 fwrt->dump.active_trigs[id].conf->occurrences = cpu_to_le32(occur);
1509 2034
1510 desc->len = len; 2035 desc->len = len;
1511 desc->trig_desc.type = cpu_to_le32(id); 2036 desc->trig_desc.type = cpu_to_le32(id);
@@ -1670,27 +2195,13 @@ void iwl_fw_dbg_read_d3_debug_data(struct iwl_fw_runtime *fwrt)
1670IWL_EXPORT_SYMBOL(iwl_fw_dbg_read_d3_debug_data); 2195IWL_EXPORT_SYMBOL(iwl_fw_dbg_read_d3_debug_data);
1671 2196
1672static void 2197static void
1673iwl_fw_dbg_buffer_allocation(struct iwl_fw_runtime *fwrt, 2198iwl_fw_dbg_buffer_allocation(struct iwl_fw_runtime *fwrt, u32 size)
1674 struct iwl_fw_ini_allocation_tlv *alloc)
1675{ 2199{
1676 struct iwl_trans *trans = fwrt->trans; 2200 struct iwl_trans *trans = fwrt->trans;
1677 struct iwl_ldbg_config_cmd ldbg_cmd = {
1678 .type = cpu_to_le32(BUFFER_ALLOCATION),
1679 };
1680 struct iwl_buffer_allocation_cmd *cmd = &ldbg_cmd.buffer_allocation;
1681 struct iwl_host_cmd hcmd = {
1682 .id = LDBG_CONFIG_CMD,
1683 .flags = CMD_ASYNC,
1684 .data[0] = &ldbg_cmd,
1685 .len[0] = sizeof(ldbg_cmd),
1686 };
1687 void *virtual_addr = NULL; 2201 void *virtual_addr = NULL;
1688 u32 size = le32_to_cpu(alloc->size);
1689 dma_addr_t phys_addr; 2202 dma_addr_t phys_addr;
1690 2203
1691 if (!trans->num_blocks && 2204 if (WARN_ON_ONCE(trans->num_blocks == ARRAY_SIZE(trans->fw_mon)))
1692 le32_to_cpu(alloc->buffer_location) !=
1693 IWL_FW_INI_LOCATION_DRAM_PATH)
1694 return; 2205 return;
1695 2206
1696 virtual_addr = 2207 virtual_addr =
@@ -1702,25 +2213,63 @@ iwl_fw_dbg_buffer_allocation(struct iwl_fw_runtime *fwrt,
1702 if (!virtual_addr) 2213 if (!virtual_addr)
1703 IWL_ERR(fwrt, "Failed to allocate debug memory\n"); 2214 IWL_ERR(fwrt, "Failed to allocate debug memory\n");
1704 2215
1705 if (WARN_ON_ONCE(trans->num_blocks == ARRAY_SIZE(trans->fw_mon)))
1706 return;
1707
1708 trans->fw_mon[trans->num_blocks].block = virtual_addr; 2216 trans->fw_mon[trans->num_blocks].block = virtual_addr;
1709 trans->fw_mon[trans->num_blocks].physical = phys_addr; 2217 trans->fw_mon[trans->num_blocks].physical = phys_addr;
1710 trans->fw_mon[trans->num_blocks].size = size; 2218 trans->fw_mon[trans->num_blocks].size = size;
1711 trans->num_blocks++; 2219 trans->num_blocks++;
1712 2220
1713 IWL_DEBUG_FW(trans, "Allocated debug block of size %d\n", size); 2221 IWL_DEBUG_FW(trans, "Allocated debug block of size %d\n", size);
2222}
2223
2224static void iwl_fw_dbg_buffer_apply(struct iwl_fw_runtime *fwrt,
2225 struct iwl_fw_ini_allocation_data *alloc,
2226 enum iwl_fw_ini_apply_point pnt)
2227{
2228 struct iwl_trans *trans = fwrt->trans;
2229 struct iwl_ldbg_config_cmd ldbg_cmd = {
2230 .type = cpu_to_le32(BUFFER_ALLOCATION),
2231 };
2232 struct iwl_buffer_allocation_cmd *cmd = &ldbg_cmd.buffer_allocation;
2233 struct iwl_host_cmd hcmd = {
2234 .id = LDBG_CONFIG_CMD,
2235 .flags = CMD_ASYNC,
2236 .data[0] = &ldbg_cmd,
2237 .len[0] = sizeof(ldbg_cmd),
2238 };
2239 int block_idx = trans->num_blocks;
2240 u32 buf_location = le32_to_cpu(alloc->tlv.buffer_location);
2241
2242 if (buf_location == IWL_FW_INI_LOCATION_SRAM_PATH) {
2243 if (!WARN(pnt != IWL_FW_INI_APPLY_EARLY,
2244 "Invalid apply point %d for SMEM buffer allocation",
2245 pnt))
2246 /* set sram monitor by enabling bit 7 */
2247 iwl_set_bit(fwrt->trans, CSR_HW_IF_CONFIG_REG,
2248 CSR_HW_IF_CONFIG_REG_BIT_MONITOR_SRAM);
2249 return;
2250 }
2251
2252 if (buf_location != IWL_FW_INI_LOCATION_DRAM_PATH)
2253 return;
2254
2255 if (!alloc->is_alloc) {
2256 iwl_fw_dbg_buffer_allocation(fwrt,
2257 le32_to_cpu(alloc->tlv.size));
2258 if (block_idx == trans->num_blocks)
2259 return;
2260 alloc->is_alloc = 1;
2261 }
1714 2262
1715 /* First block is assigned via registers / context info */ 2263 /* First block is assigned via registers / context info */
1716 if (trans->num_blocks == 1) 2264 if (trans->num_blocks == 1)
1717 return; 2265 return;
1718 2266
1719 cmd->num_frags = cpu_to_le32(1); 2267 cmd->num_frags = cpu_to_le32(1);
1720 cmd->fragments[0].address = cpu_to_le64(phys_addr); 2268 cmd->fragments[0].address =
1721 cmd->fragments[0].size = alloc->size; 2269 cpu_to_le64(trans->fw_mon[block_idx].physical);
1722 cmd->allocation_id = alloc->allocation_id; 2270 cmd->fragments[0].size = alloc->tlv.size;
1723 cmd->buffer_location = alloc->buffer_location; 2271 cmd->allocation_id = alloc->tlv.allocation_id;
2272 cmd->buffer_location = alloc->tlv.buffer_location;
1724 2273
1725 iwl_trans_send_cmd(trans, &hcmd); 2274 iwl_trans_send_cmd(trans, &hcmd);
1726} 2275}
@@ -1749,9 +2298,9 @@ static void iwl_fw_dbg_update_regions(struct iwl_fw_runtime *fwrt,
1749 int i, size = le32_to_cpu(tlv->num_regions); 2298 int i, size = le32_to_cpu(tlv->num_regions);
1750 2299
1751 for (i = 0; i < size; i++) { 2300 for (i = 0; i < size; i++) {
1752 struct iwl_fw_ini_region_cfg *reg = iter; 2301 struct iwl_fw_ini_region_cfg *reg = iter, **active;
1753 int id = le32_to_cpu(reg->region_id); 2302 int id = le32_to_cpu(reg->region_id);
1754 struct iwl_fw_ini_active_regs *active; 2303 u32 type = le32_to_cpu(reg->region_type);
1755 2304
1756 if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_regs), 2305 if (WARN(id >= ARRAY_SIZE(fwrt->dump.active_regs),
1757 "Invalid region id %d for apply point %d\n", id, pnt)) 2306 "Invalid region id %d for apply point %d\n", id, pnt))
@@ -1759,26 +2308,47 @@ static void iwl_fw_dbg_update_regions(struct iwl_fw_runtime *fwrt,
1759 2308
1760 active = &fwrt->dump.active_regs[id]; 2309 active = &fwrt->dump.active_regs[id];
1761 2310
1762 if (ext && active->apply_point == pnt) 2311 if (*active)
1763 IWL_WARN(fwrt->trans, 2312 IWL_WARN(fwrt->trans, "region TLV %d override\n", id);
1764 "External region TLV overrides FW default %x\n",
1765 id);
1766 2313
1767 IWL_DEBUG_FW(fwrt, 2314 IWL_DEBUG_FW(fwrt,
1768 "%s: apply point %d, activating region ID %d\n", 2315 "%s: apply point %d, activating region ID %d\n",
1769 __func__, pnt, id); 2316 __func__, pnt, id);
1770 2317
1771 active->reg = reg; 2318 *active = reg;
1772 active->apply_point = pnt;
1773 2319
1774 if (le32_to_cpu(reg->region_type) != 2320 if (type == IWL_FW_INI_REGION_TXF ||
1775 IWL_FW_INI_REGION_DRAM_BUFFER) 2321 type == IWL_FW_INI_REGION_RXF)
1776 iter += le32_to_cpu(reg->num_regions) * sizeof(__le32); 2322 iter += le32_to_cpu(reg->fifos.num_of_registers) *
2323 sizeof(__le32);
2324 else if (type != IWL_FW_INI_REGION_DRAM_BUFFER)
2325 iter += le32_to_cpu(reg->internal.num_of_ranges) *
2326 sizeof(__le32);
1777 2327
1778 iter += sizeof(*reg); 2328 iter += sizeof(*reg);
1779 } 2329 }
1780} 2330}
1781 2331
2332static int iwl_fw_dbg_trig_realloc(struct iwl_fw_runtime *fwrt,
2333 struct iwl_fw_ini_active_triggers *active,
2334 u32 id, int size)
2335{
2336 void *ptr;
2337
2338 if (size <= active->size)
2339 return 0;
2340
2341 ptr = krealloc(active->trig, size, GFP_KERNEL);
2342 if (!ptr) {
2343 IWL_ERR(fwrt, "Failed to allocate memory for trigger %d\n", id);
2344 return -ENOMEM;
2345 }
2346 active->trig = ptr;
2347 active->size = size;
2348
2349 return 0;
2350}
2351
1782static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt, 2352static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt,
1783 struct iwl_fw_ini_trigger_tlv *tlv, 2353 struct iwl_fw_ini_trigger_tlv *tlv,
1784 bool ext, 2354 bool ext,
@@ -1791,43 +2361,61 @@ static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt,
1791 struct iwl_fw_ini_trigger *trig = iter; 2361 struct iwl_fw_ini_trigger *trig = iter;
1792 struct iwl_fw_ini_active_triggers *active; 2362 struct iwl_fw_ini_active_triggers *active;
1793 int id = le32_to_cpu(trig->trigger_id); 2363 int id = le32_to_cpu(trig->trigger_id);
1794 u32 num; 2364 u32 trig_regs_size = le32_to_cpu(trig->num_regions) *
2365 sizeof(__le32);
1795 2366
1796 if (WARN_ON(id >= ARRAY_SIZE(fwrt->dump.active_trigs))) 2367 if (WARN_ON(id >= ARRAY_SIZE(fwrt->dump.active_trigs)))
1797 break; 2368 break;
1798 2369
1799 active = &fwrt->dump.active_trigs[id]; 2370 active = &fwrt->dump.active_trigs[id];
1800 2371
1801 if (active->apply_point != apply_point) { 2372 if (!active->active) {
1802 active->conf = NULL; 2373 size_t trig_size = sizeof(*trig) + trig_regs_size;
1803 active->conf_ext = NULL;
1804 }
1805 2374
1806 num = le32_to_cpu(trig->num_regions); 2375 if (iwl_fw_dbg_trig_realloc(fwrt, active, id,
2376 trig_size))
2377 goto next;
1807 2378
1808 if (ext && active->apply_point == apply_point) { 2379 memcpy(active->trig, trig, trig_size);
1809 num += le32_to_cpu(active->conf->num_regions); 2380
1810 if (trig->ignore_default) { 2381 } else {
1811 active->conf_ext = active->conf; 2382 u32 conf_override =
1812 active->conf = trig; 2383 !(le32_to_cpu(trig->override_trig) & 0xff);
2384 u32 region_override =
2385 !(le32_to_cpu(trig->override_trig) & 0xff00);
2386 u32 offset = 0;
2387 u32 active_regs =
2388 le32_to_cpu(active->trig->num_regions);
2389 u32 new_regs = le32_to_cpu(trig->num_regions);
2390 int mem_to_add = trig_regs_size;
2391
2392 if (region_override) {
2393 mem_to_add -= active_regs * sizeof(__le32);
1813 } else { 2394 } else {
1814 active->conf_ext = trig; 2395 offset += active_regs;
2396 new_regs += active_regs;
1815 } 2397 }
1816 } else { 2398
1817 active->conf = trig; 2399 if (iwl_fw_dbg_trig_realloc(fwrt, active, id,
2400 active->size + mem_to_add))
2401 goto next;
2402
2403 if (conf_override)
2404 memcpy(active->trig, trig, sizeof(*trig));
2405
2406 memcpy(active->trig->data + offset, trig->data,
2407 trig_regs_size);
2408 active->trig->num_regions = cpu_to_le32(new_regs);
1818 } 2409 }
1819 2410
1820 /* Since zero means infinity - just set to -1 */ 2411 /* Since zero means infinity - just set to -1 */
1821 if (!le32_to_cpu(trig->occurrences)) 2412 if (!le32_to_cpu(active->trig->occurrences))
1822 trig->occurrences = cpu_to_le32(-1); 2413 active->trig->occurrences = cpu_to_le32(-1);
1823 if (!le32_to_cpu(trig->ignore_consec))
1824 trig->ignore_consec = cpu_to_le32(-1);
1825 2414
1826 iter += sizeof(*trig) + 2415 active->active = true;
1827 le32_to_cpu(trig->num_regions) * sizeof(__le32); 2416next:
2417 iter += sizeof(*trig) + trig_regs_size;
1828 2418
1829 active->active = num;
1830 active->apply_point = apply_point;
1831 } 2419 }
1832} 2420}
1833 2421
@@ -1844,9 +2432,13 @@ static void _iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
1844 u32 type = le32_to_cpu(tlv->type); 2432 u32 type = le32_to_cpu(tlv->type);
1845 2433
1846 switch (type) { 2434 switch (type) {
1847 case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION: 2435 case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION: {
1848 iwl_fw_dbg_buffer_allocation(fwrt, ini_tlv); 2436 struct iwl_fw_ini_allocation_data *buf_alloc = ini_tlv;
2437
2438 iwl_fw_dbg_buffer_apply(fwrt, ini_tlv, pnt);
2439 iter += sizeof(buf_alloc->is_alloc);
1849 break; 2440 break;
2441 }
1850 case IWL_UCODE_TLV_TYPE_HCMD: 2442 case IWL_UCODE_TLV_TYPE_HCMD:
1851 if (pnt < IWL_FW_INI_APPLY_AFTER_ALIVE) { 2443 if (pnt < IWL_FW_INI_APPLY_AFTER_ALIVE) {
1852 IWL_ERR(fwrt, 2444 IWL_ERR(fwrt,
@@ -1877,6 +2469,16 @@ void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
1877 enum iwl_fw_ini_apply_point apply_point) 2469 enum iwl_fw_ini_apply_point apply_point)
1878{ 2470{
1879 void *data = &fwrt->trans->apply_points[apply_point]; 2471 void *data = &fwrt->trans->apply_points[apply_point];
2472 int i;
2473
2474 if (apply_point == IWL_FW_INI_APPLY_EARLY) {
2475 for (i = 0; i < IWL_FW_INI_MAX_REGION_ID; i++)
2476 fwrt->dump.active_regs[i] = NULL;
2477
2478 /* disable the triggers, used in recovery flow */
2479 for (i = 0; i < IWL_FW_TRIGGER_ID_NUM; i++)
2480 fwrt->dump.active_trigs[i].active = false;
2481 }
1880 2482
1881 _iwl_fw_dbg_apply_point(fwrt, data, apply_point, false); 2483 _iwl_fw_dbg_apply_point(fwrt, data, apply_point, false);
1882 2484
@@ -1884,3 +2486,27 @@ void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
1884 _iwl_fw_dbg_apply_point(fwrt, data, apply_point, true); 2486 _iwl_fw_dbg_apply_point(fwrt, data, apply_point, true);
1885} 2487}
1886IWL_EXPORT_SYMBOL(iwl_fw_dbg_apply_point); 2488IWL_EXPORT_SYMBOL(iwl_fw_dbg_apply_point);
2489
2490void iwl_fwrt_stop_device(struct iwl_fw_runtime *fwrt)
2491{
2492 /* if the wait event timeout elapses instead of wake up then
2493 * the driver did not receive NMI interrupt and can not assume the FW
2494 * is halted
2495 */
2496 int ret = wait_event_timeout(fwrt->trans->fw_halt_waitq,
2497 !test_bit(STATUS_FW_WAIT_DUMP,
2498 &fwrt->trans->status),
2499 msecs_to_jiffies(2000));
2500 if (!ret) {
2501 /* failed to receive NMI interrupt, assuming the FW is stuck */
2502 set_bit(STATUS_FW_ERROR, &fwrt->trans->status);
2503
2504 clear_bit(STATUS_FW_WAIT_DUMP, &fwrt->trans->status);
2505 }
2506
2507 /* Assuming the op mode mutex is held at this point */
2508 iwl_fw_dbg_collect_sync(fwrt);
2509
2510 iwl_trans_stop_device(fwrt->trans);
2511}
2512IWL_EXPORT_SYMBOL(iwl_fwrt_stop_device);
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
index 330229d2a61d..a199056234d3 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
@@ -8,7 +8,7 @@
8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 10 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
11 * Copyright(c) 2018 Intel Corporation 11 * Copyright(c) 2018 - 2019 Intel Corporation
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of version 2 of the GNU General Public License as 14 * it under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
31 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 31 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
33 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 33 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
34 * Copyright(c) 2018 Intel Corporation 34 * Copyright(c) 2018 - 2019 Intel Corporation
35 * All rights reserved. 35 * All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -112,6 +112,8 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt);
112int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt, 112int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
113 const struct iwl_fw_dump_desc *desc, 113 const struct iwl_fw_dump_desc *desc,
114 bool monitor_only, unsigned int delay); 114 bool monitor_only, unsigned int delay);
115int iwl_fw_dbg_error_collect(struct iwl_fw_runtime *fwrt,
116 enum iwl_fw_dbg_trigger trig_type);
115int _iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt, 117int _iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
116 enum iwl_fw_dbg_trigger trig, 118 enum iwl_fw_dbg_trigger trig,
117 const char *str, size_t len, 119 const char *str, size_t len,
@@ -160,9 +162,9 @@ iwl_fw_dbg_trigger_stop_conf_match(struct iwl_fw_runtime *fwrt,
160} 162}
161 163
162static inline bool 164static inline bool
163iwl_fw_dbg_no_trig_window(struct iwl_fw_runtime *fwrt, u32 id, u32 dis_ms) 165iwl_fw_dbg_no_trig_window(struct iwl_fw_runtime *fwrt, u32 id, u32 dis_usec)
164{ 166{
165 unsigned long wind_jiff = msecs_to_jiffies(dis_ms); 167 unsigned long wind_jiff = usecs_to_jiffies(dis_usec);
166 168
167 /* If this is the first event checked, jump to update start ts */ 169 /* If this is the first event checked, jump to update start ts */
168 if (fwrt->dump.non_collect_ts_start[id] && 170 if (fwrt->dump.non_collect_ts_start[id] &&
@@ -179,11 +181,12 @@ iwl_fw_dbg_trigger_check_stop(struct iwl_fw_runtime *fwrt,
179 struct wireless_dev *wdev, 181 struct wireless_dev *wdev,
180 struct iwl_fw_dbg_trigger_tlv *trig) 182 struct iwl_fw_dbg_trigger_tlv *trig)
181{ 183{
184 u32 usec = le16_to_cpu(trig->trig_dis_ms) * USEC_PER_MSEC;
185
182 if (wdev && !iwl_fw_dbg_trigger_vif_match(trig, wdev)) 186 if (wdev && !iwl_fw_dbg_trigger_vif_match(trig, wdev))
183 return false; 187 return false;
184 188
185 if (iwl_fw_dbg_no_trig_window(fwrt, le32_to_cpu(trig->id), 189 if (iwl_fw_dbg_no_trig_window(fwrt, le32_to_cpu(trig->id), usec)) {
186 le16_to_cpu(trig->trig_dis_ms))) {
187 IWL_WARN(fwrt, "Trigger %d occurred while no-collect window.\n", 190 IWL_WARN(fwrt, "Trigger %d occurred while no-collect window.\n",
188 trig->id); 191 trig->id);
189 return false; 192 return false;
@@ -220,23 +223,22 @@ _iwl_fw_dbg_trigger_on(struct iwl_fw_runtime *fwrt,
220}) 223})
221 224
222static inline bool 225static inline bool
223_iwl_fw_ini_trigger_on(struct iwl_fw_runtime *fwrt, 226iwl_fw_ini_trigger_on(struct iwl_fw_runtime *fwrt,
224 const enum iwl_fw_dbg_trigger id) 227 enum iwl_fw_ini_trigger_id id)
225{ 228{
226 struct iwl_fw_ini_active_triggers *trig = &fwrt->dump.active_trigs[id]; 229 struct iwl_fw_ini_trigger *trig;
227 u32 ms; 230 u32 usec;
231
228 232
229 if (!fwrt->trans->ini_valid)
230 return false;
231 233
232 if (!trig || !trig->active) 234 if (!fwrt->trans->ini_valid || id >= IWL_FW_TRIGGER_ID_NUM ||
235 !fwrt->dump.active_trigs[id].active)
233 return false; 236 return false;
234 237
235 ms = le32_to_cpu(trig->conf->ignore_consec); 238 trig = fwrt->dump.active_trigs[id].trig;
236 if (ms) 239 usec = le32_to_cpu(trig->ignore_consec);
237 ms /= USEC_PER_MSEC;
238 240
239 if (iwl_fw_dbg_no_trig_window(fwrt, id, ms)) { 241 if (iwl_fw_dbg_no_trig_window(fwrt, id, usec)) {
240 IWL_WARN(fwrt, "Trigger %d fired in no-collect window\n", id); 242 IWL_WARN(fwrt, "Trigger %d fired in no-collect window\n", id);
241 return false; 243 return false;
242 } 244 }
@@ -244,12 +246,6 @@ _iwl_fw_ini_trigger_on(struct iwl_fw_runtime *fwrt,
244 return true; 246 return true;
245} 247}
246 248
247#define iwl_fw_ini_trigger_on(fwrt, wdev, id) ({ \
248 BUILD_BUG_ON(!__builtin_constant_p(id)); \
249 BUILD_BUG_ON((id) >= IWL_FW_TRIGGER_ID_NUM); \
250 _iwl_fw_ini_trigger_on((fwrt), (wdev), (id)); \
251})
252
253static inline void 249static inline void
254_iwl_fw_dbg_trigger_simple_stop(struct iwl_fw_runtime *fwrt, 250_iwl_fw_dbg_trigger_simple_stop(struct iwl_fw_runtime *fwrt,
255 struct wireless_dev *wdev, 251 struct wireless_dev *wdev,
@@ -296,13 +292,13 @@ _iwl_fw_dbg_stop_recording(struct iwl_trans *trans,
296 } 292 }
297 293
298 if (params) { 294 if (params) {
299 params->in_sample = iwl_read_prph(trans, DBGC_IN_SAMPLE); 295 params->in_sample = iwl_read_umac_prph(trans, DBGC_IN_SAMPLE);
300 params->out_ctrl = iwl_read_prph(trans, DBGC_OUT_CTRL); 296 params->out_ctrl = iwl_read_umac_prph(trans, DBGC_OUT_CTRL);
301 } 297 }
302 298
303 iwl_write_prph(trans, DBGC_IN_SAMPLE, 0); 299 iwl_write_umac_prph(trans, DBGC_IN_SAMPLE, 0);
304 udelay(100); 300 udelay(100);
305 iwl_write_prph(trans, DBGC_OUT_CTRL, 0); 301 iwl_write_umac_prph(trans, DBGC_OUT_CTRL, 0);
306#ifdef CONFIG_IWLWIFI_DEBUGFS 302#ifdef CONFIG_IWLWIFI_DEBUGFS
307 trans->dbg_rec_on = false; 303 trans->dbg_rec_on = false;
308#endif 304#endif
@@ -330,9 +326,9 @@ _iwl_fw_dbg_restart_recording(struct iwl_trans *trans,
330 iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1); 326 iwl_clear_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1);
331 iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1); 327 iwl_set_bits_prph(trans, MON_BUFF_SAMPLE_CTL, 0x1);
332 } else { 328 } else {
333 iwl_write_prph(trans, DBGC_IN_SAMPLE, params->in_sample); 329 iwl_write_umac_prph(trans, DBGC_IN_SAMPLE, params->in_sample);
334 udelay(100); 330 udelay(100);
335 iwl_write_prph(trans, DBGC_OUT_CTRL, params->out_ctrl); 331 iwl_write_umac_prph(trans, DBGC_OUT_CTRL, params->out_ctrl);
336 } 332 }
337} 333}
338 334
@@ -373,7 +369,9 @@ static inline bool iwl_fw_dbg_is_d3_debug_enabled(struct iwl_fw_runtime *fwrt)
373{ 369{
374 return fw_has_capa(&fwrt->fw->ucode_capa, 370 return fw_has_capa(&fwrt->fw->ucode_capa,
375 IWL_UCODE_TLV_CAPA_D3_DEBUG) && 371 IWL_UCODE_TLV_CAPA_D3_DEBUG) &&
376 fwrt->trans->cfg->d3_debug_data_length && 372 fwrt->trans->cfg->d3_debug_data_length && fwrt->ops &&
373 fwrt->ops->d3_debug_enable &&
374 fwrt->ops->d3_debug_enable(fwrt->ops_ctx) &&
377 iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_D3_DEBUG_DATA); 375 iwl_fw_dbg_type_on(fwrt, IWL_FW_ERROR_DUMP_D3_DEBUG_DATA);
378} 376}
379 377
@@ -434,10 +432,33 @@ static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) {}
434 432
435#endif /* CONFIG_IWLWIFI_DEBUGFS */ 433#endif /* CONFIG_IWLWIFI_DEBUGFS */
436 434
437void iwl_fw_assert_error_dump(struct iwl_fw_runtime *fwrt);
438void iwl_fw_alive_error_dump(struct iwl_fw_runtime *fwrt);
439void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt); 435void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt);
440void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt, 436void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
441 enum iwl_fw_ini_apply_point apply_point); 437 enum iwl_fw_ini_apply_point apply_point);
442 438
439void iwl_fwrt_stop_device(struct iwl_fw_runtime *fwrt);
440
441static inline void iwl_fw_lmac1_set_alive_err_table(struct iwl_trans *trans,
442 u32 lmac_error_event_table)
443{
444 if (!(trans->error_event_table_tlv_status &
445 IWL_ERROR_EVENT_TABLE_LMAC1) ||
446 WARN_ON(trans->lmac_error_event_table[0] !=
447 lmac_error_event_table))
448 trans->lmac_error_event_table[0] = lmac_error_event_table;
449}
450
451static inline void iwl_fw_umac_set_alive_err_table(struct iwl_trans *trans,
452 u32 umac_error_event_table)
453{
454 if (!(trans->error_event_table_tlv_status &
455 IWL_ERROR_EVENT_TABLE_UMAC) ||
456 WARN_ON(trans->umac_error_event_table !=
457 umac_error_event_table))
458 trans->umac_error_event_table = umac_error_event_table;
459}
460
461/* This bit is used to differentiate the legacy dump from the ini dump */
462#define INI_DUMP_BIT BIT(31)
463
443#endif /* __iwl_fw_dbg_h__ */ 464#endif /* __iwl_fw_dbg_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c
index 3e120dd47305..c1aa4360736b 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c
@@ -173,9 +173,8 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
173 _FWRT_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_fw_runtime) 173 _FWRT_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_fw_runtime)
174 174
175#define FWRT_DEBUGFS_ADD_FILE_ALIAS(alias, name, parent, mode) do { \ 175#define FWRT_DEBUGFS_ADD_FILE_ALIAS(alias, name, parent, mode) do { \
176 if (!debugfs_create_file(alias, mode, parent, fwrt, \ 176 debugfs_create_file(alias, mode, parent, fwrt, \
177 &iwl_dbgfs_##name##_ops)) \ 177 &iwl_dbgfs_##name##_ops); \
178 goto err; \
179 } while (0) 178 } while (0)
180#define FWRT_DEBUGFS_ADD_FILE(name, parent, mode) \ 179#define FWRT_DEBUGFS_ADD_FILE(name, parent, mode) \
181 FWRT_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode) 180 FWRT_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode)
@@ -321,14 +320,10 @@ out:
321 320
322FWRT_DEBUGFS_WRITE_FILE_OPS(send_hcmd, 512); 321FWRT_DEBUGFS_WRITE_FILE_OPS(send_hcmd, 512);
323 322
324int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, 323void iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt,
325 struct dentry *dbgfs_dir) 324 struct dentry *dbgfs_dir)
326{ 325{
327 INIT_DELAYED_WORK(&fwrt->timestamp.wk, iwl_fw_timestamp_marker_wk); 326 INIT_DELAYED_WORK(&fwrt->timestamp.wk, iwl_fw_timestamp_marker_wk);
328 FWRT_DEBUGFS_ADD_FILE(timestamp_marker, dbgfs_dir, 0200); 327 FWRT_DEBUGFS_ADD_FILE(timestamp_marker, dbgfs_dir, 0200);
329 FWRT_DEBUGFS_ADD_FILE(send_hcmd, dbgfs_dir, 0200); 328 FWRT_DEBUGFS_ADD_FILE(send_hcmd, dbgfs_dir, 0200);
330 return 0;
331err:
332 IWL_ERR(fwrt, "Can't create the fwrt debugfs directory\n");
333 return -ENOMEM;
334} 329}
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h
index 88255035e8ef..fde40ff88451 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.h
@@ -63,14 +63,11 @@
63#include "runtime.h" 63#include "runtime.h"
64 64
65#ifdef CONFIG_IWLWIFI_DEBUGFS 65#ifdef CONFIG_IWLWIFI_DEBUGFS
66int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, 66void iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt,
67 struct dentry *dbgfs_dir); 67 struct dentry *dbgfs_dir);
68 68
69#else 69#else
70static inline int iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt, 70static inline void iwl_fwrt_dbgfs_register(struct iwl_fw_runtime *fwrt,
71 struct dentry *dbgfs_dir) 71 struct dentry *dbgfs_dir) { }
72{
73 return 0;
74}
75 72
76#endif /* CONFIG_IWLWIFI_DEBUGFS */ 73#endif /* CONFIG_IWLWIFI_DEBUGFS */
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
index c02425a1e64f..9b5077bd46c3 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
@@ -8,7 +8,7 @@
8 * Copyright(c) 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11 * Copyright (C) 2018 Intel Corporation 11 * Copyright (C) 2018 - 2019 Intel Corporation
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of version 2 of the GNU General Public License as 14 * it under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
31 * Copyright(c) 2014 Intel Corporation. All rights reserved. 31 * Copyright(c) 2014 Intel Corporation. All rights reserved.
32 * Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH 32 * Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH
33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
34 * Copyright (C) 2018 Intel Corporation 34 * Copyright (C) 2018 - 2019 Intel Corporation
35 * All rights reserved. 35 * All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -275,22 +275,68 @@ struct iwl_fw_error_dump_mem {
275}; 275};
276 276
277/** 277/**
278 * struct iwl_fw_error_dump_named_mem - chunk of memory 278 * struct iwl_fw_ini_error_dump_range - range of memory
279 * @type: &enum iwl_fw_error_dump_mem_type 279 * @start_addr: the start address of this range
280 * @offset: the offset from which the memory was read 280 * @range_data_size: the size of this range, in bytes
281 * @name_len: name length 281 * @data: the actual memory
282 * @name: file name
283 * @data: the content of the memory
284 */ 282 */
285struct iwl_fw_error_dump_named_mem { 283struct iwl_fw_ini_error_dump_range {
286 __le32 type; 284 __le32 start_addr;
287 __le32 offset; 285 __le32 range_data_size;
288 u8 name_len; 286 __le32 data[];
289 u8 name[32]; 287} __packed;
290 u8 data[]; 288
289/**
290 * struct iwl_fw_ini_error_dump_header - ini region dump header
291 * @num_of_ranges: number of ranges in this region
292 * @name_len: number of bytes allocated to the name string of this region
293 * @name: name of the region
294 */
295struct iwl_fw_ini_error_dump_header {
296 __le32 num_of_ranges;
297 __le32 name_len;
298 u8 name[IWL_FW_INI_MAX_NAME];
291}; 299};
292 300
293/** 301/**
302 * struct iwl_fw_ini_error_dump - ini region dump
303 * @header: the header of this region
304 * @ranges: the memory ranges of this region
305 */
306struct iwl_fw_ini_error_dump {
307 struct iwl_fw_ini_error_dump_header header;
308 struct iwl_fw_ini_error_dump_range ranges[];
309} __packed;
310
311/* This bit is used to differentiate between lmac and umac rxf */
312#define IWL_RXF_UMAC_BIT BIT(31)
313
314/**
315 * struct iwl_fw_ini_fifo_error_dump_range - ini fifo range dump
316 * @fifo_num: the fifo num. In case of rxf and umac rxf, set BIT(31) to
317 * distinguish between lmac and umac
318 * @num_of_registers: num of registers to dump, dword size each
319 * @range_data_size: the size of the registers and fifo data
320 * @data: fifo data
321 */
322struct iwl_fw_ini_fifo_error_dump_range {
323 __le32 fifo_num;
324 __le32 num_of_registers;
325 __le32 range_data_size;
326 __le32 data[];
327} __packed;
328
329/**
330 * struct iwl_fw_ini_fifo_error_dump - ini fifo region dump
331 * @header: the header of this region
332 * @ranges: the memory ranges of this region
333 */
334struct iwl_fw_ini_fifo_error_dump {
335 struct iwl_fw_ini_error_dump_header header;
336 struct iwl_fw_ini_fifo_error_dump_range ranges[];
337} __packed;
338
339/**
294 * struct iwl_fw_error_dump_rb - content of an Receive Buffer 340 * struct iwl_fw_error_dump_rb - content of an Receive Buffer
295 * @index: the index of the Receive Buffer in the Rx queue 341 * @index: the index of the Receive Buffer in the Rx queue
296 * @rxq: the RB's Rx queue 342 * @rxq: the RB's Rx queue
@@ -305,6 +351,20 @@ struct iwl_fw_error_dump_rb {
305}; 351};
306 352
307/** 353/**
354 * struct iwl_fw_ini_monitor_dram_dump - ini dram monitor dump
355 * @header - header of the region
356 * @write_ptr - write pointer position in the dram
357 * @cycle_cnt - cycles count
358 * @ranges - the memory ranges of this this region
359 */
360struct iwl_fw_ini_monitor_dram_dump {
361 struct iwl_fw_ini_error_dump_header header;
362 __le32 write_ptr;
363 __le32 cycle_cnt;
364 struct iwl_fw_ini_error_dump_range ranges[];
365} __packed;
366
367/**
308 * struct iwl_fw_error_dump_paging - content of the UMAC's image page 368 * struct iwl_fw_error_dump_paging - content of the UMAC's image page
309 * block on DRAM 369 * block on DRAM
310 * @index: the index of the page block 370 * @index: the index of the page block
@@ -355,7 +415,9 @@ iwl_fw_error_next_data(struct iwl_fw_error_dump_data *data)
355 * @FW_DBG_TDLS: trigger log collection upon TDLS related events. 415 * @FW_DBG_TDLS: trigger log collection upon TDLS related events.
356 * @FW_DBG_TRIGGER_TX_STATUS: trigger log collection upon tx status when 416 * @FW_DBG_TRIGGER_TX_STATUS: trigger log collection upon tx status when
357 * the firmware sends a tx reply. 417 * the firmware sends a tx reply.
358 * @FW_DBG_TRIGGER_NO_ALIVE: trigger log collection if alive flow fails 418 * @FW_DBG_TRIGGER_ALIVE_TIMEOUT: trigger log collection if alive flow timeouts
419 * @FW_DBG_TRIGGER_DRIVER: trigger log collection upon a flow failure
420 * in the driver.
359 */ 421 */
360enum iwl_fw_dbg_trigger { 422enum iwl_fw_dbg_trigger {
361 FW_DBG_TRIGGER_INVALID = 0, 423 FW_DBG_TRIGGER_INVALID = 0,
@@ -373,7 +435,8 @@ enum iwl_fw_dbg_trigger {
373 FW_DBG_TRIGGER_TX_LATENCY, 435 FW_DBG_TRIGGER_TX_LATENCY,
374 FW_DBG_TRIGGER_TDLS, 436 FW_DBG_TRIGGER_TDLS,
375 FW_DBG_TRIGGER_TX_STATUS, 437 FW_DBG_TRIGGER_TX_STATUS,
376 FW_DBG_TRIGGER_NO_ALIVE, 438 FW_DBG_TRIGGER_ALIVE_TIMEOUT,
439 FW_DBG_TRIGGER_DRIVER,
377 440
378 /* must be last */ 441 /* must be last */
379 FW_DBG_TRIGGER_MAX, 442 FW_DBG_TRIGGER_MAX,
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index e8b00b795cbb..641c95d03b15 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -9,6 +9,7 @@
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11 * Copyright(c) 2018 Intel Corporation 11 * Copyright(c) 2018 Intel Corporation
12 * Copyright(c) 2019 Intel Corporation
12 * 13 *
13 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of version 2 of the GNU General Public License as 15 * it under the terms of version 2 of the GNU General Public License as
@@ -32,6 +33,7 @@
32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 33 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 34 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
34 * Copyright(c) 2018 Intel Corporation 35 * Copyright(c) 2018 Intel Corporation
36 * Copyright(c) 2019 Intel Corporation
35 * All rights reserved. 37 * All rights reserved.
36 * 38 *
37 * Redistribution and use in source and binary forms, with or without 39 * Redistribution and use in source and binary forms, with or without
@@ -143,6 +145,9 @@ enum iwl_ucode_tlv_type {
143 IWL_UCODE_TLV_FW_GSCAN_CAPA = 50, 145 IWL_UCODE_TLV_FW_GSCAN_CAPA = 50,
144 IWL_UCODE_TLV_FW_MEM_SEG = 51, 146 IWL_UCODE_TLV_FW_MEM_SEG = 51,
145 IWL_UCODE_TLV_IML = 52, 147 IWL_UCODE_TLV_IML = 52,
148 IWL_UCODE_TLV_UMAC_DEBUG_ADDRS = 54,
149 IWL_UCODE_TLV_LMAC_DEBUG_ADDRS = 55,
150 IWL_UCODE_TLV_FW_RECOVERY_INFO = 57,
146 IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION = IWL_UCODE_INI_TLV_GROUP | 0x1, 151 IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION = IWL_UCODE_INI_TLV_GROUP | 0x1,
147 IWL_UCODE_TLV_TYPE_HCMD = IWL_UCODE_INI_TLV_GROUP | 0x2, 152 IWL_UCODE_TLV_TYPE_HCMD = IWL_UCODE_INI_TLV_GROUP | 0x2,
148 IWL_UCODE_TLV_TYPE_REGIONS = IWL_UCODE_INI_TLV_GROUP | 0x3, 153 IWL_UCODE_TLV_TYPE_REGIONS = IWL_UCODE_INI_TLV_GROUP | 0x3,
@@ -263,6 +268,12 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t;
263 * @IWL_UCODE_TLV_API_FRAG_EBS: This ucode supports fragmented EBS 268 * @IWL_UCODE_TLV_API_FRAG_EBS: This ucode supports fragmented EBS
264 * @IWL_UCODE_TLV_API_REDUCE_TX_POWER: This ucode supports v5 of 269 * @IWL_UCODE_TLV_API_REDUCE_TX_POWER: This ucode supports v5 of
265 * the REDUCE_TX_POWER_CMD. 270 * the REDUCE_TX_POWER_CMD.
271 * @IWL_UCODE_TLV_API_SHORT_BEACON_NOTIF: This ucode supports the short
272 * version of the beacon notification.
273 * @IWL_UCODE_TLV_API_BEACON_FILTER_V4: This ucode supports v4 of
274 * BEACON_FILTER_CONFIG_API_S_VER_4.
275 * @IWL_UCODE_TLV_API_FTM_NEW_RANGE_REQ: This ucode supports v7 of
276 * LOCATION_RANGE_REQ_CMD_API_S and v6 of LOCATION_RANGE_RESP_NTFY_API_S.
266 * 277 *
267 * @NUM_IWL_UCODE_TLV_API: number of bits used 278 * @NUM_IWL_UCODE_TLV_API: number of bits used
268 */ 279 */
@@ -287,6 +298,9 @@ enum iwl_ucode_tlv_api {
287 IWL_UCODE_TLV_API_ADAPTIVE_DWELL_V2 = (__force iwl_ucode_tlv_api_t)42, 298 IWL_UCODE_TLV_API_ADAPTIVE_DWELL_V2 = (__force iwl_ucode_tlv_api_t)42,
288 IWL_UCODE_TLV_API_FRAG_EBS = (__force iwl_ucode_tlv_api_t)44, 299 IWL_UCODE_TLV_API_FRAG_EBS = (__force iwl_ucode_tlv_api_t)44,
289 IWL_UCODE_TLV_API_REDUCE_TX_POWER = (__force iwl_ucode_tlv_api_t)45, 300 IWL_UCODE_TLV_API_REDUCE_TX_POWER = (__force iwl_ucode_tlv_api_t)45,
301 IWL_UCODE_TLV_API_SHORT_BEACON_NOTIF = (__force iwl_ucode_tlv_api_t)46,
302 IWL_UCODE_TLV_API_BEACON_FILTER_V4 = (__force iwl_ucode_tlv_api_t)47,
303 IWL_UCODE_TLV_API_FTM_NEW_RANGE_REQ = (__force iwl_ucode_tlv_api_t)49,
290 304
291 NUM_IWL_UCODE_TLV_API 305 NUM_IWL_UCODE_TLV_API
292#ifdef __CHECKER__ 306#ifdef __CHECKER__
@@ -333,6 +347,7 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t;
333 * @IWL_UCODE_TLV_CAPA_TLC_OFFLOAD: firmware implements rate scaling algorithm 347 * @IWL_UCODE_TLV_CAPA_TLC_OFFLOAD: firmware implements rate scaling algorithm
334 * @IWL_UCODE_TLV_CAPA_DYNAMIC_QUOTA: firmware implements quota related 348 * @IWL_UCODE_TLV_CAPA_DYNAMIC_QUOTA: firmware implements quota related
335 * @IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2: firmware implements Coex Schema 2 349 * @IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2: firmware implements Coex Schema 2
350 * IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD: firmware supports CSA command
336 * @IWL_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS: firmware supports ultra high band 351 * @IWL_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS: firmware supports ultra high band
337 * (6 GHz). 352 * (6 GHz).
338 * @IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE: extended DTS measurement 353 * @IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE: extended DTS measurement
@@ -363,12 +378,15 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t;
363 * capability. 378 * capability.
364 * @IWL_UCODE_TLV_CAPA_CSI_REPORTING: firmware is capable of being configured 379 * @IWL_UCODE_TLV_CAPA_CSI_REPORTING: firmware is capable of being configured
365 * to report the CSI information with (certain) RX frames 380 * to report the CSI information with (certain) RX frames
381 * @IWL_UCODE_TLV_CAPA_FTM_CALIBRATED: has FTM calibrated and thus supports both
382 * initiator and responder
366 * 383 *
367 * @IWL_UCODE_TLV_CAPA_MLME_OFFLOAD: supports MLME offload 384 * @IWL_UCODE_TLV_CAPA_MLME_OFFLOAD: supports MLME offload
368 * 385 *
369 * @NUM_IWL_UCODE_TLV_CAPA: number of bits used 386 * @NUM_IWL_UCODE_TLV_CAPA: number of bits used
370 */ 387 */
371enum iwl_ucode_tlv_capa { 388enum iwl_ucode_tlv_capa {
389 /* set 0 */
372 IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = (__force iwl_ucode_tlv_capa_t)0, 390 IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = (__force iwl_ucode_tlv_capa_t)0,
373 IWL_UCODE_TLV_CAPA_LAR_SUPPORT = (__force iwl_ucode_tlv_capa_t)1, 391 IWL_UCODE_TLV_CAPA_LAR_SUPPORT = (__force iwl_ucode_tlv_capa_t)1,
374 IWL_UCODE_TLV_CAPA_UMAC_SCAN = (__force iwl_ucode_tlv_capa_t)2, 392 IWL_UCODE_TLV_CAPA_UMAC_SCAN = (__force iwl_ucode_tlv_capa_t)2,
@@ -390,6 +408,8 @@ enum iwl_ucode_tlv_capa {
390 IWL_UCODE_TLV_CAPA_LAR_MULTI_MCC = (__force iwl_ucode_tlv_capa_t)29, 408 IWL_UCODE_TLV_CAPA_LAR_MULTI_MCC = (__force iwl_ucode_tlv_capa_t)29,
391 IWL_UCODE_TLV_CAPA_BT_COEX_RRC = (__force iwl_ucode_tlv_capa_t)30, 409 IWL_UCODE_TLV_CAPA_BT_COEX_RRC = (__force iwl_ucode_tlv_capa_t)30,
392 IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT = (__force iwl_ucode_tlv_capa_t)31, 410 IWL_UCODE_TLV_CAPA_GSCAN_SUPPORT = (__force iwl_ucode_tlv_capa_t)31,
411
412 /* set 1 */
393 IWL_UCODE_TLV_CAPA_STA_PM_NOTIF = (__force iwl_ucode_tlv_capa_t)38, 413 IWL_UCODE_TLV_CAPA_STA_PM_NOTIF = (__force iwl_ucode_tlv_capa_t)38,
394 IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT = (__force iwl_ucode_tlv_capa_t)39, 414 IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT = (__force iwl_ucode_tlv_capa_t)39,
395 IWL_UCODE_TLV_CAPA_CDB_SUPPORT = (__force iwl_ucode_tlv_capa_t)40, 415 IWL_UCODE_TLV_CAPA_CDB_SUPPORT = (__force iwl_ucode_tlv_capa_t)40,
@@ -397,7 +417,11 @@ enum iwl_ucode_tlv_capa {
397 IWL_UCODE_TLV_CAPA_TLC_OFFLOAD = (__force iwl_ucode_tlv_capa_t)43, 417 IWL_UCODE_TLV_CAPA_TLC_OFFLOAD = (__force iwl_ucode_tlv_capa_t)43,
398 IWL_UCODE_TLV_CAPA_DYNAMIC_QUOTA = (__force iwl_ucode_tlv_capa_t)44, 418 IWL_UCODE_TLV_CAPA_DYNAMIC_QUOTA = (__force iwl_ucode_tlv_capa_t)44,
399 IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2 = (__force iwl_ucode_tlv_capa_t)45, 419 IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2 = (__force iwl_ucode_tlv_capa_t)45,
420 IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD = (__force iwl_ucode_tlv_capa_t)46,
400 IWL_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS = (__force iwl_ucode_tlv_capa_t)48, 421 IWL_UCODE_TLV_CAPA_ULTRA_HB_CHANNELS = (__force iwl_ucode_tlv_capa_t)48,
422 IWL_UCODE_TLV_CAPA_FTM_CALIBRATED = (__force iwl_ucode_tlv_capa_t)47,
423
424 /* set 2 */
401 IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64, 425 IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64,
402 IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS = (__force iwl_ucode_tlv_capa_t)65, 426 IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS = (__force iwl_ucode_tlv_capa_t)65,
403 IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT = (__force iwl_ucode_tlv_capa_t)67, 427 IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT = (__force iwl_ucode_tlv_capa_t)67,
@@ -418,6 +442,7 @@ enum iwl_ucode_tlv_capa {
418 IWL_UCODE_TLV_CAPA_MCC_UPDATE_11AX_SUPPORT = (__force iwl_ucode_tlv_capa_t)89, 442 IWL_UCODE_TLV_CAPA_MCC_UPDATE_11AX_SUPPORT = (__force iwl_ucode_tlv_capa_t)89,
419 IWL_UCODE_TLV_CAPA_CSI_REPORTING = (__force iwl_ucode_tlv_capa_t)90, 443 IWL_UCODE_TLV_CAPA_CSI_REPORTING = (__force iwl_ucode_tlv_capa_t)90,
420 444
445 /* set 3 */
421 IWL_UCODE_TLV_CAPA_MLME_OFFLOAD = (__force iwl_ucode_tlv_capa_t)96, 446 IWL_UCODE_TLV_CAPA_MLME_OFFLOAD = (__force iwl_ucode_tlv_capa_t)96,
422 447
423 NUM_IWL_UCODE_TLV_CAPA 448 NUM_IWL_UCODE_TLV_CAPA
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.h b/drivers/net/wireless/intel/iwlwifi/fw/img.h
index 12333167ea23..f4c5a4d73206 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/img.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/img.h
@@ -105,6 +105,8 @@ struct iwl_ucode_capabilities {
105 u32 n_scan_channels; 105 u32 n_scan_channels;
106 u32 standard_phy_calibration_size; 106 u32 standard_phy_calibration_size;
107 u32 flags; 107 u32 flags;
108 u32 error_log_addr;
109 u32 error_log_size;
108 unsigned long _api[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_API)]; 110 unsigned long _api[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_API)];
109 unsigned long _capa[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_CAPA)]; 111 unsigned long _capa[BITS_TO_LONGS(NUM_IWL_UCODE_TLV_CAPA)];
110}; 112};
@@ -223,27 +225,24 @@ struct iwl_fw_dbg {
223}; 225};
224 226
225/** 227/**
228 * @tlv: the buffer allocation tlv
229 * @is_alloc: indicates if the buffer was already allocated
230 */
231struct iwl_fw_ini_allocation_data {
232 struct iwl_fw_ini_allocation_tlv tlv;
233 u32 is_alloc;
234} __packed;
235
236/**
226 * struct iwl_fw_ini_active_triggers 237 * struct iwl_fw_ini_active_triggers
227 * @active: is this trigger active 238 * @active: is this trigger active
228 * @apply_point: last apply point that updated this trigger 239 * @size: allocated memory size of the trigger
229 * @conf: active trigger 240 * @trig: trigger
230 * @conf_ext: second trigger, contains extra regions to dump
231 */ 241 */
232struct iwl_fw_ini_active_triggers { 242struct iwl_fw_ini_active_triggers {
233 bool active; 243 bool active;
234 enum iwl_fw_ini_apply_point apply_point; 244 size_t size;
235 struct iwl_fw_ini_trigger *conf; 245 struct iwl_fw_ini_trigger *trig;
236 struct iwl_fw_ini_trigger *conf_ext;
237};
238
239/**
240 * struct iwl_fw_ini_active_regs
241 * @reg: active region from TLV
242 * @apply_point: apply point where it became active
243 */
244struct iwl_fw_ini_active_regs {
245 struct iwl_fw_ini_region_cfg *reg;
246 enum iwl_fw_ini_apply_point apply_point;
247}; 246};
248 247
249/** 248/**
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/init.c b/drivers/net/wireless/intel/iwlwifi/fw/init.c
index 2efac307909e..7adf4e4e841a 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/init.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/init.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2017 Intel Deutschland GmbH 8 * Copyright(c) 2017 Intel Deutschland GmbH
9 * Copyright(c) 2019 Intel Corporation
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 12 * it under the terms of version 2 of the GNU General Public License as
@@ -26,6 +27,7 @@
26 * BSD LICENSE 27 * BSD LICENSE
27 * 28 *
28 * Copyright(c) 2017 Intel Deutschland GmbH 29 * Copyright(c) 2017 Intel Deutschland GmbH
30 * Copyright(c) 2019 Intel Corporation
29 * All rights reserved. 31 * All rights reserved.
30 * 32 *
31 * Redistribution and use in source and binary forms, with or without 33 * Redistribution and use in source and binary forms, with or without
@@ -74,6 +76,7 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
74 fwrt->ops_ctx = ops_ctx; 76 fwrt->ops_ctx = ops_ctx;
75 INIT_DELAYED_WORK(&fwrt->dump.wk, iwl_fw_error_dump_wk); 77 INIT_DELAYED_WORK(&fwrt->dump.wk, iwl_fw_error_dump_wk);
76 iwl_fwrt_dbgfs_register(fwrt, dbgfs_dir); 78 iwl_fwrt_dbgfs_register(fwrt, dbgfs_dir);
79 init_waitqueue_head(&fwrt->trans->fw_halt_waitq);
77} 80}
78IWL_EXPORT_SYMBOL(iwl_fw_runtime_init); 81IWL_EXPORT_SYMBOL(iwl_fw_runtime_init);
79 82
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
index a0fcbb28114b..a5fe1a8ca426 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
@@ -6,7 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2017 Intel Deutschland GmbH 8 * Copyright(c) 2017 Intel Deutschland GmbH
9 * Copyright(c) 2018 Intel Corporation 9 * Copyright (C) 2018-2019 Intel Corporation
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 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 12 * it under the terms of version 2 of the GNU General Public License as
@@ -27,7 +27,7 @@
27 * BSD LICENSE 27 * BSD LICENSE
28 * 28 *
29 * Copyright(c) 2017 Intel Deutschland GmbH 29 * Copyright(c) 2017 Intel Deutschland GmbH
30 * Copyright(c) 2018 Intel Corporation 30 * Copyright (C) 2018-2019 Intel Corporation
31 * All rights reserved. 31 * All rights reserved.
32 * 32 *
33 * Redistribution and use in source and binary forms, with or without 33 * Redistribution and use in source and binary forms, with or without
@@ -73,6 +73,7 @@ struct iwl_fw_runtime_ops {
73 void (*dump_end)(void *ctx); 73 void (*dump_end)(void *ctx);
74 bool (*fw_running)(void *ctx); 74 bool (*fw_running)(void *ctx);
75 int (*send_hcmd)(void *ctx, struct iwl_host_cmd *host_cmd); 75 int (*send_hcmd)(void *ctx, struct iwl_host_cmd *host_cmd);
76 bool (*d3_debug_enable)(void *ctx);
76}; 77};
77 78
78#define MAX_NUM_LMAC 2 79#define MAX_NUM_LMAC 2
@@ -90,7 +91,6 @@ struct iwl_fwrt_shared_mem_cfg {
90 91
91enum iwl_fw_runtime_status { 92enum iwl_fw_runtime_status {
92 IWL_FWRT_STATUS_DUMPING = 0, 93 IWL_FWRT_STATUS_DUMPING = 0,
93 IWL_FWRT_STATUS_WAIT_ALIVE,
94}; 94};
95 95
96/** 96/**
@@ -138,12 +138,13 @@ struct iwl_fw_runtime {
138 u8 conf; 138 u8 conf;
139 139
140 /* ts of the beginning of a non-collect fw dbg data period */ 140 /* 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]; 141 unsigned long non_collect_ts_start[IWL_FW_TRIGGER_ID_NUM];
142 u32 *d3_debug_data; 142 u32 *d3_debug_data;
143 struct iwl_fw_ini_active_regs active_regs[IWL_FW_INI_MAX_REGION_ID]; 143 struct iwl_fw_ini_region_cfg *active_regs[IWL_FW_INI_MAX_REGION_ID];
144 struct iwl_fw_ini_active_triggers active_trigs[IWL_FW_TRIGGER_ID_NUM]; 144 struct iwl_fw_ini_active_triggers active_trigs[IWL_FW_TRIGGER_ID_NUM];
145 u32 lmac_err_id[MAX_NUM_LMAC]; 145 u32 lmac_err_id[MAX_NUM_LMAC];
146 u32 umac_err_id; 146 u32 umac_err_id;
147 void *fifo_iter;
147 } dump; 148 } dump;
148#ifdef CONFIG_IWLWIFI_DEBUGFS 149#ifdef CONFIG_IWLWIFI_DEBUGFS
149 struct { 150 struct {
@@ -161,8 +162,20 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
161 162
162static inline void iwl_fw_runtime_free(struct iwl_fw_runtime *fwrt) 163static inline void iwl_fw_runtime_free(struct iwl_fw_runtime *fwrt)
163{ 164{
165 int i;
166
164 kfree(fwrt->dump.d3_debug_data); 167 kfree(fwrt->dump.d3_debug_data);
165 fwrt->dump.d3_debug_data = NULL; 168 fwrt->dump.d3_debug_data = NULL;
169
170 for (i = 0; i < IWL_FW_TRIGGER_ID_NUM; i++) {
171 struct iwl_fw_ini_active_triggers *active =
172 &fwrt->dump.active_trigs[i];
173
174 active->active = false;
175 active->size = 0;
176 kfree(active->trig);
177 active->trig = NULL;
178 }
166} 179}
167 180
168void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt); 181void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt);
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index ff942532fac3..f5f87773667b 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -7,7 +7,7 @@
7 * 7 *
8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * Copyright (C) 2016 - 2017 Intel Deutschland GmbH 9 * Copyright (C) 2016 - 2017 Intel Deutschland GmbH
10 * Copyright(c) 2018 Intel Corporation 10 * Copyright(c) 2018 - 2019 Intel Corporation
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify 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 13 * it under the terms of version 2 of the GNU General Public License as
@@ -29,7 +29,7 @@
29 * 29 *
30 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 30 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
31 * Copyright (C) 2016 - 2017 Intel Deutschland GmbH 31 * Copyright (C) 2016 - 2017 Intel Deutschland GmbH
32 * Copyright(c) 2018 Intel Corporation 32 * Copyright(c) 2018 - 2019 Intel Corporation
33 * All rights reserved. 33 * All rights reserved.
34 * 34 *
35 * Redistribution and use in source and binary forms, with or without 35 * Redistribution and use in source and binary forms, with or without
@@ -89,6 +89,7 @@ enum iwl_device_family {
89 IWL_DEVICE_FAMILY_9000, 89 IWL_DEVICE_FAMILY_9000,
90 IWL_DEVICE_FAMILY_22000, 90 IWL_DEVICE_FAMILY_22000,
91 IWL_DEVICE_FAMILY_22560, 91 IWL_DEVICE_FAMILY_22560,
92 IWL_DEVICE_FAMILY_AX210,
92}; 93};
93 94
94/* 95/*
@@ -379,6 +380,9 @@ struct iwl_csr_params {
379 * @nvm_type: see &enum iwl_nvm_type 380 * @nvm_type: see &enum iwl_nvm_type
380 * @d3_debug_data_base_addr: base address where D3 debug data is stored 381 * @d3_debug_data_base_addr: base address where D3 debug data is stored
381 * @d3_debug_data_length: length of the D3 debug data 382 * @d3_debug_data_length: length of the D3 debug data
383 * @bisr_workaround: BISR hardware workaround (for 22260 series devices)
384 * @min_txq_size: minimum number of slots required in a TX queue
385 * @umac_prph_offset: offset to add to UMAC periphery address
382 * 386 *
383 * We enable the driver to be backward compatible wrt. hardware features. 387 * We enable the driver to be backward compatible wrt. hardware features.
384 * API differences in uCode shouldn't be handled here but through TLVs 388 * API differences in uCode shouldn't be handled here but through TLVs
@@ -428,7 +432,8 @@ struct iwl_cfg {
428 use_tfh:1, 432 use_tfh:1,
429 gen2:1, 433 gen2:1,
430 cdb:1, 434 cdb:1,
431 dbgc_supported:1; 435 dbgc_supported:1,
436 bisr_workaround:1;
432 u8 valid_tx_ant; 437 u8 valid_tx_ant;
433 u8 valid_rx_ant; 438 u8 valid_rx_ant;
434 u8 non_shared_ant; 439 u8 non_shared_ant;
@@ -443,37 +448,12 @@ struct iwl_cfg {
443 u32 extra_phy_cfg_flags; 448 u32 extra_phy_cfg_flags;
444 u32 d3_debug_data_base_addr; 449 u32 d3_debug_data_base_addr;
445 u32 d3_debug_data_length; 450 u32 d3_debug_data_length;
451 u32 min_txq_size;
452 u32 umac_prph_offset;
446}; 453};
447 454
448static const struct iwl_csr_params iwl_csr_v1 = { 455extern const struct iwl_csr_params iwl_csr_v1;
449 .flag_mac_clock_ready = 0, 456extern const struct iwl_csr_params iwl_csr_v2;
450 .flag_val_mac_access_en = 0,
451 .flag_init_done = 2,
452 .flag_mac_access_req = 3,
453 .flag_sw_reset = 7,
454 .flag_master_dis = 8,
455 .flag_stop_master = 9,
456 .addr_sw_reset = (CSR_BASE + 0x020),
457 .mac_addr0_otp = 0x380,
458 .mac_addr1_otp = 0x384,
459 .mac_addr0_strap = 0x388,
460 .mac_addr1_strap = 0x38C
461};
462
463static const struct iwl_csr_params iwl_csr_v2 = {
464 .flag_init_done = 6,
465 .flag_mac_clock_ready = 20,
466 .flag_val_mac_access_en = 20,
467 .flag_mac_access_req = 21,
468 .flag_master_dis = 28,
469 .flag_stop_master = 29,
470 .flag_sw_reset = 31,
471 .addr_sw_reset = (CSR_BASE + 0x024),
472 .mac_addr0_otp = 0x30,
473 .mac_addr1_otp = 0x34,
474 .mac_addr0_strap = 0x38,
475 .mac_addr1_strap = 0x3C
476};
477 457
478/* 458/*
479 * This list declares the config structures for all devices. 459 * This list declares the config structures for all devices.
@@ -568,7 +548,7 @@ extern const struct iwl_cfg iwl9560_killer_s_2ac_cfg_shared_clk;
568extern const struct iwl_cfg iwl22000_2ac_cfg_hr; 548extern const struct iwl_cfg iwl22000_2ac_cfg_hr;
569extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb; 549extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb;
570extern const struct iwl_cfg iwl22000_2ac_cfg_jf; 550extern const struct iwl_cfg iwl22000_2ac_cfg_jf;
571extern const struct iwl_cfg iwl22560_2ax_cfg_hr; 551extern const struct iwl_cfg iwl_ax101_cfg_qu_hr;
572extern const struct iwl_cfg iwl22000_2ax_cfg_hr; 552extern const struct iwl_cfg iwl22000_2ax_cfg_hr;
573extern const struct iwl_cfg iwl22260_2ax_cfg; 553extern const struct iwl_cfg iwl22260_2ax_cfg;
574extern const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0; 554extern const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0;
@@ -585,9 +565,13 @@ extern const struct iwl_cfg iwl22000_2ax_cfg_jf;
585extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0_f0; 565extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0_f0;
586extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0_f0; 566extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0_f0;
587extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0; 567extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_b0;
588extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_jf_b0; 568extern const struct iwl_cfg iwl9560_2ac_cfg_qnj_jf_b0;
589extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0; 569extern const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0;
590extern const struct iwl_cfg iwl22560_2ax_cfg_su_cdb; 570extern const struct iwl_cfg iwl22560_2ax_cfg_su_cdb;
571extern const struct iwl_cfg iwlax210_2ax_cfg_so_jf_a0;
572extern const struct iwl_cfg iwlax210_2ax_cfg_so_hr_a0;
573extern const struct iwl_cfg iwlax210_2ax_cfg_so_gf_a0;
574extern const struct iwl_cfg iwlax210_2ax_cfg_ty_gf_a0;
591#endif /* CPTCFG_IWLMVM || CPTCFG_IWLFMAC */ 575#endif /* CPTCFG_IWLMVM || CPTCFG_IWLFMAC */
592 576
593#endif /* __IWL_CONFIG_H__ */ 577#endif /* __IWL_CONFIG_H__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
index 42af421bbc3c..aea6d03e545a 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
@@ -180,6 +180,7 @@
180/* Bits for CSR_HW_IF_CONFIG_REG */ 180/* Bits for CSR_HW_IF_CONFIG_REG */
181#define CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH (0x00000003) 181#define CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH (0x00000003)
182#define CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP (0x0000000C) 182#define CSR_HW_IF_CONFIG_REG_MSK_MAC_STEP (0x0000000C)
183#define CSR_HW_IF_CONFIG_REG_BIT_MONITOR_SRAM (0x00000080)
183#define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x000000C0) 184#define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x000000C0)
184#define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100) 185#define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100)
185#define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200) 186#define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200)
@@ -327,11 +328,14 @@ enum {
327#define CSR_HW_REV_TYPE_QNJ (0x0000360) 328#define CSR_HW_REV_TYPE_QNJ (0x0000360)
328#define CSR_HW_REV_TYPE_QNJ_B0 (0x0000364) 329#define CSR_HW_REV_TYPE_QNJ_B0 (0x0000364)
329#define CSR_HW_REV_TYPE_HR_CDB (0x0000340) 330#define CSR_HW_REV_TYPE_HR_CDB (0x0000340)
331#define CSR_HW_REV_TYPE_SO (0x0000370)
332#define CSR_HW_REV_TYPE_TY (0x0000420)
330 333
331/* RF_ID value */ 334/* RF_ID value */
332#define CSR_HW_RF_ID_TYPE_JF (0x00105100) 335#define CSR_HW_RF_ID_TYPE_JF (0x00105100)
333#define CSR_HW_RF_ID_TYPE_HR (0x0010A000) 336#define CSR_HW_RF_ID_TYPE_HR (0x0010A000)
334#define CSR_HW_RF_ID_TYPE_HRCDB (0x00109F00) 337#define CSR_HW_RF_ID_TYPE_HRCDB (0x00109F00)
338#define CSR_HW_RF_ID_TYPE_GF (0x0010D000)
335 339
336/* HW_RF CHIP ID */ 340/* HW_RF CHIP ID */
337#define CSR_HW_RF_ID_TYPE_CHIP_ID(_val) (((_val) >> 12) & 0xFFF) 341#define CSR_HW_RF_ID_TYPE_CHIP_ID(_val) (((_val) >> 12) & 0xFFF)
@@ -593,6 +597,7 @@ enum msix_hw_int_causes {
593 MSIX_HW_INT_CAUSES_REG_ALIVE = BIT(0), 597 MSIX_HW_INT_CAUSES_REG_ALIVE = BIT(0),
594 MSIX_HW_INT_CAUSES_REG_WAKEUP = BIT(1), 598 MSIX_HW_INT_CAUSES_REG_WAKEUP = BIT(1),
595 MSIX_HW_INT_CAUSES_REG_IPC = BIT(1), 599 MSIX_HW_INT_CAUSES_REG_IPC = BIT(1),
600 MSIX_HW_INT_CAUSES_REG_IML = BIT(2),
596 MSIX_HW_INT_CAUSES_REG_SW_ERR_V2 = BIT(5), 601 MSIX_HW_INT_CAUSES_REG_SW_ERR_V2 = BIT(5),
597 MSIX_HW_INT_CAUSES_REG_CT_KILL = BIT(6), 602 MSIX_HW_INT_CAUSES_REG_CT_KILL = BIT(6),
598 MSIX_HW_INT_CAUSES_REG_RF_KILL = BIT(7), 603 MSIX_HW_INT_CAUSES_REG_RF_KILL = BIT(7),
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
index 43d815cb3ce9..5798f434f68f 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
@@ -71,6 +71,7 @@ void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
71 u32 apply_point = le32_to_cpu(header->apply_point); 71 u32 apply_point = le32_to_cpu(header->apply_point);
72 72
73 int copy_size = le32_to_cpu(tlv->length) + sizeof(*tlv); 73 int copy_size = le32_to_cpu(tlv->length) + sizeof(*tlv);
74 int offset_size = copy_size;
74 75
75 if (WARN_ONCE(apply_point >= IWL_FW_INI_APPLY_NUM, 76 if (WARN_ONCE(apply_point >= IWL_FW_INI_APPLY_NUM,
76 "Invalid apply point id %d\n", apply_point)) 77 "Invalid apply point id %d\n", apply_point))
@@ -81,17 +82,25 @@ void iwl_fw_dbg_copy_tlv(struct iwl_trans *trans, struct iwl_ucode_tlv *tlv,
81 else 82 else
82 data = &trans->apply_points[apply_point]; 83 data = &trans->apply_points[apply_point];
83 84
85 /* add room for is_alloc field in &iwl_fw_ini_allocation_data struct */
86 if (le32_to_cpu(tlv->type) == IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION) {
87 struct iwl_fw_ini_allocation_data *buf_alloc =
88 (void *)tlv->data;
89
90 offset_size += sizeof(buf_alloc->is_alloc);
91 }
92
84 /* 93 /*
85 * Make sure we still have room to copy this TLV. Offset points to the 94 * Make sure we still have room to copy this TLV. Offset points to the
86 * location the last copy ended. 95 * location the last copy ended.
87 */ 96 */
88 if (WARN_ONCE(data->offset + copy_size > data->size, 97 if (WARN_ONCE(data->offset + offset_size > data->size,
89 "Not enough memory for apply point %d\n", 98 "Not enough memory for apply point %d\n",
90 apply_point)) 99 apply_point))
91 return; 100 return;
92 101
93 memcpy(data->data + data->offset, (void *)tlv, copy_size); 102 memcpy(data->data + data->offset, (void *)tlv, copy_size);
94 data->offset += copy_size; 103 data->offset += offset_size;
95} 104}
96 105
97void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data, 106void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data,
@@ -129,6 +138,16 @@ void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data,
129 if (WARN_ON(apply >= IWL_FW_INI_APPLY_NUM)) 138 if (WARN_ON(apply >= IWL_FW_INI_APPLY_NUM))
130 continue; 139 continue;
131 140
141 /* add room for is_alloc field in &iwl_fw_ini_allocation_data
142 * struct
143 */
144 if (tlv_type == IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION) {
145 struct iwl_fw_ini_allocation_data *buf_alloc =
146 (void *)tlv->data;
147
148 size[apply] += sizeof(buf_alloc->is_alloc);
149 }
150
132 size[apply] += sizeof(*tlv) + tlv_len; 151 size[apply] += sizeof(*tlv) + tlv_len;
133 } 152 }
134 153
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-debug.h b/drivers/net/wireless/intel/iwlwifi/iwl-debug.h
index a2af68a0d34b..655ff5694560 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-debug.h
@@ -1,6 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
4 * Copyright (C) 2018 Intel Corporation
4 * 5 *
5 * Portions of this file are derived from the ipw3945 project. 6 * Portions of this file are derived from the ipw3945 project.
6 * 7 *
@@ -159,7 +160,7 @@ do { \
159/* 0x000F0000 - 0x00010000 */ 160/* 0x000F0000 - 0x00010000 */
160#define IWL_DL_FW 0x00010000 161#define IWL_DL_FW 0x00010000
161#define IWL_DL_RF_KILL 0x00020000 162#define IWL_DL_RF_KILL 0x00020000
162#define IWL_DL_FW_ERRORS 0x00040000 163#define IWL_DL_TPT 0x00040000
163/* 0x00F00000 - 0x00100000 */ 164/* 0x00F00000 - 0x00100000 */
164#define IWL_DL_RATE 0x00100000 165#define IWL_DL_RATE 0x00100000
165#define IWL_DL_CALIB 0x00200000 166#define IWL_DL_CALIB 0x00200000
@@ -193,7 +194,6 @@ do { \
193#define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a) 194#define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a)
194#define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a) 195#define IWL_DEBUG_FW(p, f, a...) IWL_DEBUG(p, IWL_DL_FW, f, ## a)
195#define IWL_DEBUG_RF_KILL(p, f, a...) IWL_DEBUG(p, IWL_DL_RF_KILL, f, ## a) 196#define IWL_DEBUG_RF_KILL(p, f, a...) IWL_DEBUG(p, IWL_DL_RF_KILL, f, ## a)
196#define IWL_DEBUG_FW_ERRORS(p, f, a...) IWL_DEBUG(p, IWL_DL_FW_ERRORS, f, ## a)
197#define IWL_DEBUG_DROP(p, f, a...) IWL_DEBUG(p, IWL_DL_DROP, f, ## a) 197#define IWL_DEBUG_DROP(p, f, a...) IWL_DEBUG(p, IWL_DL_DROP, f, ## a)
198#define IWL_DEBUG_DROP_LIMIT(p, f, a...) \ 198#define IWL_DEBUG_DROP_LIMIT(p, f, a...) \
199 IWL_DEBUG_LIMIT(p, IWL_DL_DROP, f, ## a) 199 IWL_DEBUG_LIMIT(p, IWL_DL_DROP, f, ## a)
@@ -215,6 +215,7 @@ do { \
215#define IWL_DEBUG_DEV_RADIO(p, f, a...) IWL_DEBUG_DEV(p, IWL_DL_RADIO, f, ## a) 215#define IWL_DEBUG_DEV_RADIO(p, f, a...) IWL_DEBUG_DEV(p, IWL_DL_RADIO, f, ## a)
216#define IWL_DEBUG_POWER(p, f, a...) IWL_DEBUG(p, IWL_DL_POWER, f, ## a) 216#define IWL_DEBUG_POWER(p, f, a...) IWL_DEBUG(p, IWL_DL_POWER, f, ## a)
217#define IWL_DEBUG_11H(p, f, a...) IWL_DEBUG(p, IWL_DL_11H, f, ## a) 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#define IWL_DEBUG_RPM(p, f, a...) IWL_DEBUG(p, IWL_DL_RPM, f, ## a) 219#define IWL_DEBUG_RPM(p, f, a...) IWL_DEBUG(p, IWL_DL_RPM, f, ## a)
219#define IWL_DEBUG_LAR(p, f, a...) IWL_DEBUG(p, IWL_DL_LAR, f, ## a) 220#define IWL_DEBUG_LAR(p, f, a...) IWL_DEBUG(p, IWL_DL_LAR, f, ## a)
220 221
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index 2efa1dfe9b4c..689a65b11cc3 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -8,6 +8,7 @@
8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11 * Copyright(c) 2018 - 2019 Intel Corporation
11 * 12 *
12 * This program is free software; you can redistribute it and/or modify 13 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -30,6 +31,7 @@
30 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 31 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
31 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
32 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
34 * Copyright(c) 2018 - 2019 Intel Corporation
33 * All rights reserved. 35 * All rights reserved.
34 * 36 *
35 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -75,6 +77,7 @@
75#include "iwl-dbg-tlv.h" 77#include "iwl-dbg-tlv.h"
76#include "iwl-config.h" 78#include "iwl-config.h"
77#include "iwl-modparams.h" 79#include "iwl-modparams.h"
80#include "fw/api/alive.h"
78 81
79/****************************************************************************** 82/******************************************************************************
80 * 83 *
@@ -588,6 +591,8 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv,
588 return 0; 591 return 0;
589} 592}
590 593
594#define FW_ADDR_CACHE_CONTROL 0xC0000000
595
591static int iwl_parse_tlv_firmware(struct iwl_drv *drv, 596static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
592 const struct firmware *ucode_raw, 597 const struct firmware *ucode_raw,
593 struct iwl_firmware_pieces *pieces, 598 struct iwl_firmware_pieces *pieces,
@@ -1085,6 +1090,52 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
1085 return -ENOMEM; 1090 return -ENOMEM;
1086 break; 1091 break;
1087 } 1092 }
1093 case IWL_UCODE_TLV_FW_RECOVERY_INFO: {
1094 struct {
1095 __le32 buf_addr;
1096 __le32 buf_size;
1097 } *recov_info = (void *)tlv_data;
1098
1099 if (tlv_len != sizeof(*recov_info))
1100 goto invalid_tlv_len;
1101 capa->error_log_addr =
1102 le32_to_cpu(recov_info->buf_addr);
1103 capa->error_log_size =
1104 le32_to_cpu(recov_info->buf_size);
1105 }
1106 break;
1107 case IWL_UCODE_TLV_UMAC_DEBUG_ADDRS: {
1108 struct iwl_umac_debug_addrs *dbg_ptrs =
1109 (void *)tlv_data;
1110
1111 if (tlv_len != sizeof(*dbg_ptrs))
1112 goto invalid_tlv_len;
1113 if (drv->trans->cfg->device_family <
1114 IWL_DEVICE_FAMILY_22000)
1115 break;
1116 drv->trans->umac_error_event_table =
1117 le32_to_cpu(dbg_ptrs->error_info_addr) &
1118 ~FW_ADDR_CACHE_CONTROL;
1119 drv->trans->error_event_table_tlv_status |=
1120 IWL_ERROR_EVENT_TABLE_UMAC;
1121 break;
1122 }
1123 case IWL_UCODE_TLV_LMAC_DEBUG_ADDRS: {
1124 struct iwl_lmac_debug_addrs *dbg_ptrs =
1125 (void *)tlv_data;
1126
1127 if (tlv_len != sizeof(*dbg_ptrs))
1128 goto invalid_tlv_len;
1129 if (drv->trans->cfg->device_family <
1130 IWL_DEVICE_FAMILY_22000)
1131 break;
1132 drv->trans->lmac_error_event_table[0] =
1133 le32_to_cpu(dbg_ptrs->error_event_table_ptr) &
1134 ~FW_ADDR_CACHE_CONTROL;
1135 drv->trans->error_event_table_tlv_status |=
1136 IWL_ERROR_EVENT_TABLE_LMAC1;
1137 break;
1138 }
1088 case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION: 1139 case IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION:
1089 case IWL_UCODE_TLV_TYPE_HCMD: 1140 case IWL_UCODE_TLV_TYPE_HCMD:
1090 case IWL_UCODE_TLV_TYPE_REGIONS: 1141 case IWL_UCODE_TLV_TYPE_REGIONS:
@@ -1202,11 +1253,6 @@ _iwl_op_mode_start(struct iwl_drv *drv, struct iwlwifi_opmode_table *op)
1202#ifdef CONFIG_IWLWIFI_DEBUGFS 1253#ifdef CONFIG_IWLWIFI_DEBUGFS
1203 drv->dbgfs_op_mode = debugfs_create_dir(op->name, 1254 drv->dbgfs_op_mode = debugfs_create_dir(op->name,
1204 drv->dbgfs_drv); 1255 drv->dbgfs_drv);
1205 if (!drv->dbgfs_op_mode) {
1206 IWL_ERR(drv,
1207 "failed to create opmode debugfs directory\n");
1208 return op_mode;
1209 }
1210 dbgfs_dir = drv->dbgfs_op_mode; 1256 dbgfs_dir = drv->dbgfs_op_mode;
1211#endif 1257#endif
1212 1258
@@ -1262,8 +1308,8 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1262 fw->ucode_capa.standard_phy_calibration_size = 1308 fw->ucode_capa.standard_phy_calibration_size =
1263 IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE; 1309 IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE;
1264 fw->ucode_capa.n_scan_channels = IWL_DEFAULT_SCAN_CHANNELS; 1310 fw->ucode_capa.n_scan_channels = IWL_DEFAULT_SCAN_CHANNELS;
1265 /* dump all fw memory areas by default except d3 debug data */ 1311 /* dump all fw memory areas by default */
1266 fw->dbg.dump_mask = 0xfffdffff; 1312 fw->dbg.dump_mask = 0xffffffff;
1267 1313
1268 pieces = kzalloc(sizeof(*pieces), GFP_KERNEL); 1314 pieces = kzalloc(sizeof(*pieces), GFP_KERNEL);
1269 if (!pieces) 1315 if (!pieces)
@@ -1569,20 +1615,8 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans)
1569 drv->dbgfs_drv = debugfs_create_dir(dev_name(trans->dev), 1615 drv->dbgfs_drv = debugfs_create_dir(dev_name(trans->dev),
1570 iwl_dbgfs_root); 1616 iwl_dbgfs_root);
1571 1617
1572 if (!drv->dbgfs_drv) {
1573 IWL_ERR(drv, "failed to create debugfs directory\n");
1574 ret = -ENOMEM;
1575 goto err_free_tlv;
1576 }
1577
1578 /* Create transport layer debugfs dir */ 1618 /* Create transport layer debugfs dir */
1579 drv->trans->dbgfs_dir = debugfs_create_dir("trans", drv->dbgfs_drv); 1619 drv->trans->dbgfs_dir = debugfs_create_dir("trans", drv->dbgfs_drv);
1580
1581 if (!drv->trans->dbgfs_dir) {
1582 IWL_ERR(drv, "failed to create transport debugfs directory\n");
1583 ret = -ENOMEM;
1584 goto err_free_dbgfs;
1585 }
1586#endif 1620#endif
1587 1621
1588 ret = iwl_request_firmware(drv, true); 1622 ret = iwl_request_firmware(drv, true);
@@ -1595,9 +1629,7 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans)
1595 1629
1596err_fw: 1630err_fw:
1597#ifdef CONFIG_IWLWIFI_DEBUGFS 1631#ifdef CONFIG_IWLWIFI_DEBUGFS
1598err_free_dbgfs:
1599 debugfs_remove_recursive(drv->dbgfs_drv); 1632 debugfs_remove_recursive(drv->dbgfs_drv);
1600err_free_tlv:
1601 iwl_fw_dbg_free(drv->trans); 1633 iwl_fw_dbg_free(drv->trans);
1602#endif 1634#endif
1603 kfree(drv); 1635 kfree(drv);
@@ -1708,9 +1740,6 @@ static int __init iwl_drv_init(void)
1708#ifdef CONFIG_IWLWIFI_DEBUGFS 1740#ifdef CONFIG_IWLWIFI_DEBUGFS
1709 /* Create the root of iwlwifi debugfs subsystem. */ 1741 /* Create the root of iwlwifi debugfs subsystem. */
1710 iwl_dbgfs_root = debugfs_create_dir(DRV_NAME, NULL); 1742 iwl_dbgfs_root = debugfs_create_dir(DRV_NAME, NULL);
1711
1712 if (!iwl_dbgfs_root)
1713 return -EFAULT;
1714#endif 1743#endif
1715 1744
1716 return iwl_pci_register_driver(); 1745 return iwl_pci_register_driver();
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c
index 75940ac406b9..04338c3a6205 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c
@@ -850,8 +850,7 @@ iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg,
850 if (WARN_ON(!cfg || !cfg->eeprom_params)) 850 if (WARN_ON(!cfg || !cfg->eeprom_params))
851 return NULL; 851 return NULL;
852 852
853 data = kzalloc(sizeof(*data) + 853 data = kzalloc(struct_size(data, channels, IWL_NUM_CHANNELS),
854 sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS,
855 GFP_KERNEL); 854 GFP_KERNEL);
856 if (!data) 855 if (!data)
857 return NULL; 856 return NULL;
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c
index a6db6a814257..82e87192119e 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c
@@ -193,34 +193,25 @@ static int iwl_init_otp_access(struct iwl_trans *trans)
193{ 193{
194 int ret; 194 int ret;
195 195
196 /* Enable 40MHz radio clock */ 196 ret = iwl_finish_nic_init(trans);
197 iwl_write32(trans, CSR_GP_CNTRL, 197 if (ret)
198 iwl_read32(trans, CSR_GP_CNTRL) | 198 return ret;
199 BIT(trans->cfg->csr->flag_init_done)); 199
200 200 iwl_set_bits_prph(trans, APMG_PS_CTRL_REG,
201 /* wait for clock to be ready */ 201 APMG_PS_CTRL_VAL_RESET_REQ);
202 ret = iwl_poll_bit(trans, CSR_GP_CNTRL, 202 udelay(5);
203 BIT(trans->cfg->csr->flag_mac_clock_ready), 203 iwl_clear_bits_prph(trans, APMG_PS_CTRL_REG,
204 BIT(trans->cfg->csr->flag_mac_clock_ready), 204 APMG_PS_CTRL_VAL_RESET_REQ);
205 25000); 205
206 if (ret < 0) { 206 /*
207 IWL_ERR(trans, "Time out access OTP\n"); 207 * CSR auto clock gate disable bit -
208 } else { 208 * this is only applicable for HW with OTP shadow RAM
209 iwl_set_bits_prph(trans, APMG_PS_CTRL_REG, 209 */
210 APMG_PS_CTRL_VAL_RESET_REQ); 210 if (trans->cfg->base_params->shadow_ram_support)
211 udelay(5); 211 iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
212 iwl_clear_bits_prph(trans, APMG_PS_CTRL_REG, 212 CSR_RESET_LINK_PWR_MGMT_DISABLED);
213 APMG_PS_CTRL_VAL_RESET_REQ); 213
214 214 return 0;
215 /*
216 * CSR auto clock gate disable bit -
217 * this is only applicable for HW with OTP shadow RAM
218 */
219 if (trans->cfg->base_params->shadow_ram_support)
220 iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
221 CSR_RESET_LINK_PWR_MGMT_DISABLED);
222 }
223 return ret;
224} 215}
225 216
226static int iwl_read_otp_word(struct iwl_trans *trans, u16 addr, 217static int iwl_read_otp_word(struct iwl_trans *trans, u16 addr,
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.c b/drivers/net/wireless/intel/iwlwifi/iwl-io.c
index ffd1e649bfa0..a704e25af810 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-io.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.c
@@ -7,6 +7,7 @@
7 * 7 *
8 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH 9 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
10 * Copyright(C) 2018 - 2019 Intel Corporation
10 * 11 *
11 * This program is free software; you can redistribute it and/or modify it 12 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of version 2 of the GNU General Public License as 13 * under the terms of version 2 of the GNU General Public License as
@@ -28,6 +29,7 @@
28 * 29 *
29 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. 30 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
30 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH 31 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
32 * Copyright (C) 2018 - 2019 Intel Corporation
31 * All rights reserved. 33 * All rights reserved.
32 * 34 *
33 * Redistribution and use in source and binary forms, with or without 35 * Redistribution and use in source and binary forms, with or without
@@ -68,6 +70,36 @@
68#include "iwl-prph.h" 70#include "iwl-prph.h"
69#include "iwl-fh.h" 71#include "iwl-fh.h"
70 72
73const struct iwl_csr_params iwl_csr_v1 = {
74 .flag_mac_clock_ready = 0,
75 .flag_val_mac_access_en = 0,
76 .flag_init_done = 2,
77 .flag_mac_access_req = 3,
78 .flag_sw_reset = 7,
79 .flag_master_dis = 8,
80 .flag_stop_master = 9,
81 .addr_sw_reset = CSR_BASE + 0x020,
82 .mac_addr0_otp = 0x380,
83 .mac_addr1_otp = 0x384,
84 .mac_addr0_strap = 0x388,
85 .mac_addr1_strap = 0x38C
86};
87
88const struct iwl_csr_params iwl_csr_v2 = {
89 .flag_init_done = 6,
90 .flag_mac_clock_ready = 20,
91 .flag_val_mac_access_en = 20,
92 .flag_mac_access_req = 21,
93 .flag_master_dis = 28,
94 .flag_stop_master = 29,
95 .flag_sw_reset = 31,
96 .addr_sw_reset = CSR_BASE + 0x024,
97 .mac_addr0_otp = 0x30,
98 .mac_addr1_otp = 0x34,
99 .mac_addr0_strap = 0x38,
100 .mac_addr1_strap = 0x3C
101};
102
71void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val) 103void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val)
72{ 104{
73 trace_iwlwifi_dev_iowrite8(trans->dev, ofs, val); 105 trace_iwlwifi_dev_iowrite8(trans->dev, ofs, val);
@@ -275,9 +307,12 @@ void iwl_force_nmi(struct iwl_trans *trans)
275 if (trans->cfg->device_family < IWL_DEVICE_FAMILY_9000) 307 if (trans->cfg->device_family < IWL_DEVICE_FAMILY_9000)
276 iwl_write_prph(trans, DEVICE_SET_NMI_REG, 308 iwl_write_prph(trans, DEVICE_SET_NMI_REG,
277 DEVICE_SET_NMI_VAL_DRV); 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);
278 else 313 else
279 iwl_write_prph(trans, UREG_NIC_SET_NMI_DRIVER, 314 iwl_write_umac_prph(trans, UREG_DOORBELL_TO_ISR6,
280 UREG_NIC_SET_NMI_DRIVER_NMI_FROM_DRIVER_MSK); 315 UREG_DOORBELL_TO_ISR6_NMI_BIT);
281} 316}
282IWL_EXPORT_SYMBOL(iwl_force_nmi); 317IWL_EXPORT_SYMBOL(iwl_force_nmi);
283 318
@@ -456,3 +491,43 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf)
456 491
457 return 0; 492 return 0;
458} 493}
494
495int iwl_finish_nic_init(struct iwl_trans *trans)
496{
497 int err;
498
499 if (trans->cfg->bisr_workaround) {
500 /* ensure the TOP FSM isn't still in previous reset */
501 mdelay(2);
502 }
503
504 /*
505 * Set "initialization complete" bit to move adapter from
506 * D0U* --> D0A* (powered-up active) state.
507 */
508 iwl_set_bit(trans, CSR_GP_CNTRL,
509 BIT(trans->cfg->csr->flag_init_done));
510
511 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
512 udelay(2);
513
514 /*
515 * Wait for clock stabilization; once stabilized, access to
516 * device-internal resources is supported, e.g. iwl_write_prph()
517 * and accesses to uCode SRAM.
518 */
519 err = iwl_poll_bit(trans, CSR_GP_CNTRL,
520 BIT(trans->cfg->csr->flag_mac_clock_ready),
521 BIT(trans->cfg->csr->flag_mac_clock_ready),
522 25000);
523 if (err < 0)
524 IWL_DEBUG_INFO(trans, "Failed to wake NIC\n");
525
526 if (trans->cfg->bisr_workaround) {
527 /* ensure BISR shift has finished */
528 udelay(200);
529 }
530
531 return err < 0 ? err : 0;
532}
533IWL_EXPORT_SYMBOL(iwl_finish_nic_init);
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.h b/drivers/net/wireless/intel/iwlwifi/iwl-io.h
index 61477e58352d..920e2146ea3f 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-io.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.h
@@ -5,6 +5,8 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright (C) 2018 - 2019 Intel Corporation
9 *
8 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of version 2 of the GNU General Public License as 11 * under the terms of version 2 of the GNU General Public License as
10 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
@@ -23,6 +25,7 @@
23 * 25 *
24 * BSD LICENSE 26 * BSD LICENSE
25 * 27 *
28 * Copyright (C) 2018 - 2019 Intel Corporation
26 * All rights reserved. 29 * All rights reserved.
27 * 30 *
28 * Redistribution and use in source and binary forms, with or without 31 * Redistribution and use in source and binary forms, with or without
@@ -96,7 +99,48 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
96void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask); 99void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask);
97void iwl_force_nmi(struct iwl_trans *trans); 100void iwl_force_nmi(struct iwl_trans *trans);
98 101
102int iwl_finish_nic_init(struct iwl_trans *trans);
103
99/* Error handling */ 104/* Error handling */
100int iwl_dump_fh(struct iwl_trans *trans, char **buf); 105int iwl_dump_fh(struct iwl_trans *trans, char **buf);
101 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 */
112static inline u32 iwl_umac_prph(struct iwl_trans *trans, u32 ofs)
113{
114 return ofs + trans->cfg->umac_prph_offset;
115}
116
117static 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
122static 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
127static 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
133static 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
139static 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}
145
102#endif 146#endif
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index 63c081e5c63a..87d6de7efdd2 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -8,7 +8,7 @@
8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11 * Copyright(c) 2018 Intel Corporation 11 * Copyright(c) 2018 - 2019 Intel Corporation
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of version 2 of the GNU General Public License as 14 * it under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
31 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 31 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
34 * Copyright(c) 2018 Intel Corporation 34 * Copyright(c) 2018 - 2019 Intel Corporation
35 * All rights reserved. 35 * All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -463,6 +463,9 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
463 } 463 }
464 464
465 vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map; 465 vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map;
466
467 vht_cap->vht_mcs.tx_highest |=
468 cpu_to_le16(IEEE80211_VHT_EXT_NSS_BW_CAPABLE);
466} 469}
467 470
468static struct ieee80211_sband_iftype_data iwl_he_capa[] = { 471static struct ieee80211_sband_iftype_data iwl_he_capa[] = {
@@ -930,15 +933,13 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
930 const __le16 *ch_section; 933 const __le16 *ch_section;
931 934
932 if (cfg->nvm_type != IWL_NVM_EXT) 935 if (cfg->nvm_type != IWL_NVM_EXT)
933 data = kzalloc(sizeof(*data) + 936 data = kzalloc(struct_size(data, channels,
934 sizeof(struct ieee80211_channel) * 937 IWL_NVM_NUM_CHANNELS),
935 IWL_NVM_NUM_CHANNELS, 938 GFP_KERNEL);
936 GFP_KERNEL);
937 else 939 else
938 data = kzalloc(sizeof(*data) + 940 data = kzalloc(struct_size(data, channels,
939 sizeof(struct ieee80211_channel) * 941 IWL_NVM_NUM_CHANNELS_EXT),
940 IWL_NVM_NUM_CHANNELS_EXT, 942 GFP_KERNEL);
941 GFP_KERNEL);
942 if (!data) 943 if (!data)
943 return NULL; 944 return NULL;
944 945
@@ -1086,12 +1087,12 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
1086 int max_num_ch = cfg->nvm_type == IWL_NVM_EXT ? 1087 int max_num_ch = cfg->nvm_type == IWL_NVM_EXT ?
1087 IWL_NVM_NUM_CHANNELS_EXT : IWL_NVM_NUM_CHANNELS; 1088 IWL_NVM_NUM_CHANNELS_EXT : IWL_NVM_NUM_CHANNELS;
1088 1089
1089 if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES))
1090 return ERR_PTR(-EINVAL);
1091
1092 if (WARN_ON(num_of_ch > max_num_ch)) 1090 if (WARN_ON(num_of_ch > max_num_ch))
1093 num_of_ch = max_num_ch; 1091 num_of_ch = max_num_ch;
1094 1092
1093 if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES))
1094 return ERR_PTR(-EINVAL);
1095
1095 IWL_DEBUG_DEV(dev, IWL_DL_LAR, "building regdom for %d channels\n", 1096 IWL_DEBUG_DEV(dev, IWL_DL_LAR, "building regdom for %d channels\n",
1096 num_of_ch); 1097 num_of_ch);
1097 1098
@@ -1425,9 +1426,7 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
1425 if (empty_otp) 1426 if (empty_otp)
1426 IWL_INFO(trans, "OTP is empty\n"); 1427 IWL_INFO(trans, "OTP is empty\n");
1427 1428
1428 nvm = kzalloc(sizeof(*nvm) + 1429 nvm = kzalloc(struct_size(nvm, channels, IWL_NUM_CHANNELS), GFP_KERNEL);
1429 sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS,
1430 GFP_KERNEL);
1431 if (!nvm) { 1430 if (!nvm) {
1432 ret = -ENOMEM; 1431 ret = -ENOMEM;
1433 goto out; 1432 goto out;
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
index 3aaa5f06461c..1af9f9e1ecd4 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
@@ -8,7 +8,7 @@
8 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 Intel Deutschland GmbH 10 * Copyright(c) 2016 Intel Deutschland GmbH
11 * Copyright (C) 2018 Intel Corporation 11 * Copyright (C) 2018 - 2019 Intel Corporation
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of version 2 of the GNU General Public License as 14 * it under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
31 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 31 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
32 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
33 * Copyright(c) 2016 Intel Deutschland GmbH 33 * Copyright(c) 2016 Intel Deutschland GmbH
34 * Copyright (C) 2018 Intel Corporation 34 * Copyright (C) 2018 - 2019 Intel Corporation
35 * All rights reserved. 35 * All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -433,4 +433,7 @@ enum {
433#define HPM_DEBUG 0xA03440 433#define HPM_DEBUG 0xA03440
434#define PERSISTENCE_BIT BIT(12) 434#define PERSISTENCE_BIT BIT(12)
435#define PREG_WFPM_ACCESS BIT(12) 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#endif /* __iwl_prph_h__ */ 439#endif /* __iwl_prph_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index a7009cd4232d..bbebbf3efd57 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -8,6 +8,7 @@
8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11 * Copyright(c) 2018 - 2019 Intel Corporation
11 * 12 *
12 * This program is free software; you can redistribute it and/or modify 13 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -30,6 +31,7 @@
30 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 31 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
31 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
32 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
34 * Copyright(c) 2018 - 2019 Intel Corporation
33 * All rights reserved. 35 * All rights reserved.
34 * 36 *
35 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -230,6 +232,12 @@ enum iwl_hcmd_dataflag {
230 IWL_HCMD_DFL_DUP = BIT(1), 232 IWL_HCMD_DFL_DUP = BIT(1),
231}; 233};
232 234
235enum 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
233/** 241/**
234 * struct iwl_host_cmd - Host command to the uCode 242 * struct iwl_host_cmd - Host command to the uCode
235 * 243 *
@@ -330,6 +338,7 @@ enum iwl_d3_status {
330 * are sent 338 * are sent
331 * @STATUS_TRANS_IDLE: the trans is idle - general commands are not to be sent 339 * @STATUS_TRANS_IDLE: the trans is idle - general commands are not to be sent
332 * @STATUS_TRANS_DEAD: trans is dead - avoid any read/write operation 340 * @STATUS_TRANS_DEAD: trans is dead - avoid any read/write operation
341 * @STATUS_FW_WAIT_DUMP: if set, wait until cleared before collecting dump
333 */ 342 */
334enum iwl_trans_status { 343enum iwl_trans_status {
335 STATUS_SYNC_HCMD_ACTIVE, 344 STATUS_SYNC_HCMD_ACTIVE,
@@ -342,6 +351,7 @@ enum iwl_trans_status {
342 STATUS_TRANS_GOING_IDLE, 351 STATUS_TRANS_GOING_IDLE,
343 STATUS_TRANS_IDLE, 352 STATUS_TRANS_IDLE,
344 STATUS_TRANS_DEAD, 353 STATUS_TRANS_DEAD,
354 STATUS_FW_WAIT_DUMP,
345}; 355};
346 356
347static inline int 357static inline int
@@ -684,6 +694,9 @@ enum iwl_plat_pm_mode {
684 */ 694 */
685#define IWL_TRANS_IDLE_TIMEOUT 2000 695#define IWL_TRANS_IDLE_TIMEOUT 2000
686 696
697/* Max time to wait for nmi interrupt */
698#define IWL_TRANS_NMI_TIMEOUT (HZ / 4)
699
687/** 700/**
688 * struct iwl_dram_data 701 * struct iwl_dram_data
689 * @physical: page phy pointer 702 * @physical: page phy pointer
@@ -697,6 +710,20 @@ struct iwl_dram_data {
697}; 710};
698 711
699/** 712/**
713 * struct iwl_self_init_dram - dram data used by self init process
714 * @fw: lmac and umac dram data
715 * @fw_cnt: total number of items in array
716 * @paging: paging dram data
717 * @paging_cnt: total number of items in array
718 */
719struct iwl_self_init_dram {
720 struct iwl_dram_data *fw;
721 int fw_cnt;
722 struct iwl_dram_data *paging;
723 int paging_cnt;
724};
725
726/**
700 * struct iwl_trans - transport common data 727 * struct iwl_trans - transport common data
701 * 728 *
702 * @ops - pointer to iwl_trans_ops 729 * @ops - pointer to iwl_trans_ops
@@ -738,6 +765,10 @@ struct iwl_dram_data {
738 * mode is set during the initialization phase and is not 765 * mode is set during the initialization phase and is not
739 * supposed to change during runtime. 766 * supposed to change during runtime.
740 * @dbg_rec_on: true iff there is a fw debug recording currently active 767 * @dbg_rec_on: true iff there is a fw debug recording currently active
768 * @lmac_error_event_table: addrs of lmacs error tables
769 * @umac_error_event_table: addr of umac error table
770 * @error_event_table_tlv_status: bitmap that indicates what error table
771 * pointers was recevied via TLV. use enum &iwl_error_event_table_status
741 */ 772 */
742struct iwl_trans { 773struct iwl_trans {
743 const struct iwl_trans_ops *ops; 774 const struct iwl_trans_ops *ops;
@@ -790,12 +821,18 @@ struct iwl_trans {
790 u8 dbg_n_dest_reg; 821 u8 dbg_n_dest_reg;
791 int num_blocks; 822 int num_blocks;
792 struct iwl_dram_data fw_mon[IWL_FW_INI_APPLY_NUM]; 823 struct iwl_dram_data fw_mon[IWL_FW_INI_APPLY_NUM];
824 struct iwl_self_init_dram init_dram;
793 825
794 enum iwl_plat_pm_mode system_pm_mode; 826 enum iwl_plat_pm_mode system_pm_mode;
795 enum iwl_plat_pm_mode runtime_pm_mode; 827 enum iwl_plat_pm_mode runtime_pm_mode;
796 bool suspending; 828 bool suspending;
797 bool dbg_rec_on; 829 bool dbg_rec_on;
798 830
831 u32 lmac_error_event_table[2];
832 u32 umac_error_event_table;
833 unsigned int error_event_table_tlv_status;
834 wait_queue_head_t fw_halt_waitq;
835
799 /* pointer to trans specific struct */ 836 /* pointer to trans specific struct */
800 /*Ensure that this pointer will always be aligned to sizeof pointer */ 837 /*Ensure that this pointer will always be aligned to sizeof pointer */
801 char trans_specific[0] __aligned(sizeof(void *)); 838 char trans_specific[0] __aligned(sizeof(void *));
@@ -1202,6 +1239,10 @@ static inline void iwl_trans_fw_error(struct iwl_trans *trans)
1202 /* prevent double restarts due to the same erroneous FW */ 1239 /* prevent double restarts due to the same erroneous FW */
1203 if (!test_and_set_bit(STATUS_FW_ERROR, &trans->status)) 1240 if (!test_and_set_bit(STATUS_FW_ERROR, &trans->status))
1204 iwl_op_mode_nic_error(trans->op_mode); 1241 iwl_op_mode_nic_error(trans->op_mode);
1242
1243 if (test_and_clear_bit(STATUS_FW_WAIT_DUMP, &trans->status))
1244 wake_up(&trans->fw_halt_waitq);
1245
1205} 1246}
1206 1247
1207/***************************************************** 1248/*****************************************************
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/Makefile b/drivers/net/wireless/intel/iwlwifi/mvm/Makefile
index 30cbd981efbd..dd268c4bd371 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/Makefile
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/Makefile
@@ -5,6 +5,7 @@ iwlmvm-y += utils.o rx.o rxmq.o tx.o binding.o quota.o sta.o sf.o
5iwlmvm-y += scan.o time-event.o rs.o rs-fw.o 5iwlmvm-y += scan.o time-event.o rs.o rs-fw.o
6iwlmvm-y += power.o coex.o 6iwlmvm-y += power.o coex.o
7iwlmvm-y += tt.o offloading.o tdls.o 7iwlmvm-y += tt.o offloading.o tdls.o
8iwlmvm-y += ftm-responder.o ftm-initiator.o
8iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o 9iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o
9iwlmvm-$(CONFIG_IWLWIFI_LEDS) += led.o 10iwlmvm-$(CONFIG_IWLWIFI_LEDS) += led.o
10iwlmvm-$(CONFIG_PM) += d3.o 11iwlmvm-$(CONFIG_PM) += d3.o
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c
index 730e37744dc0..3d2abbc5c76c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c
@@ -241,7 +241,6 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
241 struct iwl_bt_coex_reduced_txp_update_cmd cmd = {}; 241 struct iwl_bt_coex_reduced_txp_update_cmd cmd = {};
242 struct iwl_mvm_sta *mvmsta; 242 struct iwl_mvm_sta *mvmsta;
243 u32 value; 243 u32 value;
244 int ret;
245 244
246 mvmsta = iwl_mvm_sta_from_staid_protected(mvm, sta_id); 245 mvmsta = iwl_mvm_sta_from_staid_protected(mvm, sta_id);
247 if (!mvmsta) 246 if (!mvmsta)
@@ -262,10 +261,8 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
262 cmd.reduced_txp = cpu_to_le32(value); 261 cmd.reduced_txp = cpu_to_le32(value);
263 mvmsta->bt_reduced_txpower = enable; 262 mvmsta->bt_reduced_txpower = enable;
264 263
265 ret = iwl_mvm_send_cmd_pdu(mvm, BT_COEX_UPDATE_REDUCED_TXP, CMD_ASYNC, 264 return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_UPDATE_REDUCED_TXP,
266 sizeof(cmd), &cmd); 265 CMD_ASYNC, sizeof(cmd), &cmd);
267
268 return ret;
269} 266}
270 267
271struct iwl_bt_iterator_data { 268struct iwl_bt_iterator_data {
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
index d96ada3c06fc..dff14f1ec55f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/constants.h
@@ -8,6 +8,7 @@
8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2015 Intel Deutschland GmbH 10 * Copyright(c) 2015 Intel Deutschland GmbH
11 * Copyright(c) 2018 - 2019 Intel Corporation
11 * 12 *
12 * This program is free software; you can redistribute it and/or modify 13 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -30,6 +31,7 @@
30 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. 31 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
31 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
32 * Copyright(c) 2015 Intel Deutschland GmbH 33 * Copyright(c) 2015 Intel Deutschland GmbH
34 * Copyright(c) 2018 - 2019 Intel Corporation
33 * All rights reserved. 35 * All rights reserved.
34 * 36 *
35 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -63,6 +65,7 @@
63#define __MVM_CONSTANTS_H 65#define __MVM_CONSTANTS_H
64 66
65#include <linux/ieee80211.h> 67#include <linux/ieee80211.h>
68#include "fw-api.h"
66 69
67#define IWL_MVM_UAPSD_NOAGG_BSSIDS_NUM 20 70#define IWL_MVM_UAPSD_NOAGG_BSSIDS_NUM 20
68 71
@@ -114,6 +117,7 @@
114#define IWL_MVM_TCM_LOWLAT_ENABLE_THRESH 100 /* packets/10 seconds */ 117#define IWL_MVM_TCM_LOWLAT_ENABLE_THRESH 100 /* packets/10 seconds */
115#define IWL_MVM_UAPSD_NONAGG_PERIOD 5000 /* msecs */ 118#define IWL_MVM_UAPSD_NONAGG_PERIOD 5000 /* msecs */
116#define IWL_MVM_UAPSD_NOAGG_LIST_LEN IWL_MVM_UAPSD_NOAGG_BSSIDS_NUM 119#define IWL_MVM_UAPSD_NOAGG_LIST_LEN IWL_MVM_UAPSD_NOAGG_BSSIDS_NUM
120#define IWL_MVM_NON_TRANSMITTING_AP 0
117#define IWL_MVM_RS_NUM_TRY_BEFORE_ANT_TOGGLE 1 121#define IWL_MVM_RS_NUM_TRY_BEFORE_ANT_TOGGLE 1
118#define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE 2 122#define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE 2
119#define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE_TW 1 123#define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE_TW 1
@@ -145,5 +149,8 @@
145#define IWL_MVM_RS_TPC_SR_NO_INCREASE 85 /* percent */ 149#define IWL_MVM_RS_TPC_SR_NO_INCREASE 85 /* percent */
146#define IWL_MVM_RS_TPC_TX_POWER_STEP 3 150#define IWL_MVM_RS_TPC_TX_POWER_STEP 3
147#define IWL_MVM_ENABLE_EBS 1 151#define IWL_MVM_ENABLE_EBS 1
152#define IWL_MVM_FTM_INITIATOR_ALGO IWL_TOF_ALGO_TYPE_MAX_LIKE
153#define IWL_MVM_FTM_INITIATOR_DYNACK true
154#define IWL_MVM_D3_DEBUG false
148 155
149#endif /* __MVM_CONSTANTS_H */ 156#endif /* __MVM_CONSTANTS_H */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 36ed7d6fc971..808bc6f363d0 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -1899,7 +1899,7 @@ static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac,
1899static int iwl_mvm_check_rt_status(struct iwl_mvm *mvm, 1899static int iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
1900 struct ieee80211_vif *vif) 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 struct error_table_start { 1903 struct error_table_start {
1904 /* cf. struct iwl_error_event_table */ 1904 /* cf. struct iwl_error_event_table */
1905 u32 valid; 1905 u32 valid;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
index e136475a34f6..776b24f54200 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
@@ -8,7 +8,7 @@
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11 * Copyright(c) 2018 Intel Corporation 11 * Copyright(c) 2018 - 2019 Intel Corporation
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of version 2 of the GNU General Public License as 14 * it under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
34 * Copyright(c) 2018 Intel Corporation 34 * Copyright(c) 2018 - 2019 Intel Corporation
35 * All rights reserved. 35 * All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -1188,6 +1188,111 @@ out:
1188 return ret ?: count; 1188 return ret ?: count;
1189} 1189}
1190 1190
1191static 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 mvm->beacon_inject_active = true;
1242
1243 mvmvif = iwl_mvm_vif_from_mac80211(vif);
1244 info = IEEE80211_SKB_CB(beacon);
1245 rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif);
1246 flags = iwl_mvm_mac80211_idx_to_hwrate(rate);
1247
1248 if (rate == IWL_FIRST_CCK_RATE)
1249 flags |= IWL_MAC_BEACON_CCK;
1250
1251 beacon_cmd.flags = cpu_to_le16(flags);
1252 beacon_cmd.byte_cnt = cpu_to_le16((u16)beacon->len);
1253 beacon_cmd.template_id = cpu_to_le32((u32)mvmvif->id);
1254
1255 iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd.tim_idx,
1256 &beacon_cmd.tim_size,
1257 beacon->data, beacon->len);
1258
1259 mutex_lock(&mvm->mutex);
1260 iwl_mvm_mac_ctxt_send_beacon_cmd(mvm, beacon, &beacon_cmd,
1261 sizeof(beacon_cmd));
1262 mutex_unlock(&mvm->mutex);
1263
1264 dev_kfree_skb(beacon);
1265
1266 rcu_read_unlock();
1267 return 0;
1268
1269out_err:
1270 rcu_read_unlock();
1271 return -EINVAL;
1272}
1273
1274static ssize_t iwl_dbgfs_inject_beacon_ie_write(struct iwl_mvm *mvm,
1275 char *buf, size_t count,
1276 loff_t *ppos)
1277{
1278 int ret = _iwl_dbgfs_inject_beacon_ie(mvm, buf, count);
1279
1280 mvm->hw->extra_beacon_tailroom = 0;
1281 return ret ?: count;
1282}
1283
1284static ssize_t iwl_dbgfs_inject_beacon_ie_restore_write(struct iwl_mvm *mvm,
1285 char *buf,
1286 size_t count,
1287 loff_t *ppos)
1288{
1289 int ret = _iwl_dbgfs_inject_beacon_ie(mvm, NULL, 0);
1290
1291 mvm->hw->extra_beacon_tailroom = 0;
1292 mvm->beacon_inject_active = false;
1293 return ret ?: count;
1294}
1295
1191static ssize_t iwl_dbgfs_fw_dbg_conf_read(struct file *file, 1296static ssize_t iwl_dbgfs_fw_dbg_conf_read(struct file *file,
1192 char __user *user_buf, 1297 char __user *user_buf,
1193 size_t count, loff_t *ppos) 1298 size_t count, loff_t *ppos)
@@ -1684,6 +1789,7 @@ iwl_dbgfs_send_echo_cmd_write(struct iwl_mvm *mvm, char *buf,
1684 1789
1685struct iwl_mvm_sniffer_apply { 1790struct iwl_mvm_sniffer_apply {
1686 struct iwl_mvm *mvm; 1791 struct iwl_mvm *mvm;
1792 u8 *bssid;
1687 u16 aid; 1793 u16 aid;
1688}; 1794};
1689 1795
@@ -1693,6 +1799,8 @@ static bool iwl_mvm_sniffer_apply(struct iwl_notif_wait_data *notif_data,
1693 struct iwl_mvm_sniffer_apply *apply = data; 1799 struct iwl_mvm_sniffer_apply *apply = data;
1694 1800
1695 apply->mvm->cur_aid = cpu_to_le16(apply->aid); 1801 apply->mvm->cur_aid = cpu_to_le16(apply->aid);
1802 memcpy(apply->mvm->cur_bssid, apply->bssid,
1803 sizeof(apply->mvm->cur_bssid));
1696 1804
1697 return true; 1805 return true;
1698} 1806}
@@ -1725,6 +1833,7 @@ iwl_dbgfs_he_sniffer_params_write(struct iwl_mvm *mvm, char *buf,
1725 he_mon_cmd.aid = cpu_to_le16(aid); 1833 he_mon_cmd.aid = cpu_to_le16(aid);
1726 1834
1727 apply.aid = aid; 1835 apply.aid = aid;
1836 apply.bssid = (void *)he_mon_cmd.bssid;
1728 1837
1729 mutex_lock(&mvm->mutex); 1838 mutex_lock(&mvm->mutex);
1730 1839
@@ -1754,6 +1863,23 @@ iwl_dbgfs_he_sniffer_params_write(struct iwl_mvm *mvm, char *buf,
1754} 1863}
1755 1864
1756static ssize_t 1865static ssize_t
1866iwl_dbgfs_he_sniffer_params_read(struct file *file, char __user *user_buf,
1867 size_t count, loff_t *ppos)
1868{
1869 struct iwl_mvm *mvm = file->private_data;
1870 u8 buf[32];
1871 int len;
1872
1873 len = scnprintf(buf, sizeof(buf),
1874 "%d %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
1875 le16_to_cpu(mvm->cur_aid), mvm->cur_bssid[0],
1876 mvm->cur_bssid[1], mvm->cur_bssid[2], mvm->cur_bssid[3],
1877 mvm->cur_bssid[4], mvm->cur_bssid[5]);
1878
1879 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1880}
1881
1882static ssize_t
1757iwl_dbgfs_uapsd_noagg_bssids_read(struct file *file, char __user *user_buf, 1883iwl_dbgfs_uapsd_noagg_bssids_read(struct file *file, char __user *user_buf,
1758 size_t count, loff_t *ppos) 1884 size_t count, loff_t *ppos)
1759{ 1885{
@@ -1806,6 +1932,8 @@ MVM_DEBUGFS_WRITE_FILE_OPS(max_amsdu_len, 8);
1806MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl, 1932MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl,
1807 (IWL_RSS_INDIRECTION_TABLE_SIZE * 2)); 1933 (IWL_RSS_INDIRECTION_TABLE_SIZE * 2));
1808MVM_DEBUGFS_WRITE_FILE_OPS(inject_packet, 512); 1934MVM_DEBUGFS_WRITE_FILE_OPS(inject_packet, 512);
1935MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie, 512);
1936MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie_restore, 512);
1809 1937
1810MVM_DEBUGFS_READ_FILE_OPS(uapsd_noagg_bssids); 1938MVM_DEBUGFS_READ_FILE_OPS(uapsd_noagg_bssids);
1811 1939
@@ -1821,7 +1949,7 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram, 8);
1821MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile); 1949MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile);
1822#endif 1950#endif
1823 1951
1824MVM_DEBUGFS_WRITE_FILE_OPS(he_sniffer_params, 32); 1952MVM_DEBUGFS_READ_WRITE_FILE_OPS(he_sniffer_params, 32);
1825 1953
1826static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf, 1954static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf,
1827 size_t count, loff_t *ppos) 1955 size_t count, loff_t *ppos)
@@ -2007,10 +2135,12 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
2007 MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, 0200); 2135 MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, 0200);
2008 MVM_DEBUGFS_ADD_FILE(indirection_tbl, mvm->debugfs_dir, 0200); 2136 MVM_DEBUGFS_ADD_FILE(indirection_tbl, mvm->debugfs_dir, 0200);
2009 MVM_DEBUGFS_ADD_FILE(inject_packet, mvm->debugfs_dir, 0200); 2137 MVM_DEBUGFS_ADD_FILE(inject_packet, mvm->debugfs_dir, 0200);
2138 MVM_DEBUGFS_ADD_FILE(inject_beacon_ie, mvm->debugfs_dir, 0200);
2139 MVM_DEBUGFS_ADD_FILE(inject_beacon_ie_restore, mvm->debugfs_dir, 0200);
2010#ifdef CONFIG_ACPI 2140#ifdef CONFIG_ACPI
2011 MVM_DEBUGFS_ADD_FILE(sar_geo_profile, dbgfs_dir, 0400); 2141 MVM_DEBUGFS_ADD_FILE(sar_geo_profile, dbgfs_dir, 0400);
2012#endif 2142#endif
2013 MVM_DEBUGFS_ADD_FILE(he_sniffer_params, mvm->debugfs_dir, 0200); 2143 MVM_DEBUGFS_ADD_FILE(he_sniffer_params, mvm->debugfs_dir, 0600);
2014 2144
2015 if (!debugfs_create_bool("enable_scan_iteration_notif", 2145 if (!debugfs_create_bool("enable_scan_iteration_notif",
2016 0600, 2146 0600,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
new file mode 100644
index 000000000000..e9822a3ec373
--- /dev/null
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
@@ -0,0 +1,654 @@
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
70struct 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
77static 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
91void 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
121static int
122iwl_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
135static 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
165static 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
199static 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
233static int
234iwl_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
269static 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
309int 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
369void 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
386static 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
401static 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
417static 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
441static 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
460static 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
481void 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
604void 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}
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c
new file mode 100644
index 000000000000..1513b8b4062f
--- /dev/null
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c
@@ -0,0 +1,244 @@
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
65static int
66iwl_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
109static int
110iwl_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
155int 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
203void 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
212void 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}
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index d3dc9d276e0f..00a47f6f1d81 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -8,7 +8,7 @@
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11 * Copyright(c) 2018 Intel Corporation 11 * Copyright(c) 2018 - 2019 Intel Corporation
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of version 2 of the GNU General Public License as 14 * it under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
34 * Copyright(c) 2018 Intel Corporation 34 * Copyright(c) 2018 - 2019 Intel Corporation
35 * All rights reserved. 35 * All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -105,12 +105,12 @@ static int iwl_send_rss_cfg_cmd(struct iwl_mvm *mvm)
105 int i; 105 int i;
106 struct iwl_rss_config_cmd cmd = { 106 struct iwl_rss_config_cmd cmd = {
107 .flags = cpu_to_le32(IWL_RSS_ENABLE), 107 .flags = cpu_to_le32(IWL_RSS_ENABLE),
108 .hash_mask = IWL_RSS_HASH_TYPE_IPV4_TCP | 108 .hash_mask = BIT(IWL_RSS_HASH_TYPE_IPV4_TCP) |
109 IWL_RSS_HASH_TYPE_IPV4_UDP | 109 BIT(IWL_RSS_HASH_TYPE_IPV4_UDP) |
110 IWL_RSS_HASH_TYPE_IPV4_PAYLOAD | 110 BIT(IWL_RSS_HASH_TYPE_IPV4_PAYLOAD) |
111 IWL_RSS_HASH_TYPE_IPV6_TCP | 111 BIT(IWL_RSS_HASH_TYPE_IPV6_TCP) |
112 IWL_RSS_HASH_TYPE_IPV6_UDP | 112 BIT(IWL_RSS_HASH_TYPE_IPV6_UDP) |
113 IWL_RSS_HASH_TYPE_IPV6_PAYLOAD, 113 BIT(IWL_RSS_HASH_TYPE_IPV6_PAYLOAD),
114 }; 114 };
115 115
116 if (mvm->trans->num_rx_queues == 1) 116 if (mvm->trans->num_rx_queues == 1)
@@ -127,13 +127,17 @@ static int iwl_send_rss_cfg_cmd(struct iwl_mvm *mvm)
127 127
128static int iwl_configure_rxq(struct iwl_mvm *mvm) 128static int iwl_configure_rxq(struct iwl_mvm *mvm)
129{ 129{
130 int i, num_queues, size; 130 int i, num_queues, size, ret;
131 struct iwl_rfh_queue_config *cmd; 131 struct iwl_rfh_queue_config *cmd;
132 struct iwl_host_cmd hcmd = {
133 .id = WIDE_ID(DATA_PATH_GROUP, RFH_QUEUE_CONFIG_CMD),
134 .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
135 };
132 136
133 /* Do not configure default queue, it is configured via context info */ 137 /* Do not configure default queue, it is configured via context info */
134 num_queues = mvm->trans->num_rx_queues - 1; 138 num_queues = mvm->trans->num_rx_queues - 1;
135 139
136 size = sizeof(*cmd) + num_queues * sizeof(struct iwl_rfh_queue_data); 140 size = struct_size(cmd, data, num_queues);
137 141
138 cmd = kzalloc(size, GFP_KERNEL); 142 cmd = kzalloc(size, GFP_KERNEL);
139 if (!cmd) 143 if (!cmd)
@@ -154,10 +158,14 @@ static int iwl_configure_rxq(struct iwl_mvm *mvm)
154 cmd->data[i].fr_bd_wid = cpu_to_le32(data.fr_bd_wid); 158 cmd->data[i].fr_bd_wid = cpu_to_le32(data.fr_bd_wid);
155 } 159 }
156 160
157 return iwl_mvm_send_cmd_pdu(mvm, 161 hcmd.data[0] = cmd;
158 WIDE_ID(DATA_PATH_GROUP, 162 hcmd.len[0] = size;
159 RFH_QUEUE_CONFIG_CMD), 163
160 0, size, cmd); 164 ret = iwl_mvm_send_cmd(mvm, &hcmd);
165
166 kfree(cmd);
167
168 return ret;
161} 169}
162 170
163static int iwl_mvm_send_dqa_cmd(struct iwl_mvm *mvm) 171static int iwl_mvm_send_dqa_cmd(struct iwl_mvm *mvm)
@@ -210,7 +218,7 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
210 struct iwl_lmac_alive *lmac1; 218 struct iwl_lmac_alive *lmac1;
211 struct iwl_lmac_alive *lmac2 = NULL; 219 struct iwl_lmac_alive *lmac2 = NULL;
212 u16 status; 220 u16 status;
213 u32 umac_error_event_table; 221 u32 lmac_error_event_table, umac_error_event_table;
214 222
215 if (iwl_rx_packet_payload_len(pkt) == sizeof(*palive)) { 223 if (iwl_rx_packet_payload_len(pkt) == sizeof(*palive)) {
216 palive = (void *)pkt->data; 224 palive = (void *)pkt->data;
@@ -225,30 +233,35 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
225 status = le16_to_cpu(palive3->status); 233 status = le16_to_cpu(palive3->status);
226 } 234 }
227 235
228 mvm->error_event_table[0] = le32_to_cpu(lmac1->error_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);
239
229 if (lmac2) 240 if (lmac2)
230 mvm->error_event_table[1] = 241 mvm->trans->lmac_error_event_table[1] =
231 le32_to_cpu(lmac2->error_event_table_ptr); 242 le32_to_cpu(lmac2->dbg_ptrs.error_event_table_ptr);
232 mvm->log_event_table = le32_to_cpu(lmac1->log_event_table_ptr);
233 243
234 umac_error_event_table = le32_to_cpu(umac->error_info_addr); 244 umac_error_event_table = le32_to_cpu(umac->dbg_ptrs.error_info_addr);
235 245
236 if (!umac_error_event_table) { 246 if (!umac_error_event_table) {
237 mvm->support_umac_log = false; 247 mvm->support_umac_log = false;
238 } else if (umac_error_event_table >= 248 } else if (umac_error_event_table >=
239 mvm->trans->cfg->min_umac_error_event_table) { 249 mvm->trans->cfg->min_umac_error_event_table) {
240 mvm->support_umac_log = true; 250 mvm->support_umac_log = true;
241 mvm->umac_error_event_table = umac_error_event_table;
242 } else { 251 } else {
243 IWL_ERR(mvm, 252 IWL_ERR(mvm,
244 "Not valid error log pointer 0x%08X for %s uCode\n", 253 "Not valid error log pointer 0x%08X for %s uCode\n",
245 mvm->umac_error_event_table, 254 umac_error_event_table,
246 (mvm->fwrt.cur_fw_img == IWL_UCODE_INIT) ? 255 (mvm->fwrt.cur_fw_img == IWL_UCODE_INIT) ?
247 "Init" : "RT"); 256 "Init" : "RT");
248 mvm->support_umac_log = false; 257 mvm->support_umac_log = false;
249 } 258 }
250 259
251 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);
252 alive_data->valid = status == IWL_ALIVE_STATUS_OK; 265 alive_data->valid = status == IWL_ALIVE_STATUS_OK;
253 266
254 IWL_DEBUG_FW(mvm, 267 IWL_DEBUG_FW(mvm,
@@ -299,7 +312,6 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
299 enum iwl_ucode_type old_type = mvm->fwrt.cur_fw_img; 312 enum iwl_ucode_type old_type = mvm->fwrt.cur_fw_img;
300 static const u16 alive_cmd[] = { MVM_ALIVE }; 313 static const u16 alive_cmd[] = { MVM_ALIVE };
301 314
302 set_bit(IWL_FWRT_STATUS_WAIT_ALIVE, &mvm->fwrt.status);
303 if (ucode_type == IWL_UCODE_REGULAR && 315 if (ucode_type == IWL_UCODE_REGULAR &&
304 iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_START_FROM_ALIVE) && 316 iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_START_FROM_ALIVE) &&
305 !(fw_has_capa(&mvm->fw->ucode_capa, 317 !(fw_has_capa(&mvm->fw->ucode_capa,
@@ -332,11 +344,16 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
332 if (ret) { 344 if (ret) {
333 struct iwl_trans *trans = mvm->trans; 345 struct iwl_trans *trans = mvm->trans;
334 346
347 if (ret == -ETIMEDOUT)
348 iwl_fw_dbg_error_collect(&mvm->fwrt,
349 FW_DBG_TRIGGER_ALIVE_TIMEOUT);
350
335 if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000) 351 if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000)
336 IWL_ERR(mvm, 352 IWL_ERR(mvm,
337 "SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n", 353 "SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n",
338 iwl_read_prph(trans, UMAG_SB_CPU_1_STATUS), 354 iwl_read_umac_prph(trans, UMAG_SB_CPU_1_STATUS),
339 iwl_read_prph(trans, UMAG_SB_CPU_2_STATUS)); 355 iwl_read_umac_prph(trans,
356 UMAG_SB_CPU_2_STATUS));
340 else if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000) 357 else if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000)
341 IWL_ERR(mvm, 358 IWL_ERR(mvm,
342 "SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n", 359 "SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n",
@@ -377,7 +394,6 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
377#ifdef CONFIG_IWLWIFI_DEBUGFS 394#ifdef CONFIG_IWLWIFI_DEBUGFS
378 iwl_fw_set_dbg_rec_on(&mvm->fwrt); 395 iwl_fw_set_dbg_rec_on(&mvm->fwrt);
379#endif 396#endif
380 clear_bit(IWL_FWRT_STATUS_WAIT_ALIVE, &mvm->fwrt.status);
381 397
382 return 0; 398 return 0;
383} 399}
@@ -403,13 +419,15 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
403 iwl_wait_init_complete, 419 iwl_wait_init_complete,
404 NULL); 420 NULL);
405 421
422 iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_EARLY);
423
406 /* Will also start the device */ 424 /* Will also start the device */
407 ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR); 425 ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR);
408 if (ret) { 426 if (ret) {
409 IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret); 427 IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret);
410 iwl_fw_assert_error_dump(&mvm->fwrt);
411 goto error; 428 goto error;
412 } 429 }
430 iwl_fw_dbg_apply_point(&mvm->fwrt, IWL_FW_INI_APPLY_AFTER_ALIVE);
413 431
414 /* Send init config command to mark that we are sending NVM access 432 /* Send init config command to mark that we are sending NVM access
415 * commands 433 * commands
@@ -628,10 +646,10 @@ static int iwl_mvm_config_ltr(struct iwl_mvm *mvm)
628} 646}
629 647
630#ifdef CONFIG_ACPI 648#ifdef CONFIG_ACPI
631static int iwl_mvm_sar_set_profile(struct iwl_mvm *mvm, 649static inline int iwl_mvm_sar_set_profile(struct iwl_mvm *mvm,
632 union acpi_object *table, 650 union acpi_object *table,
633 struct iwl_mvm_sar_profile *profile, 651 struct iwl_mvm_sar_profile *profile,
634 bool enabled) 652 bool enabled)
635{ 653{
636 int i; 654 int i;
637 655
@@ -962,6 +980,57 @@ int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
962} 980}
963#endif /* CONFIG_ACPI */ 981#endif /* CONFIG_ACPI */
964 982
983void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
984{
985 u32 error_log_size = mvm->fw->ucode_capa.error_log_size;
986 int ret;
987 u32 resp;
988
989 struct iwl_fw_error_recovery_cmd recovery_cmd = {
990 .flags = cpu_to_le32(flags),
991 .buf_size = 0,
992 };
993 struct iwl_host_cmd host_cmd = {
994 .id = WIDE_ID(SYSTEM_GROUP, FW_ERROR_RECOVERY_CMD),
995 .flags = CMD_WANT_SKB,
996 .data = {&recovery_cmd, },
997 .len = {sizeof(recovery_cmd), },
998 };
999
1000 /* no error log was defined in TLV */
1001 if (!error_log_size)
1002 return;
1003
1004 if (flags & ERROR_RECOVERY_UPDATE_DB) {
1005 /* no buf was allocated while HW reset */
1006 if (!mvm->error_recovery_buf)
1007 return;
1008
1009 host_cmd.data[1] = mvm->error_recovery_buf;
1010 host_cmd.len[1] = error_log_size;
1011 host_cmd.dataflags[1] = IWL_HCMD_DFL_NOCOPY;
1012 recovery_cmd.buf_size = cpu_to_le32(error_log_size);
1013 }
1014
1015 ret = iwl_mvm_send_cmd(mvm, &host_cmd);
1016 kfree(mvm->error_recovery_buf);
1017 mvm->error_recovery_buf = NULL;
1018
1019 if (ret) {
1020 IWL_ERR(mvm, "Failed to send recovery cmd %d\n", ret);
1021 return;
1022 }
1023
1024 /* skb respond is only relevant in ERROR_RECOVERY_UPDATE_DB */
1025 if (flags & ERROR_RECOVERY_UPDATE_DB) {
1026 resp = le32_to_cpu(*(__le32 *)host_cmd.resp_pkt->data);
1027 if (resp)
1028 IWL_ERR(mvm,
1029 "Failed to send recovery cmd blob was invalid %d\n",
1030 resp);
1031 }
1032}
1033
965static int iwl_mvm_sar_init(struct iwl_mvm *mvm) 1034static int iwl_mvm_sar_init(struct iwl_mvm *mvm)
966{ 1035{
967 int ret; 1036 int ret;
@@ -1052,7 +1121,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
1052 ret = iwl_mvm_load_rt_fw(mvm); 1121 ret = iwl_mvm_load_rt_fw(mvm);
1053 if (ret) { 1122 if (ret) {
1054 IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret); 1123 IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret);
1055 iwl_fw_assert_error_dump(&mvm->fwrt); 1124 iwl_fw_dbg_error_collect(&mvm->fwrt, FW_DBG_TRIGGER_DRIVER);
1056 goto error; 1125 goto error;
1057 } 1126 }
1058 1127
@@ -1198,6 +1267,12 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
1198 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) 1267 if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
1199 iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN); 1268 iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN);
1200 1269
1270 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
1271 iwl_mvm_send_recovery_cmd(mvm, ERROR_RECOVERY_UPDATE_DB);
1272
1273 if (iwl_acpi_get_eckv(mvm->dev, &mvm->ext_clock_valid))
1274 IWL_DEBUG_INFO(mvm, "ECKV table doesn't exist in BIOS\n");
1275
1201 ret = iwl_mvm_sar_init(mvm); 1276 ret = iwl_mvm_sar_init(mvm);
1202 if (ret == 0) { 1277 if (ret == 0) {
1203 ret = iwl_mvm_sar_geo_init(mvm); 1278 ret = iwl_mvm_sar_geo_init(mvm);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/led.c b/drivers/net/wireless/intel/iwlwifi/mvm/led.c
index 9bb1de1cad64..4348bb00e761 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/led.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/led.c
@@ -7,6 +7,7 @@
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2017 Intel Deutschland GmbH 9 * Copyright(c) 2017 Intel Deutschland GmbH
10 * Copyright(c) 2018 Intel Corporation
10 * 11 *
11 * This program is free software; you can redistribute it and/or modify 12 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -28,6 +29,7 @@
28 * 29 *
29 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 30 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
30 * Copyright(c) 2017 Intel Deutschland GmbH 31 * Copyright(c) 2017 Intel Deutschland GmbH
32 * Copyright(c) 2018 Intel Corporation
31 * All rights reserved. 33 * All rights reserved.
32 * 34 *
33 * Redistribution and use in source and binary forms, with or without 35 * Redistribution and use in source and binary forms, with or without
@@ -113,6 +115,7 @@ int iwl_mvm_leds_init(struct iwl_mvm *mvm)
113 switch (mode) { 115 switch (mode) {
114 case IWL_LED_BLINK: 116 case IWL_LED_BLINK:
115 IWL_ERR(mvm, "Blink led mode not supported, used default\n"); 117 IWL_ERR(mvm, "Blink led mode not supported, used default\n");
118 /* fall through */
116 case IWL_LED_DEFAULT: 119 case IWL_LED_DEFAULT:
117 case IWL_LED_RF_STATE: 120 case IWL_LED_RF_STATE:
118 mode = IWL_LED_RF_STATE; 121 mode = IWL_LED_RF_STATE;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
index 7cfdd07d8736..6a70dece447d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
@@ -706,8 +706,7 @@ static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
706 if (vif->probe_req_reg && vif->bss_conf.assoc && vif->p2p) 706 if (vif->probe_req_reg && vif->bss_conf.assoc && vif->p2p)
707 cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST); 707 cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST);
708 708
709 if (vif->bss_conf.assoc && vif->bss_conf.he_support && 709 if (vif->bss_conf.he_support && !iwlwifi_mod_params.disable_11ax) {
710 !iwlwifi_mod_params.disable_11ax) {
711 cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_11AX); 710 cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_11AX);
712 if (vif->bss_conf.twt_requester) 711 if (vif->bss_conf.twt_requester)
713 ctxt_sta->data_policy |= cpu_to_le32(TWT_SUPPORTED); 712 ctxt_sta->data_policy |= cpu_to_le32(TWT_SUPPORTED);
@@ -812,9 +811,9 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_device(struct iwl_mvm *mvm,
812 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); 811 return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
813} 812}
814 813
815static void iwl_mvm_mac_ctxt_set_tim(struct iwl_mvm *mvm, 814void iwl_mvm_mac_ctxt_set_tim(struct iwl_mvm *mvm,
816 __le32 *tim_index, __le32 *tim_size, 815 __le32 *tim_index, __le32 *tim_size,
817 u8 *beacon, u32 frame_size) 816 u8 *beacon, u32 frame_size)
818{ 817{
819 u32 tim_idx; 818 u32 tim_idx;
820 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon; 819 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon;
@@ -854,8 +853,8 @@ static u32 iwl_mvm_find_ie_offset(u8 *beacon, u8 eid, u32 frame_size)
854 return ie - beacon; 853 return ie - beacon;
855} 854}
856 855
857static u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct ieee80211_tx_info *info, 856u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct ieee80211_tx_info *info,
858 struct ieee80211_vif *vif) 857 struct ieee80211_vif *vif)
859{ 858{
860 u8 rate; 859 u8 rate;
861 860
@@ -905,9 +904,9 @@ static void iwl_mvm_mac_ctxt_set_tx(struct iwl_mvm *mvm,
905 904
906} 905}
907 906
908static int iwl_mvm_mac_ctxt_send_beacon_cmd(struct iwl_mvm *mvm, 907int iwl_mvm_mac_ctxt_send_beacon_cmd(struct iwl_mvm *mvm,
909 struct sk_buff *beacon, 908 struct sk_buff *beacon,
910 void *data, int len) 909 void *data, int len)
911{ 910{
912 struct iwl_host_cmd cmd = { 911 struct iwl_host_cmd cmd = {
913 .id = BEACON_TEMPLATE_CMD, 912 .id = BEACON_TEMPLATE_CMD,
@@ -1010,13 +1009,16 @@ static int iwl_mvm_mac_ctxt_send_beacon_v9(struct iwl_mvm *mvm,
1010 sizeof(beacon_cmd)); 1009 sizeof(beacon_cmd));
1011} 1010}
1012 1011
1013static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm, 1012int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
1014 struct ieee80211_vif *vif, 1013 struct ieee80211_vif *vif,
1015 struct sk_buff *beacon) 1014 struct sk_buff *beacon)
1016{ 1015{
1017 if (WARN_ON(!beacon)) 1016 if (WARN_ON(!beacon))
1018 return -EINVAL; 1017 return -EINVAL;
1019 1018
1019 if (IWL_MVM_NON_TRANSMITTING_AP)
1020 return 0;
1021
1020 if (!fw_has_capa(&mvm->fw->ucode_capa, 1022 if (!fw_has_capa(&mvm->fw->ucode_capa,
1021 IWL_UCODE_TLV_CAPA_CSA_AND_TBTT_OFFLOAD)) 1023 IWL_UCODE_TLV_CAPA_CSA_AND_TBTT_OFFLOAD))
1022 return iwl_mvm_mac_ctxt_send_beacon_v6(mvm, vif, beacon); 1024 return iwl_mvm_mac_ctxt_send_beacon_v6(mvm, vif, beacon);
@@ -1042,6 +1044,11 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
1042 if (!beacon) 1044 if (!beacon)
1043 return -ENOMEM; 1045 return -ENOMEM;
1044 1046
1047#ifdef CONFIG_IWLWIFI_DEBUGFS
1048 if (mvm->beacon_inject_active)
1049 return -EBUSY;
1050#endif
1051
1045 ret = iwl_mvm_mac_ctxt_send_beacon(mvm, vif, beacon); 1052 ret = iwl_mvm_mac_ctxt_send_beacon(mvm, vif, beacon);
1046 dev_kfree_skb(beacon); 1053 dev_kfree_skb(beacon);
1047 return ret; 1054 return ret;
@@ -1330,7 +1337,7 @@ void iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
1330{ 1337{
1331 struct iwl_rx_packet *pkt = rxb_addr(rxb); 1338 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1332 struct iwl_extended_beacon_notif *beacon = (void *)pkt->data; 1339 struct iwl_extended_beacon_notif *beacon = (void *)pkt->data;
1333 struct iwl_mvm_tx_resp *beacon_notify_hdr; 1340 struct iwl_extended_beacon_notif_v5 *beacon_v5 = (void *)pkt->data;
1334 struct ieee80211_vif *csa_vif; 1341 struct ieee80211_vif *csa_vif;
1335 struct ieee80211_vif *tx_blocked_vif; 1342 struct ieee80211_vif *tx_blocked_vif;
1336 struct agg_tx_status *agg_status; 1343 struct agg_tx_status *agg_status;
@@ -1338,18 +1345,29 @@ void iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
1338 1345
1339 lockdep_assert_held(&mvm->mutex); 1346 lockdep_assert_held(&mvm->mutex);
1340 1347
1341 beacon_notify_hdr = &beacon->beacon_notify_hdr;
1342 mvm->ap_last_beacon_gp2 = le32_to_cpu(beacon->gp2); 1348 mvm->ap_last_beacon_gp2 = le32_to_cpu(beacon->gp2);
1343 mvm->ibss_manager = beacon->ibss_mgr_status != 0;
1344 1349
1345 agg_status = iwl_mvm_get_agg_status(mvm, beacon_notify_hdr); 1350 if (!iwl_mvm_is_short_beacon_notif_supported(mvm)) {
1346 status = le16_to_cpu(agg_status->status) & TX_STATUS_MSK; 1351 struct iwl_mvm_tx_resp *beacon_notify_hdr =
1347 IWL_DEBUG_RX(mvm, 1352 &beacon_v5->beacon_notify_hdr;
1348 "beacon status %#x retries:%d tsf:0x%016llX gp2:0x%X rate:%d\n", 1353
1349 status, beacon_notify_hdr->failure_frame, 1354 mvm->ibss_manager = beacon_v5->ibss_mgr_status != 0;
1350 le64_to_cpu(beacon->tsf), 1355 agg_status = iwl_mvm_get_agg_status(mvm, beacon_notify_hdr);
1351 mvm->ap_last_beacon_gp2, 1356 status = le16_to_cpu(agg_status->status) & TX_STATUS_MSK;
1352 le32_to_cpu(beacon_notify_hdr->initial_rate)); 1357 IWL_DEBUG_RX(mvm,
1358 "beacon status %#x retries:%d tsf:0x%016llX gp2:0x%X rate:%d\n",
1359 status, beacon_notify_hdr->failure_frame,
1360 le64_to_cpu(beacon->tsf),
1361 mvm->ap_last_beacon_gp2,
1362 le32_to_cpu(beacon_notify_hdr->initial_rate));
1363 } else {
1364 mvm->ibss_manager = beacon->ibss_mgr_status != 0;
1365 status = le32_to_cpu(beacon->status) & TX_STATUS_MSK;
1366 IWL_DEBUG_RX(mvm,
1367 "beacon status %#x tsf:0x%016llX gp2:0x%X\n",
1368 status, le64_to_cpu(beacon->tsf),
1369 mvm->ap_last_beacon_gp2);
1370 }
1353 1371
1354 csa_vif = rcu_dereference_protected(mvm->csa_vif, 1372 csa_vif = rcu_dereference_protected(mvm->csa_vif,
1355 lockdep_is_held(&mvm->mutex)); 1373 lockdep_is_held(&mvm->mutex));
@@ -1539,42 +1557,58 @@ void iwl_mvm_channel_switch_noa_notif(struct iwl_mvm *mvm,
1539{ 1557{
1540 struct iwl_rx_packet *pkt = rxb_addr(rxb); 1558 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1541 struct iwl_channel_switch_noa_notif *notif = (void *)pkt->data; 1559 struct iwl_channel_switch_noa_notif *notif = (void *)pkt->data;
1542 struct ieee80211_vif *csa_vif; 1560 struct ieee80211_vif *csa_vif, *vif;
1543 struct iwl_mvm_vif *mvmvif; 1561 struct iwl_mvm_vif *mvmvif;
1544 int len = iwl_rx_packet_payload_len(pkt); 1562 int len = iwl_rx_packet_payload_len(pkt);
1545 u32 id_n_color; 1563 u32 id_n_color, csa_id, mac_id;
1546 1564
1547 if (WARN_ON_ONCE(len < sizeof(*notif))) 1565 if (WARN_ON_ONCE(len < sizeof(*notif)))
1548 return; 1566 return;
1549 1567
1550 rcu_read_lock();
1551
1552 csa_vif = rcu_dereference(mvm->csa_vif);
1553 if (WARN_ON(!csa_vif || !csa_vif->csa_active))
1554 goto out_unlock;
1555
1556 id_n_color = le32_to_cpu(notif->id_and_color); 1568 id_n_color = le32_to_cpu(notif->id_and_color);
1569 mac_id = id_n_color & FW_CTXT_ID_MSK;
1557 1570
1558 mvmvif = iwl_mvm_vif_from_mac80211(csa_vif); 1571 if (WARN_ON_ONCE(mac_id >= NUM_MAC_INDEX_DRIVER))
1559 if (WARN(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color) != id_n_color, 1572 return;
1560 "channel switch noa notification on unexpected vif (csa_vif=%d, notif=%d)",
1561 FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color), id_n_color))
1562 goto out_unlock;
1563 1573
1564 IWL_DEBUG_INFO(mvm, "Channel Switch Started Notification\n"); 1574 rcu_read_lock();
1575 vif = rcu_dereference(mvm->vif_id_to_mac[mac_id]);
1565 1576
1566 schedule_delayed_work(&mvm->cs_tx_unblock_dwork, 1577 switch (vif->type) {
1567 msecs_to_jiffies(IWL_MVM_CS_UNBLOCK_TX_TIMEOUT * 1578 case NL80211_IFTYPE_AP:
1568 csa_vif->bss_conf.beacon_int)); 1579 csa_vif = rcu_dereference(mvm->csa_vif);
1580 if (WARN_ON(!csa_vif || !csa_vif->csa_active ||
1581 csa_vif != vif))
1582 goto out_unlock;
1569 1583
1570 ieee80211_csa_finish(csa_vif); 1584 mvmvif = iwl_mvm_vif_from_mac80211(csa_vif);
1585 csa_id = FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color);
1586 if (WARN(csa_id != id_n_color,
1587 "channel switch noa notification on unexpected vif (csa_vif=%d, notif=%d)",
1588 csa_id, id_n_color))
1589 goto out_unlock;
1571 1590
1572 rcu_read_unlock(); 1591 IWL_DEBUG_INFO(mvm, "Channel Switch Started Notification\n");
1573 1592
1574 RCU_INIT_POINTER(mvm->csa_vif, NULL); 1593 schedule_delayed_work(&mvm->cs_tx_unblock_dwork,
1594 msecs_to_jiffies(IWL_MVM_CS_UNBLOCK_TX_TIMEOUT *
1595 csa_vif->bss_conf.beacon_int));
1575 1596
1576 return; 1597 ieee80211_csa_finish(csa_vif);
1577 1598
1599 rcu_read_unlock();
1600
1601 RCU_INIT_POINTER(mvm->csa_vif, NULL);
1602 return;
1603 case NL80211_IFTYPE_STATION:
1604 iwl_mvm_csa_client_absent(mvm, vif);
1605 ieee80211_chswitch_done(vif, true);
1606 break;
1607 default:
1608 /* should never happen */
1609 WARN_ON_ONCE(1);
1610 break;
1611 }
1578out_unlock: 1612out_unlock:
1579 rcu_read_unlock(); 1613 rcu_read_unlock();
1580} 1614}
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index e098884dd915..3a92c09d4692 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -184,6 +184,29 @@ static const struct iwl_fw_bcast_filter iwl_mvm_default_bcast_filters[] = {
184}; 184};
185#endif 185#endif
186 186
187static 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
187void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type) 210void iwl_mvm_ref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
188{ 211{
189 if (!iwl_mvm_is_d0i3_supported(mvm)) 212 if (!iwl_mvm_is_d0i3_supported(mvm))
@@ -420,6 +443,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
420 WLAN_CIPHER_SUITE_TKIP, 443 WLAN_CIPHER_SUITE_TKIP,
421 WLAN_CIPHER_SUITE_CCMP, 444 WLAN_CIPHER_SUITE_CCMP,
422 }; 445 };
446#ifdef CONFIG_PM_SLEEP
447 bool unified = fw_has_capa(&mvm->fw->ucode_capa,
448 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
449#endif
423 450
424 /* Tell mac80211 our characteristics */ 451 /* Tell mac80211 our characteristics */
425 ieee80211_hw_set(hw, SIGNAL_DBM); 452 ieee80211_hw_set(hw, SIGNAL_DBM);
@@ -544,6 +571,13 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
544 hw->wiphy->n_cipher_suites++; 571 hw->wiphy->n_cipher_suites++;
545 } 572 }
546 573
574 if (fw_has_capa(&mvm->fw->ucode_capa,
575 IWL_UCODE_TLV_CAPA_FTM_CALIBRATED)) {
576 wiphy_ext_feature_set(hw->wiphy,
577 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER);
578 hw->wiphy->pmsr_capa = &iwl_mvm_pmsr_capa;
579 }
580
547 ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS); 581 ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
548 hw->wiphy->features |= 582 hw->wiphy->features |=
549 NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR | 583 NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
@@ -709,7 +743,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
709 hw->wiphy->wowlan = &mvm->wowlan; 743 hw->wiphy->wowlan = &mvm->wowlan;
710 } 744 }
711 745
712 if (mvm->fw->img[IWL_UCODE_WOWLAN].num_sec && 746 if ((unified || mvm->fw->img[IWL_UCODE_WOWLAN].num_sec) &&
713 mvm->trans->ops->d3_suspend && 747 mvm->trans->ops->d3_suspend &&
714 mvm->trans->ops->d3_resume && 748 mvm->trans->ops->d3_resume &&
715 device_can_wakeup(mvm->trans->dev)) { 749 device_can_wakeup(mvm->trans->dev)) {
@@ -762,15 +796,15 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
762 hw->netdev_features |= IWL_TX_CSUM_NETIF_FLAGS; 796 hw->netdev_features |= IWL_TX_CSUM_NETIF_FLAGS;
763 } 797 }
764 798
765 ret = ieee80211_register_hw(mvm->hw);
766 if (ret)
767 iwl_mvm_leds_exit(mvm);
768 mvm->init_status |= IWL_MVM_INIT_STATUS_REG_HW_INIT_COMPLETE;
769
770 if (mvm->cfg->vht_mu_mimo_supported) 799 if (mvm->cfg->vht_mu_mimo_supported)
771 wiphy_ext_feature_set(hw->wiphy, 800 wiphy_ext_feature_set(hw->wiphy,
772 NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER); 801 NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER);
773 802
803 ret = ieee80211_register_hw(mvm->hw);
804 if (ret) {
805 iwl_mvm_leds_exit(mvm);
806 }
807
774 return ret; 808 return ret;
775} 809}
776 810
@@ -907,8 +941,14 @@ void iwl_mvm_mac_itxq_xmit(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
907 IWL_PLAT_PM_MODE_DISABLED))) { 941 IWL_PLAT_PM_MODE_DISABLED))) {
908 skb = ieee80211_tx_dequeue(hw, txq); 942 skb = ieee80211_tx_dequeue(hw, txq);
909 943
910 if (!skb) 944 if (!skb) {
945 if (txq->sta)
946 IWL_DEBUG_TX(mvm,
947 "TXQ of sta %pM tid %d is now empty\n",
948 txq->sta->addr,
949 txq->tid);
911 break; 950 break;
951 }
912 952
913 if (!txq->sta) 953 if (!txq->sta)
914 iwl_mvm_tx_skb_non_sta(mvm, skb); 954 iwl_mvm_tx_skb_non_sta(mvm, skb);
@@ -1177,6 +1217,8 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
1177 iwl_mvm_cleanup_roc_te(mvm); 1217 iwl_mvm_cleanup_roc_te(mvm);
1178 ieee80211_remain_on_channel_expired(mvm->hw); 1218 ieee80211_remain_on_channel_expired(mvm->hw);
1179 1219
1220 iwl_mvm_ftm_restart(mvm);
1221
1180 /* 1222 /*
1181 * cleanup all interfaces, even inactive ones, as some might have 1223 * cleanup all interfaces, even inactive ones, as some might have
1182 * gone down during the HW restart 1224 * gone down during the HW restart
@@ -1290,6 +1332,8 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm)
1290 /* allow transport/FW low power modes */ 1332 /* allow transport/FW low power modes */
1291 iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN); 1333 iwl_mvm_unref(mvm, IWL_MVM_REF_UCODE_DOWN);
1292 1334
1335 iwl_mvm_send_recovery_cmd(mvm, ERROR_RECOVERY_END_OF_RECOVERY);
1336
1293 /* 1337 /*
1294 * If we have TDLS peers, remove them. We don't know the last seqno/PN 1338 * If we have TDLS peers, remove them. We don't know the last seqno/PN
1295 * of packets the FW sent out, so we must reconnect. 1339 * of packets the FW sent out, so we must reconnect.
@@ -1653,6 +1697,9 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
1653 IEEE80211_VIF_SUPPORTS_CQM_RSSI); 1697 IEEE80211_VIF_SUPPORTS_CQM_RSSI);
1654 } 1698 }
1655 1699
1700 if (vif->bss_conf.ftm_responder)
1701 memset(&mvm->ftm_resp_stats, 0, sizeof(mvm->ftm_resp_stats));
1702
1656 iwl_mvm_vif_dbgfs_clean(mvm, vif); 1703 iwl_mvm_vif_dbgfs_clean(mvm, vif);
1657 1704
1658 /* 1705 /*
@@ -2363,7 +2410,10 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
2363 * If update fails - SF might be running in associated 2410 * If update fails - SF might be running in associated
2364 * mode while disassociated - which is forbidden. 2411 * mode while disassociated - which is forbidden.
2365 */ 2412 */
2366 WARN_ONCE(iwl_mvm_sf_update(mvm, vif, false), 2413 ret = iwl_mvm_sf_update(mvm, vif, false);
2414 WARN_ONCE(ret &&
2415 !test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED,
2416 &mvm->status),
2367 "Failed to update SF upon disassociation\n"); 2417 "Failed to update SF upon disassociation\n");
2368 2418
2369 /* 2419 /*
@@ -2584,6 +2634,8 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
2584 if (iwl_mvm_phy_ctx_count(mvm) > 1) 2634 if (iwl_mvm_phy_ctx_count(mvm) > 1)
2585 iwl_mvm_teardown_tdls_peers(mvm); 2635 iwl_mvm_teardown_tdls_peers(mvm);
2586 2636
2637 iwl_mvm_ftm_restart_responder(mvm, vif);
2638
2587 goto out_unlock; 2639 goto out_unlock;
2588 2640
2589out_quota_failed: 2641out_quota_failed:
@@ -2695,6 +2747,15 @@ iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm,
2695 bss_conf->txpower); 2747 bss_conf->txpower);
2696 iwl_mvm_set_tx_power(mvm, vif, bss_conf->txpower); 2748 iwl_mvm_set_tx_power(mvm, vif, bss_conf->txpower);
2697 } 2749 }
2750
2751 if (changes & BSS_CHANGED_FTM_RESPONDER) {
2752 int ret = iwl_mvm_ftm_start_responder(mvm, vif);
2753
2754 if (ret)
2755 IWL_WARN(mvm, "Failed to enable FTM responder (%d)\n",
2756 ret);
2757 }
2758
2698} 2759}
2699 2760
2700static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw, 2761static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
@@ -3106,11 +3167,15 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
3106 } else if (old_state == IEEE80211_STA_AUTH && 3167 } else if (old_state == IEEE80211_STA_AUTH &&
3107 new_state == IEEE80211_STA_ASSOC) { 3168 new_state == IEEE80211_STA_ASSOC) {
3108 if (vif->type == NL80211_IFTYPE_AP) { 3169 if (vif->type == NL80211_IFTYPE_AP) {
3170 vif->bss_conf.he_support = sta->he_cap.has_he;
3109 mvmvif->ap_assoc_sta_count++; 3171 mvmvif->ap_assoc_sta_count++;
3110 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); 3172 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
3111 if (vif->bss_conf.he_support && 3173 if (vif->bss_conf.he_support &&
3112 !iwlwifi_mod_params.disable_11ax) 3174 !iwlwifi_mod_params.disable_11ax)
3113 iwl_mvm_cfg_he_sta(mvm, vif, mvm_sta->sta_id); 3175 iwl_mvm_cfg_he_sta(mvm, vif, mvm_sta->sta_id);
3176 } else if (vif->type == NL80211_IFTYPE_STATION) {
3177 vif->bss_conf.he_support = sta->he_cap.has_he;
3178 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
3114 } 3179 }
3115 3180
3116 iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band, 3181 iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
@@ -3118,6 +3183,24 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
3118 ret = iwl_mvm_update_sta(mvm, vif, sta); 3183 ret = iwl_mvm_update_sta(mvm, vif, sta);
3119 } else if (old_state == IEEE80211_STA_ASSOC && 3184 } else if (old_state == IEEE80211_STA_ASSOC &&
3120 new_state == IEEE80211_STA_AUTHORIZED) { 3185 new_state == IEEE80211_STA_AUTHORIZED) {
3186 /* if wep is used, need to set the key for the station now */
3187 if (vif->type == NL80211_IFTYPE_AP && mvmvif->ap_wep_key) {
3188 mvm_sta->wep_key =
3189 kmemdup(mvmvif->ap_wep_key,
3190 sizeof(*mvmvif->ap_wep_key) +
3191 mvmvif->ap_wep_key->keylen,
3192 GFP_KERNEL);
3193 if (!mvm_sta->wep_key) {
3194 ret = -ENOMEM;
3195 goto out_unlock;
3196 }
3197
3198 ret = iwl_mvm_set_sta_key(mvm, vif, sta,
3199 mvm_sta->wep_key,
3200 STA_KEY_IDX_INVALID);
3201 } else {
3202 ret = 0;
3203 }
3121 3204
3122 /* we don't support TDLS during DCM */ 3205 /* we don't support TDLS during DCM */
3123 if (iwl_mvm_phy_ctx_count(mvm) > 1) 3206 if (iwl_mvm_phy_ctx_count(mvm) > 1)
@@ -3132,18 +3215,13 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
3132 3215
3133 iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band, 3216 iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
3134 true); 3217 true);
3135
3136 /* if wep is used, need to set the key for the station now */
3137 if (vif->type == NL80211_IFTYPE_AP && mvmvif->ap_wep_key)
3138 ret = iwl_mvm_set_sta_key(mvm, vif, sta,
3139 mvmvif->ap_wep_key,
3140 STA_KEY_IDX_INVALID);
3141 else
3142 ret = 0;
3143 } else if (old_state == IEEE80211_STA_AUTHORIZED && 3218 } else if (old_state == IEEE80211_STA_AUTHORIZED &&
3144 new_state == IEEE80211_STA_ASSOC) { 3219 new_state == IEEE80211_STA_ASSOC) {
3145 /* disable beacon filtering */ 3220 /* disable beacon filtering */
3146 WARN_ON(iwl_mvm_disable_beacon_filter(mvm, vif, 0)); 3221 ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
3222 WARN_ON(ret &&
3223 !test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED,
3224 &mvm->status));
3147 ret = 0; 3225 ret = 0;
3148 } else if (old_state == IEEE80211_STA_ASSOC && 3226 } else if (old_state == IEEE80211_STA_ASSOC &&
3149 new_state == IEEE80211_STA_AUTH) { 3227 new_state == IEEE80211_STA_AUTH) {
@@ -3167,12 +3245,18 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
3167 /* Remove STA key if this is an AP using WEP */ 3245 /* Remove STA key if this is an AP using WEP */
3168 if (vif->type == NL80211_IFTYPE_AP && mvmvif->ap_wep_key) { 3246 if (vif->type == NL80211_IFTYPE_AP && mvmvif->ap_wep_key) {
3169 int rm_ret = iwl_mvm_remove_sta_key(mvm, vif, sta, 3247 int rm_ret = iwl_mvm_remove_sta_key(mvm, vif, sta,
3170 mvmvif->ap_wep_key); 3248 mvm_sta->wep_key);
3171 3249
3172 if (!ret) 3250 if (!ret)
3173 ret = rm_ret; 3251 ret = rm_ret;
3252 kfree(mvm_sta->wep_key);
3253 mvm_sta->wep_key = NULL;
3174 } 3254 }
3175 3255
3256 if (unlikely(ret &&
3257 test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED,
3258 &mvm->status)))
3259 ret = 0;
3176 } else { 3260 } else {
3177 ret = -EIO; 3261 ret = -EIO;
3178 } 3262 }
@@ -3816,11 +3900,43 @@ static int iwl_mvm_cancel_roc(struct ieee80211_hw *hw)
3816 return 0; 3900 return 0;
3817} 3901}
3818 3902
3903struct iwl_mvm_ftm_responder_iter_data {
3904 bool responder;
3905 struct ieee80211_chanctx_conf *ctx;
3906};
3907
3908static void iwl_mvm_ftm_responder_chanctx_iter(void *_data, u8 *mac,
3909 struct ieee80211_vif *vif)
3910{
3911 struct iwl_mvm_ftm_responder_iter_data *data = _data;
3912
3913 if (rcu_access_pointer(vif->chanctx_conf) == data->ctx &&
3914 vif->type == NL80211_IFTYPE_AP && vif->bss_conf.ftmr_params)
3915 data->responder = true;
3916}
3917
3918static bool iwl_mvm_is_ftm_responder_chanctx(struct iwl_mvm *mvm,
3919 struct ieee80211_chanctx_conf *ctx)
3920{
3921 struct iwl_mvm_ftm_responder_iter_data data = {
3922 .responder = false,
3923 .ctx = ctx,
3924 };
3925
3926 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
3927 IEEE80211_IFACE_ITER_NORMAL,
3928 iwl_mvm_ftm_responder_chanctx_iter,
3929 &data);
3930 return data.responder;
3931}
3932
3819static int __iwl_mvm_add_chanctx(struct iwl_mvm *mvm, 3933static int __iwl_mvm_add_chanctx(struct iwl_mvm *mvm,
3820 struct ieee80211_chanctx_conf *ctx) 3934 struct ieee80211_chanctx_conf *ctx)
3821{ 3935{
3822 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv; 3936 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
3823 struct iwl_mvm_phy_ctxt *phy_ctxt; 3937 struct iwl_mvm_phy_ctxt *phy_ctxt;
3938 bool responder = iwl_mvm_is_ftm_responder_chanctx(mvm, ctx);
3939 struct cfg80211_chan_def *def = responder ? &ctx->def : &ctx->min_def;
3824 int ret; 3940 int ret;
3825 3941
3826 lockdep_assert_held(&mvm->mutex); 3942 lockdep_assert_held(&mvm->mutex);
@@ -3833,7 +3949,7 @@ static int __iwl_mvm_add_chanctx(struct iwl_mvm *mvm,
3833 goto out; 3949 goto out;
3834 } 3950 }
3835 3951
3836 ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->min_def, 3952 ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, def,
3837 ctx->rx_chains_static, 3953 ctx->rx_chains_static,
3838 ctx->rx_chains_dynamic); 3954 ctx->rx_chains_dynamic);
3839 if (ret) { 3955 if (ret) {
@@ -3888,6 +4004,8 @@ static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
3888 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 4004 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3889 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv; 4005 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
3890 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id]; 4006 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
4007 bool responder = iwl_mvm_is_ftm_responder_chanctx(mvm, ctx);
4008 struct cfg80211_chan_def *def = responder ? &ctx->def : &ctx->min_def;
3891 4009
3892 if (WARN_ONCE((phy_ctxt->ref > 1) && 4010 if (WARN_ONCE((phy_ctxt->ref > 1) &&
3893 (changed & ~(IEEE80211_CHANCTX_CHANGE_WIDTH | 4011 (changed & ~(IEEE80211_CHANCTX_CHANGE_WIDTH |
@@ -3902,17 +4020,17 @@ static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
3902 4020
3903 /* we are only changing the min_width, may be a noop */ 4021 /* we are only changing the min_width, may be a noop */
3904 if (changed == IEEE80211_CHANCTX_CHANGE_MIN_WIDTH) { 4022 if (changed == IEEE80211_CHANCTX_CHANGE_MIN_WIDTH) {
3905 if (phy_ctxt->width == ctx->min_def.width) 4023 if (phy_ctxt->width == def->width)
3906 goto out_unlock; 4024 goto out_unlock;
3907 4025
3908 /* we are just toggling between 20_NOHT and 20 */ 4026 /* we are just toggling between 20_NOHT and 20 */
3909 if (phy_ctxt->width <= NL80211_CHAN_WIDTH_20 && 4027 if (phy_ctxt->width <= NL80211_CHAN_WIDTH_20 &&
3910 ctx->min_def.width <= NL80211_CHAN_WIDTH_20) 4028 def->width <= NL80211_CHAN_WIDTH_20)
3911 goto out_unlock; 4029 goto out_unlock;
3912 } 4030 }
3913 4031
3914 iwl_mvm_bt_coex_vif_change(mvm); 4032 iwl_mvm_bt_coex_vif_change(mvm);
3915 iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->min_def, 4033 iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, def,
3916 ctx->rx_chains_static, 4034 ctx->rx_chains_static,
3917 ctx->rx_chains_dynamic); 4035 ctx->rx_chains_dynamic);
3918 4036
@@ -3941,6 +4059,7 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
3941 mvmvif->ap_ibss_active = true; 4059 mvmvif->ap_ibss_active = true;
3942 break; 4060 break;
3943 } 4061 }
4062 /* fall through */
3944 case NL80211_IFTYPE_ADHOC: 4063 case NL80211_IFTYPE_ADHOC:
3945 /* 4064 /*
3946 * The AP binding flow is handled as part of the start_ap flow 4065 * The AP binding flow is handled as part of the start_ap flow
@@ -3993,25 +4112,30 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
3993 } 4112 }
3994 4113
3995 if (switching_chanctx && vif->type == NL80211_IFTYPE_STATION) { 4114 if (switching_chanctx && vif->type == NL80211_IFTYPE_STATION) {
3996 u32 duration = 3 * vif->bss_conf.beacon_int; 4115 mvmvif->csa_bcn_pending = true;
3997 4116
3998 /* iwl_mvm_protect_session() reads directly from the 4117 if (!fw_has_capa(&mvm->fw->ucode_capa,
3999 * device (the system time), so make sure it is 4118 IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD)) {
4000 * available. 4119 u32 duration = 3 * vif->bss_conf.beacon_int;
4001 */
4002 ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PROTECT_CSA);
4003 if (ret)
4004 goto out_remove_binding;
4005 4120
4006 /* Protect the session to make sure we hear the first
4007 * beacon on the new channel.
4008 */
4009 mvmvif->csa_bcn_pending = true;
4010 iwl_mvm_protect_session(mvm, vif, duration, duration,
4011 vif->bss_conf.beacon_int / 2,
4012 true);
4013 4121
4014 iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_CSA); 4122 /* iwl_mvm_protect_session() reads directly from the
4123 * device (the system time), so make sure it is
4124 * available.
4125 */
4126 ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PROTECT_CSA);
4127 if (ret)
4128 goto out_remove_binding;
4129
4130 /* Protect the session to make sure we hear the first
4131 * beacon on the new channel.
4132 */
4133 iwl_mvm_protect_session(mvm, vif, duration, duration,
4134 vif->bss_conf.beacon_int / 2,
4135 true);
4136
4137 iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_CSA);
4138 }
4015 4139
4016 iwl_mvm_update_quotas(mvm, false, NULL); 4140 iwl_mvm_update_quotas(mvm, false, NULL);
4017 } 4141 }
@@ -4081,7 +4205,9 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm,
4081 4205
4082 disabled_vif = vif; 4206 disabled_vif = vif;
4083 4207
4084 iwl_mvm_mac_ctxt_changed(mvm, vif, true, NULL); 4208 if (!fw_has_capa(&mvm->fw->ucode_capa,
4209 IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
4210 iwl_mvm_mac_ctxt_changed(mvm, vif, true, NULL);
4085 break; 4211 break;
4086 default: 4212 default:
4087 break; 4213 break;
@@ -4332,6 +4458,27 @@ static void iwl_mvm_channel_switch(struct ieee80211_hw *hw,
4332 "dummy channel switch op\n"); 4458 "dummy channel switch op\n");
4333} 4459}
4334 4460
4461static int iwl_mvm_schedule_client_csa(struct iwl_mvm *mvm,
4462 struct ieee80211_vif *vif,
4463 struct ieee80211_channel_switch *chsw)
4464{
4465 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
4466 struct iwl_chan_switch_te_cmd cmd = {
4467 .mac_id = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
4468 mvmvif->color)),
4469 .action = cpu_to_le32(FW_CTXT_ACTION_ADD),
4470 .tsf = cpu_to_le32(chsw->timestamp),
4471 .cs_count = chsw->count,
4472 };
4473
4474 lockdep_assert_held(&mvm->mutex);
4475
4476 return iwl_mvm_send_cmd_pdu(mvm,
4477 WIDE_ID(MAC_CONF_GROUP,
4478 CHANNEL_SWITCH_TIME_EVENT_CMD),
4479 0, sizeof(cmd), &cmd);
4480}
4481
4335static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw, 4482static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
4336 struct ieee80211_vif *vif, 4483 struct ieee80211_vif *vif,
4337 struct ieee80211_channel_switch *chsw) 4484 struct ieee80211_channel_switch *chsw)
@@ -4399,14 +4546,19 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
4399 if (chsw->block_tx) 4546 if (chsw->block_tx)
4400 iwl_mvm_csa_client_absent(mvm, vif); 4547 iwl_mvm_csa_client_absent(mvm, vif);
4401 4548
4402 iwl_mvm_schedule_csa_period(mvm, vif, vif->bss_conf.beacon_int,
4403 apply_time);
4404 if (mvmvif->bf_data.bf_enabled) { 4549 if (mvmvif->bf_data.bf_enabled) {
4405 ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0); 4550 ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
4406 if (ret) 4551 if (ret)
4407 goto out_unlock; 4552 goto out_unlock;
4408 } 4553 }
4409 4554
4555 if (fw_has_capa(&mvm->fw->ucode_capa,
4556 IWL_UCODE_TLV_CAPA_CHANNEL_SWITCH_CMD))
4557 iwl_mvm_schedule_client_csa(mvm, vif, chsw);
4558 else
4559 iwl_mvm_schedule_csa_period(mvm, vif,
4560 vif->bss_conf.beacon_int,
4561 apply_time);
4410 break; 4562 break;
4411 default: 4563 default:
4412 break; 4564 break;
@@ -4799,6 +4951,60 @@ static void iwl_mvm_sync_rx_queues(struct ieee80211_hw *hw)
4799 mutex_unlock(&mvm->mutex); 4951 mutex_unlock(&mvm->mutex);
4800} 4952}
4801 4953
4954static int
4955iwl_mvm_mac_get_ftm_responder_stats(struct ieee80211_hw *hw,
4956 struct ieee80211_vif *vif,
4957 struct cfg80211_ftm_responder_stats *stats)
4958{
4959 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
4960 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
4961
4962 if (vif->p2p || vif->type != NL80211_IFTYPE_AP ||
4963 !mvmvif->ap_ibss_active || !vif->bss_conf.ftm_responder)
4964 return -EINVAL;
4965
4966 mutex_lock(&mvm->mutex);
4967 *stats = mvm->ftm_resp_stats;
4968 mutex_unlock(&mvm->mutex);
4969
4970 stats->filled = BIT(NL80211_FTM_STATS_SUCCESS_NUM) |
4971 BIT(NL80211_FTM_STATS_PARTIAL_NUM) |
4972 BIT(NL80211_FTM_STATS_FAILED_NUM) |
4973 BIT(NL80211_FTM_STATS_ASAP_NUM) |
4974 BIT(NL80211_FTM_STATS_NON_ASAP_NUM) |
4975 BIT(NL80211_FTM_STATS_TOTAL_DURATION_MSEC) |
4976 BIT(NL80211_FTM_STATS_UNKNOWN_TRIGGERS_NUM) |
4977 BIT(NL80211_FTM_STATS_RESCHEDULE_REQUESTS_NUM) |
4978 BIT(NL80211_FTM_STATS_OUT_OF_WINDOW_TRIGGERS_NUM);
4979
4980 return 0;
4981}
4982
4983static int iwl_mvm_start_pmsr(struct ieee80211_hw *hw,
4984 struct ieee80211_vif *vif,
4985 struct cfg80211_pmsr_request *request)
4986{
4987 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
4988 int ret;
4989
4990 mutex_lock(&mvm->mutex);
4991 ret = iwl_mvm_ftm_start(mvm, vif, request);
4992 mutex_unlock(&mvm->mutex);
4993
4994 return ret;
4995}
4996
4997static void iwl_mvm_abort_pmsr(struct ieee80211_hw *hw,
4998 struct ieee80211_vif *vif,
4999 struct cfg80211_pmsr_request *request)
5000{
5001 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
5002
5003 mutex_lock(&mvm->mutex);
5004 iwl_mvm_ftm_abort(mvm, request);
5005 mutex_unlock(&mvm->mutex);
5006}
5007
4802static bool iwl_mvm_can_hw_csum(struct sk_buff *skb) 5008static bool iwl_mvm_can_hw_csum(struct sk_buff *skb)
4803{ 5009{
4804 u8 protocol = ip_hdr(skb)->protocol; 5010 u8 protocol = ip_hdr(skb)->protocol;
@@ -4901,6 +5107,10 @@ const struct ieee80211_ops iwl_mvm_hw_ops = {
4901#endif 5107#endif
4902 .get_survey = iwl_mvm_mac_get_survey, 5108 .get_survey = iwl_mvm_mac_get_survey,
4903 .sta_statistics = iwl_mvm_mac_sta_statistics, 5109 .sta_statistics = iwl_mvm_mac_sta_statistics,
5110 .get_ftm_responder_stats = iwl_mvm_mac_get_ftm_responder_stats,
5111 .start_pmsr = iwl_mvm_start_pmsr,
5112 .abort_pmsr = iwl_mvm_abort_pmsr,
5113
4904 .can_aggregate_in_amsdu = iwl_mvm_mac_can_aggregate, 5114 .can_aggregate_in_amsdu = iwl_mvm_mac_can_aggregate,
4905#ifdef CONFIG_IWLWIFI_DEBUGFS 5115#ifdef CONFIG_IWLWIFI_DEBUGFS
4906 .sta_add_debugfs = iwl_mvm_sta_add_debugfs, 5116 .sta_add_debugfs = iwl_mvm_sta_add_debugfs,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 12e9ecc3ee27..bca6f6b536d9 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -879,9 +879,6 @@ struct iwl_mvm {
879 879
880 bool hw_registered; 880 bool hw_registered;
881 bool calibrating; 881 bool calibrating;
882 u32 error_event_table[2];
883 u32 log_event_table;
884 u32 umac_error_event_table;
885 bool support_umac_log; 882 bool support_umac_log;
886 883
887 u32 ampdu_ref; 884 u32 ampdu_ref;
@@ -981,6 +978,7 @@ struct iwl_mvm {
981 u32 dbgfs_prph_reg_addr; 978 u32 dbgfs_prph_reg_addr;
982 bool disable_power_off; 979 bool disable_power_off;
983 bool disable_power_off_d3; 980 bool disable_power_off_d3;
981 bool beacon_inject_active;
984 982
985 bool scan_iter_notif_enabled; 983 bool scan_iter_notif_enabled;
986 984
@@ -1017,6 +1015,7 @@ struct iwl_mvm {
1017 1015
1018 /* -1 for always, 0 for never, >0 for that many times */ 1016 /* -1 for always, 0 for never, >0 for that many times */
1019 s8 fw_restart; 1017 s8 fw_restart;
1018 u8 *error_recovery_buf;
1020 1019
1021#ifdef CONFIG_IWLWIFI_LEDS 1020#ifdef CONFIG_IWLWIFI_LEDS
1022 struct led_classdev led; 1021 struct led_classdev led;
@@ -1106,6 +1105,8 @@ struct iwl_mvm {
1106 1105
1107 /* Indicate if device power save is allowed */ 1106 /* Indicate if device power save is allowed */
1108 u8 ps_disabled; /* u8 instead of bool to ease debugfs_create_* usage */ 1107 u8 ps_disabled; /* u8 instead of bool to ease debugfs_create_* usage */
1108 /* Indicate if 32Khz external clock is valid */
1109 u32 ext_clock_valid;
1109 unsigned int max_amsdu_len; /* used for debugfs only */ 1110 unsigned int max_amsdu_len; /* used for debugfs only */
1110 1111
1111 struct ieee80211_vif __rcu *csa_vif; 1112 struct ieee80211_vif __rcu *csa_vif;
@@ -1150,6 +1151,14 @@ struct iwl_mvm {
1150 u32 ciphers[IWL_MVM_NUM_CIPHERS]; 1151 u32 ciphers[IWL_MVM_NUM_CIPHERS];
1151 struct ieee80211_cipher_scheme cs[IWL_UCODE_MAX_CS]; 1152 struct ieee80211_cipher_scheme cs[IWL_UCODE_MAX_CS];
1152 1153
1154 struct cfg80211_ftm_responder_stats ftm_resp_stats;
1155 struct {
1156 struct cfg80211_pmsr_request *req;
1157 struct wireless_dev *req_wdev;
1158 struct list_head loc_list;
1159 int responses[IWL_MVM_TOF_MAX_APS];
1160 } ftm_initiator;
1161
1153 struct ieee80211_vif *nan_vif; 1162 struct ieee80211_vif *nan_vif;
1154#define IWL_MAX_BAID 32 1163#define IWL_MAX_BAID 32
1155 struct iwl_mvm_baid_data __rcu *baid_map[IWL_MAX_BAID]; 1164 struct iwl_mvm_baid_data __rcu *baid_map[IWL_MAX_BAID];
@@ -1167,6 +1176,7 @@ struct iwl_mvm {
1167 1176
1168 /* sniffer data to include in radiotap */ 1177 /* sniffer data to include in radiotap */
1169 __le16 cur_aid; 1178 __le16 cur_aid;
1179 u8 cur_bssid[ETH_ALEN];
1170 1180
1171#ifdef CONFIG_ACPI 1181#ifdef CONFIG_ACPI
1172 struct iwl_mvm_sar_profile sar_profiles[ACPI_SAR_PROFILE_NUM]; 1182 struct iwl_mvm_sar_profile sar_profiles[ACPI_SAR_PROFILE_NUM];
@@ -1211,7 +1221,6 @@ enum iwl_mvm_status {
1211enum iwl_mvm_init_status { 1221enum iwl_mvm_init_status {
1212 IWL_MVM_INIT_STATUS_THERMAL_INIT_COMPLETE = BIT(0), 1222 IWL_MVM_INIT_STATUS_THERMAL_INIT_COMPLETE = BIT(0),
1213 IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE = BIT(1), 1223 IWL_MVM_INIT_STATUS_LEDS_INIT_COMPLETE = BIT(1),
1214 IWL_MVM_INIT_STATUS_REG_HW_INIT_COMPLETE = BIT(2),
1215}; 1224};
1216 1225
1217static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm) 1226static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm)
@@ -1311,6 +1320,12 @@ static inline bool iwl_mvm_is_frag_ebs_supported(struct iwl_mvm *mvm)
1311 return fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_FRAG_EBS); 1320 return fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_FRAG_EBS);
1312} 1321}
1313 1322
1323static inline bool iwl_mvm_is_short_beacon_notif_supported(struct iwl_mvm *mvm)
1324{
1325 return fw_has_api(&mvm->fw->ucode_capa,
1326 IWL_UCODE_TLV_API_SHORT_BEACON_NOTIF);
1327}
1328
1314static inline bool iwl_mvm_enter_d0i3_on_suspend(struct iwl_mvm *mvm) 1329static inline bool iwl_mvm_enter_d0i3_on_suspend(struct iwl_mvm *mvm)
1315{ 1330{
1316 /* For now we only use this mode to differentiate between 1331 /* For now we only use this mode to differentiate between
@@ -1646,6 +1661,7 @@ void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
1646void iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb); 1661void iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
1647void iwl_mvm_mfu_assert_dump_notif(struct iwl_mvm *mvm, 1662void iwl_mvm_mfu_assert_dump_notif(struct iwl_mvm *mvm,
1648 struct iwl_rx_cmd_buffer *rxb); 1663 struct iwl_rx_cmd_buffer *rxb);
1664void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags);
1649void iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb); 1665void iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
1650void iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm, 1666void iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
1651 struct iwl_rx_cmd_buffer *rxb); 1667 struct iwl_rx_cmd_buffer *rxb);
@@ -1680,6 +1696,17 @@ int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1680int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 1696int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
1681int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm, 1697int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
1682 struct ieee80211_vif *vif); 1698 struct ieee80211_vif *vif);
1699int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
1700 struct ieee80211_vif *vif,
1701 struct sk_buff *beacon);
1702int iwl_mvm_mac_ctxt_send_beacon_cmd(struct iwl_mvm *mvm,
1703 struct sk_buff *beacon,
1704 void *data, int len);
1705u8 iwl_mvm_mac_ctxt_get_lowest_rate(struct ieee80211_tx_info *info,
1706 struct ieee80211_vif *vif);
1707void iwl_mvm_mac_ctxt_set_tim(struct iwl_mvm *mvm,
1708 __le32 *tim_index, __le32 *tim_size,
1709 u8 *beacon, u32 frame_size);
1683void iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, 1710void iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
1684 struct iwl_rx_cmd_buffer *rxb); 1711 struct iwl_rx_cmd_buffer *rxb);
1685void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, 1712void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
@@ -2007,15 +2034,12 @@ static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm)
2007 &mvm->status)) 2034 &mvm->status))
2008 iwl_fw_dbg_collect_desc(&mvm->fwrt, &iwl_dump_desc_assert, 2035 iwl_fw_dbg_collect_desc(&mvm->fwrt, &iwl_dump_desc_assert,
2009 false, 0); 2036 false, 0);
2010 /* calling this function without using dump_start/end since at this 2037
2011 * point we already hold the op mode mutex
2012 */
2013 iwl_fw_dbg_collect_sync(&mvm->fwrt);
2014 iwl_fw_cancel_timestamp(&mvm->fwrt); 2038 iwl_fw_cancel_timestamp(&mvm->fwrt);
2015 iwl_free_fw_paging(&mvm->fwrt);
2016 clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status); 2039 clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status);
2040 iwl_fwrt_stop_device(&mvm->fwrt);
2041 iwl_free_fw_paging(&mvm->fwrt);
2017 iwl_fw_dump_conf_clear(&mvm->fwrt); 2042 iwl_fw_dump_conf_clear(&mvm->fwrt);
2018 iwl_trans_stop_device(mvm->trans);
2019} 2043}
2020 2044
2021/* Re-configure the SCD for a queue that has already been configured */ 2045/* Re-configure the SCD for a queue that has already been configured */
@@ -2057,6 +2081,23 @@ void iwl_mvm_update_changed_regdom(struct iwl_mvm *mvm);
2057int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 2081int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
2058 bool added_vif); 2082 bool added_vif);
2059 2083
2084/* FTM responder */
2085int iwl_mvm_ftm_start_responder(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
2086void iwl_mvm_ftm_restart_responder(struct iwl_mvm *mvm,
2087 struct ieee80211_vif *vif);
2088void iwl_mvm_ftm_responder_stats(struct iwl_mvm *mvm,
2089 struct iwl_rx_cmd_buffer *rxb);
2090
2091/* FTM initiator */
2092void iwl_mvm_ftm_restart(struct iwl_mvm *mvm);
2093void iwl_mvm_ftm_range_resp(struct iwl_mvm *mvm,
2094 struct iwl_rx_cmd_buffer *rxb);
2095void iwl_mvm_ftm_lc_notif(struct iwl_mvm *mvm,
2096 struct iwl_rx_cmd_buffer *rxb);
2097int iwl_mvm_ftm_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
2098 struct cfg80211_pmsr_request *request);
2099void iwl_mvm_ftm_abort(struct iwl_mvm *mvm, struct cfg80211_pmsr_request *req);
2100
2060/* TDLS */ 2101/* TDLS */
2061 2102
2062/* 2103/*
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 5e4f8b767d10..ba27dce4c2bb 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -82,7 +82,6 @@
82#include "fw/api/scan.h" 82#include "fw/api/scan.h"
83#include "time-event.h" 83#include "time-event.h"
84#include "fw-api.h" 84#include "fw-api.h"
85#include "fw/api/scan.h"
86#include "fw/acpi.h" 85#include "fw/acpi.h"
87 86
88#define DRV_DESCRIPTION "The new Intel(R) wireless AGN driver for Linux" 87#define DRV_DESCRIPTION "The new Intel(R) wireless AGN driver for Linux"
@@ -301,6 +300,14 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
301 RX_HANDLER_ASYNC_LOCKED), 300 RX_HANDLER_ASYNC_LOCKED),
302 RX_HANDLER(MFUART_LOAD_NOTIFICATION, iwl_mvm_rx_mfuart_notif, 301 RX_HANDLER(MFUART_LOAD_NOTIFICATION, iwl_mvm_rx_mfuart_notif,
303 RX_HANDLER_SYNC), 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
304 RX_HANDLER_GRP(DEBUG_GROUP, MFU_ASSERT_DUMP_NTF, 311 RX_HANDLER_GRP(DEBUG_GROUP, MFU_ASSERT_DUMP_NTF,
305 iwl_mvm_mfu_assert_dump_notif, RX_HANDLER_SYNC), 312 iwl_mvm_mfu_assert_dump_notif, RX_HANDLER_SYNC),
306 RX_HANDLER_GRP(PROT_OFFLOAD_GROUP, STORED_BEACON_NTF, 313 RX_HANDLER_GRP(PROT_OFFLOAD_GROUP, STORED_BEACON_NTF,
@@ -415,12 +422,14 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
415static const struct iwl_hcmd_names iwl_mvm_system_names[] = { 422static const struct iwl_hcmd_names iwl_mvm_system_names[] = {
416 HCMD_NAME(SHARED_MEM_CFG_CMD), 423 HCMD_NAME(SHARED_MEM_CFG_CMD),
417 HCMD_NAME(INIT_EXTENDED_CFG_CMD), 424 HCMD_NAME(INIT_EXTENDED_CFG_CMD),
425 HCMD_NAME(FW_ERROR_RECOVERY_CMD),
418}; 426};
419 427
420/* Please keep this array *SORTED* by hex value. 428/* Please keep this array *SORTED* by hex value.
421 * Access is done through binary search 429 * Access is done through binary search
422 */ 430 */
423static const struct iwl_hcmd_names iwl_mvm_mac_conf_names[] = { 431static const struct iwl_hcmd_names iwl_mvm_mac_conf_names[] = {
432 HCMD_NAME(CHANNEL_SWITCH_TIME_EVENT_CMD),
424 HCMD_NAME(CHANNEL_SWITCH_NOA_NOTIF), 433 HCMD_NAME(CHANNEL_SWITCH_NOA_NOTIF),
425}; 434};
426 435
@@ -445,6 +454,7 @@ static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = {
445 HCMD_NAME(TRIGGER_RX_QUEUES_NOTIF_CMD), 454 HCMD_NAME(TRIGGER_RX_QUEUES_NOTIF_CMD),
446 HCMD_NAME(STA_HE_CTXT_CMD), 455 HCMD_NAME(STA_HE_CTXT_CMD),
447 HCMD_NAME(RFH_QUEUE_CONFIG_CMD), 456 HCMD_NAME(RFH_QUEUE_CONFIG_CMD),
457 HCMD_NAME(TLC_MNG_CONFIG_CMD),
448 HCMD_NAME(CHEST_COLLECTOR_FILTER_CONFIG_CMD), 458 HCMD_NAME(CHEST_COLLECTOR_FILTER_CONFIG_CMD),
449 HCMD_NAME(STA_PM_NOTIF), 459 HCMD_NAME(STA_PM_NOTIF),
450 HCMD_NAME(MU_GROUP_MGMT_NOTIF), 460 HCMD_NAME(MU_GROUP_MGMT_NOTIF),
@@ -591,11 +601,17 @@ static int iwl_mvm_fwrt_send_hcmd(void *ctx, struct iwl_host_cmd *host_cmd)
591 return ret; 601 return ret;
592} 602}
593 603
604static bool iwl_mvm_d3_debug_enable(void *ctx)
605{
606 return IWL_MVM_D3_DEBUG;
607}
608
594static const struct iwl_fw_runtime_ops iwl_mvm_fwrt_ops = { 609static const struct iwl_fw_runtime_ops iwl_mvm_fwrt_ops = {
595 .dump_start = iwl_mvm_fwrt_dump_start, 610 .dump_start = iwl_mvm_fwrt_dump_start,
596 .dump_end = iwl_mvm_fwrt_dump_end, 611 .dump_end = iwl_mvm_fwrt_dump_end,
597 .fw_running = iwl_mvm_fwrt_fw_running, 612 .fw_running = iwl_mvm_fwrt_fw_running,
598 .send_hcmd = iwl_mvm_fwrt_send_hcmd, 613 .send_hcmd = iwl_mvm_fwrt_send_hcmd,
614 .d3_debug_enable = iwl_mvm_d3_debug_enable,
599}; 615};
600 616
601static struct iwl_op_mode * 617static struct iwl_op_mode *
@@ -690,6 +706,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
690 INIT_LIST_HEAD(&mvm->aux_roc_te_list); 706 INIT_LIST_HEAD(&mvm->aux_roc_te_list);
691 INIT_LIST_HEAD(&mvm->async_handlers_list); 707 INIT_LIST_HEAD(&mvm->async_handlers_list);
692 spin_lock_init(&mvm->time_event_lock); 708 spin_lock_init(&mvm->time_event_lock);
709 INIT_LIST_HEAD(&mvm->ftm_initiator.loc_list);
693 710
694 INIT_WORK(&mvm->async_handlers_wk, iwl_mvm_async_handlers_wk); 711 INIT_WORK(&mvm->async_handlers_wk, iwl_mvm_async_handlers_wk);
695 INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk); 712 INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk);
@@ -817,8 +834,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
817 mutex_lock(&mvm->mutex); 834 mutex_lock(&mvm->mutex);
818 iwl_mvm_ref(mvm, IWL_MVM_REF_INIT_UCODE); 835 iwl_mvm_ref(mvm, IWL_MVM_REF_INIT_UCODE);
819 err = iwl_run_init_mvm_ucode(mvm, true); 836 err = iwl_run_init_mvm_ucode(mvm, true);
820 if (test_bit(IWL_FWRT_STATUS_WAIT_ALIVE, &mvm->fwrt.status)) 837 if (err)
821 iwl_fw_alive_error_dump(&mvm->fwrt); 838 iwl_fw_dbg_error_collect(&mvm->fwrt, FW_DBG_TRIGGER_DRIVER);
822 if (!iwlmvm_mod_params.init_dbg || !err) 839 if (!iwlmvm_mod_params.init_dbg || !err)
823 iwl_mvm_stop_device(mvm); 840 iwl_mvm_stop_device(mvm);
824 iwl_mvm_unref(mvm, IWL_MVM_REF_INIT_UCODE); 841 iwl_mvm_unref(mvm, IWL_MVM_REF_INIT_UCODE);
@@ -902,15 +919,15 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
902 919
903 iwl_mvm_thermal_exit(mvm); 920 iwl_mvm_thermal_exit(mvm);
904 921
905 if (mvm->init_status & IWL_MVM_INIT_STATUS_REG_HW_INIT_COMPLETE) { 922 ieee80211_unregister_hw(mvm->hw);
906 ieee80211_unregister_hw(mvm->hw);
907 mvm->init_status &= ~IWL_MVM_INIT_STATUS_REG_HW_INIT_COMPLETE;
908 }
909 923
910 kfree(mvm->scan_cmd); 924 kfree(mvm->scan_cmd);
911 kfree(mvm->mcast_filter_cmd); 925 kfree(mvm->mcast_filter_cmd);
912 mvm->mcast_filter_cmd = NULL; 926 mvm->mcast_filter_cmd = NULL;
913 927
928 kfree(mvm->error_recovery_buf);
929 mvm->error_recovery_buf = NULL;
930
914#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS) 931#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS)
915 kfree(mvm->d3_resume_sram); 932 kfree(mvm->d3_resume_sram);
916#endif 933#endif
@@ -1105,6 +1122,12 @@ static void iwl_mvm_async_cb(struct iwl_op_mode *op_mode,
1105 iwl_trans_block_txq_ptrs(mvm->trans, false); 1122 iwl_trans_block_txq_ptrs(mvm->trans, false);
1106} 1123}
1107 1124
1125static int iwl_mvm_is_static_queue(struct iwl_mvm *mvm, int queue)
1126{
1127 return queue == mvm->aux_queue || queue == mvm->probe_queue ||
1128 queue == mvm->p2p_dev_queue || queue == mvm->snif_queue;
1129}
1130
1108static void iwl_mvm_queue_state_change(struct iwl_op_mode *op_mode, 1131static void iwl_mvm_queue_state_change(struct iwl_op_mode *op_mode,
1109 int hw_queue, bool start) 1132 int hw_queue, bool start)
1110{ 1133{
@@ -1131,6 +1154,15 @@ static void iwl_mvm_queue_state_change(struct iwl_op_mode *op_mode,
1131 goto out; 1154 goto out;
1132 mvmsta = iwl_mvm_sta_from_mac80211(sta); 1155 mvmsta = iwl_mvm_sta_from_mac80211(sta);
1133 1156
1157 if (iwl_mvm_is_static_queue(mvm, hw_queue)) {
1158 if (!start)
1159 ieee80211_stop_queues(mvm->hw);
1160 else if (mvmsta->sta_state != IEEE80211_STA_NOTEXIST)
1161 ieee80211_wake_queues(mvm->hw);
1162
1163 goto out;
1164 }
1165
1134 if (iwl_mvm_has_new_tx_api(mvm)) { 1166 if (iwl_mvm_has_new_tx_api(mvm)) {
1135 int tid = mvm->tvqm_info[hw_queue].txq_tid; 1167 int tid = mvm->tvqm_info[hw_queue].txq_tid;
1136 1168
@@ -1285,12 +1317,29 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
1285 reprobe->dev = mvm->trans->dev; 1317 reprobe->dev = mvm->trans->dev;
1286 INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk); 1318 INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk);
1287 schedule_work(&reprobe->work); 1319 schedule_work(&reprobe->work);
1320 } else if (test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED,
1321 &mvm->status)) {
1322 IWL_ERR(mvm, "HW restart already requested, but not started\n");
1288 } else if (mvm->fwrt.cur_fw_img == IWL_UCODE_REGULAR && 1323 } else if (mvm->fwrt.cur_fw_img == IWL_UCODE_REGULAR &&
1289 mvm->hw_registered && 1324 mvm->hw_registered &&
1290 !test_bit(STATUS_TRANS_DEAD, &mvm->trans->status)) { 1325 !test_bit(STATUS_TRANS_DEAD, &mvm->trans->status)) {
1291 /* don't let the transport/FW power down */ 1326 /* don't let the transport/FW power down */
1292 iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); 1327 iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
1293 1328
1329 if (mvm->fw->ucode_capa.error_log_size) {
1330 u32 src_size = mvm->fw->ucode_capa.error_log_size;
1331 u32 src_addr = mvm->fw->ucode_capa.error_log_addr;
1332 u8 *recover_buf = kzalloc(src_size, GFP_ATOMIC);
1333
1334 if (recover_buf) {
1335 mvm->error_recovery_buf = recover_buf;
1336 iwl_trans_read_mem_bytes(mvm->trans,
1337 src_addr,
1338 recover_buf,
1339 src_size);
1340 }
1341 }
1342
1294 if (fw_error && mvm->fw_restart > 0) 1343 if (fw_error && mvm->fw_restart > 0)
1295 mvm->fw_restart--; 1344 mvm->fw_restart--;
1296 set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status); 1345 set_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
index f369173db11c..86e40bae57e3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c
@@ -109,6 +109,7 @@ u8 iwl_mvm_get_ctrl_pos(struct cfg80211_chan_def *chandef)
109 return PHY_VHT_CTRL_POS_4_ABOVE; 109 return PHY_VHT_CTRL_POS_4_ABOVE;
110 default: 110 default:
111 WARN(1, "Invalid channel definition"); 111 WARN(1, "Invalid channel definition");
112 /* fall through */
112 case 0: 113 case 0:
113 /* 114 /*
114 * The FW is expected to check the control channel position only 115 * The FW is expected to check the control channel position only
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/power.c b/drivers/net/wireless/intel/iwlwifi/mvm/power.c
index 5a0a28fd762d..36f5fa1ee793 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/power.c
@@ -8,6 +8,7 @@
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
10 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 10 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
11 * Copyright (C) 2018 - 2019 Intel Corporation
11 * 12 *
12 * This program is free software; you can redistribute it and/or modify 13 * 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 * it under the terms of version 2 of the GNU General Public License as
@@ -30,6 +31,7 @@
30 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
31 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
32 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH 33 * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
34 * Copyright (C) 2018 - 2019 Intel Corporation
33 * All rights reserved. 35 * All rights reserved.
34 * 36 *
35 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -79,6 +81,8 @@ int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm,
79 struct iwl_beacon_filter_cmd *cmd, 81 struct iwl_beacon_filter_cmd *cmd,
80 u32 flags) 82 u32 flags)
81{ 83{
84 u16 len;
85
82 IWL_DEBUG_POWER(mvm, "ba_enable_beacon_abort is: %d\n", 86 IWL_DEBUG_POWER(mvm, "ba_enable_beacon_abort is: %d\n",
83 le32_to_cpu(cmd->ba_enable_beacon_abort)); 87 le32_to_cpu(cmd->ba_enable_beacon_abort));
84 IWL_DEBUG_POWER(mvm, "ba_escape_timer is: %d\n", 88 IWL_DEBUG_POWER(mvm, "ba_escape_timer is: %d\n",
@@ -101,9 +105,23 @@ int iwl_mvm_beacon_filter_send_cmd(struct iwl_mvm *mvm,
101 le32_to_cpu(cmd->bf_temp_fast_filter)); 105 le32_to_cpu(cmd->bf_temp_fast_filter));
102 IWL_DEBUG_POWER(mvm, "bf_temp_slow_filter is: %d\n", 106 IWL_DEBUG_POWER(mvm, "bf_temp_slow_filter is: %d\n",
103 le32_to_cpu(cmd->bf_temp_slow_filter)); 107 le32_to_cpu(cmd->bf_temp_slow_filter));
108 IWL_DEBUG_POWER(mvm, "bf_threshold_absolute_low is: %d, %d\n",
109 le32_to_cpu(cmd->bf_threshold_absolute_low[0]),
110 le32_to_cpu(cmd->bf_threshold_absolute_low[1]));
111
112 IWL_DEBUG_POWER(mvm, "bf_threshold_absolute_high is: %d, %d\n",
113 le32_to_cpu(cmd->bf_threshold_absolute_high[0]),
114 le32_to_cpu(cmd->bf_threshold_absolute_high[1]));
115
116 if (fw_has_api(&mvm->fw->ucode_capa,
117 IWL_UCODE_TLV_API_BEACON_FILTER_V4))
118 len = sizeof(struct iwl_beacon_filter_cmd);
119 else
120 len = offsetof(struct iwl_beacon_filter_cmd,
121 bf_threshold_absolute_low);
104 122
105 return iwl_mvm_send_cmd_pdu(mvm, REPLY_BEACON_FILTERING_CMD, flags, 123 return iwl_mvm_send_cmd_pdu(mvm, REPLY_BEACON_FILTERING_CMD, flags,
106 sizeof(struct iwl_beacon_filter_cmd), cmd); 124 len, cmd);
107} 125}
108 126
109static 127static
@@ -526,6 +544,9 @@ int iwl_mvm_power_update_device(struct iwl_mvm *mvm)
526 cmd.flags &= 544 cmd.flags &=
527 cpu_to_le16(~DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK); 545 cpu_to_le16(~DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK);
528#endif 546#endif
547 if (mvm->ext_clock_valid)
548 cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_32K_CLK_VALID_MSK);
549
529 IWL_DEBUG_POWER(mvm, 550 IWL_DEBUG_POWER(mvm,
530 "Sending device power command with flags = 0x%X\n", 551 "Sending device power command with flags = 0x%X\n",
531 cmd.flags); 552 cmd.flags);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
index 09866f50857a..e231a44d2423 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
@@ -3,7 +3,7 @@
3 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 3 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
4 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 4 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
5 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 5 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
6 * Copyright(c) 2018 Intel Corporation 6 * Copyright(c) 2018 - 2019 Intel Corporation
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of version 2 of the GNU General Public License as 9 * under the terms of version 2 of the GNU General Public License as
@@ -1643,8 +1643,26 @@ static s32 rs_get_best_rate(struct iwl_mvm *mvm,
1643 1643
1644static u32 rs_bw_from_sta_bw(struct ieee80211_sta *sta) 1644static u32 rs_bw_from_sta_bw(struct ieee80211_sta *sta)
1645{ 1645{
1646 struct ieee80211_sta_vht_cap *sta_vht_cap = &sta->vht_cap;
1647 struct ieee80211_vht_cap vht_cap = {
1648 .vht_cap_info = cpu_to_le32(sta_vht_cap->cap),
1649 .supp_mcs = sta_vht_cap->vht_mcs,
1650 };
1651
1646 switch (sta->bandwidth) { 1652 switch (sta->bandwidth) {
1647 case IEEE80211_STA_RX_BW_160: 1653 case IEEE80211_STA_RX_BW_160:
1654 /*
1655 * Don't use 160 MHz if VHT extended NSS support
1656 * says we cannot use 2 streams, we don't want to
1657 * deal with this.
1658 * We only check MCS 0 - they will support that if
1659 * we got here at all and we don't care which MCS,
1660 * we want to determine a more global state.
1661 */
1662 if (ieee80211_get_vht_max_nss(&vht_cap,
1663 IEEE80211_VHT_CHANWIDTH_160MHZ,
1664 0, true) < sta->rx_nss)
1665 return RATE_MCS_CHAN_WIDTH_80;
1648 return RATE_MCS_CHAN_WIDTH_160; 1666 return RATE_MCS_CHAN_WIDTH_160;
1649 case IEEE80211_STA_RX_BW_80: 1667 case IEEE80211_STA_RX_BW_80:
1650 return RATE_MCS_CHAN_WIDTH_80; 1668 return RATE_MCS_CHAN_WIDTH_80;
@@ -1757,7 +1775,12 @@ static void rs_set_amsdu_len(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1757 else 1775 else
1758 mvmsta->amsdu_enabled = 0xFFFF; 1776 mvmsta->amsdu_enabled = 0xFFFF;
1759 1777
1760 mvmsta->max_amsdu_len = sta->max_amsdu_len; 1778 if (mvmsta->vif->bss_conf.he_support &&
1779 !iwlwifi_mod_params.disable_11ax)
1780 mvmsta->max_amsdu_len = sta->max_amsdu_len;
1781 else
1782 mvmsta->max_amsdu_len = min_t(int, sta->max_amsdu_len, 8500);
1783
1761 sta->max_rc_amsdu_len = mvmsta->max_amsdu_len; 1784 sta->max_rc_amsdu_len = mvmsta->max_amsdu_len;
1762 1785
1763 for (i = 0; i < IWL_MAX_TID_COUNT; i++) { 1786 for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
@@ -1791,7 +1814,7 @@ static bool rs_tweak_rate_tbl(struct iwl_mvm *mvm,
1791 struct iwl_scale_tbl_info *tbl, 1814 struct iwl_scale_tbl_info *tbl,
1792 enum rs_action scale_action) 1815 enum rs_action scale_action)
1793{ 1816{
1794 if (sta->bandwidth != IEEE80211_STA_RX_BW_80) 1817 if (rs_bw_from_sta_bw(sta) != RATE_MCS_CHAN_WIDTH_80)
1795 return false; 1818 return false;
1796 1819
1797 if (!is_vht_siso(&tbl->rate)) 1820 if (!is_vht_siso(&tbl->rate))
@@ -4122,6 +4145,7 @@ static const struct rate_control_ops rs_mvm_ops_drv = {
4122 .add_sta_debugfs = rs_drv_add_sta_debugfs, 4145 .add_sta_debugfs = rs_drv_add_sta_debugfs,
4123 .remove_sta_debugfs = rs_remove_sta_debugfs, 4146 .remove_sta_debugfs = rs_remove_sta_debugfs,
4124#endif 4147#endif
4148 .capa = RATE_CTRL_CAPA_VHT_EXT_NSS_BW,
4125}; 4149};
4126 4150
4127void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 4151void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
index 235ab26ca429..fbd3014e8b82 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
@@ -222,7 +222,7 @@ static u32 iwl_mvm_set_mac80211_rx_flag(struct iwl_mvm *mvm,
222 !(rx_pkt_status & RX_MPDU_RES_STATUS_TTAK_OK)) 222 !(rx_pkt_status & RX_MPDU_RES_STATUS_TTAK_OK))
223 return 0; 223 return 0;
224 *crypt_len = IEEE80211_TKIP_IV_LEN; 224 *crypt_len = IEEE80211_TKIP_IV_LEN;
225 /* fall through if TTAK OK */ 225 /* fall through */
226 226
227 case RX_MPDU_RES_STATUS_SEC_WEP_ENC: 227 case RX_MPDU_RES_STATUS_SEC_WEP_ENC:
228 if (!(rx_pkt_status & RX_MPDU_RES_STATUS_ICV_OK)) 228 if (!(rx_pkt_status & RX_MPDU_RES_STATUS_ICV_OK))
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 2c56f73d688e..1e03acf30762 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -66,11 +66,37 @@
66#include "mvm.h" 66#include "mvm.h"
67#include "fw-api.h" 67#include "fw-api.h"
68 68
69static void *iwl_mvm_skb_get_hdr(struct sk_buff *skb)
70{
71 struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
72 u8 *data = skb->data;
73
74 /* Alignment concerns */
75 BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he) % 4);
76 BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_he_mu) % 4);
77 BUILD_BUG_ON(sizeof(struct ieee80211_radiotap_lsig) % 4);
78 BUILD_BUG_ON(sizeof(struct ieee80211_vendor_radiotap) % 4);
79
80 if (rx_status->flag & RX_FLAG_RADIOTAP_HE)
81 data += sizeof(struct ieee80211_radiotap_he);
82 if (rx_status->flag & RX_FLAG_RADIOTAP_HE_MU)
83 data += sizeof(struct ieee80211_radiotap_he_mu);
84 if (rx_status->flag & RX_FLAG_RADIOTAP_LSIG)
85 data += sizeof(struct ieee80211_radiotap_lsig);
86 if (rx_status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA) {
87 struct ieee80211_vendor_radiotap *radiotap = (void *)data;
88
89 data += sizeof(*radiotap) + radiotap->len + radiotap->pad;
90 }
91
92 return data;
93}
94
69static inline int iwl_mvm_check_pn(struct iwl_mvm *mvm, struct sk_buff *skb, 95static inline int iwl_mvm_check_pn(struct iwl_mvm *mvm, struct sk_buff *skb,
70 int queue, struct ieee80211_sta *sta) 96 int queue, struct ieee80211_sta *sta)
71{ 97{
72 struct iwl_mvm_sta *mvmsta; 98 struct iwl_mvm_sta *mvmsta;
73 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 99 struct ieee80211_hdr *hdr = iwl_mvm_skb_get_hdr(skb);
74 struct ieee80211_rx_status *stats = IEEE80211_SKB_RXCB(skb); 100 struct ieee80211_rx_status *stats = IEEE80211_SKB_RXCB(skb);
75 struct iwl_mvm_key_pn *ptk_pn; 101 struct iwl_mvm_key_pn *ptk_pn;
76 int res; 102 int res;
@@ -197,12 +223,15 @@ static void iwl_mvm_add_rtap_sniffer_config(struct iwl_mvm *mvm,
197{ 223{
198 struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); 224 struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
199 struct ieee80211_vendor_radiotap *radiotap; 225 struct ieee80211_vendor_radiotap *radiotap;
200 int size = sizeof(*radiotap) + sizeof(__le16); 226 const int size = sizeof(*radiotap) + sizeof(__le16);
201 227
202 if (!mvm->cur_aid) 228 if (!mvm->cur_aid)
203 return; 229 return;
204 230
205 radiotap = skb_put(skb, size); 231 /* ensure alignment */
232 BUILD_BUG_ON((size + 2) % 4);
233
234 radiotap = skb_put(skb, size + 2);
206 radiotap->align = 1; 235 radiotap->align = 1;
207 /* Intel OUI */ 236 /* Intel OUI */
208 radiotap->oui[0] = 0xf6; 237 radiotap->oui[0] = 0xf6;
@@ -212,10 +241,12 @@ static void iwl_mvm_add_rtap_sniffer_config(struct iwl_mvm *mvm,
212 radiotap->subns = 1; 241 radiotap->subns = 1;
213 radiotap->present = 0x1; 242 radiotap->present = 0x1;
214 radiotap->len = size - sizeof(*radiotap); 243 radiotap->len = size - sizeof(*radiotap);
215 radiotap->pad = 0; 244 radiotap->pad = 2;
216 245
217 /* fill the data now */ 246 /* fill the data now */
218 memcpy(radiotap->data, &mvm->cur_aid, sizeof(mvm->cur_aid)); 247 memcpy(radiotap->data, &mvm->cur_aid, sizeof(mvm->cur_aid));
248 /* and clear the padding */
249 memset(radiotap->data + sizeof(__le16), 0, radiotap->pad);
219 250
220 rx_status->flag |= RX_FLAG_RADIOTAP_VENDOR_DATA; 251 rx_status->flag |= RX_FLAG_RADIOTAP_VENDOR_DATA;
221} 252}
@@ -227,10 +258,7 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm,
227 struct ieee80211_sta *sta, 258 struct ieee80211_sta *sta,
228 bool csi) 259 bool csi)
229{ 260{
230 struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); 261 if (iwl_mvm_check_pn(mvm, skb, queue, sta))
231
232 if (!(rx_status->flag & RX_FLAG_NO_PSDU) &&
233 iwl_mvm_check_pn(mvm, skb, queue, sta))
234 kfree_skb(skb); 262 kfree_skb(skb);
235 else 263 else
236 ieee80211_rx_napi(mvm->hw, sta, skb, napi); 264 ieee80211_rx_napi(mvm->hw, sta, skb, napi);
@@ -310,7 +338,7 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
310 stats->flag |= RX_FLAG_MMIC_ERROR; 338 stats->flag |= RX_FLAG_MMIC_ERROR;
311 339
312 *crypt_len = IEEE80211_TKIP_IV_LEN; 340 *crypt_len = IEEE80211_TKIP_IV_LEN;
313 /* fall through if TTAK OK */ 341 /* fall through */
314 case IWL_RX_MPDU_STATUS_SEC_WEP: 342 case IWL_RX_MPDU_STATUS_SEC_WEP:
315 if (!(status & IWL_RX_MPDU_STATUS_ICV_OK)) 343 if (!(status & IWL_RX_MPDU_STATUS_ICV_OK))
316 return -1; 344 return -1;
@@ -663,7 +691,7 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
663 struct sk_buff *skb, 691 struct sk_buff *skb,
664 struct iwl_rx_mpdu_desc *desc) 692 struct iwl_rx_mpdu_desc *desc)
665{ 693{
666 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 694 struct ieee80211_hdr *hdr = iwl_mvm_skb_get_hdr(skb);
667 struct iwl_mvm_sta *mvm_sta; 695 struct iwl_mvm_sta *mvm_sta;
668 struct iwl_mvm_baid_data *baid_data; 696 struct iwl_mvm_baid_data *baid_data;
669 struct iwl_mvm_reorder_buffer *buffer; 697 struct iwl_mvm_reorder_buffer *buffer;
@@ -960,6 +988,7 @@ iwl_mvm_decode_he_phy_ru_alloc(struct iwl_mvm_rx_phy_data *phy_data,
960 * the TSF/timers are not be transmitted in HE-MU. 988 * the TSF/timers are not be transmitted in HE-MU.
961 */ 989 */
962 u8 ru = le32_get_bits(phy_data->d1, IWL_RX_PHY_DATA1_HE_RU_ALLOC_MASK); 990 u8 ru = le32_get_bits(phy_data->d1, IWL_RX_PHY_DATA1_HE_RU_ALLOC_MASK);
991 u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK;
963 u8 offs = 0; 992 u8 offs = 0;
964 993
965 rx_status->bw = RATE_INFO_BW_HE_RU; 994 rx_status->bw = RATE_INFO_BW_HE_RU;
@@ -1002,19 +1031,27 @@ iwl_mvm_decode_he_phy_ru_alloc(struct iwl_mvm_rx_phy_data *phy_data,
1002 he->data2 |= 1031 he->data2 |=
1003 cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC); 1032 cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRISEC_80_SEC);
1004 1033
1005 if (he_mu) {
1006#define CHECK_BW(bw) \ 1034#define CHECK_BW(bw) \
1007 BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_ ## bw ## MHZ != \ 1035 BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_ ## bw ## MHZ != \
1036 RATE_MCS_CHAN_WIDTH_##bw >> RATE_MCS_CHAN_WIDTH_POS); \
1037 BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_DATA6_TB_PPDU_BW_ ## bw ## MHZ != \
1008 RATE_MCS_CHAN_WIDTH_##bw >> RATE_MCS_CHAN_WIDTH_POS) 1038 RATE_MCS_CHAN_WIDTH_##bw >> RATE_MCS_CHAN_WIDTH_POS)
1009 CHECK_BW(20); 1039 CHECK_BW(20);
1010 CHECK_BW(40); 1040 CHECK_BW(40);
1011 CHECK_BW(80); 1041 CHECK_BW(80);
1012 CHECK_BW(160); 1042 CHECK_BW(160);
1043
1044 if (he_mu)
1013 he_mu->flags2 |= 1045 he_mu->flags2 |=
1014 le16_encode_bits(FIELD_GET(RATE_MCS_CHAN_WIDTH_MSK, 1046 le16_encode_bits(FIELD_GET(RATE_MCS_CHAN_WIDTH_MSK,
1015 rate_n_flags), 1047 rate_n_flags),
1016 IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW); 1048 IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW);
1017 } 1049 else if (he_type == RATE_MCS_HE_TYPE_TRIG)
1050 he->data6 |=
1051 cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA6_TB_PPDU_BW_KNOWN) |
1052 le16_encode_bits(FIELD_GET(RATE_MCS_CHAN_WIDTH_MSK,
1053 rate_n_flags),
1054 IEEE80211_RADIOTAP_HE_DATA6_TB_PPDU_BW);
1018} 1055}
1019 1056
1020static void iwl_mvm_decode_he_phy_data(struct iwl_mvm *mvm, 1057static void iwl_mvm_decode_he_phy_data(struct iwl_mvm *mvm,
@@ -1037,16 +1074,16 @@ static void iwl_mvm_decode_he_phy_data(struct iwl_mvm *mvm,
1037 IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE2_KNOWN | 1074 IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE2_KNOWN |
1038 IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE3_KNOWN | 1075 IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE3_KNOWN |
1039 IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE4_KNOWN); 1076 IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE4_KNOWN);
1040 he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0, 1077 he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d2,
1041 IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE1), 1078 IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE1),
1042 IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE1); 1079 IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE1);
1043 he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0, 1080 he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d2,
1044 IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE2), 1081 IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE2),
1045 IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE2); 1082 IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE2);
1046 he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0, 1083 he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d2,
1047 IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE3), 1084 IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE3),
1048 IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE3); 1085 IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE3);
1049 he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0, 1086 he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d2,
1050 IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE4), 1087 IWL_RX_PHY_DATA2_HE_TB_EXT_SPTL_REUSE4),
1051 IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE4); 1088 IEEE80211_RADIOTAP_HE_DATA4_TB_SPTL_REUSE4);
1052 /* fall through */ 1089 /* fall through */
@@ -1056,7 +1093,6 @@ static void iwl_mvm_decode_he_phy_data(struct iwl_mvm *mvm,
1056 case IWL_RX_PHY_INFO_TYPE_HE_TB: 1093 case IWL_RX_PHY_INFO_TYPE_HE_TB:
1057 /* HE common */ 1094 /* HE common */
1058 he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN | 1095 he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN |
1059 IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN |
1060 IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN | 1096 IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN |
1061 IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN); 1097 IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN);
1062 he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN | 1098 he->data2 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN |
@@ -1076,9 +1112,6 @@ static void iwl_mvm_decode_he_phy_data(struct iwl_mvm *mvm,
1076 he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0, 1112 he->data3 |= le16_encode_bits(le32_get_bits(phy_data->d0,
1077 IWL_RX_PHY_DATA0_HE_LDPC_EXT_SYM), 1113 IWL_RX_PHY_DATA0_HE_LDPC_EXT_SYM),
1078 IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG); 1114 IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG);
1079 he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0,
1080 IWL_RX_PHY_DATA0_HE_SPATIAL_REUSE_MASK),
1081 IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE);
1082 he->data5 |= le16_encode_bits(le32_get_bits(phy_data->d0, 1115 he->data5 |= le16_encode_bits(le32_get_bits(phy_data->d0,
1083 IWL_RX_PHY_DATA0_HE_PRE_FEC_PAD_MASK), 1116 IWL_RX_PHY_DATA0_HE_PRE_FEC_PAD_MASK),
1084 IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD); 1117 IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD);
@@ -1099,6 +1132,20 @@ static void iwl_mvm_decode_he_phy_data(struct iwl_mvm *mvm,
1099 1132
1100 switch (phy_data->info_type) { 1133 switch (phy_data->info_type) {
1101 case IWL_RX_PHY_INFO_TYPE_HE_MU_EXT: 1134 case IWL_RX_PHY_INFO_TYPE_HE_MU_EXT:
1135 case IWL_RX_PHY_INFO_TYPE_HE_MU:
1136 case IWL_RX_PHY_INFO_TYPE_HE_SU:
1137 he->data1 |= cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_SPTL_REUSE_KNOWN);
1138 he->data4 |= le16_encode_bits(le32_get_bits(phy_data->d0,
1139 IWL_RX_PHY_DATA0_HE_SPATIAL_REUSE_MASK),
1140 IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE);
1141 break;
1142 default:
1143 /* nothing here */
1144 break;
1145 }
1146
1147 switch (phy_data->info_type) {
1148 case IWL_RX_PHY_INFO_TYPE_HE_MU_EXT:
1102 he_mu->flags1 |= 1149 he_mu->flags1 |=
1103 le16_encode_bits(le16_get_bits(phy_data->d4, 1150 le16_encode_bits(le16_get_bits(phy_data->d4,
1104 IWL_RX_PHY_DATA4_HE_MU_EXT_SIGB_DCM), 1151 IWL_RX_PHY_DATA4_HE_MU_EXT_SIGB_DCM),
@@ -1165,22 +1212,16 @@ static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb,
1165 .flags2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW_KNOWN | 1212 .flags2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_MU_FLAGS2_PUNC_FROM_SIG_A_BW_KNOWN |
1166 IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN), 1213 IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN),
1167 }; 1214 };
1168 unsigned int radiotap_len = 0;
1169 1215
1170 he = skb_put_data(skb, &known, sizeof(known)); 1216 he = skb_put_data(skb, &known, sizeof(known));
1171 radiotap_len += sizeof(known);
1172 rx_status->flag |= RX_FLAG_RADIOTAP_HE; 1217 rx_status->flag |= RX_FLAG_RADIOTAP_HE;
1173 1218
1174 if (phy_data->info_type == IWL_RX_PHY_INFO_TYPE_HE_MU || 1219 if (phy_data->info_type == IWL_RX_PHY_INFO_TYPE_HE_MU ||
1175 phy_data->info_type == IWL_RX_PHY_INFO_TYPE_HE_MU_EXT) { 1220 phy_data->info_type == IWL_RX_PHY_INFO_TYPE_HE_MU_EXT) {
1176 he_mu = skb_put_data(skb, &mu_known, sizeof(mu_known)); 1221 he_mu = skb_put_data(skb, &mu_known, sizeof(mu_known));
1177 radiotap_len += sizeof(mu_known);
1178 rx_status->flag |= RX_FLAG_RADIOTAP_HE_MU; 1222 rx_status->flag |= RX_FLAG_RADIOTAP_HE_MU;
1179 } 1223 }
1180 1224
1181 /* temporarily hide the radiotap data */
1182 __skb_pull(skb, radiotap_len);
1183
1184 /* report the AMPDU-EOF bit on single frames */ 1225 /* report the AMPDU-EOF bit on single frames */
1185 if (!queue && !(phy_info & IWL_RX_MPDU_PHY_AMPDU)) { 1226 if (!queue && !(phy_info & IWL_RX_MPDU_PHY_AMPDU)) {
1186 rx_status->flag |= RX_FLAG_AMPDU_DETAILS; 1227 rx_status->flag |= RX_FLAG_AMPDU_DETAILS;
@@ -1766,7 +1807,7 @@ void iwl_mvm_rx_monitor_ndp(struct iwl_mvm *mvm, struct napi_struct *napi,
1766 rx_status->rate_idx = rate; 1807 rx_status->rate_idx = rate;
1767 } 1808 }
1768 1809
1769 iwl_mvm_pass_packet_to_mac80211(mvm, napi, skb, queue, sta, false); 1810 ieee80211_rx_napi(mvm->hw, sta, skb, napi);
1770out: 1811out:
1771 rcu_read_unlock(); 1812 rcu_read_unlock();
1772} 1813}
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index 86d598d5b68f..78694bc38e76 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -8,7 +8,7 @@
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11 * Copyright(c) 2018 Intel Corporation 11 * Copyright(c) 2018 - 2019 Intel Corporation
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of version 2 of the GNU General Public License as 14 * it under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
34 * Copyright(c) 2018 Intel Corporation 34 * Copyright(c) 2018 - 2019 Intel Corporation
35 * All rights reserved. 35 * All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -1580,6 +1580,11 @@ static int iwl_mvm_check_running_scans(struct iwl_mvm *mvm, int type)
1580 * scheduled scan before starting a normal scan. 1580 * scheduled scan before starting a normal scan.
1581 */ 1581 */
1582 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;
1587
1583 if (iwl_mvm_num_scans(mvm) < mvm->max_scans) 1588 if (iwl_mvm_num_scans(mvm) < mvm->max_scans)
1584 return 0; 1589 return 0;
1585 1590
@@ -1616,10 +1621,10 @@ static int iwl_mvm_check_running_scans(struct iwl_mvm *mvm, int type)
1616 if (mvm->scan_status & IWL_MVM_SCAN_SCHED_MASK) 1621 if (mvm->scan_status & IWL_MVM_SCAN_SCHED_MASK)
1617 return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED, 1622 return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED,
1618 true); 1623 true);
1619 1624 /* Something is wrong if no scan was running but we
1620 /* fall through, something is wrong if no scan was 1625 * ran out of scans.
1621 * running but we ran out of scans.
1622 */ 1626 */
1627 /* fall through */
1623 default: 1628 default:
1624 WARN_ON(1); 1629 WARN_ON(1);
1625 break; 1630 break;
@@ -1976,9 +1981,8 @@ static int iwl_mvm_scan_stop_wait(struct iwl_mvm *mvm, int type)
1976 return ret; 1981 return ret;
1977 } 1982 }
1978 1983
1979 ret = iwl_wait_notification(&mvm->notif_wait, &wait_scan_done, 1 * HZ); 1984 return iwl_wait_notification(&mvm->notif_wait, &wait_scan_done,
1980 1985 1 * HZ);
1981 return ret;
1982} 1986}
1983 1987
1984int iwl_mvm_scan_size(struct iwl_mvm *mvm) 1988int iwl_mvm_scan_size(struct iwl_mvm *mvm)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index c5a01470a3bc..498c315291cf 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -314,7 +314,6 @@ static int iwl_mvm_invalidate_sta_queue(struct iwl_mvm *mvm, int queue,
314 struct iwl_mvm_sta *mvmsta; 314 struct iwl_mvm_sta *mvmsta;
315 u32 status; 315 u32 status;
316 u8 sta_id; 316 u8 sta_id;
317 int ret;
318 317
319 if (WARN_ON(iwl_mvm_has_new_tx_api(mvm))) 318 if (WARN_ON(iwl_mvm_has_new_tx_api(mvm)))
320 return -EINVAL; 319 return -EINVAL;
@@ -349,11 +348,9 @@ static int iwl_mvm_invalidate_sta_queue(struct iwl_mvm *mvm, int queue,
349 348
350 /* Notify FW of queue removal from the STA queues */ 349 /* Notify FW of queue removal from the STA queues */
351 status = ADD_STA_SUCCESS; 350 status = ADD_STA_SUCCESS;
352 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, 351 return iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA,
353 iwl_mvm_add_sta_cmd_size(mvm), 352 iwl_mvm_add_sta_cmd_size(mvm),
354 &cmd, &status); 353 &cmd, &status);
355
356 return ret;
357} 354}
358 355
359static int iwl_mvm_disable_txq(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 356static int iwl_mvm_disable_txq(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
@@ -753,7 +750,8 @@ static int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm,
753 750
754 if (tid == IWL_MAX_TID_COUNT) { 751 if (tid == IWL_MAX_TID_COUNT) {
755 tid = IWL_MGMT_TID; 752 tid = IWL_MGMT_TID;
756 size = IWL_MGMT_QUEUE_SIZE; 753 size = max_t(u32, IWL_MGMT_QUEUE_SIZE,
754 mvm->trans->cfg->min_txq_size);
757 } 755 }
758 queue = iwl_trans_txq_alloc(mvm->trans, 756 queue = iwl_trans_txq_alloc(mvm->trans,
759 cpu_to_le16(TX_QUEUE_CFG_ENABLE_QUEUE), 757 cpu_to_le16(TX_QUEUE_CFG_ENABLE_QUEUE),
@@ -794,11 +792,9 @@ static int iwl_mvm_sta_alloc_queue_tvqm(struct iwl_mvm *mvm,
794 if (queue < 0) 792 if (queue < 0)
795 return queue; 793 return queue;
796 794
797 if (sta) { 795 mvmtxq->txq_id = queue;
798 mvmtxq->txq_id = queue; 796 mvm->tvqm_info[queue].txq_tid = tid;
799 mvm->tvqm_info[queue].txq_tid = tid; 797 mvm->tvqm_info[queue].sta_id = mvmsta->sta_id;
800 mvm->tvqm_info[queue].sta_id = mvmsta->sta_id;
801 }
802 798
803 IWL_DEBUG_TX_QUEUES(mvm, "Allocated queue is %d\n", queue); 799 IWL_DEBUG_TX_QUEUES(mvm, "Allocated queue is %d\n", queue);
804 800
@@ -2340,11 +2336,13 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
2340 if (mvmvif->ap_wep_key) { 2336 if (mvmvif->ap_wep_key) {
2341 u8 key_offset = iwl_mvm_set_fw_key_idx(mvm); 2337 u8 key_offset = iwl_mvm_set_fw_key_idx(mvm);
2342 2338
2339 __set_bit(key_offset, mvm->fw_key_table);
2340
2343 if (key_offset == STA_KEY_IDX_INVALID) 2341 if (key_offset == STA_KEY_IDX_INVALID)
2344 return -ENOSPC; 2342 return -ENOSPC;
2345 2343
2346 ret = iwl_mvm_send_sta_key(mvm, mvmvif->mcast_sta.sta_id, 2344 ret = iwl_mvm_send_sta_key(mvm, mvmvif->mcast_sta.sta_id,
2347 mvmvif->ap_wep_key, 1, 0, NULL, 0, 2345 mvmvif->ap_wep_key, true, 0, NULL, 0,
2348 key_offset, 0); 2346 key_offset, 0);
2349 if (ret) 2347 if (ret)
2350 return ret; 2348 return ret;
@@ -2353,6 +2351,59 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
2353 return 0; 2351 return 0;
2354} 2352}
2355 2353
2354static int __iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, u8 sta_id,
2355 struct ieee80211_key_conf *keyconf,
2356 bool mcast)
2357{
2358 union {
2359 struct iwl_mvm_add_sta_key_cmd_v1 cmd_v1;
2360 struct iwl_mvm_add_sta_key_cmd cmd;
2361 } u = {};
2362 bool new_api = fw_has_api(&mvm->fw->ucode_capa,
2363 IWL_UCODE_TLV_API_TKIP_MIC_KEYS);
2364 __le16 key_flags;
2365 int ret, size;
2366 u32 status;
2367
2368 /* This is a valid situation for GTK removal */
2369 if (sta_id == IWL_MVM_INVALID_STA)
2370 return 0;
2371
2372 key_flags = cpu_to_le16((keyconf->keyidx << STA_KEY_FLG_KEYID_POS) &
2373 STA_KEY_FLG_KEYID_MSK);
2374 key_flags |= cpu_to_le16(STA_KEY_FLG_NO_ENC | STA_KEY_FLG_WEP_KEY_MAP);
2375 key_flags |= cpu_to_le16(STA_KEY_NOT_VALID);
2376
2377 if (mcast)
2378 key_flags |= cpu_to_le16(STA_KEY_MULTICAST);
2379
2380 /*
2381 * The fields assigned here are in the same location at the start
2382 * of the command, so we can do this union trick.
2383 */
2384 u.cmd.common.key_flags = key_flags;
2385 u.cmd.common.key_offset = keyconf->hw_key_idx;
2386 u.cmd.common.sta_id = sta_id;
2387
2388 size = new_api ? sizeof(u.cmd) : sizeof(u.cmd_v1);
2389
2390 status = ADD_STA_SUCCESS;
2391 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA_KEY, size, &u.cmd,
2392 &status);
2393
2394 switch (status) {
2395 case ADD_STA_SUCCESS:
2396 IWL_DEBUG_WEP(mvm, "MODIFY_STA: remove sta key passed\n");
2397 break;
2398 default:
2399 ret = -EIO;
2400 IWL_ERR(mvm, "MODIFY_STA: remove sta key failed\n");
2401 break;
2402 }
2403
2404 return ret;
2405}
2406
2356/* 2407/*
2357 * Send the FW a request to remove the station from it's internal data 2408 * Send the FW a request to remove the station from it's internal data
2358 * structures, and in addition remove it from the local data structure. 2409 * structures, and in addition remove it from the local data structure.
@@ -2368,6 +2419,28 @@ int iwl_mvm_rm_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
2368 2419
2369 iwl_mvm_disable_txq(mvm, NULL, mvmvif->cab_queue, 0, 0); 2420 iwl_mvm_disable_txq(mvm, NULL, mvmvif->cab_queue, 0, 0);
2370 2421
2422 if (mvmvif->ap_wep_key) {
2423 int i;
2424
2425 if (!__test_and_clear_bit(mvmvif->ap_wep_key->hw_key_idx,
2426 mvm->fw_key_table)) {
2427 IWL_ERR(mvm, "offset %d not used in fw key table.\n",
2428 mvmvif->ap_wep_key->hw_key_idx);
2429 return -ENOENT;
2430 }
2431
2432 /* track which key was deleted last */
2433 for (i = 0; i < STA_KEY_MAX_NUM; i++) {
2434 if (mvm->fw_key_deleted[i] < U8_MAX)
2435 mvm->fw_key_deleted[i]++;
2436 }
2437 mvm->fw_key_deleted[mvmvif->ap_wep_key->hw_key_idx] = 0;
2438 ret = __iwl_mvm_remove_sta_key(mvm, mvmvif->mcast_sta.sta_id,
2439 mvmvif->ap_wep_key, true);
2440 if (ret)
2441 return ret;
2442 }
2443
2371 ret = iwl_mvm_rm_sta_common(mvm, mvmvif->mcast_sta.sta_id); 2444 ret = iwl_mvm_rm_sta_common(mvm, mvmvif->mcast_sta.sta_id);
2372 if (ret) 2445 if (ret)
2373 IWL_WARN(mvm, "Failed sending remove station\n"); 2446 IWL_WARN(mvm, "Failed sending remove station\n");
@@ -3399,59 +3472,6 @@ static int __iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
3399 return ret; 3472 return ret;
3400} 3473}
3401 3474
3402static int __iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, u8 sta_id,
3403 struct ieee80211_key_conf *keyconf,
3404 bool mcast)
3405{
3406 union {
3407 struct iwl_mvm_add_sta_key_cmd_v1 cmd_v1;
3408 struct iwl_mvm_add_sta_key_cmd cmd;
3409 } u = {};
3410 bool new_api = fw_has_api(&mvm->fw->ucode_capa,
3411 IWL_UCODE_TLV_API_TKIP_MIC_KEYS);
3412 __le16 key_flags;
3413 int ret, size;
3414 u32 status;
3415
3416 /* This is a valid situation for GTK removal */
3417 if (sta_id == IWL_MVM_INVALID_STA)
3418 return 0;
3419
3420 key_flags = cpu_to_le16((keyconf->keyidx << STA_KEY_FLG_KEYID_POS) &
3421 STA_KEY_FLG_KEYID_MSK);
3422 key_flags |= cpu_to_le16(STA_KEY_FLG_NO_ENC | STA_KEY_FLG_WEP_KEY_MAP);
3423 key_flags |= cpu_to_le16(STA_KEY_NOT_VALID);
3424
3425 if (mcast)
3426 key_flags |= cpu_to_le16(STA_KEY_MULTICAST);
3427
3428 /*
3429 * The fields assigned here are in the same location at the start
3430 * of the command, so we can do this union trick.
3431 */
3432 u.cmd.common.key_flags = key_flags;
3433 u.cmd.common.key_offset = keyconf->hw_key_idx;
3434 u.cmd.common.sta_id = sta_id;
3435
3436 size = new_api ? sizeof(u.cmd) : sizeof(u.cmd_v1);
3437
3438 status = ADD_STA_SUCCESS;
3439 ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA_KEY, size, &u.cmd,
3440 &status);
3441
3442 switch (status) {
3443 case ADD_STA_SUCCESS:
3444 IWL_DEBUG_WEP(mvm, "MODIFY_STA: remove sta key passed\n");
3445 break;
3446 default:
3447 ret = -EIO;
3448 IWL_ERR(mvm, "MODIFY_STA: remove sta key failed\n");
3449 break;
3450 }
3451
3452 return ret;
3453}
3454
3455int iwl_mvm_set_sta_key(struct iwl_mvm *mvm, 3475int iwl_mvm_set_sta_key(struct iwl_mvm *mvm,
3456 struct ieee80211_vif *vif, 3476 struct ieee80211_vif *vif,
3457 struct ieee80211_sta *sta, 3477 struct ieee80211_sta *sta,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
index 0614296244b3..79700c7310a1 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
@@ -394,6 +394,7 @@ struct iwl_mvm_rxq_dup_data {
394 * the BA window. To be used for UAPSD only. 394 * the BA window. To be used for UAPSD only.
395 * @ptk_pn: per-queue PTK PN data structures 395 * @ptk_pn: per-queue PTK PN data structures
396 * @dup_data: per queue duplicate packet detection data 396 * @dup_data: per queue duplicate packet detection data
397 * @wep_key: used in AP mode. Is a duplicate of the WEP key.
397 * @deferred_traffic_tid_map: indication bitmap of deferred traffic per-TID 398 * @deferred_traffic_tid_map: indication bitmap of deferred traffic per-TID
398 * @tx_ant: the index of the antenna to use for data tx to this station. Only 399 * @tx_ant: the index of the antenna to use for data tx to this station. Only
399 * used during connection establishment (e.g. for the 4 way handshake 400 * used during connection establishment (e.g. for the 4 way handshake
@@ -425,6 +426,8 @@ struct iwl_mvm_sta {
425 struct iwl_mvm_key_pn __rcu *ptk_pn[4]; 426 struct iwl_mvm_key_pn __rcu *ptk_pn[4];
426 struct iwl_mvm_rxq_dup_data *dup_data; 427 struct iwl_mvm_rxq_dup_data *dup_data;
427 428
429 struct ieee80211_key_conf *wep_key;
430
428 u8 reserved_queue; 431 u8 reserved_queue;
429 432
430 /* Temporary, until the new TLC will control the Tx protection */ 433 /* Temporary, until the new TLC will control the Tx protection */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
index 5b34100e9099..9693fa4cdc39 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
@@ -85,7 +85,7 @@ void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
85{ 85{
86 lockdep_assert_held(&mvm->time_event_lock); 86 lockdep_assert_held(&mvm->time_event_lock);
87 87
88 if (!te_data->vif) 88 if (!te_data || !te_data->vif)
89 return; 89 return;
90 90
91 list_del(&te_data->list); 91 list_del(&te_data->list);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index ac62eb8c4b36..0c2aabc842f9 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -8,7 +8,7 @@
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11 * Copyright(c) 2018 Intel Corporation 11 * Copyright(c) 2018 - 2019 Intel Corporation
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of version 2 of the GNU General Public License as 14 * it under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
34 * Copyright(c) 2018 Intel Corporation 34 * Copyright(c) 2018 - 2019 Intel Corporation
35 * All rights reserved. 35 * All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -209,7 +209,9 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
209 u16 offload_assist = 0; 209 u16 offload_assist = 0;
210 u8 ac; 210 u8 ac;
211 211
212 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) 212 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) ||
213 (ieee80211_is_probe_resp(fc) &&
214 !is_multicast_ether_addr(hdr->addr1)))
213 tx_flags |= TX_CMD_FLG_ACK; 215 tx_flags |= TX_CMD_FLG_ACK;
214 else 216 else
215 tx_flags &= ~TX_CMD_FLG_ACK; 217 tx_flags &= ~TX_CMD_FLG_ACK;
@@ -278,7 +280,7 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
278 } 280 }
279 281
280 if (ieee80211_is_data(fc) && len > mvm->rts_threshold && 282 if (ieee80211_is_data(fc) && len > mvm->rts_threshold &&
281 !is_multicast_ether_addr(ieee80211_get_DA(hdr))) 283 !is_multicast_ether_addr(hdr->addr1))
282 tx_flags |= TX_CMD_FLG_PROT_REQUIRE; 284 tx_flags |= TX_CMD_FLG_PROT_REQUIRE;
283 285
284 if (fw_has_capa(&mvm->fw->ucode_capa, 286 if (fw_has_capa(&mvm->fw->ucode_capa,
@@ -719,6 +721,9 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
719 IEEE80211_TX_CTL_TX_OFFCHAN; 721 IEEE80211_TX_CTL_TX_OFFCHAN;
720 int queue = -1; 722 int queue = -1;
721 723
724 if (IWL_MVM_NON_TRANSMITTING_AP && ieee80211_is_probe_resp(fc))
725 return -1;
726
722 memcpy(&info, skb->cb, sizeof(info)); 727 memcpy(&info, skb->cb, sizeof(info));
723 728
724 if (WARN_ON_ONCE(info.flags & IEEE80211_TX_CTL_AMPDU)) 729 if (WARN_ON_ONCE(info.flags & IEEE80211_TX_CTL_AMPDU))
@@ -1078,6 +1083,9 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
1078 fc = hdr->frame_control; 1083 fc = hdr->frame_control;
1079 hdrlen = ieee80211_hdrlen(fc); 1084 hdrlen = ieee80211_hdrlen(fc);
1080 1085
1086 if (IWL_MVM_NON_TRANSMITTING_AP && ieee80211_is_probe_resp(fc))
1087 return -1;
1088
1081 if (WARN_ON_ONCE(!mvmsta)) 1089 if (WARN_ON_ONCE(!mvmsta))
1082 return -1; 1090 return -1;
1083 1091
@@ -1107,12 +1115,14 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
1107 */ 1115 */
1108 if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) { 1116 if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc)) {
1109 tid = ieee80211_get_tid(hdr); 1117 tid = ieee80211_get_tid(hdr);
1110 if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT)) 1118 if (WARN_ONCE(tid >= IWL_MAX_TID_COUNT, "Invalid TID %d", tid))
1111 goto drop_unlock_sta; 1119 goto drop_unlock_sta;
1112 1120
1113 is_ampdu = info->flags & IEEE80211_TX_CTL_AMPDU; 1121 is_ampdu = info->flags & IEEE80211_TX_CTL_AMPDU;
1114 if (WARN_ON_ONCE(is_ampdu && 1122 if (WARN_ONCE(is_ampdu &&
1115 mvmsta->tid_data[tid].state != IWL_AGG_ON)) 1123 mvmsta->tid_data[tid].state != IWL_AGG_ON,
1124 "Invalid internal agg state %d for TID %d",
1125 mvmsta->tid_data[tid].state, tid))
1116 goto drop_unlock_sta; 1126 goto drop_unlock_sta;
1117 1127
1118 seq_number = mvmsta->tid_data[tid].seq_number; 1128 seq_number = mvmsta->tid_data[tid].seq_number;
@@ -1134,7 +1144,7 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
1134 1144
1135 WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM); 1145 WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM);
1136 1146
1137 if (WARN_ON_ONCE(txq_id == IWL_MVM_INVALID_QUEUE)) { 1147 if (WARN_ONCE(txq_id == IWL_MVM_INVALID_QUEUE, "Invalid TXQ id")) {
1138 iwl_trans_free_tx_cmd(mvm->trans, dev_cmd); 1148 iwl_trans_free_tx_cmd(mvm->trans, dev_cmd);
1139 spin_unlock(&mvmsta->lock); 1149 spin_unlock(&mvmsta->lock);
1140 return 0; 1150 return 0;
@@ -1184,6 +1194,7 @@ drop_unlock_sta:
1184 iwl_trans_free_tx_cmd(mvm->trans, dev_cmd); 1194 iwl_trans_free_tx_cmd(mvm->trans, dev_cmd);
1185 spin_unlock(&mvmsta->lock); 1195 spin_unlock(&mvmsta->lock);
1186drop: 1196drop:
1197 IWL_DEBUG_TX(mvm, "TX to [%d|%d] dropped\n", mvmsta->sta_id, tid);
1187 return -1; 1198 return -1;
1188} 1199}
1189 1200
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
index 211c4638d690..4649327abb45 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
@@ -294,6 +294,7 @@ static const struct {
294 { "SYSASSERT", 0x35 }, 294 { "SYSASSERT", 0x35 },
295 { "UCODE_VERSION_MISMATCH", 0x37 }, 295 { "UCODE_VERSION_MISMATCH", 0x37 },
296 { "BAD_COMMAND", 0x38 }, 296 { "BAD_COMMAND", 0x38 },
297 { "BAD_COMMAND", 0x39 },
297 { "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C }, 298 { "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C },
298 { "FATAL_ERROR", 0x3D }, 299 { "FATAL_ERROR", 0x3D },
299 { "NMI_TRM_HW_ERR", 0x46 }, 300 { "NMI_TRM_HW_ERR", 0x46 },
@@ -456,12 +457,14 @@ static void iwl_mvm_dump_umac_error_log(struct iwl_mvm *mvm)
456{ 457{
457 struct iwl_trans *trans = mvm->trans; 458 struct iwl_trans *trans = mvm->trans;
458 struct iwl_umac_error_event_table table; 459 struct iwl_umac_error_event_table table;
460 u32 base = mvm->trans->umac_error_event_table;
459 461
460 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))
461 return; 465 return;
462 466
463 iwl_trans_read_mem_bytes(trans, mvm->umac_error_event_table, &table, 467 iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table));
464 sizeof(table));
465 468
466 if (table.valid) 469 if (table.valid)
467 mvm->fwrt.dump.umac_err_id = table.error_id; 470 mvm->fwrt.dump.umac_err_id = table.error_id;
@@ -493,7 +496,7 @@ static void iwl_mvm_dump_lmac_error_log(struct iwl_mvm *mvm, u8 lmac_num)
493{ 496{
494 struct iwl_trans *trans = mvm->trans; 497 struct iwl_trans *trans = mvm->trans;
495 struct iwl_error_event_table table; 498 struct iwl_error_event_table table;
496 u32 val, base = mvm->error_event_table[lmac_num]; 499 u32 val, base = mvm->trans->lmac_error_event_table[lmac_num];
497 500
498 if (mvm->fwrt.cur_fw_img == IWL_UCODE_INIT) { 501 if (mvm->fwrt.cur_fw_img == IWL_UCODE_INIT) {
499 if (!base) 502 if (!base)
@@ -522,23 +525,9 @@ static void iwl_mvm_dump_lmac_error_log(struct iwl_mvm *mvm, u8 lmac_num)
522 /* reset the device */ 525 /* reset the device */
523 iwl_trans_sw_reset(trans); 526 iwl_trans_sw_reset(trans);
524 527
525 /* set INIT_DONE flag */ 528 err = iwl_finish_nic_init(trans);
526 iwl_set_bit(trans, CSR_GP_CNTRL, 529 if (err)
527 BIT(trans->cfg->csr->flag_init_done));
528
529 /* and wait for clock stabilization */
530 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
531 udelay(2);
532
533 err = iwl_poll_bit(trans, CSR_GP_CNTRL,
534 BIT(trans->cfg->csr->flag_mac_clock_ready),
535 BIT(trans->cfg->csr->flag_mac_clock_ready),
536 25000);
537 if (err < 0) {
538 IWL_DEBUG_INFO(trans,
539 "Failed to reset the card for the dump\n");
540 return; 530 return;
541 }
542 } 531 }
543 532
544 iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table)); 533 iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table));
@@ -603,7 +592,7 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
603 592
604 iwl_mvm_dump_lmac_error_log(mvm, 0); 593 iwl_mvm_dump_lmac_error_log(mvm, 0);
605 594
606 if (mvm->error_event_table[1]) 595 if (mvm->trans->lmac_error_event_table[1])
607 iwl_mvm_dump_lmac_error_log(mvm, 1); 596 iwl_mvm_dump_lmac_error_log(mvm, 1);
608 597
609 iwl_mvm_dump_umac_error_log(mvm); 598 iwl_mvm_dump_umac_error_log(mvm);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
index ceb3aa03d561..1e36459948db 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2018 Intel Corporation 8 * Copyright(c) 2018 - 2019 Intel Corporation
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 11 * it under the terms of version 2 of the GNU General Public License as
@@ -18,7 +18,7 @@
18 * 18 *
19 * BSD LICENSE 19 * BSD LICENSE
20 * 20 *
21 * Copyright(c) 2018 Intel Corporation 21 * Copyright(c) 2018 - 2019 Intel Corporation
22 * All rights reserved. 22 * All rights reserved.
23 * 23 *
24 * Redistribution and use in source and binary forms, with or without 24 * Redistribution and use in source and binary forms, with or without
@@ -66,6 +66,7 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
66 void *iml_img; 66 void *iml_img;
67 u32 control_flags = 0; 67 u32 control_flags = 0;
68 int ret; 68 int ret;
69 int cmdq_size = max_t(u32, TFD_CMD_SLOTS, trans->cfg->min_txq_size);
69 70
70 /* Allocate prph scratch */ 71 /* Allocate prph scratch */
71 prph_scratch = dma_alloc_coherent(trans->dev, sizeof(*prph_scratch), 72 prph_scratch = dma_alloc_coherent(trans->dev, sizeof(*prph_scratch),
@@ -151,7 +152,7 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
151 ctxt_info_gen3->mcr_base_addr = 152 ctxt_info_gen3->mcr_base_addr =
152 cpu_to_le64(trans_pcie->rxq->used_bd_dma); 153 cpu_to_le64(trans_pcie->rxq->used_bd_dma);
153 ctxt_info_gen3->mtr_size = 154 ctxt_info_gen3->mtr_size =
154 cpu_to_le16(TFD_QUEUE_CB_SIZE(TFD_CMD_SLOTS)); 155 cpu_to_le16(TFD_QUEUE_CB_SIZE(cmdq_size));
155 ctxt_info_gen3->mcr_size = 156 ctxt_info_gen3->mcr_size =
156 cpu_to_le16(RX_QUEUE_CB_SIZE(MQ_RX_TABLE_SIZE)); 157 cpu_to_le16(RX_QUEUE_CB_SIZE(MQ_RX_TABLE_SIZE));
157 158
@@ -175,8 +176,13 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
175 iwl_write64(trans, CSR_IML_DATA_ADDR, 176 iwl_write64(trans, CSR_IML_DATA_ADDR,
176 trans_pcie->iml_dma_addr); 177 trans_pcie->iml_dma_addr);
177 iwl_write32(trans, CSR_IML_SIZE_ADDR, trans->iml_len); 178 iwl_write32(trans, CSR_IML_SIZE_ADDR, trans->iml_len);
178 iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL, CSR_AUTO_FUNC_BOOT_ENA); 179
179 iwl_set_bit(trans, CSR_GP_CNTRL, CSR_AUTO_FUNC_INIT); 180 iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL,
181 CSR_AUTO_FUNC_BOOT_ENA);
182 if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
183 iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1);
184 else
185 iwl_set_bit(trans, CSR_GP_CNTRL, CSR_AUTO_FUNC_INIT);
180 186
181 return 0; 187 return 0;
182} 188}
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c
index 7f4aaa810ea1..9274e317cc77 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c
@@ -59,8 +59,7 @@
59 59
60void iwl_pcie_ctxt_info_free_paging(struct iwl_trans *trans) 60void iwl_pcie_ctxt_info_free_paging(struct iwl_trans *trans)
61{ 61{
62 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 62 struct iwl_self_init_dram *dram = &trans->init_dram;
63 struct iwl_self_init_dram *dram = &trans_pcie->init_dram;
64 int i; 63 int i;
65 64
66 if (!dram->paging) { 65 if (!dram->paging) {
@@ -83,8 +82,7 @@ int iwl_pcie_init_fw_sec(struct iwl_trans *trans,
83 const struct fw_img *fw, 82 const struct fw_img *fw,
84 struct iwl_context_info_dram *ctxt_dram) 83 struct iwl_context_info_dram *ctxt_dram)
85{ 84{
86 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 85 struct iwl_self_init_dram *dram = &trans->init_dram;
87 struct iwl_self_init_dram *dram = &trans_pcie->init_dram;
88 int i, ret, lmac_cnt, umac_cnt, paging_cnt; 86 int i, ret, lmac_cnt, umac_cnt, paging_cnt;
89 87
90 if (WARN(dram->paging, 88 if (WARN(dram->paging,
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index a22e47639a4e..2b94e4cef56c 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -8,7 +8,7 @@
8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016-2017 Intel Deutschland GmbH 10 * Copyright(c) 2016-2017 Intel Deutschland GmbH
11 * Copyright(c) 2018 Intel Corporation 11 * Copyright(c) 2018 - 2019 Intel Corporation
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of version 2 of the GNU General Public License as 14 * it under the terms of version 2 of the GNU General Public License as
@@ -32,7 +32,7 @@
32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
33 * All rights reserved. 33 * All rights reserved.
34 * Copyright(c) 2017 Intel Deutschland GmbH 34 * Copyright(c) 2017 Intel Deutschland GmbH
35 * Copyright(c) 2018 Intel Corporation 35 * Copyright(c) 2018 - 2019 Intel Corporation
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions 38 * modification, are permitted provided that the following conditions
@@ -517,6 +517,8 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
517 {IWL_PCI_DEVICE(0x02F0, 0x0034, iwl9560_2ac_cfg_soc)}, 517 {IWL_PCI_DEVICE(0x02F0, 0x0034, iwl9560_2ac_cfg_soc)},
518 {IWL_PCI_DEVICE(0x02F0, 0x0038, iwl9560_2ac_160_cfg_soc)}, 518 {IWL_PCI_DEVICE(0x02F0, 0x0038, iwl9560_2ac_160_cfg_soc)},
519 {IWL_PCI_DEVICE(0x02F0, 0x003C, iwl9560_2ac_160_cfg_soc)}, 519 {IWL_PCI_DEVICE(0x02F0, 0x003C, iwl9560_2ac_160_cfg_soc)},
520 {IWL_PCI_DEVICE(0x02F0, 0x0040, iwl_ax101_cfg_qu_hr)},
521 {IWL_PCI_DEVICE(0x02F0, 0x0044, iwl_ax101_cfg_qu_hr)},
520 {IWL_PCI_DEVICE(0x02F0, 0x0060, iwl9461_2ac_cfg_soc)}, 522 {IWL_PCI_DEVICE(0x02F0, 0x0060, iwl9461_2ac_cfg_soc)},
521 {IWL_PCI_DEVICE(0x02F0, 0x0064, iwl9461_2ac_cfg_soc)}, 523 {IWL_PCI_DEVICE(0x02F0, 0x0064, iwl9461_2ac_cfg_soc)},
522 {IWL_PCI_DEVICE(0x02F0, 0x00A0, iwl9462_2ac_cfg_soc)}, 524 {IWL_PCI_DEVICE(0x02F0, 0x00A0, iwl9462_2ac_cfg_soc)},
@@ -525,6 +527,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
525 {IWL_PCI_DEVICE(0x02F0, 0x0234, iwl9560_2ac_cfg_soc)}, 527 {IWL_PCI_DEVICE(0x02F0, 0x0234, iwl9560_2ac_cfg_soc)},
526 {IWL_PCI_DEVICE(0x02F0, 0x0238, iwl9560_2ac_cfg_soc)}, 528 {IWL_PCI_DEVICE(0x02F0, 0x0238, iwl9560_2ac_cfg_soc)},
527 {IWL_PCI_DEVICE(0x02F0, 0x023C, iwl9560_2ac_cfg_soc)}, 529 {IWL_PCI_DEVICE(0x02F0, 0x023C, iwl9560_2ac_cfg_soc)},
530 {IWL_PCI_DEVICE(0x02F0, 0x0244, iwl_ax101_cfg_qu_hr)},
528 {IWL_PCI_DEVICE(0x02F0, 0x0260, iwl9461_2ac_cfg_soc)}, 531 {IWL_PCI_DEVICE(0x02F0, 0x0260, iwl9461_2ac_cfg_soc)},
529 {IWL_PCI_DEVICE(0x02F0, 0x0264, iwl9461_2ac_cfg_soc)}, 532 {IWL_PCI_DEVICE(0x02F0, 0x0264, iwl9461_2ac_cfg_soc)},
530 {IWL_PCI_DEVICE(0x02F0, 0x02A0, iwl9462_2ac_cfg_soc)}, 533 {IWL_PCI_DEVICE(0x02F0, 0x02A0, iwl9462_2ac_cfg_soc)},
@@ -542,6 +545,8 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
542 {IWL_PCI_DEVICE(0x06F0, 0x0034, iwl9560_2ac_cfg_soc)}, 545 {IWL_PCI_DEVICE(0x06F0, 0x0034, iwl9560_2ac_cfg_soc)},
543 {IWL_PCI_DEVICE(0x06F0, 0x0038, iwl9560_2ac_160_cfg_soc)}, 546 {IWL_PCI_DEVICE(0x06F0, 0x0038, iwl9560_2ac_160_cfg_soc)},
544 {IWL_PCI_DEVICE(0x06F0, 0x003C, iwl9560_2ac_160_cfg_soc)}, 547 {IWL_PCI_DEVICE(0x06F0, 0x003C, iwl9560_2ac_160_cfg_soc)},
548 {IWL_PCI_DEVICE(0x06F0, 0x0040, iwl_ax101_cfg_qu_hr)},
549 {IWL_PCI_DEVICE(0x06F0, 0x0044, iwl_ax101_cfg_qu_hr)},
545 {IWL_PCI_DEVICE(0x06F0, 0x0060, iwl9461_2ac_cfg_soc)}, 550 {IWL_PCI_DEVICE(0x06F0, 0x0060, iwl9461_2ac_cfg_soc)},
546 {IWL_PCI_DEVICE(0x06F0, 0x0064, iwl9461_2ac_cfg_soc)}, 551 {IWL_PCI_DEVICE(0x06F0, 0x0064, iwl9461_2ac_cfg_soc)},
547 {IWL_PCI_DEVICE(0x06F0, 0x00A0, iwl9462_2ac_cfg_soc)}, 552 {IWL_PCI_DEVICE(0x06F0, 0x00A0, iwl9462_2ac_cfg_soc)},
@@ -550,6 +555,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
550 {IWL_PCI_DEVICE(0x06F0, 0x0234, iwl9560_2ac_cfg_soc)}, 555 {IWL_PCI_DEVICE(0x06F0, 0x0234, iwl9560_2ac_cfg_soc)},
551 {IWL_PCI_DEVICE(0x06F0, 0x0238, iwl9560_2ac_cfg_soc)}, 556 {IWL_PCI_DEVICE(0x06F0, 0x0238, iwl9560_2ac_cfg_soc)},
552 {IWL_PCI_DEVICE(0x06F0, 0x023C, iwl9560_2ac_cfg_soc)}, 557 {IWL_PCI_DEVICE(0x06F0, 0x023C, iwl9560_2ac_cfg_soc)},
558 {IWL_PCI_DEVICE(0x06F0, 0x0244, iwl_ax101_cfg_qu_hr)},
553 {IWL_PCI_DEVICE(0x06F0, 0x0260, iwl9461_2ac_cfg_soc)}, 559 {IWL_PCI_DEVICE(0x06F0, 0x0260, iwl9461_2ac_cfg_soc)},
554 {IWL_PCI_DEVICE(0x06F0, 0x0264, iwl9461_2ac_cfg_soc)}, 560 {IWL_PCI_DEVICE(0x06F0, 0x0264, iwl9461_2ac_cfg_soc)},
555 {IWL_PCI_DEVICE(0x06F0, 0x02A0, iwl9462_2ac_cfg_soc)}, 561 {IWL_PCI_DEVICE(0x06F0, 0x02A0, iwl9462_2ac_cfg_soc)},
@@ -597,6 +603,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
597 {IWL_PCI_DEVICE(0x2526, 0x2030, iwl9560_2ac_160_cfg_soc)}, 603 {IWL_PCI_DEVICE(0x2526, 0x2030, iwl9560_2ac_160_cfg_soc)},
598 {IWL_PCI_DEVICE(0x2526, 0x2034, iwl9560_2ac_160_cfg_soc)}, 604 {IWL_PCI_DEVICE(0x2526, 0x2034, iwl9560_2ac_160_cfg_soc)},
599 {IWL_PCI_DEVICE(0x2526, 0x4010, iwl9260_2ac_160_cfg)}, 605 {IWL_PCI_DEVICE(0x2526, 0x4010, iwl9260_2ac_160_cfg)},
606 {IWL_PCI_DEVICE(0x2526, 0x4018, iwl9260_2ac_160_cfg)},
600 {IWL_PCI_DEVICE(0x2526, 0x401C, iwl9260_2ac_160_cfg)}, 607 {IWL_PCI_DEVICE(0x2526, 0x401C, iwl9260_2ac_160_cfg)},
601 {IWL_PCI_DEVICE(0x2526, 0x4030, iwl9560_2ac_160_cfg)}, 608 {IWL_PCI_DEVICE(0x2526, 0x4030, iwl9560_2ac_160_cfg)},
602 {IWL_PCI_DEVICE(0x2526, 0x4034, iwl9560_2ac_160_cfg_soc)}, 609 {IWL_PCI_DEVICE(0x2526, 0x4034, iwl9560_2ac_160_cfg_soc)},
@@ -614,6 +621,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
614 {IWL_PCI_DEVICE(0x2720, 0x0034, iwl9560_2ac_160_cfg)}, 621 {IWL_PCI_DEVICE(0x2720, 0x0034, iwl9560_2ac_160_cfg)},
615 {IWL_PCI_DEVICE(0x2720, 0x0038, iwl9560_2ac_160_cfg)}, 622 {IWL_PCI_DEVICE(0x2720, 0x0038, iwl9560_2ac_160_cfg)},
616 {IWL_PCI_DEVICE(0x2720, 0x003C, iwl9560_2ac_160_cfg)}, 623 {IWL_PCI_DEVICE(0x2720, 0x003C, iwl9560_2ac_160_cfg)},
624 {IWL_PCI_DEVICE(0x2720, 0x0044, iwl_ax101_cfg_qu_hr)},
617 {IWL_PCI_DEVICE(0x2720, 0x0060, iwl9461_2ac_cfg_soc)}, 625 {IWL_PCI_DEVICE(0x2720, 0x0060, iwl9461_2ac_cfg_soc)},
618 {IWL_PCI_DEVICE(0x2720, 0x0064, iwl9461_2ac_cfg_soc)}, 626 {IWL_PCI_DEVICE(0x2720, 0x0064, iwl9461_2ac_cfg_soc)},
619 {IWL_PCI_DEVICE(0x2720, 0x00A0, iwl9462_2ac_cfg_soc)}, 627 {IWL_PCI_DEVICE(0x2720, 0x00A0, iwl9462_2ac_cfg_soc)},
@@ -622,6 +630,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
622 {IWL_PCI_DEVICE(0x2720, 0x0234, iwl9560_2ac_cfg)}, 630 {IWL_PCI_DEVICE(0x2720, 0x0234, iwl9560_2ac_cfg)},
623 {IWL_PCI_DEVICE(0x2720, 0x0238, iwl9560_2ac_cfg)}, 631 {IWL_PCI_DEVICE(0x2720, 0x0238, iwl9560_2ac_cfg)},
624 {IWL_PCI_DEVICE(0x2720, 0x023C, iwl9560_2ac_cfg)}, 632 {IWL_PCI_DEVICE(0x2720, 0x023C, iwl9560_2ac_cfg)},
633 {IWL_PCI_DEVICE(0x2720, 0x0244, iwl_ax101_cfg_qu_hr)},
625 {IWL_PCI_DEVICE(0x2720, 0x0260, iwl9461_2ac_cfg_soc)}, 634 {IWL_PCI_DEVICE(0x2720, 0x0260, iwl9461_2ac_cfg_soc)},
626 {IWL_PCI_DEVICE(0x2720, 0x0264, iwl9461_2ac_cfg_soc)}, 635 {IWL_PCI_DEVICE(0x2720, 0x0264, iwl9461_2ac_cfg_soc)},
627 {IWL_PCI_DEVICE(0x2720, 0x02A0, iwl9462_2ac_cfg_soc)}, 636 {IWL_PCI_DEVICE(0x2720, 0x02A0, iwl9462_2ac_cfg_soc)},
@@ -699,6 +708,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
699 {IWL_PCI_DEVICE(0x34F0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, 708 {IWL_PCI_DEVICE(0x34F0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)},
700 {IWL_PCI_DEVICE(0x34F0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, 709 {IWL_PCI_DEVICE(0x34F0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
701 {IWL_PCI_DEVICE(0x34F0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, 710 {IWL_PCI_DEVICE(0x34F0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)},
711 {IWL_PCI_DEVICE(0x34F0, 0x0044, iwl_ax101_cfg_qu_hr)},
702 {IWL_PCI_DEVICE(0x34F0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, 712 {IWL_PCI_DEVICE(0x34F0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)},
703 {IWL_PCI_DEVICE(0x34F0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, 713 {IWL_PCI_DEVICE(0x34F0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)},
704 {IWL_PCI_DEVICE(0x34F0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, 714 {IWL_PCI_DEVICE(0x34F0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)},
@@ -707,6 +717,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
707 {IWL_PCI_DEVICE(0x34F0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, 717 {IWL_PCI_DEVICE(0x34F0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)},
708 {IWL_PCI_DEVICE(0x34F0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, 718 {IWL_PCI_DEVICE(0x34F0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)},
709 {IWL_PCI_DEVICE(0x34F0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, 719 {IWL_PCI_DEVICE(0x34F0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)},
720 {IWL_PCI_DEVICE(0x34F0, 0x0244, iwl_ax101_cfg_qu_hr)},
710 {IWL_PCI_DEVICE(0x34F0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, 721 {IWL_PCI_DEVICE(0x34F0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)},
711 {IWL_PCI_DEVICE(0x34F0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, 722 {IWL_PCI_DEVICE(0x34F0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)},
712 {IWL_PCI_DEVICE(0x34F0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, 723 {IWL_PCI_DEVICE(0x34F0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)},
@@ -753,6 +764,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
753 {IWL_PCI_DEVICE(0x43F0, 0x0034, iwl9560_2ac_cfg_soc)}, 764 {IWL_PCI_DEVICE(0x43F0, 0x0034, iwl9560_2ac_cfg_soc)},
754 {IWL_PCI_DEVICE(0x43F0, 0x0038, iwl9560_2ac_160_cfg_soc)}, 765 {IWL_PCI_DEVICE(0x43F0, 0x0038, iwl9560_2ac_160_cfg_soc)},
755 {IWL_PCI_DEVICE(0x43F0, 0x003C, iwl9560_2ac_160_cfg_soc)}, 766 {IWL_PCI_DEVICE(0x43F0, 0x003C, iwl9560_2ac_160_cfg_soc)},
767 {IWL_PCI_DEVICE(0x43F0, 0x0044, iwl_ax101_cfg_qu_hr)},
756 {IWL_PCI_DEVICE(0x43F0, 0x0060, iwl9461_2ac_cfg_soc)}, 768 {IWL_PCI_DEVICE(0x43F0, 0x0060, iwl9461_2ac_cfg_soc)},
757 {IWL_PCI_DEVICE(0x43F0, 0x0064, iwl9461_2ac_cfg_soc)}, 769 {IWL_PCI_DEVICE(0x43F0, 0x0064, iwl9461_2ac_cfg_soc)},
758 {IWL_PCI_DEVICE(0x43F0, 0x00A0, iwl9462_2ac_cfg_soc)}, 770 {IWL_PCI_DEVICE(0x43F0, 0x00A0, iwl9462_2ac_cfg_soc)},
@@ -761,6 +773,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
761 {IWL_PCI_DEVICE(0x43F0, 0x0234, iwl9560_2ac_cfg_soc)}, 773 {IWL_PCI_DEVICE(0x43F0, 0x0234, iwl9560_2ac_cfg_soc)},
762 {IWL_PCI_DEVICE(0x43F0, 0x0238, iwl9560_2ac_cfg_soc)}, 774 {IWL_PCI_DEVICE(0x43F0, 0x0238, iwl9560_2ac_cfg_soc)},
763 {IWL_PCI_DEVICE(0x43F0, 0x023C, iwl9560_2ac_cfg_soc)}, 775 {IWL_PCI_DEVICE(0x43F0, 0x023C, iwl9560_2ac_cfg_soc)},
776 {IWL_PCI_DEVICE(0x43F0, 0x0244, iwl_ax101_cfg_qu_hr)},
764 {IWL_PCI_DEVICE(0x43F0, 0x0260, iwl9461_2ac_cfg_soc)}, 777 {IWL_PCI_DEVICE(0x43F0, 0x0260, iwl9461_2ac_cfg_soc)},
765 {IWL_PCI_DEVICE(0x43F0, 0x0264, iwl9461_2ac_cfg_soc)}, 778 {IWL_PCI_DEVICE(0x43F0, 0x0264, iwl9461_2ac_cfg_soc)},
766 {IWL_PCI_DEVICE(0x43F0, 0x02A0, iwl9462_2ac_cfg_soc)}, 779 {IWL_PCI_DEVICE(0x43F0, 0x02A0, iwl9462_2ac_cfg_soc)},
@@ -820,6 +833,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
820 {IWL_PCI_DEVICE(0xA0F0, 0x0034, iwl9560_2ac_cfg_soc)}, 833 {IWL_PCI_DEVICE(0xA0F0, 0x0034, iwl9560_2ac_cfg_soc)},
821 {IWL_PCI_DEVICE(0xA0F0, 0x0038, iwl9560_2ac_160_cfg_soc)}, 834 {IWL_PCI_DEVICE(0xA0F0, 0x0038, iwl9560_2ac_160_cfg_soc)},
822 {IWL_PCI_DEVICE(0xA0F0, 0x003C, iwl9560_2ac_160_cfg_soc)}, 835 {IWL_PCI_DEVICE(0xA0F0, 0x003C, iwl9560_2ac_160_cfg_soc)},
836 {IWL_PCI_DEVICE(0xA0F0, 0x0044, iwl_ax101_cfg_qu_hr)},
823 {IWL_PCI_DEVICE(0xA0F0, 0x0060, iwl9461_2ac_cfg_soc)}, 837 {IWL_PCI_DEVICE(0xA0F0, 0x0060, iwl9461_2ac_cfg_soc)},
824 {IWL_PCI_DEVICE(0xA0F0, 0x0064, iwl9461_2ac_cfg_soc)}, 838 {IWL_PCI_DEVICE(0xA0F0, 0x0064, iwl9461_2ac_cfg_soc)},
825 {IWL_PCI_DEVICE(0xA0F0, 0x00A0, iwl9462_2ac_cfg_soc)}, 839 {IWL_PCI_DEVICE(0xA0F0, 0x00A0, iwl9462_2ac_cfg_soc)},
@@ -828,6 +842,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
828 {IWL_PCI_DEVICE(0xA0F0, 0x0234, iwl9560_2ac_cfg_soc)}, 842 {IWL_PCI_DEVICE(0xA0F0, 0x0234, iwl9560_2ac_cfg_soc)},
829 {IWL_PCI_DEVICE(0xA0F0, 0x0238, iwl9560_2ac_cfg_soc)}, 843 {IWL_PCI_DEVICE(0xA0F0, 0x0238, iwl9560_2ac_cfg_soc)},
830 {IWL_PCI_DEVICE(0xA0F0, 0x023C, iwl9560_2ac_cfg_soc)}, 844 {IWL_PCI_DEVICE(0xA0F0, 0x023C, iwl9560_2ac_cfg_soc)},
845 {IWL_PCI_DEVICE(0xA0F0, 0x0244, iwl_ax101_cfg_qu_hr)},
831 {IWL_PCI_DEVICE(0xA0F0, 0x0260, iwl9461_2ac_cfg_soc)}, 846 {IWL_PCI_DEVICE(0xA0F0, 0x0260, iwl9461_2ac_cfg_soc)},
832 {IWL_PCI_DEVICE(0xA0F0, 0x0264, iwl9461_2ac_cfg_soc)}, 847 {IWL_PCI_DEVICE(0xA0F0, 0x0264, iwl9461_2ac_cfg_soc)},
833 {IWL_PCI_DEVICE(0xA0F0, 0x02A0, iwl9462_2ac_cfg_soc)}, 848 {IWL_PCI_DEVICE(0xA0F0, 0x02A0, iwl9462_2ac_cfg_soc)},
@@ -872,82 +887,92 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
872 {IWL_PCI_DEVICE(0xA370, 0x40A4, iwl9462_2ac_cfg_soc)}, 887 {IWL_PCI_DEVICE(0xA370, 0x40A4, iwl9462_2ac_cfg_soc)},
873 {IWL_PCI_DEVICE(0xA370, 0x4234, iwl9560_2ac_cfg_soc)}, 888 {IWL_PCI_DEVICE(0xA370, 0x4234, iwl9560_2ac_cfg_soc)},
874 {IWL_PCI_DEVICE(0xA370, 0x42A4, iwl9462_2ac_cfg_soc)}, 889 {IWL_PCI_DEVICE(0xA370, 0x42A4, iwl9462_2ac_cfg_soc)},
890 {IWL_PCI_DEVICE(0x2720, 0x0030, iwl9560_2ac_cfg_qnj_jf_b0)},
875 891
876/* 22000 Series */ 892/* 22000 Series */
877 {IWL_PCI_DEVICE(0x02F0, 0x0070, iwl22560_2ax_cfg_hr)}, 893 {IWL_PCI_DEVICE(0x02F0, 0x0070, iwl_ax101_cfg_qu_hr)},
878 {IWL_PCI_DEVICE(0x02F0, 0x0074, iwl22560_2ax_cfg_hr)}, 894 {IWL_PCI_DEVICE(0x02F0, 0x0074, iwl_ax101_cfg_qu_hr)},
879 {IWL_PCI_DEVICE(0x02F0, 0x0078, iwl22560_2ax_cfg_hr)}, 895 {IWL_PCI_DEVICE(0x02F0, 0x0078, iwl_ax101_cfg_qu_hr)},
880 {IWL_PCI_DEVICE(0x02F0, 0x007C, iwl22560_2ax_cfg_hr)}, 896 {IWL_PCI_DEVICE(0x02F0, 0x007C, iwl_ax101_cfg_qu_hr)},
881 {IWL_PCI_DEVICE(0x02F0, 0x0310, iwl22560_2ax_cfg_hr)}, 897 {IWL_PCI_DEVICE(0x02F0, 0x0310, iwl_ax101_cfg_qu_hr)},
882 {IWL_PCI_DEVICE(0x02F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, 898 {IWL_PCI_DEVICE(0x02F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)},
883 {IWL_PCI_DEVICE(0x02F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, 899 {IWL_PCI_DEVICE(0x02F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)},
884 {IWL_PCI_DEVICE(0x02F0, 0x4070, iwl22560_2ax_cfg_hr)}, 900 {IWL_PCI_DEVICE(0x02F0, 0x4070, iwl_ax101_cfg_qu_hr)},
885 {IWL_PCI_DEVICE(0x06F0, 0x0070, iwl22560_2ax_cfg_hr)}, 901 {IWL_PCI_DEVICE(0x06F0, 0x0070, iwl_ax101_cfg_qu_hr)},
886 {IWL_PCI_DEVICE(0x06F0, 0x0074, iwl22560_2ax_cfg_hr)}, 902 {IWL_PCI_DEVICE(0x06F0, 0x0074, iwl_ax101_cfg_qu_hr)},
887 {IWL_PCI_DEVICE(0x06F0, 0x0078, iwl22560_2ax_cfg_hr)}, 903 {IWL_PCI_DEVICE(0x06F0, 0x0078, iwl_ax101_cfg_qu_hr)},
888 {IWL_PCI_DEVICE(0x06F0, 0x007C, iwl22560_2ax_cfg_hr)}, 904 {IWL_PCI_DEVICE(0x06F0, 0x007C, iwl_ax101_cfg_qu_hr)},
889 {IWL_PCI_DEVICE(0x06F0, 0x0310, iwl22560_2ax_cfg_hr)}, 905 {IWL_PCI_DEVICE(0x06F0, 0x0310, iwl_ax101_cfg_qu_hr)},
890 {IWL_PCI_DEVICE(0x06F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, 906 {IWL_PCI_DEVICE(0x06F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)},
891 {IWL_PCI_DEVICE(0x06F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, 907 {IWL_PCI_DEVICE(0x06F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)},
892 {IWL_PCI_DEVICE(0x06F0, 0x4070, iwl22560_2ax_cfg_hr)}, 908 {IWL_PCI_DEVICE(0x06F0, 0x4070, iwl_ax101_cfg_qu_hr)},
893 {IWL_PCI_DEVICE(0x2720, 0x0000, iwl22560_2ax_cfg_hr)}, 909 {IWL_PCI_DEVICE(0x2720, 0x0000, iwl_ax101_cfg_qu_hr)},
894 {IWL_PCI_DEVICE(0x2720, 0x0030, iwl9560_2ac_160_cfg_soc)}, 910 {IWL_PCI_DEVICE(0x2720, 0x0040, iwl_ax101_cfg_qu_hr)},
895 {IWL_PCI_DEVICE(0x2720, 0x0040, iwl22560_2ax_cfg_hr)},
896 {IWL_PCI_DEVICE(0x2720, 0x0070, iwl22000_2ac_cfg_hr_cdb)}, 911 {IWL_PCI_DEVICE(0x2720, 0x0070, iwl22000_2ac_cfg_hr_cdb)},
897 {IWL_PCI_DEVICE(0x2720, 0x0074, iwl22560_2ax_cfg_hr)}, 912 {IWL_PCI_DEVICE(0x2720, 0x0074, iwl_ax101_cfg_qu_hr)},
898 {IWL_PCI_DEVICE(0x2720, 0x0078, iwl22560_2ax_cfg_hr)}, 913 {IWL_PCI_DEVICE(0x2720, 0x0078, iwl_ax101_cfg_qu_hr)},
899 {IWL_PCI_DEVICE(0x2720, 0x007C, iwl22560_2ax_cfg_hr)}, 914 {IWL_PCI_DEVICE(0x2720, 0x007C, iwl_ax101_cfg_qu_hr)},
900 {IWL_PCI_DEVICE(0x2720, 0x0090, iwl22000_2ac_cfg_hr_cdb)}, 915 {IWL_PCI_DEVICE(0x2720, 0x0090, iwl22000_2ac_cfg_hr_cdb)},
901 {IWL_PCI_DEVICE(0x2720, 0x0310, iwl22000_2ac_cfg_hr_cdb)}, 916 {IWL_PCI_DEVICE(0x2720, 0x0310, iwl22000_2ac_cfg_hr_cdb)},
902 {IWL_PCI_DEVICE(0x2720, 0x0A10, iwl22000_2ac_cfg_hr_cdb)}, 917 {IWL_PCI_DEVICE(0x2720, 0x0A10, iwl22000_2ac_cfg_hr_cdb)},
903 {IWL_PCI_DEVICE(0x2720, 0x1080, iwl22560_2ax_cfg_hr)}, 918 {IWL_PCI_DEVICE(0x2720, 0x1080, iwl_ax101_cfg_qu_hr)},
904 {IWL_PCI_DEVICE(0x2720, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, 919 {IWL_PCI_DEVICE(0x2720, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)},
905 {IWL_PCI_DEVICE(0x2720, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, 920 {IWL_PCI_DEVICE(0x2720, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)},
906 {IWL_PCI_DEVICE(0x2720, 0x4070, iwl22560_2ax_cfg_hr)}, 921 {IWL_PCI_DEVICE(0x2720, 0x4070, iwl_ax101_cfg_qu_hr)},
907 {IWL_PCI_DEVICE(0x34F0, 0x0040, iwl22560_2ax_cfg_hr)}, 922 {IWL_PCI_DEVICE(0x34F0, 0x0040, iwl_ax101_cfg_qu_hr)},
908 {IWL_PCI_DEVICE(0x34F0, 0x0070, iwl22560_2ax_cfg_hr)}, 923 {IWL_PCI_DEVICE(0x34F0, 0x0070, iwl_ax101_cfg_qu_hr)},
909 {IWL_PCI_DEVICE(0x34F0, 0x0074, iwl22560_2ax_cfg_hr)}, 924 {IWL_PCI_DEVICE(0x34F0, 0x0074, iwl_ax101_cfg_qu_hr)},
910 {IWL_PCI_DEVICE(0x34F0, 0x0078, iwl22560_2ax_cfg_hr)}, 925 {IWL_PCI_DEVICE(0x34F0, 0x0078, iwl_ax101_cfg_qu_hr)},
911 {IWL_PCI_DEVICE(0x34F0, 0x007C, iwl22560_2ax_cfg_hr)}, 926 {IWL_PCI_DEVICE(0x34F0, 0x007C, iwl_ax101_cfg_qu_hr)},
912 {IWL_PCI_DEVICE(0x34F0, 0x0310, iwl22560_2ax_cfg_hr)}, 927 {IWL_PCI_DEVICE(0x34F0, 0x0310, iwl_ax101_cfg_qu_hr)},
913 {IWL_PCI_DEVICE(0x34F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, 928 {IWL_PCI_DEVICE(0x34F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)},
914 {IWL_PCI_DEVICE(0x34F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, 929 {IWL_PCI_DEVICE(0x34F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)},
915 {IWL_PCI_DEVICE(0x34F0, 0x4070, iwl22560_2ax_cfg_hr)}, 930 {IWL_PCI_DEVICE(0x34F0, 0x4070, iwl_ax101_cfg_qu_hr)},
916 {IWL_PCI_DEVICE(0x40C0, 0x0000, iwl22560_2ax_cfg_su_cdb)}, 931 {IWL_PCI_DEVICE(0x40C0, 0x0000, iwl22560_2ax_cfg_su_cdb)},
917 {IWL_PCI_DEVICE(0x40C0, 0x0010, iwl22560_2ax_cfg_su_cdb)}, 932 {IWL_PCI_DEVICE(0x40C0, 0x0010, iwl22560_2ax_cfg_su_cdb)},
918 {IWL_PCI_DEVICE(0x40c0, 0x0090, iwl22560_2ax_cfg_su_cdb)}, 933 {IWL_PCI_DEVICE(0x40c0, 0x0090, iwl22560_2ax_cfg_su_cdb)},
919 {IWL_PCI_DEVICE(0x40C0, 0x0310, iwl22560_2ax_cfg_su_cdb)}, 934 {IWL_PCI_DEVICE(0x40C0, 0x0310, iwl22560_2ax_cfg_su_cdb)},
920 {IWL_PCI_DEVICE(0x40C0, 0x0A10, iwl22560_2ax_cfg_su_cdb)}, 935 {IWL_PCI_DEVICE(0x40C0, 0x0A10, iwl22560_2ax_cfg_su_cdb)},
921 {IWL_PCI_DEVICE(0x43F0, 0x0040, iwl22560_2ax_cfg_hr)}, 936 {IWL_PCI_DEVICE(0x43F0, 0x0040, iwl_ax101_cfg_qu_hr)},
922 {IWL_PCI_DEVICE(0x43F0, 0x0070, iwl22560_2ax_cfg_hr)}, 937 {IWL_PCI_DEVICE(0x43F0, 0x0070, iwl_ax101_cfg_qu_hr)},
923 {IWL_PCI_DEVICE(0x43F0, 0x0074, iwl22560_2ax_cfg_hr)}, 938 {IWL_PCI_DEVICE(0x43F0, 0x0074, iwl_ax101_cfg_qu_hr)},
924 {IWL_PCI_DEVICE(0x43F0, 0x0078, iwl22560_2ax_cfg_hr)}, 939 {IWL_PCI_DEVICE(0x43F0, 0x0078, iwl_ax101_cfg_qu_hr)},
925 {IWL_PCI_DEVICE(0x43F0, 0x007C, iwl22560_2ax_cfg_hr)}, 940 {IWL_PCI_DEVICE(0x43F0, 0x007C, iwl_ax101_cfg_qu_hr)},
926 {IWL_PCI_DEVICE(0x43F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, 941 {IWL_PCI_DEVICE(0x43F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)},
927 {IWL_PCI_DEVICE(0x43F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, 942 {IWL_PCI_DEVICE(0x43F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)},
928 {IWL_PCI_DEVICE(0x43F0, 0x4070, iwl22560_2ax_cfg_hr)}, 943 {IWL_PCI_DEVICE(0x43F0, 0x4070, iwl_ax101_cfg_qu_hr)},
929 {IWL_PCI_DEVICE(0xA0F0, 0x0000, iwl22560_2ax_cfg_hr)}, 944 {IWL_PCI_DEVICE(0xA0F0, 0x0000, iwl_ax101_cfg_qu_hr)},
930 {IWL_PCI_DEVICE(0xA0F0, 0x0040, iwl22560_2ax_cfg_hr)}, 945 {IWL_PCI_DEVICE(0xA0F0, 0x0040, iwl_ax101_cfg_qu_hr)},
931 {IWL_PCI_DEVICE(0xA0F0, 0x0070, iwl22560_2ax_cfg_hr)}, 946 {IWL_PCI_DEVICE(0xA0F0, 0x0070, iwl_ax101_cfg_qu_hr)},
932 {IWL_PCI_DEVICE(0xA0F0, 0x0074, iwl22560_2ax_cfg_hr)}, 947 {IWL_PCI_DEVICE(0xA0F0, 0x0074, iwl_ax101_cfg_qu_hr)},
933 {IWL_PCI_DEVICE(0xA0F0, 0x0078, iwl22560_2ax_cfg_hr)}, 948 {IWL_PCI_DEVICE(0xA0F0, 0x0078, iwl_ax101_cfg_qu_hr)},
934 {IWL_PCI_DEVICE(0xA0F0, 0x007C, iwl22560_2ax_cfg_hr)}, 949 {IWL_PCI_DEVICE(0xA0F0, 0x007C, iwl_ax101_cfg_qu_hr)},
935 {IWL_PCI_DEVICE(0xA0F0, 0x00B0, iwl22560_2ax_cfg_hr)}, 950 {IWL_PCI_DEVICE(0xA0F0, 0x00B0, iwl_ax101_cfg_qu_hr)},
936 {IWL_PCI_DEVICE(0xA0F0, 0x0A10, iwl22560_2ax_cfg_hr)}, 951 {IWL_PCI_DEVICE(0xA0F0, 0x0A10, iwl_ax101_cfg_qu_hr)},
937 {IWL_PCI_DEVICE(0xA0F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)}, 952 {IWL_PCI_DEVICE(0xA0F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0)},
938 {IWL_PCI_DEVICE(0xA0F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)}, 953 {IWL_PCI_DEVICE(0xA0F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0)},
939 {IWL_PCI_DEVICE(0xA0F0, 0x4070, iwl22560_2ax_cfg_hr)}, 954 {IWL_PCI_DEVICE(0xA0F0, 0x4070, iwl_ax101_cfg_qu_hr)},
940 955
941 {IWL_PCI_DEVICE(0x2723, 0x0080, iwl22260_2ax_cfg)}, 956 {IWL_PCI_DEVICE(0x2723, 0x0080, iwl22260_2ax_cfg)},
942 {IWL_PCI_DEVICE(0x2723, 0x0084, iwl22260_2ax_cfg)}, 957 {IWL_PCI_DEVICE(0x2723, 0x0084, iwl22260_2ax_cfg)},
943 {IWL_PCI_DEVICE(0x2723, 0x0088, iwl22260_2ax_cfg)}, 958 {IWL_PCI_DEVICE(0x2723, 0x0088, iwl22260_2ax_cfg)},
944 {IWL_PCI_DEVICE(0x2723, 0x008C, iwl22260_2ax_cfg)}, 959 {IWL_PCI_DEVICE(0x2723, 0x008C, iwl22260_2ax_cfg)},
960 {IWL_PCI_DEVICE(0x2723, 0x1653, killer1650w_2ax_cfg)},
961 {IWL_PCI_DEVICE(0x2723, 0x1654, killer1650x_2ax_cfg)},
945 {IWL_PCI_DEVICE(0x2723, 0x4080, iwl22260_2ax_cfg)}, 962 {IWL_PCI_DEVICE(0x2723, 0x4080, iwl22260_2ax_cfg)},
946 {IWL_PCI_DEVICE(0x2723, 0x4088, iwl22260_2ax_cfg)}, 963 {IWL_PCI_DEVICE(0x2723, 0x4088, iwl22260_2ax_cfg)},
947 964
948 {IWL_PCI_DEVICE(0x1a56, 0x1653, killer1650w_2ax_cfg)}, 965 {IWL_PCI_DEVICE(0x1a56, 0x1653, killer1650w_2ax_cfg)},
949 {IWL_PCI_DEVICE(0x1a56, 0x1654, killer1650x_2ax_cfg)}, 966 {IWL_PCI_DEVICE(0x1a56, 0x1654, killer1650x_2ax_cfg)},
950 967
968 {IWL_PCI_DEVICE(0x2725, 0x0090, iwlax210_2ax_cfg_so_hr_a0)},
969 {IWL_PCI_DEVICE(0x7A70, 0x0090, iwlax210_2ax_cfg_so_hr_a0)},
970 {IWL_PCI_DEVICE(0x7A70, 0x0310, iwlax210_2ax_cfg_so_hr_a0)},
971 {IWL_PCI_DEVICE(0x2725, 0x0020, iwlax210_2ax_cfg_so_hr_a0)},
972 {IWL_PCI_DEVICE(0x2725, 0x0310, iwlax210_2ax_cfg_so_hr_a0)},
973 {IWL_PCI_DEVICE(0x2725, 0x0A10, iwlax210_2ax_cfg_so_hr_a0)},
974 {IWL_PCI_DEVICE(0x2725, 0x00B0, iwlax210_2ax_cfg_so_hr_a0)},
975
951#endif /* CONFIG_IWLMVM */ 976#endif /* CONFIG_IWLMVM */
952 977
953 {0} 978 {0}
@@ -999,7 +1024,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
999 1024
1000 if (rf_id_chp == jf_chp_id) { 1025 if (rf_id_chp == jf_chp_id) {
1001 if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ) 1026 if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QNJ)
1002 cfg = &iwl22000_2ax_cfg_qnj_jf_b0; 1027 cfg = &iwl9560_2ac_cfg_qnj_jf_b0;
1003 else 1028 else
1004 cfg = &iwl22000_2ac_cfg_jf; 1029 cfg = &iwl22000_2ac_cfg_jf;
1005 } else if (rf_id_chp == hr_chp_id) { 1030 } else if (rf_id_chp == hr_chp_id) {
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index 0d16bcc3141f..bf8b61a476c5 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -8,7 +8,7 @@
8 * Copyright(c) 2003 - 2015 Intel Corporation. All rights reserved. 8 * Copyright(c) 2003 - 2015 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11 * Copyright(c) 2018 Intel Corporation 11 * Copyright(c) 2018 - 2019 Intel Corporation
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify it 13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of version 2 of the GNU General Public License as 14 * under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
31 * Copyright(c) 2003 - 2015 Intel Corporation. All rights reserved. 31 * Copyright(c) 2003 - 2015 Intel Corporation. All rights reserved.
32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
34 * Copyright(c) 2018 Intel Corporation 34 * Copyright(c) 2018 - 2019 Intel Corporation
35 * All rights reserved. 35 * All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -400,6 +400,8 @@ struct iwl_txq {
400 u32 id; 400 u32 id;
401 int low_mark; 401 int low_mark;
402 int high_mark; 402 int high_mark;
403
404 bool overflow_tx;
403}; 405};
404 406
405static inline dma_addr_t 407static inline dma_addr_t
@@ -454,20 +456,6 @@ enum iwl_image_response_code {
454}; 456};
455 457
456/** 458/**
457 * struct iwl_self_init_dram - dram data used by self init process
458 * @fw: lmac and umac dram data
459 * @fw_cnt: total number of items in array
460 * @paging: paging dram data
461 * @paging_cnt: total number of items in array
462 */
463struct iwl_self_init_dram {
464 struct iwl_dram_data *fw;
465 int fw_cnt;
466 struct iwl_dram_data *paging;
467 int paging_cnt;
468};
469
470/**
471 * struct cont_rec: continuous recording data structure 459 * struct cont_rec: continuous recording data structure
472 * @prev_wr_ptr: the last address that was read in monitor_data 460 * @prev_wr_ptr: the last address that was read in monitor_data
473 * debugfs file 461 * debugfs file
@@ -538,6 +526,8 @@ struct cont_rec {
538 * @fh_mask: current unmasked fh causes 526 * @fh_mask: current unmasked fh causes
539 * @hw_mask: current unmasked hw causes 527 * @hw_mask: current unmasked hw causes
540 * @in_rescan: true if we have triggered a device rescan 528 * @in_rescan: true if we have triggered a device rescan
529 * @base_rb_stts: base virtual address of receive buffer status for all queues
530 * @base_rb_stts_dma: base physical address of receive buffer status
541 */ 531 */
542struct iwl_trans_pcie { 532struct iwl_trans_pcie {
543 struct iwl_rxq *rxq; 533 struct iwl_rxq *rxq;
@@ -554,7 +544,6 @@ struct iwl_trans_pcie {
554 dma_addr_t prph_info_dma_addr; 544 dma_addr_t prph_info_dma_addr;
555 dma_addr_t prph_scratch_dma_addr; 545 dma_addr_t prph_scratch_dma_addr;
556 dma_addr_t iml_dma_addr; 546 dma_addr_t iml_dma_addr;
557 struct iwl_self_init_dram init_dram;
558 struct iwl_trans *trans; 547 struct iwl_trans *trans;
559 548
560 struct net_device napi_dev; 549 struct net_device napi_dev;
@@ -630,6 +619,9 @@ struct iwl_trans_pcie {
630 cpumask_t affinity_mask[IWL_MAX_RX_HW_QUEUES]; 619 cpumask_t affinity_mask[IWL_MAX_RX_HW_QUEUES];
631 u16 tx_cmd_queue_size; 620 u16 tx_cmd_queue_size;
632 bool in_rescan; 621 bool in_rescan;
622
623 void *base_rb_stts;
624 dma_addr_t base_rb_stts_dma;
633}; 625};
634 626
635static inline struct iwl_trans_pcie * 627static inline struct iwl_trans_pcie *
@@ -813,8 +805,7 @@ static inline int iwl_pcie_ctxt_info_alloc_dma(struct iwl_trans *trans,
813 805
814static inline void iwl_pcie_ctxt_info_free_fw_img(struct iwl_trans *trans) 806static inline void iwl_pcie_ctxt_info_free_fw_img(struct iwl_trans *trans)
815{ 807{
816 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 808 struct iwl_self_init_dram *dram = &trans->init_dram;
817 struct iwl_self_init_dram *dram = &trans_pcie->init_dram;
818 int i; 809 int i;
819 810
820 if (!dram->fw) { 811 if (!dram->fw) {
@@ -1052,6 +1043,7 @@ static inline bool iwl_pcie_dbg_on(struct iwl_trans *trans)
1052 1043
1053void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state); 1044void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state);
1054void iwl_trans_pcie_dump_regs(struct iwl_trans *trans); 1045void iwl_trans_pcie_dump_regs(struct iwl_trans *trans);
1046void iwl_trans_sync_nmi(struct iwl_trans *trans);
1055 1047
1056#ifdef CONFIG_IWLWIFI_DEBUGFS 1048#ifdef CONFIG_IWLWIFI_DEBUGFS
1057int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans); 1049int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index c260d1251b5f..8d4f0628622b 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -8,7 +8,7 @@
8 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11 * Copyright(c) 2018 Intel Corporation 11 * Copyright(c) 2018 - 2019 Intel Corporation
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify it 13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of version 2 of the GNU General Public License as 14 * under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
31 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. 31 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
34 * Copyright(c) 2018 Intel Corporation 34 * Copyright(c) 2018 - 2019 Intel Corporation
35 * All rights reserved. 35 * All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -202,9 +202,9 @@ int iwl_pcie_rx_stop(struct iwl_trans *trans)
202{ 202{
203 if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) { 203 if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
204 /* TODO: remove this for 22560 once fw does it */ 204 /* TODO: remove this for 22560 once fw does it */
205 iwl_write_prph(trans, RFH_RXF_DMA_CFG_GEN3, 0); 205 iwl_write_umac_prph(trans, RFH_RXF_DMA_CFG_GEN3, 0);
206 return iwl_poll_prph_bit(trans, RFH_GEN_STATUS_GEN3, 206 return iwl_poll_umac_prph_bit(trans, RFH_GEN_STATUS_GEN3,
207 RXF_DMA_IDLE, RXF_DMA_IDLE, 1000); 207 RXF_DMA_IDLE, RXF_DMA_IDLE, 1000);
208 } else if (trans->cfg->mq_rx_supported) { 208 } else if (trans->cfg->mq_rx_supported) {
209 iwl_write_prph(trans, RFH_RXF_DMA_CFG, 0); 209 iwl_write_prph(trans, RFH_RXF_DMA_CFG, 0);
210 return iwl_poll_prph_bit(trans, RFH_GEN_STATUS, 210 return iwl_poll_prph_bit(trans, RFH_GEN_STATUS,
@@ -247,7 +247,7 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans,
247 } 247 }
248 248
249 rxq->write_actual = round_down(rxq->write, 8); 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 iwl_write32(trans, HBUS_TARG_WRPTR, 251 iwl_write32(trans, HBUS_TARG_WRPTR,
252 (rxq->write_actual | 252 (rxq->write_actual |
253 ((FIRST_RX_QUEUE + rxq->id) << 16))); 253 ((FIRST_RX_QUEUE + rxq->id) << 16)));
@@ -538,9 +538,9 @@ static void iwl_pcie_rx_allocator(struct iwl_trans *trans)
538 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 538 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
539 struct iwl_rb_allocator *rba = &trans_pcie->rba; 539 struct iwl_rb_allocator *rba = &trans_pcie->rba;
540 struct list_head local_empty; 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 /* If we were scheduled - there is at least one request */ 545 /* If we were scheduled - there is at least one request */
546 spin_lock(&rba->lock); 546 spin_lock(&rba->lock);
@@ -593,12 +593,15 @@ static void iwl_pcie_rx_allocator(struct iwl_trans *trans)
593 i++; 593 i++;
594 } 594 }
595 595
596 atomic_dec(&rba->req_pending);
596 pending--; 597 pending--;
598
597 if (!pending) { 599 if (!pending) {
598 pending = atomic_xchg(&rba->req_pending, 0); 600 pending = atomic_read(&rba->req_pending);
599 IWL_DEBUG_RX(trans, 601 if (pending)
600 "Pending allocation requests = %d\n", 602 IWL_DEBUG_TPT(trans,
601 pending); 603 "Got more pending allocation requests = %d\n",
604 pending);
602 } 605 }
603 606
604 spin_lock(&rba->lock); 607 spin_lock(&rba->lock);
@@ -609,12 +612,15 @@ static void iwl_pcie_rx_allocator(struct iwl_trans *trans)
609 spin_unlock(&rba->lock); 612 spin_unlock(&rba->lock);
610 613
611 atomic_inc(&rba->req_ready); 614 atomic_inc(&rba->req_ready);
615
612 } 616 }
613 617
614 spin_lock(&rba->lock); 618 spin_lock(&rba->lock);
615 /* return unused rbds to the allocator empty list */ 619 /* return unused rbds to the allocator empty list */
616 list_splice_tail(&local_empty, &rba->rbd_empty); 620 list_splice_tail(&local_empty, &rba->rbd_empty);
617 spin_unlock(&rba->lock); 621 spin_unlock(&rba->lock);
622
623 IWL_DEBUG_TPT(trans, "%s, exit.\n", __func__);
618} 624}
619 625
620/* 626/*
@@ -696,11 +702,6 @@ static void iwl_pcie_free_rxq_dma(struct iwl_trans *trans,
696 rxq->bd_dma = 0; 702 rxq->bd_dma = 0;
697 rxq->bd = NULL; 703 rxq->bd = NULL;
698 704
699 if (rxq->rb_stts)
700 dma_free_coherent(trans->dev,
701 use_rx_td ? sizeof(__le16) :
702 sizeof(struct iwl_rb_status),
703 rxq->rb_stts, rxq->rb_stts_dma);
704 rxq->rb_stts_dma = 0; 705 rxq->rb_stts_dma = 0;
705 rxq->rb_stts = NULL; 706 rxq->rb_stts = NULL;
706 707
@@ -737,6 +738,8 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans,
737 int free_size; 738 int free_size;
738 bool use_rx_td = (trans->cfg->device_family >= 739 bool use_rx_td = (trans->cfg->device_family >=
739 IWL_DEVICE_FAMILY_22560); 740 IWL_DEVICE_FAMILY_22560);
741 size_t rb_stts_size = use_rx_td ? sizeof(__le16) :
742 sizeof(struct iwl_rb_status);
740 743
741 spin_lock_init(&rxq->lock); 744 spin_lock_init(&rxq->lock);
742 if (trans->cfg->mq_rx_supported) 745 if (trans->cfg->mq_rx_supported)
@@ -764,12 +767,9 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans,
764 goto err; 767 goto err;
765 } 768 }
766 769
767 /* Allocate the driver's pointer to receive buffer status */ 770 rxq->rb_stts = trans_pcie->base_rb_stts + rxq->id * rb_stts_size;
768 rxq->rb_stts = dma_alloc_coherent(dev, 771 rxq->rb_stts_dma =
769 use_rx_td ? sizeof(__le16) : sizeof(struct iwl_rb_status), 772 trans_pcie->base_rb_stts_dma + rxq->id * rb_stts_size;
770 &rxq->rb_stts_dma, GFP_KERNEL);
771 if (!rxq->rb_stts)
772 goto err;
773 773
774 if (!use_rx_td) 774 if (!use_rx_td)
775 return 0; 775 return 0;
@@ -799,7 +799,6 @@ err:
799 799
800 iwl_pcie_free_rxq_dma(trans, rxq); 800 iwl_pcie_free_rxq_dma(trans, rxq);
801 } 801 }
802 kfree(trans_pcie->rxq);
803 802
804 return -ENOMEM; 803 return -ENOMEM;
805} 804}
@@ -809,6 +808,9 @@ int iwl_pcie_rx_alloc(struct iwl_trans *trans)
809 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 808 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
810 struct iwl_rb_allocator *rba = &trans_pcie->rba; 809 struct iwl_rb_allocator *rba = &trans_pcie->rba;
811 int i, ret; 810 int i, ret;
811 size_t rb_stts_size = trans->cfg->device_family >=
812 IWL_DEVICE_FAMILY_22560 ?
813 sizeof(__le16) : sizeof(struct iwl_rb_status);
812 814
813 if (WARN_ON(trans_pcie->rxq)) 815 if (WARN_ON(trans_pcie->rxq))
814 return -EINVAL; 816 return -EINVAL;
@@ -816,18 +818,46 @@ int iwl_pcie_rx_alloc(struct iwl_trans *trans)
816 trans_pcie->rxq = kcalloc(trans->num_rx_queues, sizeof(struct iwl_rxq), 818 trans_pcie->rxq = kcalloc(trans->num_rx_queues, sizeof(struct iwl_rxq),
817 GFP_KERNEL); 819 GFP_KERNEL);
818 if (!trans_pcie->rxq) 820 if (!trans_pcie->rxq)
819 return -EINVAL; 821 return -ENOMEM;
820 822
821 spin_lock_init(&rba->lock); 823 spin_lock_init(&rba->lock);
822 824
825 /*
826 * Allocate the driver's pointer to receive buffer status.
827 * Allocate for all queues continuously (HW requirement).
828 */
829 trans_pcie->base_rb_stts =
830 dma_alloc_coherent(trans->dev,
831 rb_stts_size * trans->num_rx_queues,
832 &trans_pcie->base_rb_stts_dma,
833 GFP_KERNEL);
834 if (!trans_pcie->base_rb_stts) {
835 ret = -ENOMEM;
836 goto err;
837 }
838
823 for (i = 0; i < trans->num_rx_queues; i++) { 839 for (i = 0; i < trans->num_rx_queues; i++) {
824 struct iwl_rxq *rxq = &trans_pcie->rxq[i]; 840 struct iwl_rxq *rxq = &trans_pcie->rxq[i];
825 841
842 rxq->id = i;
826 ret = iwl_pcie_alloc_rxq_dma(trans, rxq); 843 ret = iwl_pcie_alloc_rxq_dma(trans, rxq);
827 if (ret) 844 if (ret)
828 return ret; 845 goto err;
829 } 846 }
830 return 0; 847 return 0;
848
849err:
850 if (trans_pcie->base_rb_stts) {
851 dma_free_coherent(trans->dev,
852 rb_stts_size * trans->num_rx_queues,
853 trans_pcie->base_rb_stts,
854 trans_pcie->base_rb_stts_dma);
855 trans_pcie->base_rb_stts = NULL;
856 trans_pcie->base_rb_stts_dma = 0;
857 }
858 kfree(trans_pcie->rxq);
859
860 return ret;
831} 861}
832 862
833static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq) 863static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq)
@@ -1036,8 +1066,6 @@ int _iwl_pcie_rx_init(struct iwl_trans *trans)
1036 for (i = 0; i < trans->num_rx_queues; i++) { 1066 for (i = 0; i < trans->num_rx_queues; i++) {
1037 struct iwl_rxq *rxq = &trans_pcie->rxq[i]; 1067 struct iwl_rxq *rxq = &trans_pcie->rxq[i];
1038 1068
1039 rxq->id = i;
1040
1041 spin_lock(&rxq->lock); 1069 spin_lock(&rxq->lock);
1042 /* 1070 /*
1043 * Set read write pointer to reflect that we have processed 1071 * Set read write pointer to reflect that we have processed
@@ -1124,6 +1152,9 @@ void iwl_pcie_rx_free(struct iwl_trans *trans)
1124 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1152 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1125 struct iwl_rb_allocator *rba = &trans_pcie->rba; 1153 struct iwl_rb_allocator *rba = &trans_pcie->rba;
1126 int i; 1154 int i;
1155 size_t rb_stts_size = trans->cfg->device_family >=
1156 IWL_DEVICE_FAMILY_22560 ?
1157 sizeof(__le16) : sizeof(struct iwl_rb_status);
1127 1158
1128 /* 1159 /*
1129 * if rxq is NULL, it means that nothing has been allocated, 1160 * if rxq is NULL, it means that nothing has been allocated,
@@ -1138,6 +1169,15 @@ void iwl_pcie_rx_free(struct iwl_trans *trans)
1138 1169
1139 iwl_pcie_free_rbs_pool(trans); 1170 iwl_pcie_free_rbs_pool(trans);
1140 1171
1172 if (trans_pcie->base_rb_stts) {
1173 dma_free_coherent(trans->dev,
1174 rb_stts_size * trans->num_rx_queues,
1175 trans_pcie->base_rb_stts,
1176 trans_pcie->base_rb_stts_dma);
1177 trans_pcie->base_rb_stts = NULL;
1178 trans_pcie->base_rb_stts_dma = 0;
1179 }
1180
1141 for (i = 0; i < trans->num_rx_queues; i++) { 1181 for (i = 0; i < trans->num_rx_queues; i++) {
1142 struct iwl_rxq *rxq = &trans_pcie->rxq[i]; 1182 struct iwl_rxq *rxq = &trans_pcie->rxq[i];
1143 1183
@@ -1424,6 +1464,9 @@ restart:
1424 !emergency)) { 1464 !emergency)) {
1425 iwl_pcie_rx_move_to_allocator(rxq, rba); 1465 iwl_pcie_rx_move_to_allocator(rxq, rba);
1426 emergency = true; 1466 emergency = true;
1467 IWL_DEBUG_TPT(trans,
1468 "RX path is in emergency. Pending allocations %d\n",
1469 rb_pending_alloc);
1427 } 1470 }
1428 1471
1429 IWL_DEBUG_RX(trans, "Q %d: HW = %d, SW = %d\n", rxq->id, r, i); 1472 IWL_DEBUG_RX(trans, "Q %d: HW = %d, SW = %d\n", rxq->id, r, i);
@@ -1453,8 +1496,12 @@ restart:
1453 count++; 1496 count++;
1454 if (count == 8) { 1497 if (count == 8) {
1455 count = 0; 1498 count = 0;
1456 if (rb_pending_alloc < rxq->queue_size / 3) 1499 if (rb_pending_alloc < rxq->queue_size / 3) {
1500 IWL_DEBUG_TPT(trans,
1501 "RX path exited emergency. Pending allocations %d\n",
1502 rb_pending_alloc);
1457 emergency = false; 1503 emergency = false;
1504 }
1458 1505
1459 rxq->read = i; 1506 rxq->read = i;
1460 spin_unlock(&rxq->lock); 1507 spin_unlock(&rxq->lock);
@@ -2120,7 +2167,7 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
2120 } 2167 }
2121 } 2168 }
2122 2169
2123 if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560 && 2170 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_22560 &&
2124 inta_hw & MSIX_HW_INT_CAUSES_REG_IPC) { 2171 inta_hw & MSIX_HW_INT_CAUSES_REG_IPC) {
2125 /* Reflect IML transfer status */ 2172 /* Reflect IML transfer status */
2126 int res = iwl_read32(trans, CSR_IML_RESP_ADDR); 2173 int res = iwl_read32(trans, CSR_IML_RESP_ADDR);
@@ -2139,6 +2186,17 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
2139 isr_stats->wakeup++; 2186 isr_stats->wakeup++;
2140 } 2187 }
2141 2188
2189 if (inta_hw & MSIX_HW_INT_CAUSES_REG_IML) {
2190 /* Reflect IML transfer status */
2191 int res = iwl_read32(trans, CSR_IML_RESP_ADDR);
2192
2193 IWL_DEBUG_ISR(trans, "IML transfer status: %d\n", res);
2194 if (res == IWL_IMAGE_RESP_FAIL) {
2195 isr_stats->sw++;
2196 iwl_pcie_irq_handle_error(trans);
2197 }
2198 }
2199
2142 /* Chip got too hot and stopped itself */ 2200 /* Chip got too hot and stopped itself */
2143 if (inta_hw & MSIX_HW_INT_CAUSES_REG_CT_KILL) { 2201 if (inta_hw & MSIX_HW_INT_CAUSES_REG_CT_KILL) {
2144 IWL_ERR(trans, "Microcode CT kill error detected.\n"); 2202 IWL_ERR(trans, "Microcode CT kill error detected.\n");
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
index 77f3610e5ca9..9c203ca75de9 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
@@ -92,26 +92,9 @@ int iwl_pcie_gen2_apm_init(struct iwl_trans *trans)
92 92
93 iwl_pcie_apm_config(trans); 93 iwl_pcie_apm_config(trans);
94 94
95 /* 95 ret = iwl_finish_nic_init(trans);
96 * Set "initialization complete" bit to move adapter from 96 if (ret)
97 * D0U* --> D0A* (powered-up active) state.
98 */
99 iwl_set_bit(trans, CSR_GP_CNTRL,
100 BIT(trans->cfg->csr->flag_init_done));
101
102 /*
103 * Wait for clock stabilization; once stabilized, access to
104 * device-internal resources is supported, e.g. iwl_write_prph()
105 * and accesses to uCode SRAM.
106 */
107 ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
108 BIT(trans->cfg->csr->flag_mac_clock_ready),
109 BIT(trans->cfg->csr->flag_mac_clock_ready),
110 25000);
111 if (ret < 0) {
112 IWL_DEBUG_INFO(trans, "Failed to init the card\n");
113 return ret; 97 return ret;
114 }
115 98
116 set_bit(STATUS_DEVICE_ENABLED, &trans->status); 99 set_bit(STATUS_DEVICE_ENABLED, &trans->status);
117 100
@@ -188,7 +171,7 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power)
188 } 171 }
189 172
190 iwl_pcie_ctxt_info_free_paging(trans); 173 iwl_pcie_ctxt_info_free_paging(trans);
191 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_22560) 174 if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
192 iwl_pcie_ctxt_info_gen3_free(trans); 175 iwl_pcie_ctxt_info_gen3_free(trans);
193 else 176 else
194 iwl_pcie_ctxt_info_free(trans); 177 iwl_pcie_ctxt_info_free(trans);
@@ -251,6 +234,7 @@ void iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power)
251static int iwl_pcie_gen2_nic_init(struct iwl_trans *trans) 234static int iwl_pcie_gen2_nic_init(struct iwl_trans *trans)
252{ 235{
253 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 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);
254 238
255 /* TODO: most of the logic can be removed in A0 - but not in Z0 */ 239 /* TODO: most of the logic can be removed in A0 - but not in Z0 */
256 spin_lock(&trans_pcie->irq_lock); 240 spin_lock(&trans_pcie->irq_lock);
@@ -264,7 +248,7 @@ static int iwl_pcie_gen2_nic_init(struct iwl_trans *trans)
264 return -ENOMEM; 248 return -ENOMEM;
265 249
266 /* Allocate or reset and init all Tx and Command queues */ 250 /* Allocate or reset and init all Tx and Command queues */
267 if (iwl_pcie_gen2_tx_init(trans, trans_pcie->cmd_queue, TFD_CMD_SLOTS)) 251 if (iwl_pcie_gen2_tx_init(trans, trans_pcie->cmd_queue, queue_size))
268 return -ENOMEM; 252 return -ENOMEM;
269 253
270 /* enable shadow regs in HW */ 254 /* enable shadow regs in HW */
@@ -349,7 +333,7 @@ int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans,
349 goto out; 333 goto out;
350 } 334 }
351 335
352 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_22560) 336 if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
353 ret = iwl_pcie_ctxt_info_gen3_init(trans, fw); 337 ret = iwl_pcie_ctxt_info_gen3_init(trans, fw);
354 else 338 else
355 ret = iwl_pcie_ctxt_info_init(trans, fw); 339 ret = iwl_pcie_ctxt_info_init(trans, fw);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index f74281508197..fe8269d023de 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -8,7 +8,7 @@
8 * Copyright(c) 2007 - 2015 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2015 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11 * Copyright(c) 2018 Intel Corporation 11 * Copyright(c) 2018 - 2019 Intel Corporation
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of version 2 of the GNU General Public License as 14 * it under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
31 * Copyright(c) 2005 - 2015 Intel Corporation. All rights reserved. 31 * Copyright(c) 2005 - 2015 Intel Corporation. All rights reserved.
32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
34 * Copyright(c) 2018 Intel Corporation 34 * Copyright(c) 2018 - 2019 Intel Corporation
35 * All rights reserved. 35 * All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -364,26 +364,9 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans)
364 if (trans->cfg->base_params->pll_cfg) 364 if (trans->cfg->base_params->pll_cfg)
365 iwl_set_bit(trans, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL); 365 iwl_set_bit(trans, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
366 366
367 /* 367 ret = iwl_finish_nic_init(trans);
368 * Set "initialization complete" bit to move adapter from 368 if (ret)
369 * D0U* --> D0A* (powered-up active) state.
370 */
371 iwl_set_bit(trans, CSR_GP_CNTRL,
372 BIT(trans->cfg->csr->flag_init_done));
373
374 /*
375 * Wait for clock stabilization; once stabilized, access to
376 * device-internal resources is supported, e.g. iwl_write_prph()
377 * and accesses to uCode SRAM.
378 */
379 ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
380 BIT(trans->cfg->csr->flag_mac_clock_ready),
381 BIT(trans->cfg->csr->flag_mac_clock_ready),
382 25000);
383 if (ret < 0) {
384 IWL_ERR(trans, "Failed to init the card\n");
385 return ret; 369 return ret;
386 }
387 370
388 if (trans->cfg->host_interrupt_operation_mode) { 371 if (trans->cfg->host_interrupt_operation_mode) {
389 /* 372 /*
@@ -453,23 +436,8 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans)
453 436
454 iwl_trans_pcie_sw_reset(trans); 437 iwl_trans_pcie_sw_reset(trans);
455 438
456 /* 439 ret = iwl_finish_nic_init(trans);
457 * Set "initialization complete" bit to move adapter from 440 if (WARN_ON(ret)) {
458 * D0U* --> D0A* (powered-up active) state.
459 */
460 iwl_set_bit(trans, CSR_GP_CNTRL,
461 BIT(trans->cfg->csr->flag_init_done));
462
463 /*
464 * Wait for clock stabilization; once stabilized, access to
465 * device-internal resources is possible.
466 */
467 ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
468 BIT(trans->cfg->csr->flag_mac_clock_ready),
469 BIT(trans->cfg->csr->flag_mac_clock_ready),
470 25000);
471 if (WARN_ON(ret < 0)) {
472 IWL_ERR(trans, "Access time out - failed to enable LP XTAL\n");
473 /* Release XTAL ON request */ 441 /* Release XTAL ON request */
474 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, 442 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
475 CSR_GP_CNTRL_REG_FLAG_XTAL_ON); 443 CSR_GP_CNTRL_REG_FLAG_XTAL_ON);
@@ -928,13 +896,13 @@ void iwl_pcie_apply_destination(struct iwl_trans *trans)
928 if (!trans->num_blocks) 896 if (!trans->num_blocks)
929 return; 897 return;
930 898
931 iwl_write_prph(trans, MON_BUFF_BASE_ADDR_VER2, 899 iwl_write_umac_prph(trans, MON_BUFF_BASE_ADDR_VER2,
932 trans->fw_mon[0].physical >> 900 trans->fw_mon[0].physical >>
933 MON_BUFF_SHIFT_VER2); 901 MON_BUFF_SHIFT_VER2);
934 iwl_write_prph(trans, MON_BUFF_END_ADDR_VER2, 902 iwl_write_umac_prph(trans, MON_BUFF_END_ADDR_VER2,
935 (trans->fw_mon[0].physical + 903 (trans->fw_mon[0].physical +
936 trans->fw_mon[0].size - 256) >> 904 trans->fw_mon[0].size - 256) >>
937 MON_BUFF_SHIFT_VER2); 905 MON_BUFF_SHIFT_VER2);
938 return; 906 return;
939 } 907 }
940 908
@@ -1126,6 +1094,7 @@ static struct iwl_causes_list causes_list[] = {
1126 {MSIX_FH_INT_CAUSES_FH_ERR, CSR_MSIX_FH_INT_MASK_AD, 0x5}, 1094 {MSIX_FH_INT_CAUSES_FH_ERR, CSR_MSIX_FH_INT_MASK_AD, 0x5},
1127 {MSIX_HW_INT_CAUSES_REG_ALIVE, CSR_MSIX_HW_INT_MASK_AD, 0x10}, 1095 {MSIX_HW_INT_CAUSES_REG_ALIVE, CSR_MSIX_HW_INT_MASK_AD, 0x10},
1128 {MSIX_HW_INT_CAUSES_REG_WAKEUP, CSR_MSIX_HW_INT_MASK_AD, 0x11}, 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},
1129 {MSIX_HW_INT_CAUSES_REG_CT_KILL, CSR_MSIX_HW_INT_MASK_AD, 0x16}, 1098 {MSIX_HW_INT_CAUSES_REG_CT_KILL, CSR_MSIX_HW_INT_MASK_AD, 0x16},
1130 {MSIX_HW_INT_CAUSES_REG_RF_KILL, CSR_MSIX_HW_INT_MASK_AD, 0x17}, 1099 {MSIX_HW_INT_CAUSES_REG_RF_KILL, CSR_MSIX_HW_INT_MASK_AD, 0x17},
1131 {MSIX_HW_INT_CAUSES_REG_PERIODIC, CSR_MSIX_HW_INT_MASK_AD, 0x18}, 1100 {MSIX_HW_INT_CAUSES_REG_PERIODIC, CSR_MSIX_HW_INT_MASK_AD, 0x18},
@@ -1158,7 +1127,7 @@ static void iwl_pcie_map_non_rx_causes(struct iwl_trans *trans)
1158 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1127 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1159 int val = trans_pcie->def_irq | MSIX_NON_AUTO_CLEAR_CAUSE; 1128 int val = trans_pcie->def_irq | MSIX_NON_AUTO_CLEAR_CAUSE;
1160 int i, arr_size = 1129 int i, arr_size =
1161 (trans->cfg->device_family < IWL_DEVICE_FAMILY_22560) ? 1130 (trans->cfg->device_family != IWL_DEVICE_FAMILY_22560) ?
1162 ARRAY_SIZE(causes_list) : ARRAY_SIZE(causes_list_v2); 1131 ARRAY_SIZE(causes_list) : ARRAY_SIZE(causes_list_v2);
1163 1132
1164 /* 1133 /*
@@ -1168,7 +1137,7 @@ static void iwl_pcie_map_non_rx_causes(struct iwl_trans *trans)
1168 */ 1137 */
1169 for (i = 0; i < arr_size; i++) { 1138 for (i = 0; i < arr_size; i++) {
1170 struct iwl_causes_list *causes = 1139 struct iwl_causes_list *causes =
1171 (trans->cfg->device_family < IWL_DEVICE_FAMILY_22560) ? 1140 (trans->cfg->device_family != IWL_DEVICE_FAMILY_22560) ?
1172 causes_list : causes_list_v2; 1141 causes_list : causes_list_v2;
1173 1142
1174 iwl_write8(trans, CSR_MSIX_IVAR(causes[i].addr), val); 1143 iwl_write8(trans, CSR_MSIX_IVAR(causes[i].addr), val);
@@ -1214,8 +1183,8 @@ void iwl_pcie_conf_msix_hw(struct iwl_trans_pcie *trans_pcie)
1214 if (!trans_pcie->msix_enabled) { 1183 if (!trans_pcie->msix_enabled) {
1215 if (trans->cfg->mq_rx_supported && 1184 if (trans->cfg->mq_rx_supported &&
1216 test_bit(STATUS_DEVICE_ENABLED, &trans->status)) 1185 test_bit(STATUS_DEVICE_ENABLED, &trans->status))
1217 iwl_write_prph(trans, UREG_CHICK, 1186 iwl_write_umac_prph(trans, UREG_CHICK,
1218 UREG_CHICK_MSI_ENABLE); 1187 UREG_CHICK_MSI_ENABLE);
1219 return; 1188 return;
1220 } 1189 }
1221 /* 1190 /*
@@ -1224,7 +1193,7 @@ void iwl_pcie_conf_msix_hw(struct iwl_trans_pcie *trans_pcie)
1224 * prph. 1193 * prph.
1225 */ 1194 */
1226 if (test_bit(STATUS_DEVICE_ENABLED, &trans->status)) 1195 if (test_bit(STATUS_DEVICE_ENABLED, &trans->status))
1227 iwl_write_prph(trans, UREG_CHICK, UREG_CHICK_MSIX_ENABLE); 1196 iwl_write_umac_prph(trans, UREG_CHICK, UREG_CHICK_MSIX_ENABLE);
1228 1197
1229 /* 1198 /*
1230 * Each cause from the causes list above and the RX causes is 1199 * Each cause from the causes list above and the RX causes is
@@ -1558,20 +1527,10 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
1558 1527
1559 iwl_set_bit(trans, CSR_GP_CNTRL, 1528 iwl_set_bit(trans, CSR_GP_CNTRL,
1560 BIT(trans->cfg->csr->flag_mac_access_req)); 1529 BIT(trans->cfg->csr->flag_mac_access_req));
1561 iwl_set_bit(trans, CSR_GP_CNTRL,
1562 BIT(trans->cfg->csr->flag_init_done));
1563
1564 if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000)
1565 udelay(2);
1566 1530
1567 ret = iwl_poll_bit(trans, CSR_GP_CNTRL, 1531 ret = iwl_finish_nic_init(trans);
1568 BIT(trans->cfg->csr->flag_mac_clock_ready), 1532 if (ret)
1569 BIT(trans->cfg->csr->flag_mac_clock_ready),
1570 25000);
1571 if (ret < 0) {
1572 IWL_ERR(trans, "Failed to resume the device (mac ready)\n");
1573 return ret; 1533 return ret;
1574 }
1575 1534
1576 /* 1535 /*
1577 * Reconfigure IVAR table in case of MSIX or reset ict table in 1536 * Reconfigure IVAR table in case of MSIX or reset ict table in
@@ -1602,7 +1561,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
1602 } 1561 }
1603 1562
1604 IWL_DEBUG_POWER(trans, "WFPM value upon resume = 0x%08X\n", 1563 IWL_DEBUG_POWER(trans, "WFPM value upon resume = 0x%08X\n",
1605 iwl_read_prph(trans, WFPM_GP2)); 1564 iwl_read_umac_prph(trans, WFPM_GP2));
1606 1565
1607 val = iwl_read32(trans, CSR_RESET); 1566 val = iwl_read32(trans, CSR_RESET);
1608 if (val & CSR_RESET_REG_FLAG_NEVO_RESET) 1567 if (val & CSR_RESET_REG_FLAG_NEVO_RESET)
@@ -1751,15 +1710,18 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
1751 return err; 1710 return err;
1752 } 1711 }
1753 1712
1754 hpm = iwl_trans_read_prph(trans, HPM_DEBUG); 1713 hpm = iwl_read_umac_prph_no_grab(trans, HPM_DEBUG);
1755 if (hpm != 0xa5a5a5a0 && (hpm & PERSISTENCE_BIT)) { 1714 if (hpm != 0xa5a5a5a0 && (hpm & PERSISTENCE_BIT)) {
1756 if (iwl_trans_read_prph(trans, PREG_PRPH_WPROT_0) & 1715 int wfpm_val = iwl_read_umac_prph_no_grab(trans,
1757 PREG_WFPM_ACCESS) { 1716 PREG_PRPH_WPROT_0);
1717
1718 if (wfpm_val & PREG_WFPM_ACCESS) {
1758 IWL_ERR(trans, 1719 IWL_ERR(trans,
1759 "Error, can not clear persistence bit\n"); 1720 "Error, can not clear persistence bit\n");
1760 return -EPERM; 1721 return -EPERM;
1761 } 1722 }
1762 iwl_trans_write_prph(trans, HPM_DEBUG, hpm & ~PERSISTENCE_BIT); 1723 iwl_write_umac_prph_no_grab(trans, HPM_DEBUG,
1724 hpm & ~PERSISTENCE_BIT);
1763 } 1725 }
1764 1726
1765 iwl_trans_pcie_sw_reset(trans); 1727 iwl_trans_pcie_sw_reset(trans);
@@ -2281,6 +2243,7 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans, int txq_idx)
2281 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 2243 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
2282 struct iwl_txq *txq; 2244 struct iwl_txq *txq;
2283 unsigned long now = jiffies; 2245 unsigned long now = jiffies;
2246 bool overflow_tx;
2284 u8 wr_ptr; 2247 u8 wr_ptr;
2285 2248
2286 /* Make sure the NIC is still alive in the bus */ 2249 /* Make sure the NIC is still alive in the bus */
@@ -2292,18 +2255,37 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans, int txq_idx)
2292 2255
2293 IWL_DEBUG_TX_QUEUES(trans, "Emptying queue %d...\n", txq_idx); 2256 IWL_DEBUG_TX_QUEUES(trans, "Emptying queue %d...\n", txq_idx);
2294 txq = trans_pcie->txq[txq_idx]; 2257 txq = trans_pcie->txq[txq_idx];
2258
2259 spin_lock_bh(&txq->lock);
2260 overflow_tx = txq->overflow_tx ||
2261 !skb_queue_empty(&txq->overflow_q);
2262 spin_unlock_bh(&txq->lock);
2263
2295 wr_ptr = READ_ONCE(txq->write_ptr); 2264 wr_ptr = READ_ONCE(txq->write_ptr);
2296 2265
2297 while (txq->read_ptr != READ_ONCE(txq->write_ptr) && 2266 while ((txq->read_ptr != READ_ONCE(txq->write_ptr) ||
2267 overflow_tx) &&
2298 !time_after(jiffies, 2268 !time_after(jiffies,
2299 now + msecs_to_jiffies(IWL_FLUSH_WAIT_MS))) { 2269 now + msecs_to_jiffies(IWL_FLUSH_WAIT_MS))) {
2300 u8 write_ptr = READ_ONCE(txq->write_ptr); 2270 u8 write_ptr = READ_ONCE(txq->write_ptr);
2301 2271
2302 if (WARN_ONCE(wr_ptr != write_ptr, 2272 /*
2273 * If write pointer moved during the wait, warn only
2274 * if the TX came from op mode. In case TX came from
2275 * trans layer (overflow TX) don't warn.
2276 */
2277 if (WARN_ONCE(wr_ptr != write_ptr && !overflow_tx,
2303 "WR pointer moved while flushing %d -> %d\n", 2278 "WR pointer moved while flushing %d -> %d\n",
2304 wr_ptr, write_ptr)) 2279 wr_ptr, write_ptr))
2305 return -ETIMEDOUT; 2280 return -ETIMEDOUT;
2281 wr_ptr = write_ptr;
2282
2306 usleep_range(1000, 2000); 2283 usleep_range(1000, 2000);
2284
2285 spin_lock_bh(&txq->lock);
2286 overflow_tx = txq->overflow_tx ||
2287 !skb_queue_empty(&txq->overflow_q);
2288 spin_unlock_bh(&txq->lock);
2307 } 2289 }
2308 2290
2309 if (txq->read_ptr != txq->write_ptr) { 2291 if (txq->read_ptr != txq->write_ptr) {
@@ -2989,7 +2971,8 @@ static u32 iwl_trans_pcie_fh_regs_dump(struct iwl_trans *trans,
2989 i += sizeof(u32)) 2971 i += sizeof(u32))
2990 *val++ = cpu_to_le32(iwl_trans_pcie_read32(trans, i)); 2972 *val++ = cpu_to_le32(iwl_trans_pcie_read32(trans, i));
2991 else 2973 else
2992 for (i = FH_MEM_LOWER_BOUND_GEN2; i < FH_MEM_UPPER_BOUND_GEN2; 2974 for (i = iwl_umac_prph(trans, FH_MEM_LOWER_BOUND_GEN2);
2975 i < iwl_umac_prph(trans, FH_MEM_UPPER_BOUND_GEN2);
2993 i += sizeof(u32)) 2976 i += sizeof(u32))
2994 *val++ = cpu_to_le32(iwl_trans_pcie_read_prph(trans, 2977 *val++ = cpu_to_le32(iwl_trans_pcie_read_prph(trans,
2995 i)); 2978 i));
@@ -3014,11 +2997,11 @@ iwl_trans_pci_dump_marbh_monitor(struct iwl_trans *trans,
3014 if (!iwl_trans_grab_nic_access(trans, &flags)) 2997 if (!iwl_trans_grab_nic_access(trans, &flags))
3015 return 0; 2998 return 0;
3016 2999
3017 iwl_write_prph_no_grab(trans, MON_DMARB_RD_CTL_ADDR, 0x1); 3000 iwl_write_umac_prph_no_grab(trans, MON_DMARB_RD_CTL_ADDR, 0x1);
3018 for (i = 0; i < buf_size_in_dwords; i++) 3001 for (i = 0; i < buf_size_in_dwords; i++)
3019 buffer[i] = iwl_read_prph_no_grab(trans, 3002 buffer[i] = iwl_read_umac_prph_no_grab(trans,
3020 MON_DMARB_RD_DATA_ADDR); 3003 MON_DMARB_RD_DATA_ADDR);
3021 iwl_write_prph_no_grab(trans, MON_DMARB_RD_CTL_ADDR, 0x0); 3004 iwl_write_umac_prph_no_grab(trans, MON_DMARB_RD_CTL_ADDR, 0x0);
3022 3005
3023 iwl_trans_release_nic_access(trans, &flags); 3006 iwl_trans_release_nic_access(trans, &flags);
3024 3007
@@ -3033,9 +3016,9 @@ iwl_trans_pcie_dump_pointers(struct iwl_trans *trans,
3033 3016
3034 /* If there was a dest TLV - use the values from there */ 3017 /* If there was a dest TLV - use the values from there */
3035 if (trans->ini_valid) { 3018 if (trans->ini_valid) {
3036 base = MON_BUFF_BASE_ADDR_VER2; 3019 base = iwl_umac_prph(trans, MON_BUFF_BASE_ADDR_VER2);
3037 write_ptr = MON_BUFF_WRPTR_VER2; 3020 write_ptr = iwl_umac_prph(trans, MON_BUFF_WRPTR_VER2);
3038 wrap_cnt = MON_BUFF_CYCLE_CNT_VER2; 3021 wrap_cnt = iwl_umac_prph(trans, MON_BUFF_CYCLE_CNT_VER2);
3039 } else if (trans->dbg_dest_tlv) { 3022 } else if (trans->dbg_dest_tlv) {
3040 write_ptr = le32_to_cpu(trans->dbg_dest_tlv->write_ptr_reg); 3023 write_ptr = le32_to_cpu(trans->dbg_dest_tlv->write_ptr_reg);
3041 wrap_cnt = le32_to_cpu(trans->dbg_dest_tlv->wrap_count); 3024 wrap_cnt = le32_to_cpu(trans->dbg_dest_tlv->wrap_count);
@@ -3197,8 +3180,8 @@ static struct iwl_trans_dump_data
3197 if (dump_mask & BIT(IWL_FW_ERROR_DUMP_FH_REGS)) { 3180 if (dump_mask & BIT(IWL_FW_ERROR_DUMP_FH_REGS)) {
3198 if (trans->cfg->gen2) 3181 if (trans->cfg->gen2)
3199 len += sizeof(*data) + 3182 len += sizeof(*data) +
3200 (FH_MEM_UPPER_BOUND_GEN2 - 3183 (iwl_umac_prph(trans, FH_MEM_UPPER_BOUND_GEN2) -
3201 FH_MEM_LOWER_BOUND_GEN2); 3184 iwl_umac_prph(trans, FH_MEM_LOWER_BOUND_GEN2));
3202 else 3185 else
3203 len += sizeof(*data) + 3186 len += sizeof(*data) +
3204 (FH_MEM_UPPER_BOUND - 3187 (FH_MEM_UPPER_BOUND -
@@ -3220,10 +3203,10 @@ static struct iwl_trans_dump_data
3220 3203
3221 /* Paged memory for gen2 HW */ 3204 /* Paged memory for gen2 HW */
3222 if (trans->cfg->gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING)) 3205 if (trans->cfg->gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING))
3223 for (i = 0; i < trans_pcie->init_dram.paging_cnt; i++) 3206 for (i = 0; i < trans->init_dram.paging_cnt; i++)
3224 len += sizeof(*data) + 3207 len += sizeof(*data) +
3225 sizeof(struct iwl_fw_error_dump_paging) + 3208 sizeof(struct iwl_fw_error_dump_paging) +
3226 trans_pcie->init_dram.paging[i].size; 3209 trans->init_dram.paging[i].size;
3227 3210
3228 dump_data = vzalloc(len); 3211 dump_data = vzalloc(len);
3229 if (!dump_data) 3212 if (!dump_data)
@@ -3275,20 +3258,16 @@ static struct iwl_trans_dump_data
3275 3258
3276 /* Paged memory for gen2 HW */ 3259 /* Paged memory for gen2 HW */
3277 if (trans->cfg->gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING)) { 3260 if (trans->cfg->gen2 && dump_mask & BIT(IWL_FW_ERROR_DUMP_PAGING)) {
3278 for (i = 0; i < trans_pcie->init_dram.paging_cnt; i++) { 3261 for (i = 0; i < trans->init_dram.paging_cnt; i++) {
3279 struct iwl_fw_error_dump_paging *paging; 3262 struct iwl_fw_error_dump_paging *paging;
3280 dma_addr_t addr = 3263 u32 page_len = trans->init_dram.paging[i].size;
3281 trans_pcie->init_dram.paging[i].physical;
3282 u32 page_len = trans_pcie->init_dram.paging[i].size;
3283 3264
3284 data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PAGING); 3265 data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PAGING);
3285 data->len = cpu_to_le32(sizeof(*paging) + page_len); 3266 data->len = cpu_to_le32(sizeof(*paging) + page_len);
3286 paging = (void *)data->data; 3267 paging = (void *)data->data;
3287 paging->index = cpu_to_le32(i); 3268 paging->index = cpu_to_le32(i);
3288 dma_sync_single_for_cpu(trans->dev, addr, page_len,
3289 DMA_BIDIRECTIONAL);
3290 memcpy(paging->data, 3269 memcpy(paging->data,
3291 trans_pcie->init_dram.paging[i].block, page_len); 3270 trans->init_dram.paging[i].block, page_len);
3292 data = iwl_fw_error_next_data(data); 3271 data = iwl_fw_error_next_data(data);
3293 3272
3294 len += sizeof(*data) + sizeof(*paging) + page_len; 3273 len += sizeof(*data) + sizeof(*paging) + page_len;
@@ -3525,25 +3504,18 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
3525 * in-order to recognize C step driver should read chip version 3504 * in-order to recognize C step driver should read chip version
3526 * id located at the AUX bus MISC address space. 3505 * id located at the AUX bus MISC address space.
3527 */ 3506 */
3528 iwl_set_bit(trans, CSR_GP_CNTRL, 3507 ret = iwl_finish_nic_init(trans);
3529 BIT(trans->cfg->csr->flag_init_done)); 3508 if (ret)
3530 udelay(2);
3531
3532 ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
3533 BIT(trans->cfg->csr->flag_mac_clock_ready),
3534 BIT(trans->cfg->csr->flag_mac_clock_ready),
3535 25000);
3536 if (ret < 0) {
3537 IWL_DEBUG_INFO(trans, "Failed to wake up the nic\n");
3538 goto out_no_pci; 3509 goto out_no_pci;
3539 }
3540 3510
3541 if (iwl_trans_grab_nic_access(trans, &flags)) { 3511 if (iwl_trans_grab_nic_access(trans, &flags)) {
3542 u32 hw_step; 3512 u32 hw_step;
3543 3513
3544 hw_step = iwl_read_prph_no_grab(trans, WFPM_CTRL_REG); 3514 hw_step = iwl_read_umac_prph_no_grab(trans,
3515 WFPM_CTRL_REG);
3545 hw_step |= ENABLE_WFPM; 3516 hw_step |= ENABLE_WFPM;
3546 iwl_write_prph_no_grab(trans, WFPM_CTRL_REG, hw_step); 3517 iwl_write_umac_prph_no_grab(trans, WFPM_CTRL_REG,
3518 hw_step);
3547 hw_step = iwl_read_prph_no_grab(trans, AUX_MISC_REG); 3519 hw_step = iwl_read_prph_no_grab(trans, AUX_MISC_REG);
3548 hw_step = (hw_step >> HW_STEP_LOCATION_BITS) & 0xF; 3520 hw_step = (hw_step >> HW_STEP_LOCATION_BITS) & 0xF;
3549 if (hw_step == 0x3) 3521 if (hw_step == 0x3)
@@ -3558,10 +3530,20 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
3558#if IS_ENABLED(CONFIG_IWLMVM) 3530#if IS_ENABLED(CONFIG_IWLMVM)
3559 trans->hw_rf_id = iwl_read32(trans, CSR_HW_RF_ID); 3531 trans->hw_rf_id = iwl_read32(trans, CSR_HW_RF_ID);
3560 3532
3561 if (cfg == &iwl22560_2ax_cfg_hr) { 3533 if (cfg == &iwlax210_2ax_cfg_so_hr_a0) {
3534 if (trans->hw_rev == CSR_HW_REV_TYPE_TY) {
3535 trans->cfg = &iwlax210_2ax_cfg_ty_gf_a0;
3536 } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
3537 CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) {
3538 trans->cfg = &iwlax210_2ax_cfg_so_jf_a0;
3539 } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
3540 CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_GF)) {
3541 trans->cfg = &iwlax210_2ax_cfg_so_gf_a0;
3542 }
3543 } else if (cfg == &iwl_ax101_cfg_qu_hr) {
3562 if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == 3544 if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
3563 CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) { 3545 CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) {
3564 trans->cfg = &iwl22560_2ax_cfg_hr; 3546 trans->cfg = &iwl_ax101_cfg_qu_hr;
3565 } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == 3547 } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
3566 CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) { 3548 CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_JF)) {
3567 trans->cfg = &iwl22000_2ax_cfg_jf; 3549 trans->cfg = &iwl22000_2ax_cfg_jf;
@@ -3654,3 +3636,28 @@ out_no_pci:
3654 iwl_trans_free(trans); 3636 iwl_trans_free(trans);
3655 return ERR_PTR(ret); 3637 return ERR_PTR(ret);
3656} 3638}
3639
3640void iwl_trans_sync_nmi(struct iwl_trans *trans)
3641{
3642 unsigned long timeout = jiffies + IWL_TRANS_NMI_TIMEOUT;
3643
3644 iwl_disable_interrupts(trans);
3645 iwl_force_nmi(trans);
3646 while (time_after(timeout, jiffies)) {
3647 u32 inta_hw = iwl_read32(trans,
3648 CSR_MSIX_HW_INT_CAUSES_AD);
3649
3650 /* Error detected by uCode */
3651 if (inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR) {
3652 /* Clear causes register */
3653 iwl_write32(trans, CSR_MSIX_HW_INT_CAUSES_AD,
3654 inta_hw &
3655 MSIX_HW_INT_CAUSES_REG_SW_ERR);
3656 break;
3657 }
3658
3659 mdelay(1);
3660 }
3661 iwl_enable_interrupts(trans);
3662 iwl_trans_fw_error(trans);
3663}
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
index f3d2e8fe920b..88530d9f4a54 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
@@ -6,7 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2017 Intel Deutschland GmbH 8 * Copyright(c) 2017 Intel Deutschland GmbH
9 * Copyright(c) 2018 Intel Corporation 9 * Copyright(c) 2018 - 2019 Intel Corporation
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 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 12 * it under the terms of version 2 of the GNU General Public License as
@@ -20,7 +20,7 @@
20 * BSD LICENSE 20 * BSD LICENSE
21 * 21 *
22 * Copyright(c) 2017 Intel Deutschland GmbH 22 * Copyright(c) 2017 Intel Deutschland GmbH
23 * Copyright(c) 2018 Intel Corporation 23 * Copyright(c) 2018 - 2019 Intel Corporation
24 * All rights reserved. 24 * All rights reserved.
25 * 25 *
26 * Redistribution and use in source and binary forms, with or without 26 * Redistribution and use in source and binary forms, with or without
@@ -965,9 +965,7 @@ static int iwl_pcie_gen2_send_hcmd_sync(struct iwl_trans *trans,
965 cmd_str); 965 cmd_str);
966 ret = -ETIMEDOUT; 966 ret = -ETIMEDOUT;
967 967
968 iwl_force_nmi(trans); 968 iwl_trans_sync_nmi(trans);
969 iwl_trans_fw_error(trans);
970
971 goto cancel; 969 goto cancel;
972 } 970 }
973 971
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index 07395502f419..9fbd37d23e85 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -8,7 +8,7 @@
8 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11 * Copyright(c) 2018 Intel Corporation 11 * Copyright(c) 2018 - 2019 Intel Corporation
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify it 13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of version 2 of the GNU General Public License as 14 * under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
31 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. 31 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
34 * Copyright(c) 2018 Intel Corporation 34 * Copyright(c) 2018 - 2019 Intel Corporation
35 * All rights reserved. 35 * All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -995,7 +995,11 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans)
995 txq_id++) { 995 txq_id++) {
996 bool cmd_queue = (txq_id == trans_pcie->cmd_queue); 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 trans_pcie->txq[txq_id] = &trans_pcie->txq_memory[txq_id]; 1003 trans_pcie->txq[txq_id] = &trans_pcie->txq_memory[txq_id];
1000 ret = iwl_pcie_txq_alloc(trans, trans_pcie->txq[txq_id], 1004 ret = iwl_pcie_txq_alloc(trans, trans_pcie->txq[txq_id],
1001 slots_num, cmd_queue); 1005 slots_num, cmd_queue);
@@ -1044,7 +1048,11 @@ int iwl_pcie_tx_init(struct iwl_trans *trans)
1044 txq_id++) { 1048 txq_id++) {
1045 bool cmd_queue = (txq_id == trans_pcie->cmd_queue); 1049 bool cmd_queue = (txq_id == trans_pcie->cmd_queue);
1046 1050
1047 slots_num = cmd_queue ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; 1051 if (cmd_queue)
1052 slots_num = max_t(u32, TFD_CMD_SLOTS,
1053 trans->cfg->min_txq_size);
1054 else
1055 slots_num = TFD_TX_CMD_SLOTS;
1048 ret = iwl_pcie_txq_init(trans, trans_pcie->txq[txq_id], 1056 ret = iwl_pcie_txq_init(trans, trans_pcie->txq[txq_id],
1049 slots_num, cmd_queue); 1057 slots_num, cmd_queue);
1050 if (ret) { 1058 if (ret) {
@@ -1174,6 +1182,15 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
1174 skb_queue_splice_init(&txq->overflow_q, &overflow_skbs); 1182 skb_queue_splice_init(&txq->overflow_q, &overflow_skbs);
1175 1183
1176 /* 1184 /*
1185 * We are going to transmit from the overflow queue.
1186 * Remember this state so that wait_for_txq_empty will know we
1187 * are adding more packets to the TFD queue. It cannot rely on
1188 * the state of &txq->overflow_q, as we just emptied it, but
1189 * haven't TXed the content yet.
1190 */
1191 txq->overflow_tx = true;
1192
1193 /*
1177 * This is tricky: we are in reclaim path which is non 1194 * This is tricky: we are in reclaim path which is non
1178 * re-entrant, so noone will try to take the access the 1195 * re-entrant, so noone will try to take the access the
1179 * txq data from that path. We stopped tx, so we can't 1196 * txq data from that path. We stopped tx, so we can't
@@ -1201,6 +1218,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
1201 iwl_wake_queue(trans, txq); 1218 iwl_wake_queue(trans, txq);
1202 1219
1203 spin_lock_bh(&txq->lock); 1220 spin_lock_bh(&txq->lock);
1221 txq->overflow_tx = false;
1204 } 1222 }
1205 1223
1206 if (txq->read_ptr == txq->write_ptr) { 1224 if (txq->read_ptr == txq->write_ptr) {
@@ -1942,9 +1960,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
1942 iwl_get_cmd_string(trans, cmd->id)); 1960 iwl_get_cmd_string(trans, cmd->id));
1943 ret = -ETIMEDOUT; 1961 ret = -ETIMEDOUT;
1944 1962
1945 iwl_force_nmi(trans); 1963 iwl_trans_sync_nmi(trans);
1946 iwl_trans_fw_error(trans);
1947
1948 goto cancel; 1964 goto cancel;
1949 } 1965 }
1950 1966