aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/intel
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2019-02-22 15:56:24 -0500
committerDavid S. Miller <davem@davemloft.net>2019-02-22 15:56:24 -0500
commit1a2566085650be593d464c4d73ac2d20ff67c058 (patch)
treedabdfa08fd7aca827a98a321d2b4b6ac6a39f6f8 /drivers/net/wireless/intel
parentd29d1c4957d4dde1a7578b10f2a2d1fae39bd47a (diff)
parent5c0c4c85463461a9ea0a69c4e80849a71c6b1e24 (diff)
Merge tag 'wireless-drivers-next-for-davem-2019-02-22' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Valo says: ==================== wireless-drivers-next patches for 5.1 Most likely the last set of patches for 5.1. WPA3 support to ath10k and qtnfmac. FTM support to iwlwifi and ath10k. And of course other new features and bugfixes. wireless-drivers was merged due to dependency in mt76. Major changes: iwlwifi * HE radiotap * FTM (Fine Timing Measurement) initiator and responder implementation * bump supported firmware API to 46 * VHT extended NSS support * new PCI IDs for 9260 and 22000 series ath10k * change QMI interface to support the new (and backwards incompatible) interface from HL3.1 and used in recent HL2.0 branch firmware releases * support WPA3 with WCN3990 * support for mac80211 airtime fairness based on transmit rate estimation, the firmware needs to support WMI_SERVICE_PEER_STATS to enable this * report transmit airtime to mac80211 with firmwares having WMI_SERVICE_REPORT_AIRTIME feature, this to have more accurate airtime fairness based on real transmit time (instead of just estimated from transmit rate) * support Fine Timing Measurement (FTM) responder role * add dynamic VLAN support with firmware having WMI_SERVICE_PER_PACKET_SW_ENCRYPT * switch to use SPDX license identifiers ath * add new country codes for US brcmfmac * support monitor frames with the hardware/ucode header qtnfmac * enable WPA3 SAE and OWE support mt76 * beacon support for USB devices (mesh+ad-hoc only) rtlwifi * convert to use SPDX license identifiers libertas_tf * get the MAC address before registering the device ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
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