aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2014-12-02 14:50:31 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-12-02 14:50:31 -0500
commitea375117013dcca43ea4ffeb920735ab71c75ef3 (patch)
tree2d543dcb6b03b5b499088b24130f15abd5655c75
parentfbf61095bc2845c6321b6b8fa95fd755b718b88e (diff)
parent61df750cb00b69882ba3acbb82e9368d01119c93 (diff)
Merge tag 'iwlwifi-next-for-john-2014-12-02' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
"Grumbach, Emmanuel" <emmanuel.grumbach@intel.com> says: "I deprecate here -8.ucode since -9 has been published long ago. Along with that I have a new activity, we have now better infrastructure for firmware debugging. This will allow to have configurable probes insides the firmware. Luca continues his work on NetDetect, this feature is now complete. All the rest is minor fixes here and there." Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/commands.h31
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/lib.c47
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-8000.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c195
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h308
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h247
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h7
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/constants.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c208
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h44
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c46
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c19
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c16
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c31
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/offloading.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c31
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c330
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c102
26 files changed, 1258 insertions, 471 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h
index 751ae1d10b7f..7a34e4d158d1 100644
--- a/drivers/net/wireless/iwlwifi/dvm/commands.h
+++ b/drivers/net/wireless/iwlwifi/dvm/commands.h
@@ -966,21 +966,21 @@ struct iwl_rem_sta_cmd {
966 966
967 967
968/* WiFi queues mask */ 968/* WiFi queues mask */
969#define IWL_SCD_BK_MSK cpu_to_le32(BIT(0)) 969#define IWL_SCD_BK_MSK BIT(0)
970#define IWL_SCD_BE_MSK cpu_to_le32(BIT(1)) 970#define IWL_SCD_BE_MSK BIT(1)
971#define IWL_SCD_VI_MSK cpu_to_le32(BIT(2)) 971#define IWL_SCD_VI_MSK BIT(2)
972#define IWL_SCD_VO_MSK cpu_to_le32(BIT(3)) 972#define IWL_SCD_VO_MSK BIT(3)
973#define IWL_SCD_MGMT_MSK cpu_to_le32(BIT(3)) 973#define IWL_SCD_MGMT_MSK BIT(3)
974 974
975/* PAN queues mask */ 975/* PAN queues mask */
976#define IWL_PAN_SCD_BK_MSK cpu_to_le32(BIT(4)) 976#define IWL_PAN_SCD_BK_MSK BIT(4)
977#define IWL_PAN_SCD_BE_MSK cpu_to_le32(BIT(5)) 977#define IWL_PAN_SCD_BE_MSK BIT(5)
978#define IWL_PAN_SCD_VI_MSK cpu_to_le32(BIT(6)) 978#define IWL_PAN_SCD_VI_MSK BIT(6)
979#define IWL_PAN_SCD_VO_MSK cpu_to_le32(BIT(7)) 979#define IWL_PAN_SCD_VO_MSK BIT(7)
980#define IWL_PAN_SCD_MGMT_MSK cpu_to_le32(BIT(7)) 980#define IWL_PAN_SCD_MGMT_MSK BIT(7)
981#define IWL_PAN_SCD_MULTICAST_MSK cpu_to_le32(BIT(8)) 981#define IWL_PAN_SCD_MULTICAST_MSK BIT(8)
982 982
983#define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00) 983#define IWL_AGG_TX_QUEUE_MSK 0xffc00
984 984
985#define IWL_DROP_ALL BIT(1) 985#define IWL_DROP_ALL BIT(1)
986 986
@@ -1005,12 +1005,17 @@ struct iwl_rem_sta_cmd {
1005 * 1: Dump multiple MSDU according to PS, INVALID STA, TTL, TID disable. 1005 * 1: Dump multiple MSDU according to PS, INVALID STA, TTL, TID disable.
1006 * 2: Dump all FIFO 1006 * 2: Dump all FIFO
1007 */ 1007 */
1008struct iwl_txfifo_flush_cmd { 1008struct iwl_txfifo_flush_cmd_v3 {
1009 __le32 queue_control; 1009 __le32 queue_control;
1010 __le16 flush_control; 1010 __le16 flush_control;
1011 __le16 reserved; 1011 __le16 reserved;
1012} __packed; 1012} __packed;
1013 1013
1014struct iwl_txfifo_flush_cmd_v2 {
1015 __le16 queue_control;
1016 __le16 flush_control;
1017} __packed;
1018
1014/* 1019/*
1015 * REPLY_WEP_KEY = 0x20 1020 * REPLY_WEP_KEY = 0x20
1016 */ 1021 */
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c
index 02e4ede2b042..1d2223df5cb0 100644
--- a/drivers/net/wireless/iwlwifi/dvm/lib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/lib.c
@@ -137,37 +137,38 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
137 */ 137 */
138int iwlagn_txfifo_flush(struct iwl_priv *priv, u32 scd_q_msk) 138int iwlagn_txfifo_flush(struct iwl_priv *priv, u32 scd_q_msk)
139{ 139{
140 struct iwl_txfifo_flush_cmd flush_cmd; 140 struct iwl_txfifo_flush_cmd_v3 flush_cmd_v3 = {
141 struct iwl_host_cmd cmd = { 141 .flush_control = cpu_to_le16(IWL_DROP_ALL),
142 .id = REPLY_TXFIFO_FLUSH, 142 };
143 .len = { sizeof(struct iwl_txfifo_flush_cmd), }, 143 struct iwl_txfifo_flush_cmd_v2 flush_cmd_v2 = {
144 .data = { &flush_cmd, }, 144 .flush_control = cpu_to_le16(IWL_DROP_ALL),
145 }; 145 };
146 146
147 memset(&flush_cmd, 0, sizeof(flush_cmd)); 147 u32 queue_control = IWL_SCD_VO_MSK | IWL_SCD_VI_MSK |
148 IWL_SCD_BE_MSK | IWL_SCD_BK_MSK | IWL_SCD_MGMT_MSK;
148 149
149 flush_cmd.queue_control = IWL_SCD_VO_MSK | IWL_SCD_VI_MSK |
150 IWL_SCD_BE_MSK | IWL_SCD_BK_MSK |
151 IWL_SCD_MGMT_MSK;
152 if ((priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))) 150 if ((priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)))
153 flush_cmd.queue_control |= IWL_PAN_SCD_VO_MSK | 151 queue_control |= IWL_PAN_SCD_VO_MSK | IWL_PAN_SCD_VI_MSK |
154 IWL_PAN_SCD_VI_MSK | 152 IWL_PAN_SCD_BE_MSK | IWL_PAN_SCD_BK_MSK |
155 IWL_PAN_SCD_BE_MSK | 153 IWL_PAN_SCD_MGMT_MSK |
156 IWL_PAN_SCD_BK_MSK | 154 IWL_PAN_SCD_MULTICAST_MSK;
157 IWL_PAN_SCD_MGMT_MSK |
158 IWL_PAN_SCD_MULTICAST_MSK;
159 155
160 if (priv->nvm_data->sku_cap_11n_enable) 156 if (priv->nvm_data->sku_cap_11n_enable)
161 flush_cmd.queue_control |= IWL_AGG_TX_QUEUE_MSK; 157 queue_control |= IWL_AGG_TX_QUEUE_MSK;
162 158
163 if (scd_q_msk) 159 if (scd_q_msk)
164 flush_cmd.queue_control = cpu_to_le32(scd_q_msk); 160 queue_control = scd_q_msk;
165 161
166 IWL_DEBUG_INFO(priv, "queue control: 0x%x\n", 162 IWL_DEBUG_INFO(priv, "queue control: 0x%x\n", queue_control);
167 flush_cmd.queue_control); 163 flush_cmd_v3.queue_control = cpu_to_le32(queue_control);
168 flush_cmd.flush_control = cpu_to_le16(IWL_DROP_ALL); 164 flush_cmd_v2.queue_control = cpu_to_le16((u16)queue_control);
169 165
170 return iwl_dvm_send_cmd(priv, &cmd); 166 if (IWL_UCODE_API(priv->fw->ucode_ver) > 2)
167 return iwl_dvm_send_cmd_pdu(priv, REPLY_TXFIFO_FLUSH, 0,
168 sizeof(flush_cmd_v3),
169 &flush_cmd_v3);
170 return iwl_dvm_send_cmd_pdu(priv, REPLY_TXFIFO_FLUSH, 0,
171 sizeof(flush_cmd_v2), &flush_cmd_v2);
171} 172}
172 173
173void iwlagn_dev_txfifo_flush(struct iwl_priv *priv) 174void iwlagn_dev_txfifo_flush(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index 84d2a4280694..e5be2d21868f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -73,12 +73,12 @@
73#define IWL3160_UCODE_API_MAX 10 73#define IWL3160_UCODE_API_MAX 10
74 74
75/* Oldest version we won't warn about */ 75/* Oldest version we won't warn about */
76#define IWL7260_UCODE_API_OK 9 76#define IWL7260_UCODE_API_OK 10
77#define IWL3160_UCODE_API_OK 9 77#define IWL3160_UCODE_API_OK 10
78 78
79/* Lowest firmware API version supported */ 79/* Lowest firmware API version supported */
80#define IWL7260_UCODE_API_MIN 8 80#define IWL7260_UCODE_API_MIN 9
81#define IWL3160_UCODE_API_MIN 8 81#define IWL3160_UCODE_API_MIN 9
82 82
83/* NVM versions */ 83/* NVM versions */
84#define IWL7260_NVM_VERSION 0x0a1d 84#define IWL7260_NVM_VERSION 0x0a1d
@@ -89,6 +89,8 @@
89#define IWL3165_TX_POWER_VERSION 0xffff /* meaningless */ 89#define IWL3165_TX_POWER_VERSION 0xffff /* meaningless */
90#define IWL7265_NVM_VERSION 0x0a1d 90#define IWL7265_NVM_VERSION 0x0a1d
91#define IWL7265_TX_POWER_VERSION 0xffff /* meaningless */ 91#define IWL7265_TX_POWER_VERSION 0xffff /* meaningless */
92#define IWL7265D_NVM_VERSION 0x0c11
93#define IWL7265_TX_POWER_VERSION 0xffff /* meaningless */
92 94
93#define IWL7260_FW_PRE "iwlwifi-7260-" 95#define IWL7260_FW_PRE "iwlwifi-7260-"
94#define IWL7260_MODULE_FIRMWARE(api) IWL7260_FW_PRE __stringify(api) ".ucode" 96#define IWL7260_MODULE_FIRMWARE(api) IWL7260_FW_PRE __stringify(api) ".ucode"
@@ -275,7 +277,7 @@ const struct iwl_cfg iwl7265d_2ac_cfg = {
275 .fw_name_pre = IWL7265D_FW_PRE, 277 .fw_name_pre = IWL7265D_FW_PRE,
276 IWL_DEVICE_7000, 278 IWL_DEVICE_7000,
277 .ht_params = &iwl7265_ht_params, 279 .ht_params = &iwl7265_ht_params,
278 .nvm_ver = IWL7265_NVM_VERSION, 280 .nvm_ver = IWL7265D_NVM_VERSION,
279 .nvm_calib_ver = IWL7265_TX_POWER_VERSION, 281 .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
280 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, 282 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
281}; 283};
@@ -285,7 +287,7 @@ const struct iwl_cfg iwl7265d_2n_cfg = {
285 .fw_name_pre = IWL7265D_FW_PRE, 287 .fw_name_pre = IWL7265D_FW_PRE,
286 IWL_DEVICE_7000, 288 IWL_DEVICE_7000,
287 .ht_params = &iwl7265_ht_params, 289 .ht_params = &iwl7265_ht_params,
288 .nvm_ver = IWL7265_NVM_VERSION, 290 .nvm_ver = IWL7265D_NVM_VERSION,
289 .nvm_calib_ver = IWL7265_TX_POWER_VERSION, 291 .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
290 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, 292 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
291}; 293};
@@ -295,7 +297,7 @@ const struct iwl_cfg iwl7265d_n_cfg = {
295 .fw_name_pre = IWL7265D_FW_PRE, 297 .fw_name_pre = IWL7265D_FW_PRE,
296 IWL_DEVICE_7000, 298 IWL_DEVICE_7000,
297 .ht_params = &iwl7265_ht_params, 299 .ht_params = &iwl7265_ht_params,
298 .nvm_ver = IWL7265_NVM_VERSION, 300 .nvm_ver = IWL7265D_NVM_VERSION,
299 .nvm_calib_ver = IWL7265_TX_POWER_VERSION, 301 .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
300 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, 302 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
301}; 303};
diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c
index d0357b37fd8f..bf0a95cb7153 100644
--- a/drivers/net/wireless/iwlwifi/iwl-8000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-8000.c
@@ -72,10 +72,10 @@
72#define IWL8000_UCODE_API_MAX 10 72#define IWL8000_UCODE_API_MAX 10
73 73
74/* Oldest version we won't warn about */ 74/* Oldest version we won't warn about */
75#define IWL8000_UCODE_API_OK 8 75#define IWL8000_UCODE_API_OK 10
76 76
77/* Lowest firmware API version supported */ 77/* Lowest firmware API version supported */
78#define IWL8000_UCODE_API_MIN 8 78#define IWL8000_UCODE_API_MIN 9
79 79
80/* NVM versions */ 80/* NVM versions */
81#define IWL8000_NVM_VERSION 0x0a1d 81#define IWL8000_NVM_VERSION 0x0a1d
@@ -159,8 +159,8 @@ const struct iwl_cfg iwl8260_2ac_sdio_cfg = {
159 .max_vht_ampdu_exponent = MAX_VHT_AMPDU_EXPONENT_8260_SDIO, 159 .max_vht_ampdu_exponent = MAX_VHT_AMPDU_EXPONENT_8260_SDIO,
160}; 160};
161 161
162const struct iwl_cfg iwl4265_2ac_sdio_cfg = { 162const struct iwl_cfg iwl4165_2ac_sdio_cfg = {
163 .name = "Intel(R) Dual Band Wireless-AC 4265", 163 .name = "Intel(R) Dual Band Wireless-AC 4165",
164 .fw_name_pre = IWL8000_FW_PRE, 164 .fw_name_pre = IWL8000_FW_PRE,
165 IWL_DEVICE_8000, 165 IWL_DEVICE_8000,
166 .ht_params = &iwl8000_ht_params, 166 .ht_params = &iwl8000_ht_params,
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index e63cafa22ec6..3a4b9c7fc083 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -371,6 +371,7 @@ extern const struct iwl_cfg iwl8260_2n_cfg;
371extern const struct iwl_cfg iwl8260_2ac_cfg; 371extern const struct iwl_cfg iwl8260_2ac_cfg;
372extern const struct iwl_cfg iwl8260_2ac_sdio_cfg; 372extern const struct iwl_cfg iwl8260_2ac_sdio_cfg;
373extern const struct iwl_cfg iwl4265_2ac_sdio_cfg; 373extern const struct iwl_cfg iwl4265_2ac_sdio_cfg;
374extern const struct iwl_cfg iwl4165_2ac_sdio_cfg;
374#endif /* CONFIG_IWLMVM */ 375#endif /* CONFIG_IWLMVM */
375 376
376#endif /* __IWL_CONFIG_H__ */ 377#endif /* __IWL_CONFIG_H__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index d9fa8e034da2..38de1513e4de 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -78,9 +78,6 @@
78#include "iwl-config.h" 78#include "iwl-config.h"
79#include "iwl-modparams.h" 79#include "iwl-modparams.h"
80 80
81/* private includes */
82#include "iwl-fw-file.h"
83
84/****************************************************************************** 81/******************************************************************************
85 * 82 *
86 * module boiler plate 83 * module boiler plate
@@ -187,6 +184,11 @@ static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img)
187static void iwl_dealloc_ucode(struct iwl_drv *drv) 184static void iwl_dealloc_ucode(struct iwl_drv *drv)
188{ 185{
189 int i; 186 int i;
187
188 kfree(drv->fw.dbg_dest_tlv);
189 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_conf_tlv); i++)
190 kfree(drv->fw.dbg_conf_tlv[i]);
191
190 for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) 192 for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
191 iwl_free_fw_img(drv, drv->fw.img + i); 193 iwl_free_fw_img(drv, drv->fw.img + i);
192} 194}
@@ -248,6 +250,9 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
248 /* 250 /*
249 * Starting 8000B - FW name format has changed. This overwrites the 251 * Starting 8000B - FW name format has changed. This overwrites the
250 * previous name and uses the new format. 252 * previous name and uses the new format.
253 *
254 * TODO:
255 * Once there is only one supported step for 8000 family - delete this!
251 */ 256 */
252 if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) { 257 if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) {
253 char rev_step[2] = { 258 char rev_step[2] = {
@@ -258,6 +263,13 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
258 if (CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_A_STEP) 263 if (CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_A_STEP)
259 rev_step[0] = 0; 264 rev_step[0] = 0;
260 265
266 /*
267 * If hw_rev wasn't set yet - default as B-step. If it IS A-step
268 * we'll reload that FW later instead.
269 */
270 if (drv->trans->hw_rev == 0)
271 rev_step[0] = 'B';
272
261 snprintf(drv->firmware_name, sizeof(drv->firmware_name), 273 snprintf(drv->firmware_name, sizeof(drv->firmware_name),
262 "%s%s-%s.ucode", name_pre, rev_step, tag); 274 "%s%s-%s.ucode", name_pre, rev_step, tag);
263 } 275 }
@@ -301,6 +313,11 @@ struct iwl_firmware_pieces {
301 313
302 u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; 314 u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
303 u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; 315 u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
316
317 /* FW debug data parsed for driver usage */
318 struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
319 struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX];
320 size_t dbg_conf_tlv_len[FW_DBG_MAX];
304}; 321};
305 322
306/* 323/*
@@ -574,6 +591,8 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
574 char buildstr[25]; 591 char buildstr[25];
575 u32 build; 592 u32 build;
576 int num_of_cpus; 593 int num_of_cpus;
594 bool usniffer_images = false;
595 bool usniffer_req = false;
577 596
578 if (len < sizeof(*ucode)) { 597 if (len < sizeof(*ucode)) {
579 IWL_ERR(drv, "uCode has invalid length: %zd\n", len); 598 IWL_ERR(drv, "uCode has invalid length: %zd\n", len);
@@ -846,12 +865,79 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
846 capa->n_scan_channels = 865 capa->n_scan_channels =
847 le32_to_cpup((__le32 *)tlv_data); 866 le32_to_cpup((__le32 *)tlv_data);
848 break; 867 break;
868 case IWL_UCODE_TLV_FW_DBG_DEST: {
869 struct iwl_fw_dbg_dest_tlv *dest = (void *)tlv_data;
870
871 if (pieces->dbg_dest_tlv) {
872 IWL_ERR(drv,
873 "dbg destination ignored, already exists\n");
874 break;
875 }
876
877 pieces->dbg_dest_tlv = dest;
878 IWL_INFO(drv, "Found debug destination: %s\n",
879 get_fw_dbg_mode_string(dest->monitor_mode));
880
881 drv->fw.dbg_dest_reg_num =
882 tlv_len - offsetof(struct iwl_fw_dbg_dest_tlv,
883 reg_ops);
884 drv->fw.dbg_dest_reg_num /=
885 sizeof(drv->fw.dbg_dest_tlv->reg_ops[0]);
886
887 break;
888 }
889 case IWL_UCODE_TLV_FW_DBG_CONF: {
890 struct iwl_fw_dbg_conf_tlv *conf = (void *)tlv_data;
891
892 if (!pieces->dbg_dest_tlv) {
893 IWL_ERR(drv,
894 "Ignore dbg config %d - no destination configured\n",
895 conf->id);
896 break;
897 }
898
899 if (conf->id >= ARRAY_SIZE(drv->fw.dbg_conf_tlv)) {
900 IWL_ERR(drv,
901 "Skip unknown configuration: %d\n",
902 conf->id);
903 break;
904 }
905
906 if (pieces->dbg_conf_tlv[conf->id]) {
907 IWL_ERR(drv,
908 "Ignore duplicate dbg config %d\n",
909 conf->id);
910 break;
911 }
912
913 if (conf->usniffer)
914 usniffer_req = true;
915
916 IWL_INFO(drv, "Found debug configuration: %d\n",
917 conf->id);
918
919 pieces->dbg_conf_tlv[conf->id] = conf;
920 pieces->dbg_conf_tlv_len[conf->id] = tlv_len;
921 break;
922 }
923 case IWL_UCODE_TLV_SEC_RT_USNIFFER:
924 usniffer_images = true;
925 iwl_store_ucode_sec(pieces, tlv_data,
926 IWL_UCODE_REGULAR_USNIFFER,
927 tlv_len);
928 break;
849 default: 929 default:
850 IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); 930 IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
851 break; 931 break;
852 } 932 }
853 } 933 }
854 934
935 if (usniffer_req && !usniffer_images) {
936 IWL_ERR(drv,
937 "user selected to work with usniffer but usniffer image isn't available in ucode package\n");
938 return -EINVAL;
939 }
940
855 if (len) { 941 if (len) {
856 IWL_ERR(drv, "invalid TLV after parsing: %zd\n", len); 942 IWL_ERR(drv, "invalid TLV after parsing: %zd\n", len);
857 iwl_print_hex_dump(drv, IWL_DL_FW, (u8 *)data, len); 943 iwl_print_hex_dump(drv, IWL_DL_FW, (u8 *)data, len);
@@ -989,13 +1075,14 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
989 struct iwl_ucode_header *ucode; 1075 struct iwl_ucode_header *ucode;
990 struct iwlwifi_opmode_table *op; 1076 struct iwlwifi_opmode_table *op;
991 int err; 1077 int err;
992 struct iwl_firmware_pieces pieces; 1078 struct iwl_firmware_pieces *pieces;
993 const unsigned int api_max = drv->cfg->ucode_api_max; 1079 const unsigned int api_max = drv->cfg->ucode_api_max;
994 unsigned int api_ok = drv->cfg->ucode_api_ok; 1080 unsigned int api_ok = drv->cfg->ucode_api_ok;
995 const unsigned int api_min = drv->cfg->ucode_api_min; 1081 const unsigned int api_min = drv->cfg->ucode_api_min;
996 u32 api_ver; 1082 u32 api_ver;
997 int i; 1083 int i;
998 bool load_module = false; 1084 bool load_module = false;
1085 u32 hw_rev = drv->trans->hw_rev;
999 1086
1000 fw->ucode_capa.max_probe_length = IWL_DEFAULT_MAX_PROBE_LENGTH; 1087 fw->ucode_capa.max_probe_length = IWL_DEFAULT_MAX_PROBE_LENGTH;
1001 fw->ucode_capa.standard_phy_calibration_size = 1088 fw->ucode_capa.standard_phy_calibration_size =
@@ -1005,7 +1092,9 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1005 if (!api_ok) 1092 if (!api_ok)
1006 api_ok = api_max; 1093 api_ok = api_max;
1007 1094
1008 memset(&pieces, 0, sizeof(pieces)); 1095 pieces = kzalloc(sizeof(*pieces), GFP_KERNEL);
1096 if (!pieces)
1097 return;
1009 1098
1010 if (!ucode_raw) { 1099 if (!ucode_raw) {
1011 if (drv->fw_index <= api_ok) 1100 if (drv->fw_index <= api_ok)
@@ -1028,10 +1117,10 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1028 ucode = (struct iwl_ucode_header *)ucode_raw->data; 1117 ucode = (struct iwl_ucode_header *)ucode_raw->data;
1029 1118
1030 if (ucode->ver) 1119 if (ucode->ver)
1031 err = iwl_parse_v1_v2_firmware(drv, ucode_raw, &pieces); 1120 err = iwl_parse_v1_v2_firmware(drv, ucode_raw, pieces);
1032 else 1121 else
1033 err = iwl_parse_tlv_firmware(drv, ucode_raw, &pieces, 1122 err = iwl_parse_tlv_firmware(drv, ucode_raw, pieces,
1034 &fw->ucode_capa); 1123 &fw->ucode_capa);
1035 1124
1036 if (err) 1125 if (err)
1037 goto try_again; 1126 goto try_again;
@@ -1071,7 +1160,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1071 * In mvm uCode there is no difference between data and instructions 1160 * In mvm uCode there is no difference between data and instructions
1072 * sections. 1161 * sections.
1073 */ 1162 */
1074 if (!fw->mvm_fw && validate_sec_sizes(drv, &pieces, drv->cfg)) 1163 if (!fw->mvm_fw && validate_sec_sizes(drv, pieces, drv->cfg))
1075 goto try_again; 1164 goto try_again;
1076 1165
1077 /* Allocate ucode buffers for card's bus-master loading ... */ 1166 /* Allocate ucode buffers for card's bus-master loading ... */
@@ -1080,9 +1169,33 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1080 * 1) unmodified from disk 1169 * 1) unmodified from disk
1081 * 2) backup cache for save/restore during power-downs */ 1170 * 2) backup cache for save/restore during power-downs */
1082 for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) 1171 for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
1083 if (iwl_alloc_ucode(drv, &pieces, i)) 1172 if (iwl_alloc_ucode(drv, pieces, i))
1084 goto out_free_fw; 1173 goto out_free_fw;
1085 1174
1175 if (pieces->dbg_dest_tlv) {
1176 drv->fw.dbg_dest_tlv =
1177 kmemdup(pieces->dbg_dest_tlv,
1178 sizeof(*pieces->dbg_dest_tlv) +
1179 sizeof(pieces->dbg_dest_tlv->reg_ops[0]) *
1180 drv->fw.dbg_dest_reg_num, GFP_KERNEL);
1181
1182 if (!drv->fw.dbg_dest_tlv)
1183 goto out_free_fw;
1184 }
1185
1186 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_conf_tlv); i++) {
1187 if (pieces->dbg_conf_tlv[i]) {
1188 drv->fw.dbg_conf_tlv_len[i] =
1189 pieces->dbg_conf_tlv_len[i];
1190 drv->fw.dbg_conf_tlv[i] =
1191 kmemdup(pieces->dbg_conf_tlv[i],
1192 drv->fw.dbg_conf_tlv_len[i],
1193 GFP_KERNEL);
1194 if (!drv->fw.dbg_conf_tlv[i])
1195 goto out_free_fw;
1196 }
1197 }
1198
1086 /* Now that we can no longer fail, copy information */ 1199 /* Now that we can no longer fail, copy information */
1087 1200
1088 /* 1201 /*
@@ -1090,20 +1203,20 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1090 * for each event, which is of mode 1 (including timestamp) for all 1203 * for each event, which is of mode 1 (including timestamp) for all
1091 * new microcodes that include this information. 1204 * new microcodes that include this information.
1092 */ 1205 */
1093 fw->init_evtlog_ptr = pieces.init_evtlog_ptr; 1206 fw->init_evtlog_ptr = pieces->init_evtlog_ptr;
1094 if (pieces.init_evtlog_size) 1207 if (pieces->init_evtlog_size)
1095 fw->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; 1208 fw->init_evtlog_size = (pieces->init_evtlog_size - 16)/12;
1096 else 1209 else
1097 fw->init_evtlog_size = 1210 fw->init_evtlog_size =
1098 drv->cfg->base_params->max_event_log_size; 1211 drv->cfg->base_params->max_event_log_size;
1099 fw->init_errlog_ptr = pieces.init_errlog_ptr; 1212 fw->init_errlog_ptr = pieces->init_errlog_ptr;
1100 fw->inst_evtlog_ptr = pieces.inst_evtlog_ptr; 1213 fw->inst_evtlog_ptr = pieces->inst_evtlog_ptr;
1101 if (pieces.inst_evtlog_size) 1214 if (pieces->inst_evtlog_size)
1102 fw->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; 1215 fw->inst_evtlog_size = (pieces->inst_evtlog_size - 16)/12;
1103 else 1216 else
1104 fw->inst_evtlog_size = 1217 fw->inst_evtlog_size =
1105 drv->cfg->base_params->max_event_log_size; 1218 drv->cfg->base_params->max_event_log_size;
1106 fw->inst_errlog_ptr = pieces.inst_errlog_ptr; 1219 fw->inst_errlog_ptr = pieces->inst_errlog_ptr;
1107 1220
1108 /* 1221 /*
1109 * figure out the offset of chain noise reset and gain commands 1222 * figure out the offset of chain noise reset and gain commands
@@ -1162,10 +1275,55 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1162 op->name, err); 1275 op->name, err);
1163#endif 1276#endif
1164 } 1277 }
1278
1279 /*
1280 * We may have loaded the wrong FW file in 8000 HW family if it is an
1281 * A-step card, and if drv->trans->hw_rev wasn't properly read when
1282 * the FW file had been loaded. (This might happen in SDIO.) In such a
1283 * case - unload and reload the correct file.
1284 *
1285 * TODO:
1286 * Once there is only one supported step for 8000 family - delete this!
1287 */
1288 if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000 &&
1289 CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_A_STEP &&
1290 drv->trans->hw_rev != hw_rev) {
1291 char firmware_name[32];
1292
1293 /* Free previous FW resources */
1294 if (drv->op_mode)
1295 _iwl_op_mode_stop(drv);
1296 iwl_dealloc_ucode(drv);
1297
1298 /* Build name of correct-step FW */
1299 snprintf(firmware_name, sizeof(firmware_name),
1300 strrchr(drv->firmware_name, '-'));
1301 snprintf(drv->firmware_name, sizeof(drv->firmware_name),
1302 "%s%s", drv->cfg->fw_name_pre, firmware_name);
1303
1304 /* Clear data before loading correct FW */
1305 list_del(&drv->list);
1306
1307 /* Request correct FW file this time */
1308 IWL_DEBUG_INFO(drv, "attempting to load A-step FW %s\n",
1309 drv->firmware_name);
1310 err = request_firmware(&ucode_raw, drv->firmware_name,
1311 drv->trans->dev);
1312 if (err) {
1313 IWL_ERR(drv, "Failed swapping FW!\n");
1314 goto out_unbind;
1315 }
1316
1317 /* Redo callback function - this time with right FW */
1318 iwl_req_fw_callback(ucode_raw, context);
1319 }
1320
1321 kfree(pieces);
1165 return; 1322 return;
1166 1323
1167 try_again: 1324 try_again:
1168 /* try next, if any */ 1325 /* try next, if any */
1326 kfree(pieces);
1169 release_firmware(ucode_raw); 1327 release_firmware(ucode_raw);
1170 if (iwl_request_firmware(drv, false)) 1328 if (iwl_request_firmware(drv, false))
1171 goto out_unbind; 1329 goto out_unbind;
@@ -1176,6 +1334,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1176 iwl_dealloc_ucode(drv); 1334 iwl_dealloc_ucode(drv);
1177 release_firmware(ucode_raw); 1335 release_firmware(ucode_raw);
1178 out_unbind: 1336 out_unbind:
1337 kfree(pieces);
1179 complete(&drv->request_firmware_complete); 1338 complete(&drv->request_firmware_complete);
1180 device_release_driver(drv->trans->dev); 1339 device_release_driver(drv->trans->dev);
1181} 1340}
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
index e30a41d04c8b..20a8a64c9fe3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
@@ -81,6 +81,7 @@
81 * @IWL_FW_ERROR_DUMP_FW_MONITOR: firmware monitor 81 * @IWL_FW_ERROR_DUMP_FW_MONITOR: firmware monitor
82 * @IWL_FW_ERROR_DUMP_PRPH: range of periphery registers - there can be several 82 * @IWL_FW_ERROR_DUMP_PRPH: range of periphery registers - there can be several
83 * sections like this in a single file. 83 * sections like this in a single file.
84 * @IWL_FW_ERROR_DUMP_FH_REGS: range of FH registers
84 */ 85 */
85enum iwl_fw_error_dump_type { 86enum iwl_fw_error_dump_type {
86 IWL_FW_ERROR_DUMP_SRAM = 0, 87 IWL_FW_ERROR_DUMP_SRAM = 0,
@@ -90,6 +91,8 @@ enum iwl_fw_error_dump_type {
90 IWL_FW_ERROR_DUMP_DEV_FW_INFO = 4, 91 IWL_FW_ERROR_DUMP_DEV_FW_INFO = 4,
91 IWL_FW_ERROR_DUMP_FW_MONITOR = 5, 92 IWL_FW_ERROR_DUMP_FW_MONITOR = 5,
92 IWL_FW_ERROR_DUMP_PRPH = 6, 93 IWL_FW_ERROR_DUMP_PRPH = 6,
94 IWL_FW_ERROR_DUMP_TXF = 7,
95 IWL_FW_ERROR_DUMP_FH_REGS = 8,
93 96
94 IWL_FW_ERROR_DUMP_MAX, 97 IWL_FW_ERROR_DUMP_MAX,
95}; 98};
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
index 401f7be36b93..f2a047f6bb3e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
@@ -131,6 +131,9 @@ enum iwl_ucode_tlv_type {
131 IWL_UCODE_TLV_API_CHANGES_SET = 29, 131 IWL_UCODE_TLV_API_CHANGES_SET = 29,
132 IWL_UCODE_TLV_ENABLED_CAPABILITIES = 30, 132 IWL_UCODE_TLV_ENABLED_CAPABILITIES = 30,
133 IWL_UCODE_TLV_N_SCAN_CHANNELS = 31, 133 IWL_UCODE_TLV_N_SCAN_CHANNELS = 31,
134 IWL_UCODE_TLV_SEC_RT_USNIFFER = 34,
135 IWL_UCODE_TLV_FW_DBG_DEST = 38,
136 IWL_UCODE_TLV_FW_DBG_CONF = 39,
134}; 137};
135 138
136struct iwl_ucode_tlv { 139struct iwl_ucode_tlv {
@@ -179,4 +182,309 @@ struct iwl_ucode_capa {
179 __le32 api_capa; 182 __le32 api_capa;
180} __packed; 183} __packed;
181 184
185/**
186 * enum iwl_ucode_tlv_flag - ucode API flags
187 * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
188 * was a separate TLV but moved here to save space.
189 * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID,
190 * treats good CRC threshold as a boolean
191 * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
192 * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.
193 * @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS
194 * @IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT: This uCode image supports uAPSD
195 * @IWL_UCODE_TLV_FLAGS_SHORT_BL: 16 entries of black list instead of 64 in scan
196 * offload profile config command.
197 * @IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six
198 * (rather than two) IPv6 addresses
199 * @IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID: not sending a probe with the SSID element
200 * from the probe request template.
201 * @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL: new NS offload (small version)
202 * @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE: new NS offload (large version)
203 * @IWL_UCODE_TLV_FLAGS_P2P_PM: P2P client supports PM as a stand alone MAC
204 * @IWL_UCODE_TLV_FLAGS_P2P_BSS_PS_DCM: support power save on BSS station and
205 * P2P client interfaces simultaneously if they are in different bindings.
206 * @IWL_UCODE_TLV_FLAGS_P2P_BSS_PS_SCM: support power save on BSS station and
207 * P2P client interfaces simultaneously if they are in same bindings.
208 * @IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT: General support for uAPSD
209 * @IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD: P2P client supports uAPSD power save
210 * @IWL_UCODE_TLV_FLAGS_BCAST_FILTERING: uCode supports broadcast filtering.
211 * @IWL_UCODE_TLV_FLAGS_GO_UAPSD: AP/GO interfaces support uAPSD clients
212 * @IWL_UCODE_TLV_FLAGS_EBS_SUPPORT: this uCode image supports EBS.
213 */
214enum iwl_ucode_tlv_flag {
215 IWL_UCODE_TLV_FLAGS_PAN = BIT(0),
216 IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1),
217 IWL_UCODE_TLV_FLAGS_MFP = BIT(2),
218 IWL_UCODE_TLV_FLAGS_P2P = BIT(3),
219 IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4),
220 IWL_UCODE_TLV_FLAGS_SHORT_BL = BIT(7),
221 IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS = BIT(10),
222 IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID = BIT(12),
223 IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL = BIT(15),
224 IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE = BIT(16),
225 IWL_UCODE_TLV_FLAGS_P2P_PM = BIT(21),
226 IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM = BIT(22),
227 IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_SCM = BIT(23),
228 IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT = BIT(24),
229 IWL_UCODE_TLV_FLAGS_EBS_SUPPORT = BIT(25),
230 IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD = BIT(26),
231 IWL_UCODE_TLV_FLAGS_BCAST_FILTERING = BIT(29),
232 IWL_UCODE_TLV_FLAGS_GO_UAPSD = BIT(30),
233};
234
235/**
236 * enum iwl_ucode_tlv_api - ucode api
237 * @IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID: wowlan config includes tid field.
238 * @IWL_UCODE_TLV_CAPA_EXTENDED_BEACON: Support Extended beacon notification
239 * @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex
240 * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA.
241 * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
242 * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API.
243 * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif.
244 * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time
245 * longer than the passive one, which is essential for fragmented scan.
246 */
247enum iwl_ucode_tlv_api {
248 IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0),
249 IWL_UCODE_TLV_CAPA_EXTENDED_BEACON = BIT(1),
250 IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3),
251 IWL_UCODE_TLV_API_CSA_FLOW = BIT(4),
252 IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5),
253 IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6),
254 IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7),
255 IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8),
256};
257
258/**
259 * enum iwl_ucode_tlv_capa - ucode capabilities
260 * @IWL_UCODE_TLV_CAPA_D0I3_SUPPORT: supports D0i3
261 * @IWL_UCODE_TLV_CAPA_LAR_SUPPORT: supports Location Aware Regulatory
262 * @IWL_UCODE_TLV_CAPA_UMAC_SCAN: supports UMAC scan.
263 * @IWL_UCODE_TLV_CAPA_TDLS_SUPPORT: support basic TDLS functionality
264 * @IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT: supports insertion of current
265 * tx power value into TPC Report action frame and Link Measurement Report
266 * action frame
267 * @IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT: supports updating current
268 * channel in DS parameter set element in probe requests.
269 * @IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT: supports adding TPC Report IE in
270 * probe requests.
271 * @IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT: supports Quiet Period requests
272 * @IWL_UCODE_TLV_CAPA_DQA_SUPPORT: supports dynamic queue allocation (DQA),
273 * which also implies support for the scheduler configuration command
274 * @IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH: supports TDLS channel switching
275 * @IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT: supports Hot Spot Command
276 */
277enum iwl_ucode_tlv_capa {
278 IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0),
279 IWL_UCODE_TLV_CAPA_LAR_SUPPORT = BIT(1),
280 IWL_UCODE_TLV_CAPA_UMAC_SCAN = BIT(2),
281 IWL_UCODE_TLV_CAPA_TDLS_SUPPORT = BIT(6),
282 IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT = BIT(8),
283 IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT = BIT(9),
284 IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT = BIT(10),
285 IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT = BIT(11),
286 IWL_UCODE_TLV_CAPA_DQA_SUPPORT = BIT(12),
287 IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH = BIT(13),
288 IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT = BIT(18),
289};
290
291/* The default calibrate table size if not specified by firmware file */
292#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE 18
293#define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE 19
294#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE 253
295
296/* The default max probe length if not specified by the firmware file */
297#define IWL_DEFAULT_MAX_PROBE_LENGTH 200
298
299/*
300 * For 16.0 uCode and above, there is no differentiation between sections,
301 * just an offset to the HW address.
302 */
303#define IWL_UCODE_SECTION_MAX 12
304#define IWL_API_ARRAY_SIZE 1
305#define IWL_CAPABILITIES_ARRAY_SIZE 1
306#define CPU1_CPU2_SEPARATOR_SECTION 0xFFFFCCCC
307
308/* uCode version contains 4 values: Major/Minor/API/Serial */
309#define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24)
310#define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16)
311#define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8)
312#define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF)
313
314/*
315 * Calibration control struct.
316 * Sent as part of the phy configuration command.
317 * @flow_trigger: bitmap for which calibrations to perform according to
318 * flow triggers.
319 * @event_trigger: bitmap for which calibrations to perform according to
320 * event triggers.
321 */
322struct iwl_tlv_calib_ctrl {
323 __le32 flow_trigger;
324 __le32 event_trigger;
325} __packed;
326
327enum iwl_fw_phy_cfg {
328 FW_PHY_CFG_RADIO_TYPE_POS = 0,
329 FW_PHY_CFG_RADIO_TYPE = 0x3 << FW_PHY_CFG_RADIO_TYPE_POS,
330 FW_PHY_CFG_RADIO_STEP_POS = 2,
331 FW_PHY_CFG_RADIO_STEP = 0x3 << FW_PHY_CFG_RADIO_STEP_POS,
332 FW_PHY_CFG_RADIO_DASH_POS = 4,
333 FW_PHY_CFG_RADIO_DASH = 0x3 << FW_PHY_CFG_RADIO_DASH_POS,
334 FW_PHY_CFG_TX_CHAIN_POS = 16,
335 FW_PHY_CFG_TX_CHAIN = 0xf << FW_PHY_CFG_TX_CHAIN_POS,
336 FW_PHY_CFG_RX_CHAIN_POS = 20,
337 FW_PHY_CFG_RX_CHAIN = 0xf << FW_PHY_CFG_RX_CHAIN_POS,
338};
339
340#define IWL_UCODE_MAX_CS 1
341
342/**
343 * struct iwl_fw_cipher_scheme - a cipher scheme supported by FW.
344 * @cipher: a cipher suite selector
345 * @flags: cipher scheme flags (currently reserved for a future use)
346 * @hdr_len: a size of MPDU security header
347 * @pn_len: a size of PN
348 * @pn_off: an offset of pn from the beginning of the security header
349 * @key_idx_off: an offset of key index byte in the security header
350 * @key_idx_mask: a bit mask of key_idx bits
351 * @key_idx_shift: bit shift needed to get key_idx
352 * @mic_len: mic length in bytes
353 * @hw_cipher: a HW cipher index used in host commands
354 */
355struct iwl_fw_cipher_scheme {
356 __le32 cipher;
357 u8 flags;
358 u8 hdr_len;
359 u8 pn_len;
360 u8 pn_off;
361 u8 key_idx_off;
362 u8 key_idx_mask;
363 u8 key_idx_shift;
364 u8 mic_len;
365 u8 hw_cipher;
366} __packed;
367
368enum iwl_fw_dbg_reg_operator {
369 CSR_ASSIGN,
370 CSR_SETBIT,
371 CSR_CLEARBIT,
372
373 PRPH_ASSIGN,
374 PRPH_SETBIT,
375 PRPH_CLEARBIT,
376};
377
378/**
379 * struct iwl_fw_dbg_reg_op - an operation on a register
380 *
381 * @op: %enum iwl_fw_dbg_reg_operator
382 * @addr: offset of the register
383 * @val: value
384 */
385struct iwl_fw_dbg_reg_op {
386 u8 op;
387 u8 reserved[3];
388 __le32 addr;
389 __le32 val;
390} __packed;
391
392/**
393 * enum iwl_fw_dbg_monitor_mode - available monitor recording modes
394 *
395 * @SMEM_MODE: monitor stores the data in SMEM
396 * @EXTERNAL_MODE: monitor stores the data in allocated DRAM
397 * @MARBH_MODE: monitor stores the data in MARBH buffer
398 */
399enum iwl_fw_dbg_monitor_mode {
400 SMEM_MODE = 0,
401 EXTERNAL_MODE = 1,
402 MARBH_MODE = 2,
403};
404
405/**
406 * struct iwl_fw_dbg_dest_tlv - configures the destination of the debug data
407 *
408 * @version: version of the TLV - currently 0
409 * @monitor_mode: %enum iwl_fw_dbg_monitor_mode
410 * @base_reg: addr of the base addr register (PRPH)
411 * @end_reg: addr of the end addr register (PRPH)
412 * @write_ptr_reg: the addr of the reg of the write pointer
413 * @wrap_count: the addr of the reg of the wrap_count
414 * @base_shift: shift right of the base addr reg
415 * @end_shift: shift right of the end addr reg
416 * @reg_ops: array of registers operations
417 *
418 * This parses IWL_UCODE_TLV_FW_DBG_DEST
419 */
420struct iwl_fw_dbg_dest_tlv {
421 u8 version;
422 u8 monitor_mode;
423 u8 reserved[2];
424 __le32 base_reg;
425 __le32 end_reg;
426 __le32 write_ptr_reg;
427 __le32 wrap_count;
428 u8 base_shift;
429 u8 end_shift;
430 struct iwl_fw_dbg_reg_op reg_ops[0];
431} __packed;
432
433struct iwl_fw_dbg_conf_hcmd {
434 u8 id;
435 u8 reserved;
436 __le16 len;
437 u8 data[0];
438} __packed;
439
440/**
441 * struct iwl_fw_dbg_trigger - a TLV that describes a debug configuration
442 *
443 * @enabled: is this trigger enabled
444 * @reserved:
445 * @len: length, in bytes, of the %trigger field
446 * @trigger: pointer to a trigger struct
447 */
448struct iwl_fw_dbg_trigger {
449 u8 enabled;
450 u8 reserved;
451 u8 len;
452 u8 trigger[0];
453} __packed;
454
455/**
456 * enum iwl_fw_dbg_conf - configurations available
457 *
458 * @FW_DBG_CUSTOM: take this configuration from alive
459 * Note that the trigger is NO-OP for this configuration
460 */
461enum iwl_fw_dbg_conf {
462 FW_DBG_CUSTOM = 0,
463
464 /* must be last */
465 FW_DBG_MAX,
466 FW_DBG_INVALID = 0xff,
467};
468
469/**
470 * struct iwl_fw_dbg_conf_tlv - a TLV that describes a debug configuration
471 *
472 * @id: %enum iwl_fw_dbg_conf
473 * @usniffer: should the uSniffer image be used
474 * @num_of_hcmds: how many HCMDs to send are present here
475 * @hcmd: a variable length host command to be sent to apply the configuration.
476 * If there is more than one HCMD to send, they will appear one after the
477 * other and be sent in the order that they appear in.
478 * This parses IWL_UCODE_TLV_FW_DBG_CONF
479 */
480struct iwl_fw_dbg_conf_tlv {
481 u8 id;
482 u8 usniffer;
483 u8 reserved;
484 u8 num_of_hcmds;
485 struct iwl_fw_dbg_conf_hcmd hcmd;
486
487 /* struct iwl_fw_dbg_trigger sits after all variable length hcmds */
488} __packed;
489
182#endif /* __iwl_fw_file_h__ */ 490#endif /* __iwl_fw_file_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index a94d244459d7..e6dc3b870949 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -70,116 +70,6 @@
70#include "iwl-fw-file.h" 70#include "iwl-fw-file.h"
71 71
72/** 72/**
73 * enum iwl_ucode_tlv_flag - ucode API flags
74 * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
75 * was a separate TLV but moved here to save space.
76 * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID,
77 * treats good CRC threshold as a boolean
78 * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
79 * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P.
80 * @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS
81 * @IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT: This uCode image supports uAPSD
82 * @IWL_UCODE_TLV_FLAGS_SHORT_BL: 16 entries of black list instead of 64 in scan
83 * offload profile config command.
84 * @IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six
85 * (rather than two) IPv6 addresses
86 * @IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID: not sending a probe with the SSID element
87 * from the probe request template.
88 * @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL: new NS offload (small version)
89 * @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE: new NS offload (large version)
90 * @IWL_UCODE_TLV_FLAGS_P2P_PM: P2P client supports PM as a stand alone MAC
91 * @IWL_UCODE_TLV_FLAGS_P2P_BSS_PS_DCM: support power save on BSS station and
92 * P2P client interfaces simultaneously if they are in different bindings.
93 * @IWL_UCODE_TLV_FLAGS_P2P_BSS_PS_SCM: support power save on BSS station and
94 * P2P client interfaces simultaneously if they are in same bindings.
95 * @IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT: General support for uAPSD
96 * @IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD: P2P client supports uAPSD power save
97 * @IWL_UCODE_TLV_FLAGS_BCAST_FILTERING: uCode supports broadcast filtering.
98 * @IWL_UCODE_TLV_FLAGS_GO_UAPSD: AP/GO interfaces support uAPSD clients
99 * @IWL_UCODE_TLV_FLAGS_EBS_SUPPORT: this uCode image supports EBS.
100 */
101enum iwl_ucode_tlv_flag {
102 IWL_UCODE_TLV_FLAGS_PAN = BIT(0),
103 IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1),
104 IWL_UCODE_TLV_FLAGS_MFP = BIT(2),
105 IWL_UCODE_TLV_FLAGS_P2P = BIT(3),
106 IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4),
107 IWL_UCODE_TLV_FLAGS_SHORT_BL = BIT(7),
108 IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS = BIT(10),
109 IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID = BIT(12),
110 IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL = BIT(15),
111 IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE = BIT(16),
112 IWL_UCODE_TLV_FLAGS_P2P_PM = BIT(21),
113 IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_DCM = BIT(22),
114 IWL_UCODE_TLV_FLAGS_BSS_P2P_PS_SCM = BIT(23),
115 IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT = BIT(24),
116 IWL_UCODE_TLV_FLAGS_EBS_SUPPORT = BIT(25),
117 IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD = BIT(26),
118 IWL_UCODE_TLV_FLAGS_BCAST_FILTERING = BIT(29),
119 IWL_UCODE_TLV_FLAGS_GO_UAPSD = BIT(30),
120};
121
122/**
123 * enum iwl_ucode_tlv_api - ucode api
124 * @IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID: wowlan config includes tid field.
125 * @IWL_UCODE_TLV_CAPA_EXTENDED_BEACON: Support Extended beacon notification
126 * @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex
127 * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA.
128 * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
129 * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API.
130 * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif.
131 * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time
132 * longer than the passive one, which is essential for fragmented scan.
133 */
134enum iwl_ucode_tlv_api {
135 IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0),
136 IWL_UCODE_TLV_CAPA_EXTENDED_BEACON = BIT(1),
137 IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3),
138 IWL_UCODE_TLV_API_CSA_FLOW = BIT(4),
139 IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5),
140 IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6),
141 IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7),
142 IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8),
143};
144
145/**
146 * enum iwl_ucode_tlv_capa - ucode capabilities
147 * @IWL_UCODE_TLV_CAPA_D0I3_SUPPORT: supports D0i3
148 * @IWL_UCODE_TLV_CAPA_UMAC_SCAN: supports UMAC scan.
149 * @IWL_UCODE_TLV_CAPA_TDLS_SUPPORT: support basic TDLS functionality
150 * @IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT: supports insertion of current
151 * tx power value into TPC Report action frame and Link Measurement Report
152 * action frame
153 * @IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT: supports updating current
154 * channel in DS parameter set element in probe requests.
155 * @IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT: supports adding TPC Report IE in
156 * probe requests.
157 * @IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT: supports Quiet Period requests
158 * @IWL_UCODE_TLV_CAPA_DQA_SUPPORT: supports dynamic queue allocation (DQA),
159 * which also implies support for the scheduler configuration command
160 * @IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH: supports TDLS channel switching
161 */
162enum iwl_ucode_tlv_capa {
163 IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0),
164 IWL_UCODE_TLV_CAPA_UMAC_SCAN = BIT(2),
165 IWL_UCODE_TLV_CAPA_TDLS_SUPPORT = BIT(6),
166 IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT = BIT(8),
167 IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT = BIT(9),
168 IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT = BIT(10),
169 IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT = BIT(11),
170 IWL_UCODE_TLV_CAPA_DQA_SUPPORT = BIT(12),
171 IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH = BIT(13),
172};
173
174/* The default calibrate table size if not specified by firmware file */
175#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE 18
176#define IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE 19
177#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE 253
178
179/* The default max probe length if not specified by the firmware file */
180#define IWL_DEFAULT_MAX_PROBE_LENGTH 200
181
182/**
183 * enum iwl_ucode_type 73 * enum iwl_ucode_type
184 * 74 *
185 * The type of ucode. 75 * The type of ucode.
@@ -187,11 +77,13 @@ enum iwl_ucode_tlv_capa {
187 * @IWL_UCODE_REGULAR: Normal runtime ucode 77 * @IWL_UCODE_REGULAR: Normal runtime ucode
188 * @IWL_UCODE_INIT: Initial ucode 78 * @IWL_UCODE_INIT: Initial ucode
189 * @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode 79 * @IWL_UCODE_WOWLAN: Wake on Wireless enabled ucode
80 * @IWL_UCODE_REGULAR_USNIFFER: Normal runtime ucode when using usniffer image
190 */ 81 */
191enum iwl_ucode_type { 82enum iwl_ucode_type {
192 IWL_UCODE_REGULAR, 83 IWL_UCODE_REGULAR,
193 IWL_UCODE_INIT, 84 IWL_UCODE_INIT,
194 IWL_UCODE_WOWLAN, 85 IWL_UCODE_WOWLAN,
86 IWL_UCODE_REGULAR_USNIFFER,
195 IWL_UCODE_TYPE_MAX, 87 IWL_UCODE_TYPE_MAX,
196}; 88};
197 89
@@ -206,14 +98,6 @@ enum iwl_ucode_sec {
206 IWL_UCODE_SECTION_DATA, 98 IWL_UCODE_SECTION_DATA,
207 IWL_UCODE_SECTION_INST, 99 IWL_UCODE_SECTION_INST,
208}; 100};
209/*
210 * For 16.0 uCode and above, there is no differentiation between sections,
211 * just an offset to the HW address.
212 */
213#define IWL_UCODE_SECTION_MAX 12
214#define IWL_API_ARRAY_SIZE 1
215#define IWL_CAPABILITIES_ARRAY_SIZE 1
216#define CPU1_CPU2_SEPARATOR_SECTION 0xFFFFCCCC
217 101
218struct iwl_ucode_capabilities { 102struct iwl_ucode_capabilities {
219 u32 max_probe_length; 103 u32 max_probe_length;
@@ -241,66 +125,6 @@ struct iwl_sf_region {
241 u32 size; 125 u32 size;
242}; 126};
243 127
244/* uCode version contains 4 values: Major/Minor/API/Serial */
245#define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24)
246#define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16)
247#define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8)
248#define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF)
249
250/*
251 * Calibration control struct.
252 * Sent as part of the phy configuration command.
253 * @flow_trigger: bitmap for which calibrations to perform according to
254 * flow triggers.
255 * @event_trigger: bitmap for which calibrations to perform according to
256 * event triggers.
257 */
258struct iwl_tlv_calib_ctrl {
259 __le32 flow_trigger;
260 __le32 event_trigger;
261} __packed;
262
263enum iwl_fw_phy_cfg {
264 FW_PHY_CFG_RADIO_TYPE_POS = 0,
265 FW_PHY_CFG_RADIO_TYPE = 0x3 << FW_PHY_CFG_RADIO_TYPE_POS,
266 FW_PHY_CFG_RADIO_STEP_POS = 2,
267 FW_PHY_CFG_RADIO_STEP = 0x3 << FW_PHY_CFG_RADIO_STEP_POS,
268 FW_PHY_CFG_RADIO_DASH_POS = 4,
269 FW_PHY_CFG_RADIO_DASH = 0x3 << FW_PHY_CFG_RADIO_DASH_POS,
270 FW_PHY_CFG_TX_CHAIN_POS = 16,
271 FW_PHY_CFG_TX_CHAIN = 0xf << FW_PHY_CFG_TX_CHAIN_POS,
272 FW_PHY_CFG_RX_CHAIN_POS = 20,
273 FW_PHY_CFG_RX_CHAIN = 0xf << FW_PHY_CFG_RX_CHAIN_POS,
274};
275
276#define IWL_UCODE_MAX_CS 1
277
278/**
279 * struct iwl_fw_cipher_scheme - a cipher scheme supported by FW.
280 * @cipher: a cipher suite selector
281 * @flags: cipher scheme flags (currently reserved for a future use)
282 * @hdr_len: a size of MPDU security header
283 * @pn_len: a size of PN
284 * @pn_off: an offset of pn from the beginning of the security header
285 * @key_idx_off: an offset of key index byte in the security header
286 * @key_idx_mask: a bit mask of key_idx bits
287 * @key_idx_shift: bit shift needed to get key_idx
288 * @mic_len: mic length in bytes
289 * @hw_cipher: a HW cipher index used in host commands
290 */
291struct iwl_fw_cipher_scheme {
292 __le32 cipher;
293 u8 flags;
294 u8 hdr_len;
295 u8 pn_len;
296 u8 pn_off;
297 u8 key_idx_off;
298 u8 key_idx_mask;
299 u8 key_idx_shift;
300 u8 mic_len;
301 u8 hw_cipher;
302} __packed;
303
304/** 128/**
305 * struct iwl_fw_cscheme_list - a cipher scheme list 129 * struct iwl_fw_cscheme_list - a cipher scheme list
306 * @size: a number of entries 130 * @size: a number of entries
@@ -327,6 +151,11 @@ struct iwl_fw_cscheme_list {
327 * @inst_errlog_ptr: error log offfset for runtime ucode. 151 * @inst_errlog_ptr: error log offfset for runtime ucode.
328 * @mvm_fw: indicates this is MVM firmware 152 * @mvm_fw: indicates this is MVM firmware
329 * @cipher_scheme: optional external cipher scheme. 153 * @cipher_scheme: optional external cipher scheme.
154 * @human_readable: human readable version
155 * @dbg_dest_tlv: points to the destination TLV for debug
156 * @dbg_conf_tlv: array of pointers to configuration TLVs for debug
157 * @dbg_conf_tlv_len: lengths of the @dbg_conf_tlv entries
158 * @dbg_dest_reg_num: num of reg_ops in %dbg_dest_tlv
330 */ 159 */
331struct iwl_fw { 160struct iwl_fw {
332 u32 ucode_ver; 161 u32 ucode_ver;
@@ -351,6 +180,68 @@ struct iwl_fw {
351 180
352 struct ieee80211_cipher_scheme cs[IWL_UCODE_MAX_CS]; 181 struct ieee80211_cipher_scheme cs[IWL_UCODE_MAX_CS];
353 u8 human_readable[FW_VER_HUMAN_READABLE_SZ]; 182 u8 human_readable[FW_VER_HUMAN_READABLE_SZ];
183
184 struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
185 struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX];
186 size_t dbg_conf_tlv_len[FW_DBG_MAX];
187
188 u8 dbg_dest_reg_num;
354}; 189};
355 190
191static inline const char *get_fw_dbg_mode_string(int mode)
192{
193 switch (mode) {
194 case SMEM_MODE:
195 return "SMEM";
196 case EXTERNAL_MODE:
197 return "EXTERNAL_DRAM";
198 case MARBH_MODE:
199 return "MARBH";
200 default:
201 return "UNKNOWN";
202 }
203}
204
205static inline const struct iwl_fw_dbg_trigger *
206iwl_fw_dbg_conf_get_trigger(const struct iwl_fw *fw, u8 id)
207{
208 const struct iwl_fw_dbg_conf_tlv *conf_tlv = fw->dbg_conf_tlv[id];
209 u8 *ptr;
210 int i;
211
212 if (!conf_tlv)
213 return NULL;
214
215 ptr = (void *)&conf_tlv->hcmd;
216 for (i = 0; i < conf_tlv->num_of_hcmds; i++) {
217 ptr += sizeof(conf_tlv->hcmd);
218 ptr += le16_to_cpu(conf_tlv->hcmd.len);
219 }
220
221 return (const struct iwl_fw_dbg_trigger *)ptr;
222}
223
224static inline bool
225iwl_fw_dbg_conf_enabled(const struct iwl_fw *fw, u8 id)
226{
227 const struct iwl_fw_dbg_trigger *trigger =
228 iwl_fw_dbg_conf_get_trigger(fw, id);
229
230 if (!trigger)
231 return false;
232
233 return trigger->enabled;
234}
235
236static inline bool
237iwl_fw_dbg_conf_usniffer(const struct iwl_fw *fw, u8 id)
238{
239 const struct iwl_fw_dbg_conf_tlv *conf_tlv = fw->dbg_conf_tlv[id];
240
241 if (!conf_tlv)
242 return false;
243
244 return conf_tlv->usniffer;
245}
246
356#endif /* __iwl_fw_h__ */ 247#endif /* __iwl_fw_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 1dae702e97ef..2df51eab1348 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -322,6 +322,7 @@ enum secure_boot_config_reg {
322 LMPM_SECURE_BOOT_CONFIG_INSPECTOR_NOT_REQ = 0x00000002, 322 LMPM_SECURE_BOOT_CONFIG_INSPECTOR_NOT_REQ = 0x00000002,
323}; 323};
324 324
325#define LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0 (0xA01E30)
325#define LMPM_SECURE_BOOT_CPU1_STATUS_ADDR (0x1E30) 326#define LMPM_SECURE_BOOT_CPU1_STATUS_ADDR (0x1E30)
326#define LMPM_SECURE_BOOT_CPU2_STATUS_ADDR (0x1E34) 327#define LMPM_SECURE_BOOT_CPU2_STATUS_ADDR (0x1E34)
327enum secure_boot_status_reg { 328enum secure_boot_status_reg {
@@ -333,6 +334,7 @@ enum secure_boot_status_reg {
333 LMPM_SECURE_BOOT_STATUS_SUCCESS = 0x00000003, 334 LMPM_SECURE_BOOT_STATUS_SUCCESS = 0x00000003,
334}; 335};
335 336
337#define FH_UCODE_LOAD_STATUS (0x1AF0)
336#define CSR_UCODE_LOAD_STATUS_ADDR (0x1E70) 338#define CSR_UCODE_LOAD_STATUS_ADDR (0x1E70)
337enum secure_load_status_reg { 339enum secure_load_status_reg {
338 LMPM_CPU_UCODE_LOADING_STARTED = 0x00000001, 340 LMPM_CPU_UCODE_LOADING_STARTED = 0x00000001,
@@ -349,10 +351,10 @@ enum secure_load_status_reg {
349 351
350#define LMPM_SECURE_INSPECTOR_CODE_MEM_SPACE (0x400000) 352#define LMPM_SECURE_INSPECTOR_CODE_MEM_SPACE (0x400000)
351#define LMPM_SECURE_INSPECTOR_DATA_MEM_SPACE (0x402000) 353#define LMPM_SECURE_INSPECTOR_DATA_MEM_SPACE (0x402000)
352#define LMPM_SECURE_CPU1_HDR_MEM_SPACE (0x404000) 354#define LMPM_SECURE_CPU1_HDR_MEM_SPACE (0x420000)
353#define LMPM_SECURE_CPU2_HDR_MEM_SPACE (0x405000) 355#define LMPM_SECURE_CPU2_HDR_MEM_SPACE (0x420400)
354 356
355#define LMPM_SECURE_TIME_OUT (50000) /* 5 msec */ 357#define LMPM_SECURE_TIME_OUT (100) /* 10 micro */
356 358
357/* Rx FIFO */ 359/* Rx FIFO */
358#define RXF_SIZE_ADDR (0xa00c88) 360#define RXF_SIZE_ADDR (0xa00c88)
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 0289803fa381..028408a6ecba 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -574,6 +574,9 @@ enum iwl_trans_state {
574 * @rx_mpdu_cmd_hdr_size: used for tracing, amount of data before the 574 * @rx_mpdu_cmd_hdr_size: used for tracing, amount of data before the
575 * start of the 802.11 header in the @rx_mpdu_cmd 575 * start of the 802.11 header in the @rx_mpdu_cmd
576 * @dflt_pwr_limit: default power limit fetched from the platform (ACPI) 576 * @dflt_pwr_limit: default power limit fetched from the platform (ACPI)
577 * @dbg_dest_tlv: points to the destination TLV for debug
578 * @dbg_conf_tlv: array of pointers to configuration TLVs for debug
579 * @dbg_dest_reg_num: num of reg_ops in %dbg_dest_tlv
577 */ 580 */
578struct iwl_trans { 581struct iwl_trans {
579 const struct iwl_trans_ops *ops; 582 const struct iwl_trans_ops *ops;
@@ -605,6 +608,10 @@ struct iwl_trans {
605 608
606 u64 dflt_pwr_limit; 609 u64 dflt_pwr_limit;
607 610
611 const struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
612 const struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX];
613 u8 dbg_dest_reg_num;
614
608 /* pointer to trans specific struct */ 615 /* pointer to trans specific struct */
609 /*Ensure that this pointer will always be aligned to sizeof pointer */ 616 /*Ensure that this pointer will always be aligned to sizeof pointer */
610 char trans_specific[0] __aligned(sizeof(void *)); 617 char trans_specific[0] __aligned(sizeof(void *));
diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h
index 17160313b3a9..3bd93476ec1c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/iwlwifi/mvm/constants.h
@@ -94,8 +94,8 @@
94#define IWL_MVM_BT_COEX_MPLUT 1 94#define IWL_MVM_BT_COEX_MPLUT 1
95#define IWL_MVM_BT_COEX_RRC 1 95#define IWL_MVM_BT_COEX_RRC 1
96#define IWL_MVM_BT_COEX_TTC 1 96#define IWL_MVM_BT_COEX_TTC 1
97#define IWL_MVM_BT_COEX_MPLUT_REG0 0x2e402280 97#define IWL_MVM_BT_COEX_MPLUT_REG0 0x28412201
98#define IWL_MVM_BT_COEX_MPLUT_REG1 0x7711a751 98#define IWL_MVM_BT_COEX_MPLUT_REG1 0x11118451
99#define IWL_MVM_BT_COEX_ANTENNA_COUPLING_THRS 30 99#define IWL_MVM_BT_COEX_ANTENNA_COUPLING_THRS 30
100#define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0 100#define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0
101#define IWL_MVM_FW_BCAST_FILTER_PASS_ALL 0 101#define IWL_MVM_FW_BCAST_FILTER_PASS_ALL 0
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 60748bd37954..744de262373e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -786,32 +786,18 @@ static int iwl_mvm_switch_to_d3(struct iwl_mvm *mvm)
786} 786}
787 787
788static int 788static int
789iwl_mvm_send_wowlan_config_cmd(struct iwl_mvm *mvm,
790 const struct iwl_wowlan_config_cmd_v3 *cmd)
791{
792 /* start only with the v2 part of the command */
793 u16 cmd_len = sizeof(cmd->common);
794
795 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID)
796 cmd_len = sizeof(*cmd);
797
798 return iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, 0,
799 cmd_len, cmd);
800}
801
802static int
803iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm, 789iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
804 struct cfg80211_wowlan *wowlan, 790 struct cfg80211_wowlan *wowlan,
805 struct iwl_wowlan_config_cmd_v3 *wowlan_config_cmd, 791 struct iwl_wowlan_config_cmd *wowlan_config_cmd,
806 struct ieee80211_vif *vif, struct iwl_mvm_vif *mvmvif, 792 struct ieee80211_vif *vif, struct iwl_mvm_vif *mvmvif,
807 struct ieee80211_sta *ap_sta) 793 struct ieee80211_sta *ap_sta)
808{ 794{
809 int ret; 795 int ret;
810 struct iwl_mvm_sta *mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv; 796 struct iwl_mvm_sta *mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv;
811 797
812 /* TODO: wowlan_config_cmd->common.wowlan_ba_teardown_tids */ 798 /* TODO: wowlan_config_cmd->wowlan_ba_teardown_tids */
813 799
814 wowlan_config_cmd->common.is_11n_connection = 800 wowlan_config_cmd->is_11n_connection =
815 ap_sta->ht_cap.ht_supported; 801 ap_sta->ht_cap.ht_supported;
816 802
817 /* Query the last used seqno and set it */ 803 /* Query the last used seqno and set it */
@@ -819,32 +805,32 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
819 if (ret < 0) 805 if (ret < 0)
820 return ret; 806 return ret;
821 807
822 wowlan_config_cmd->common.non_qos_seq = cpu_to_le16(ret); 808 wowlan_config_cmd->non_qos_seq = cpu_to_le16(ret);
823 809
824 iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, &wowlan_config_cmd->common); 810 iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, wowlan_config_cmd);
825 811
826 if (wowlan->disconnect) 812 if (wowlan->disconnect)
827 wowlan_config_cmd->common.wakeup_filter |= 813 wowlan_config_cmd->wakeup_filter |=
828 cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS | 814 cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS |
829 IWL_WOWLAN_WAKEUP_LINK_CHANGE); 815 IWL_WOWLAN_WAKEUP_LINK_CHANGE);
830 if (wowlan->magic_pkt) 816 if (wowlan->magic_pkt)
831 wowlan_config_cmd->common.wakeup_filter |= 817 wowlan_config_cmd->wakeup_filter |=
832 cpu_to_le32(IWL_WOWLAN_WAKEUP_MAGIC_PACKET); 818 cpu_to_le32(IWL_WOWLAN_WAKEUP_MAGIC_PACKET);
833 if (wowlan->gtk_rekey_failure) 819 if (wowlan->gtk_rekey_failure)
834 wowlan_config_cmd->common.wakeup_filter |= 820 wowlan_config_cmd->wakeup_filter |=
835 cpu_to_le32(IWL_WOWLAN_WAKEUP_GTK_REKEY_FAIL); 821 cpu_to_le32(IWL_WOWLAN_WAKEUP_GTK_REKEY_FAIL);
836 if (wowlan->eap_identity_req) 822 if (wowlan->eap_identity_req)
837 wowlan_config_cmd->common.wakeup_filter |= 823 wowlan_config_cmd->wakeup_filter |=
838 cpu_to_le32(IWL_WOWLAN_WAKEUP_EAP_IDENT_REQ); 824 cpu_to_le32(IWL_WOWLAN_WAKEUP_EAP_IDENT_REQ);
839 if (wowlan->four_way_handshake) 825 if (wowlan->four_way_handshake)
840 wowlan_config_cmd->common.wakeup_filter |= 826 wowlan_config_cmd->wakeup_filter |=
841 cpu_to_le32(IWL_WOWLAN_WAKEUP_4WAY_HANDSHAKE); 827 cpu_to_le32(IWL_WOWLAN_WAKEUP_4WAY_HANDSHAKE);
842 if (wowlan->n_patterns) 828 if (wowlan->n_patterns)
843 wowlan_config_cmd->common.wakeup_filter |= 829 wowlan_config_cmd->wakeup_filter |=
844 cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH); 830 cpu_to_le32(IWL_WOWLAN_WAKEUP_PATTERN_MATCH);
845 831
846 if (wowlan->rfkill_release) 832 if (wowlan->rfkill_release)
847 wowlan_config_cmd->common.wakeup_filter |= 833 wowlan_config_cmd->wakeup_filter |=
848 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT); 834 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
849 835
850 if (wowlan->tcp) { 836 if (wowlan->tcp) {
@@ -852,7 +838,7 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
852 * Set the "link change" (really "link lost") flag as well 838 * Set the "link change" (really "link lost") flag as well
853 * since that implies losing the TCP connection. 839 * since that implies losing the TCP connection.
854 */ 840 */
855 wowlan_config_cmd->common.wakeup_filter |= 841 wowlan_config_cmd->wakeup_filter |=
856 cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS | 842 cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS |
857 IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE | 843 IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE |
858 IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET | 844 IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET |
@@ -865,7 +851,7 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
865static int 851static int
866iwl_mvm_wowlan_config(struct iwl_mvm *mvm, 852iwl_mvm_wowlan_config(struct iwl_mvm *mvm,
867 struct cfg80211_wowlan *wowlan, 853 struct cfg80211_wowlan *wowlan,
868 struct iwl_wowlan_config_cmd_v3 *wowlan_config_cmd, 854 struct iwl_wowlan_config_cmd *wowlan_config_cmd,
869 struct ieee80211_vif *vif, struct iwl_mvm_vif *mvmvif, 855 struct ieee80211_vif *vif, struct iwl_mvm_vif *mvmvif,
870 struct ieee80211_sta *ap_sta) 856 struct ieee80211_sta *ap_sta)
871{ 857{
@@ -947,7 +933,9 @@ iwl_mvm_wowlan_config(struct iwl_mvm *mvm,
947 } 933 }
948 } 934 }
949 935
950 ret = iwl_mvm_send_wowlan_config_cmd(mvm, wowlan_config_cmd); 936 ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, 0,
937 sizeof(*wowlan_config_cmd),
938 wowlan_config_cmd);
951 if (ret) 939 if (ret)
952 goto out; 940 goto out;
953 941
@@ -972,7 +960,7 @@ iwl_mvm_netdetect_config(struct iwl_mvm *mvm,
972 struct cfg80211_sched_scan_request *nd_config, 960 struct cfg80211_sched_scan_request *nd_config,
973 struct ieee80211_vif *vif) 961 struct ieee80211_vif *vif)
974{ 962{
975 struct iwl_wowlan_config_cmd_v3 wowlan_config_cmd = {}; 963 struct iwl_wowlan_config_cmd wowlan_config_cmd = {};
976 int ret; 964 int ret;
977 965
978 ret = iwl_mvm_switch_to_d3(mvm); 966 ret = iwl_mvm_switch_to_d3(mvm);
@@ -981,16 +969,51 @@ iwl_mvm_netdetect_config(struct iwl_mvm *mvm,
981 969
982 /* rfkill release can be either for wowlan or netdetect */ 970 /* rfkill release can be either for wowlan or netdetect */
983 if (wowlan->rfkill_release) 971 if (wowlan->rfkill_release)
984 wowlan_config_cmd.common.wakeup_filter |= 972 wowlan_config_cmd.wakeup_filter |=
985 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT); 973 cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT);
986 974
987 ret = iwl_mvm_send_wowlan_config_cmd(mvm, &wowlan_config_cmd); 975 ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, 0,
976 sizeof(wowlan_config_cmd),
977 &wowlan_config_cmd);
988 if (ret) 978 if (ret)
989 return ret; 979 return ret;
990 980
991 ret = iwl_mvm_scan_offload_start(mvm, vif, nd_config, &mvm->nd_ies); 981 ret = iwl_mvm_scan_offload_start(mvm, vif, nd_config, &mvm->nd_ies);
982 if (ret)
983 return ret;
992 984
993 return ret; 985 if (WARN_ON(mvm->nd_match_sets || mvm->nd_channels))
986 return -EBUSY;
987
988 /* save the sched scan matchsets... */
989 if (nd_config->n_match_sets) {
990 mvm->nd_match_sets = kmemdup(nd_config->match_sets,
991 sizeof(*nd_config->match_sets) *
992 nd_config->n_match_sets,
993 GFP_KERNEL);
994 if (mvm->nd_match_sets)
995 mvm->n_nd_match_sets = nd_config->n_match_sets;
996 }
997
998 /* ...and the sched scan channels for later reporting */
999 mvm->nd_channels = kmemdup(nd_config->channels,
1000 sizeof(*nd_config->channels) *
1001 nd_config->n_channels,
1002 GFP_KERNEL);
1003 if (mvm->nd_channels)
1004 mvm->n_nd_channels = nd_config->n_channels;
1005
1006 return 0;
1007}
1008
1009static void iwl_mvm_free_nd(struct iwl_mvm *mvm)
1010{
1011 kfree(mvm->nd_match_sets);
1012 mvm->nd_match_sets = NULL;
1013 mvm->n_nd_match_sets = 0;
1014 kfree(mvm->nd_channels);
1015 mvm->nd_channels = NULL;
1016 mvm->n_nd_channels = 0;
994} 1017}
995 1018
996static int __iwl_mvm_suspend(struct ieee80211_hw *hw, 1019static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
@@ -1051,7 +1074,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
1051 1074
1052 mvm->net_detect = true; 1075 mvm->net_detect = true;
1053 } else { 1076 } else {
1054 struct iwl_wowlan_config_cmd_v3 wowlan_config_cmd = {}; 1077 struct iwl_wowlan_config_cmd wowlan_config_cmd = {};
1055 1078
1056 ap_sta = rcu_dereference_protected( 1079 ap_sta = rcu_dereference_protected(
1057 mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], 1080 mvm->fw_id_to_mac_id[mvmvif->ap_sta_id],
@@ -1104,8 +1127,10 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
1104 1127
1105 iwl_trans_d3_suspend(mvm->trans, test); 1128 iwl_trans_d3_suspend(mvm->trans, test);
1106 out: 1129 out:
1107 if (ret < 0) 1130 if (ret < 0) {
1108 ieee80211_restart_hw(mvm->hw); 1131 ieee80211_restart_hw(mvm->hw);
1132 iwl_mvm_free_nd(mvm);
1133 }
1109 out_noreset: 1134 out_noreset:
1110 mutex_unlock(&mvm->mutex); 1135 mutex_unlock(&mvm->mutex);
1111 1136
@@ -1626,15 +1651,64 @@ out_unlock:
1626 return false; 1651 return false;
1627} 1652}
1628 1653
1654struct iwl_mvm_nd_query_results {
1655 u32 matched_profiles;
1656 struct iwl_scan_offload_profile_match matches[IWL_SCAN_MAX_PROFILES];
1657};
1658
1659static int
1660iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm,
1661 struct iwl_mvm_nd_query_results *results)
1662{
1663 struct iwl_scan_offload_profiles_query *query;
1664 struct iwl_host_cmd cmd = {
1665 .id = SCAN_OFFLOAD_PROFILES_QUERY_CMD,
1666 .flags = CMD_WANT_SKB,
1667 };
1668 int ret, len;
1669
1670 ret = iwl_mvm_send_cmd(mvm, &cmd);
1671 if (ret) {
1672 IWL_ERR(mvm, "failed to query matched profiles (%d)\n", ret);
1673 return ret;
1674 }
1675
1676 /* RF-kill already asserted again... */
1677 if (!cmd.resp_pkt) {
1678 ret = -ERFKILL;
1679 goto out_free_resp;
1680 }
1681
1682 len = iwl_rx_packet_payload_len(cmd.resp_pkt);
1683 if (len < sizeof(*query)) {
1684 IWL_ERR(mvm, "Invalid scan offload profiles query response!\n");
1685 ret = -EIO;
1686 goto out_free_resp;
1687 }
1688
1689 query = (void *)cmd.resp_pkt->data;
1690
1691 results->matched_profiles = le32_to_cpu(query->matched_profiles);
1692 memcpy(results->matches, query->matches, sizeof(results->matches));
1693
1694out_free_resp:
1695 iwl_free_resp(&cmd);
1696 return ret;
1697}
1698
1629static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm, 1699static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
1630 struct ieee80211_vif *vif) 1700 struct ieee80211_vif *vif)
1631{ 1701{
1702 struct cfg80211_wowlan_nd_info *net_detect = NULL;
1632 struct cfg80211_wowlan_wakeup wakeup = { 1703 struct cfg80211_wowlan_wakeup wakeup = {
1633 .pattern_idx = -1, 1704 .pattern_idx = -1,
1634 }; 1705 };
1635 struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup; 1706 struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup;
1707 struct iwl_mvm_nd_query_results query;
1636 struct iwl_wowlan_status *fw_status; 1708 struct iwl_wowlan_status *fw_status;
1709 unsigned long matched_profiles;
1637 u32 reasons = 0; 1710 u32 reasons = 0;
1711 int i, j, n_matches, ret;
1638 1712
1639 fw_status = iwl_mvm_get_wakeup_status(mvm, vif); 1713 fw_status = iwl_mvm_get_wakeup_status(mvm, vif);
1640 if (!IS_ERR_OR_NULL(fw_status)) 1714 if (!IS_ERR_OR_NULL(fw_status))
@@ -1643,13 +1717,73 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
1643 if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) 1717 if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED)
1644 wakeup.rfkill_release = true; 1718 wakeup.rfkill_release = true;
1645 1719
1646 if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) { 1720 if (reasons != IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS)
1647 /* TODO: read and check if it was netdetect */ 1721 goto out;
1722
1723 ret = iwl_mvm_netdetect_query_results(mvm, &query);
1724 if (ret || !query.matched_profiles) {
1648 wakeup_report = NULL; 1725 wakeup_report = NULL;
1726 goto out;
1727 }
1728
1729 matched_profiles = query.matched_profiles;
1730 if (mvm->n_nd_match_sets) {
1731 n_matches = hweight_long(matched_profiles);
1732 } else {
1733 IWL_ERR(mvm, "no net detect match information available\n");
1734 n_matches = 0;
1735 }
1736
1737 net_detect = kzalloc(sizeof(*net_detect) +
1738 (n_matches * sizeof(net_detect->matches[0])),
1739 GFP_KERNEL);
1740 if (!net_detect || !n_matches)
1741 goto out_report_nd;
1742
1743 for_each_set_bit(i, &matched_profiles, mvm->n_nd_match_sets) {
1744 struct iwl_scan_offload_profile_match *fw_match;
1745 struct cfg80211_wowlan_nd_match *match;
1746 int n_channels = 0;
1747
1748 fw_match = &query.matches[i];
1749
1750 for (j = 0; j < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN; j++)
1751 n_channels += hweight8(fw_match->matching_channels[j]);
1752
1753 match = kzalloc(sizeof(*match) +
1754 (n_channels * sizeof(*match->channels)),
1755 GFP_KERNEL);
1756 if (!match)
1757 goto out_report_nd;
1758
1759 net_detect->matches[net_detect->n_matches++] = match;
1760
1761 match->ssid.ssid_len = mvm->nd_match_sets[i].ssid.ssid_len;
1762 memcpy(match->ssid.ssid, mvm->nd_match_sets[i].ssid.ssid,
1763 match->ssid.ssid_len);
1764
1765 if (mvm->n_nd_channels < n_channels)
1766 continue;
1767
1768 for (j = 0; j < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN * 8; j++)
1769 if (fw_match->matching_channels[j / 8] & (BIT(j % 8)))
1770 match->channels[match->n_channels++] =
1771 mvm->nd_channels[j]->center_freq;
1649 } 1772 }
1650 1773
1774out_report_nd:
1775 wakeup.net_detect = net_detect;
1776out:
1777 iwl_mvm_free_nd(mvm);
1778
1651 mutex_unlock(&mvm->mutex); 1779 mutex_unlock(&mvm->mutex);
1652 ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL); 1780 ieee80211_report_wowlan_wakeup(vif, wakeup_report, GFP_KERNEL);
1781
1782 if (net_detect) {
1783 for (i = 0; i < net_detect->n_matches; i++)
1784 kfree(net_detect->matches[i]);
1785 kfree(net_detect);
1786 }
1653} 1787}
1654 1788
1655static void iwl_mvm_read_d3_sram(struct iwl_mvm *mvm) 1789static void iwl_mvm_read_d3_sram(struct iwl_mvm *mvm)
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index 5a0f1049e099..33bf915cd7ea 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -1339,6 +1339,7 @@ static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file,
1339 PRINT_MVM_REF(IWL_MVM_REF_NMI); 1339 PRINT_MVM_REF(IWL_MVM_REF_NMI);
1340 PRINT_MVM_REF(IWL_MVM_REF_TM_CMD); 1340 PRINT_MVM_REF(IWL_MVM_REF_TM_CMD);
1341 PRINT_MVM_REF(IWL_MVM_REF_EXIT_WORK); 1341 PRINT_MVM_REF(IWL_MVM_REF_EXIT_WORK);
1342 PRINT_MVM_REF(IWL_MVM_REF_PROTECT_CSA);
1342 1343
1343 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1344 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1344} 1345}
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
index e74cdf2132f8..6d3bea5c59d1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h
@@ -241,16 +241,12 @@ enum iwl_wowlan_wakeup_filters {
241 IWL_WOWLAN_WAKEUP_BCN_FILTERING = BIT(16), 241 IWL_WOWLAN_WAKEUP_BCN_FILTERING = BIT(16),
242}; /* WOWLAN_WAKEUP_FILTER_API_E_VER_4 */ 242}; /* WOWLAN_WAKEUP_FILTER_API_E_VER_4 */
243 243
244struct iwl_wowlan_config_cmd_v2 { 244struct iwl_wowlan_config_cmd {
245 __le32 wakeup_filter; 245 __le32 wakeup_filter;
246 __le16 non_qos_seq; 246 __le16 non_qos_seq;
247 __le16 qos_seq[8]; 247 __le16 qos_seq[8];
248 u8 wowlan_ba_teardown_tids; 248 u8 wowlan_ba_teardown_tids;
249 u8 is_11n_connection; 249 u8 is_11n_connection;
250} __packed; /* WOWLAN_CONFIG_API_S_VER_2 */
251
252struct iwl_wowlan_config_cmd_v3 {
253 struct iwl_wowlan_config_cmd_v2 common;
254 u8 offloading_tid; 250 u8 offloading_tid;
255 u8 reserved[3]; 251 u8 reserved[3];
256} __packed; /* WOWLAN_CONFIG_API_S_VER_3 */ 252} __packed; /* WOWLAN_CONFIG_API_S_VER_3 */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index 7163eb391826..1f2acf47bfb2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -1047,4 +1047,48 @@ struct iwl_umac_scan_complete {
1047 __le32 reserved; 1047 __le32 reserved;
1048} __packed; /* SCAN_COMPLETE_NTF_UMAC_API_S_VER_1 */ 1048} __packed; /* SCAN_COMPLETE_NTF_UMAC_API_S_VER_1 */
1049 1049
1050#define SCAN_OFFLOAD_MATCHING_CHANNELS_LEN 5
1051/**
1052 * struct iwl_scan_offload_profile_match - match information
1053 * @bssid: matched bssid
1054 * @channel: channel where the match occurred
1055 * @energy:
1056 * @matching_feature:
1057 * @matching_channels: bitmap of channels that matched, referencing
1058 * the channels passed in tue scan offload request
1059 */
1060struct iwl_scan_offload_profile_match {
1061 u8 bssid[ETH_ALEN];
1062 __le16 reserved;
1063 u8 channel;
1064 u8 energy;
1065 u8 matching_feature;
1066 u8 matching_channels[SCAN_OFFLOAD_MATCHING_CHANNELS_LEN];
1067} __packed; /* SCAN_OFFLOAD_PROFILE_MATCH_RESULTS_S_VER_1 */
1068
1069/**
1070 * struct iwl_scan_offload_profiles_query - match results query response
1071 * @matched_profiles: bitmap of matched profiles, referencing the
1072 * matches passed in the scan offload request
1073 * @last_scan_age: age of the last offloaded scan
1074 * @n_scans_done: number of offloaded scans done
1075 * @gp2_d0u: GP2 when D0U occurred
1076 * @gp2_invoked: GP2 when scan offload was invoked
1077 * @resume_while_scanning: not used
1078 * @self_recovery: obsolete
1079 * @reserved: reserved
1080 * @matches: array of match information, one for each match
1081 */
1082struct iwl_scan_offload_profiles_query {
1083 __le32 matched_profiles;
1084 __le32 last_scan_age;
1085 __le32 n_scans_done;
1086 __le32 gp2_d0u;
1087 __le32 gp2_invoked;
1088 u8 resume_while_scanning;
1089 u8 self_recovery;
1090 __le16 reserved;
1091 struct iwl_scan_offload_profile_match matches[IWL_SCAN_MAX_PROFILES];
1092} __packed; /* SCAN_OFFLOAD_PROFILES_QUERY_RSP_S_VER_2 */
1093
1050#endif 1094#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 2ff4f41d79bd..88af6dd2ceaa 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -249,11 +249,9 @@ enum {
249 WOWLAN_TX_POWER_PER_DB = 0xe6, 249 WOWLAN_TX_POWER_PER_DB = 0xe6,
250 250
251 /* and for NetDetect */ 251 /* and for NetDetect */
252 NET_DETECT_CONFIG_CMD = 0x54, 252 SCAN_OFFLOAD_PROFILES_QUERY_CMD = 0x56,
253 NET_DETECT_PROFILES_QUERY_CMD = 0x56, 253 SCAN_OFFLOAD_HOTSPOTS_CONFIG_CMD = 0x58,
254 NET_DETECT_PROFILES_CMD = 0x57, 254 SCAN_OFFLOAD_HOTSPOTS_QUERY_CMD = 0x59,
255 NET_DETECT_HOTSPOTS_CMD = 0x58,
256 NET_DETECT_HOTSPOTS_QUERY_CMD = 0x59,
257 255
258 REPLY_MAX = 0xff, 256 REPLY_MAX = 0xff,
259}; 257};
@@ -1617,7 +1615,7 @@ enum iwl_sf_scenario {
1617#define SF_NUM_TIMEOUT_TYPES 2 /* Aging timer and Idle timer */ 1615#define SF_NUM_TIMEOUT_TYPES 2 /* Aging timer and Idle timer */
1618 1616
1619/* smart FIFO default values */ 1617/* smart FIFO default values */
1620#define SF_W_MARK_SISO 4096 1618#define SF_W_MARK_SISO 6144
1621#define SF_W_MARK_MIMO2 8192 1619#define SF_W_MARK_MIMO2 8192
1622#define SF_W_MARK_MIMO3 6144 1620#define SF_W_MARK_MIMO3 6144
1623#define SF_W_MARK_LEGACY 4096 1621#define SF_W_MARK_LEGACY 4096
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index bbb78710f237..d0fa6e9ed590 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -186,7 +186,12 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
186 static const u8 alive_cmd[] = { MVM_ALIVE }; 186 static const u8 alive_cmd[] = { MVM_ALIVE };
187 struct iwl_sf_region st_fwrd_space; 187 struct iwl_sf_region st_fwrd_space;
188 188
189 fw = iwl_get_ucode_image(mvm, ucode_type); 189 if (ucode_type == IWL_UCODE_REGULAR &&
190 iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_CUSTOM) &&
191 iwl_fw_dbg_conf_enabled(mvm->fw, FW_DBG_CUSTOM))
192 fw = iwl_get_ucode_image(mvm, IWL_UCODE_REGULAR_USNIFFER);
193 else
194 fw = iwl_get_ucode_image(mvm, ucode_type);
190 if (WARN_ON(!fw)) 195 if (WARN_ON(!fw))
191 return -EINVAL; 196 return -EINVAL;
192 mvm->cur_ucode = ucode_type; 197 mvm->cur_ucode = ucode_type;
@@ -394,6 +399,42 @@ out:
394 return ret; 399 return ret;
395} 400}
396 401
402static int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm,
403 enum iwl_fw_dbg_conf conf_id)
404{
405 u8 *ptr;
406 int ret;
407 int i;
408
409 if (WARN_ONCE(conf_id >= ARRAY_SIZE(mvm->fw->dbg_conf_tlv),
410 "Invalid configuration %d\n", conf_id))
411 return -EINVAL;
412
413 if (!mvm->fw->dbg_conf_tlv[conf_id])
414 return -EINVAL;
415
416 if (mvm->fw_dbg_conf != FW_DBG_INVALID)
417 IWL_WARN(mvm, "FW already configured (%d) - re-configuring\n",
418 mvm->fw_dbg_conf);
419
420 /* Send all HCMDs for configuring the FW debug */
421 ptr = (void *)&mvm->fw->dbg_conf_tlv[conf_id]->hcmd;
422 for (i = 0; i < mvm->fw->dbg_conf_tlv[conf_id]->num_of_hcmds; i++) {
423 struct iwl_fw_dbg_conf_hcmd *cmd = (void *)ptr;
424
425 ret = iwl_mvm_send_cmd_pdu(mvm, cmd->id, 0,
426 le16_to_cpu(cmd->len), cmd->data);
427 if (ret)
428 return ret;
429
430 ptr += sizeof(*cmd);
431 ptr += le16_to_cpu(cmd->len);
432 }
433
434 mvm->fw_dbg_conf = conf_id;
435 return ret;
436}
437
397int iwl_mvm_up(struct iwl_mvm *mvm) 438int iwl_mvm_up(struct iwl_mvm *mvm)
398{ 439{
399 int ret, i; 440 int ret, i;
@@ -445,6 +486,9 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
445 if (ret) 486 if (ret)
446 IWL_ERR(mvm, "Failed to initialize Smart Fifo\n"); 487 IWL_ERR(mvm, "Failed to initialize Smart Fifo\n");
447 488
489 mvm->fw_dbg_conf = FW_DBG_INVALID;
490 iwl_mvm_start_fw_dbg_conf(mvm, FW_DBG_CUSTOM);
491
448 ret = iwl_send_tx_ant_cfg(mvm, mvm->fw->valid_tx_ant); 492 ret = iwl_send_tx_ant_cfg(mvm, mvm->fw->valid_tx_ant);
449 if (ret) 493 if (ret)
450 goto error; 494 goto error;
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 0cb79bc06781..f6d86ccce6a8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -1304,31 +1304,22 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
1304 struct iwl_device_cmd *cmd) 1304 struct iwl_device_cmd *cmd)
1305{ 1305{
1306 struct iwl_rx_packet *pkt = rxb_addr(rxb); 1306 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1307 struct iwl_extended_beacon_notif *beacon = (void *)pkt->data;
1307 struct iwl_mvm_tx_resp *beacon_notify_hdr; 1308 struct iwl_mvm_tx_resp *beacon_notify_hdr;
1308 struct ieee80211_vif *csa_vif; 1309 struct ieee80211_vif *csa_vif;
1309 struct ieee80211_vif *tx_blocked_vif; 1310 struct ieee80211_vif *tx_blocked_vif;
1310 u64 tsf;
1311 u16 status; 1311 u16 status;
1312 1312
1313 lockdep_assert_held(&mvm->mutex); 1313 lockdep_assert_held(&mvm->mutex);
1314 1314
1315 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_CAPA_EXTENDED_BEACON) { 1315 beacon_notify_hdr = &beacon->beacon_notify_hdr;
1316 struct iwl_extended_beacon_notif *beacon = (void *)pkt->data; 1316 mvm->ap_last_beacon_gp2 = le32_to_cpu(beacon->gp2);
1317
1318 beacon_notify_hdr = &beacon->beacon_notify_hdr;
1319 tsf = le64_to_cpu(beacon->tsf);
1320 mvm->ap_last_beacon_gp2 = le32_to_cpu(beacon->gp2);
1321 } else {
1322 struct iwl_beacon_notif *beacon = (void *)pkt->data;
1323
1324 beacon_notify_hdr = &beacon->beacon_notify_hdr;
1325 tsf = le64_to_cpu(beacon->tsf);
1326 }
1327 1317
1328 status = le16_to_cpu(beacon_notify_hdr->status.status) & TX_STATUS_MSK; 1318 status = le16_to_cpu(beacon_notify_hdr->status.status) & TX_STATUS_MSK;
1329 IWL_DEBUG_RX(mvm, 1319 IWL_DEBUG_RX(mvm,
1330 "beacon status %#x retries:%d tsf:0x%16llX gp2:0x%X rate:%d\n", 1320 "beacon status %#x retries:%d tsf:0x%16llX gp2:0x%X rate:%d\n",
1331 status, beacon_notify_hdr->failure_frame, tsf, 1321 status, beacon_notify_hdr->failure_frame,
1322 le64_to_cpu(beacon->tsf),
1332 mvm->ap_last_beacon_gp2, 1323 mvm->ap_last_beacon_gp2,
1333 le32_to_cpu(beacon_notify_hdr->initial_rate)); 1324 le32_to_cpu(beacon_notify_hdr->initial_rate));
1334 1325
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 322d01b90c0e..31a5b3f4266c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -337,7 +337,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
337 hw->flags |= IEEE80211_HW_MFP_CAPABLE; 337 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
338 338
339 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT && 339 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT &&
340 IWL_UCODE_API(mvm->fw->ucode_ver) >= 9 &&
341 !iwlwifi_mod_params.uapsd_disable) { 340 !iwlwifi_mod_params.uapsd_disable) {
342 hw->flags |= IEEE80211_HW_SUPPORTS_UAPSD; 341 hw->flags |= IEEE80211_HW_SUPPORTS_UAPSD;
343 hw->uapsd_queues = IWL_MVM_UAPSD_QUEUES; 342 hw->uapsd_queues = IWL_MVM_UAPSD_QUEUES;
@@ -370,8 +369,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
370 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_GO_UAPSD) 369 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_GO_UAPSD)
371 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; 370 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
372 371
373 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_CSA_FLOW) 372 hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
374 hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
375 373
376 hw->wiphy->iface_combinations = iwl_mvm_iface_combinations; 374 hw->wiphy->iface_combinations = iwl_mvm_iface_combinations;
377 hw->wiphy->n_iface_combinations = 375 hw->wiphy->n_iface_combinations =
@@ -2577,9 +2575,15 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
2577 2575
2578 switch (vif->type) { 2576 switch (vif->type) {
2579 case NL80211_IFTYPE_STATION: 2577 case NL80211_IFTYPE_STATION:
2580 /* Use aux roc framework (HS20) */ 2578 if (mvm->fw->ucode_capa.capa[0] &
2581 ret = iwl_mvm_send_aux_roc_cmd(mvm, channel, 2579 IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT) {
2582 vif, duration); 2580 /* Use aux roc framework (HS20) */
2581 ret = iwl_mvm_send_aux_roc_cmd(mvm, channel,
2582 vif, duration);
2583 goto out_unlock;
2584 }
2585 IWL_ERR(mvm, "hotspot not supported\n");
2586 ret = -EINVAL;
2583 goto out_unlock; 2587 goto out_unlock;
2584 case NL80211_IFTYPE_P2P_DEVICE: 2588 case NL80211_IFTYPE_P2P_DEVICE:
2585 /* handle below */ 2589 /* handle below */
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 2ab59b850795..d24660fb4ef2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -295,7 +295,6 @@ enum iwl_bt_force_ant_mode {
295* struct iwl_mvm_vif_bf_data - beacon filtering related data 295* struct iwl_mvm_vif_bf_data - beacon filtering related data
296* @bf_enabled: indicates if beacon filtering is enabled 296* @bf_enabled: indicates if beacon filtering is enabled
297* @ba_enabled: indicated if beacon abort is enabled 297* @ba_enabled: indicated if beacon abort is enabled
298* @last_beacon_signal: last beacon rssi signal in dbm
299* @ave_beacon_signal: average beacon signal 298* @ave_beacon_signal: average beacon signal
300* @last_cqm_event: rssi of the last cqm event 299* @last_cqm_event: rssi of the last cqm event
301* @bt_coex_min_thold: minimum threshold for BT coex 300* @bt_coex_min_thold: minimum threshold for BT coex
@@ -671,6 +670,7 @@ struct iwl_mvm {
671 /* -1 for always, 0 for never, >0 for that many times */ 670 /* -1 for always, 0 for never, >0 for that many times */
672 s8 restart_fw; 671 s8 restart_fw;
673 struct work_struct fw_error_dump_wk; 672 struct work_struct fw_error_dump_wk;
673 enum iwl_fw_dbg_conf fw_dbg_conf;
674 674
675#ifdef CONFIG_IWLWIFI_LEDS 675#ifdef CONFIG_IWLWIFI_LEDS
676 struct led_classdev led; 676 struct led_classdev led;
@@ -685,6 +685,10 @@ struct iwl_mvm {
685 /* sched scan settings for net detect */ 685 /* sched scan settings for net detect */
686 struct cfg80211_sched_scan_request *nd_config; 686 struct cfg80211_sched_scan_request *nd_config;
687 struct ieee80211_scan_ies nd_ies; 687 struct ieee80211_scan_ies nd_ies;
688 struct cfg80211_match_set *nd_match_sets;
689 int n_nd_match_sets;
690 struct ieee80211_channel **nd_channels;
691 int n_nd_channels;
688 bool net_detect; 692 bool net_detect;
689#ifdef CONFIG_IWLWIFI_DEBUGFS 693#ifdef CONFIG_IWLWIFI_DEBUGFS
690 u32 d3_wake_sysassert; /* must be u32 for debugfs_create_bool */ 694 u32 d3_wake_sysassert; /* must be u32 for debugfs_create_bool */
@@ -1143,7 +1147,7 @@ iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1143} 1147}
1144#endif 1148#endif
1145void iwl_mvm_set_wowlan_qos_seq(struct iwl_mvm_sta *mvm_ap_sta, 1149void iwl_mvm_set_wowlan_qos_seq(struct iwl_mvm_sta *mvm_ap_sta,
1146 struct iwl_wowlan_config_cmd_v2 *cmd); 1150 struct iwl_wowlan_config_cmd *cmd);
1147int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm, 1151int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
1148 struct ieee80211_vif *vif, 1152 struct ieee80211_vif *vif,
1149 bool disable_offloading, 1153 bool disable_offloading,
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index af074563e770..d55fd8e3654c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -339,11 +339,15 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
339 } *file_sec; 339 } *file_sec;
340 const u8 *eof, *temp; 340 const u8 *eof, *temp;
341 int max_section_size; 341 int max_section_size;
342 const __le32 *dword_buff;
342 343
343#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF)) 344#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF))
344#define NVM_WORD2_ID(x) (x >> 12) 345#define NVM_WORD2_ID(x) (x >> 12)
345#define NVM_WORD2_LEN_FAMILY_8000(x) (2 * ((x & 0xFF) << 8 | x >> 8)) 346#define NVM_WORD2_LEN_FAMILY_8000(x) (2 * ((x & 0xFF) << 8 | x >> 8))
346#define NVM_WORD1_ID_FAMILY_8000(x) (x >> 4) 347#define NVM_WORD1_ID_FAMILY_8000(x) (x >> 4)
348#define NVM_HEADER_0 (0x2A504C54)
349#define NVM_HEADER_1 (0x4E564D2A)
350#define NVM_HEADER_SIZE (4 * sizeof(u32))
347 351
348 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n"); 352 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n");
349 353
@@ -372,12 +376,6 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
372 IWL_INFO(mvm, "Loaded NVM file %s (%zu bytes)\n", 376 IWL_INFO(mvm, "Loaded NVM file %s (%zu bytes)\n",
373 mvm->nvm_file_name, fw_entry->size); 377 mvm->nvm_file_name, fw_entry->size);
374 378
375 if (fw_entry->size < sizeof(*file_sec)) {
376 IWL_ERR(mvm, "NVM file too small\n");
377 ret = -EINVAL;
378 goto out;
379 }
380
381 if (fw_entry->size > MAX_NVM_FILE_LEN) { 379 if (fw_entry->size > MAX_NVM_FILE_LEN) {
382 IWL_ERR(mvm, "NVM file too large\n"); 380 IWL_ERR(mvm, "NVM file too large\n");
383 ret = -EINVAL; 381 ret = -EINVAL;
@@ -385,8 +383,25 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
385 } 383 }
386 384
387 eof = fw_entry->data + fw_entry->size; 385 eof = fw_entry->data + fw_entry->size;
388 386 dword_buff = (__le32 *)fw_entry->data;
389 file_sec = (void *)fw_entry->data; 387
388 /* some NVM file will contain a header.
389 * The header is identified by 2 dwords header as follow:
390 * dword[0] = 0x2A504C54
391 * dword[1] = 0x4E564D2A
392 *
393 * This header must be skipped when providing the NVM data to the FW.
394 */
395 if (fw_entry->size > NVM_HEADER_SIZE &&
396 dword_buff[0] == cpu_to_le32(NVM_HEADER_0) &&
397 dword_buff[1] == cpu_to_le32(NVM_HEADER_1)) {
398 file_sec = (void *)(fw_entry->data + NVM_HEADER_SIZE);
399 IWL_INFO(mvm, "NVM Version %08X\n", le32_to_cpu(dword_buff[2]));
400 IWL_INFO(mvm, "NVM Manufacturing date %08X\n",
401 le32_to_cpu(dword_buff[3]));
402 } else {
403 file_sec = (void *)fw_entry->data;
404 }
390 405
391 while (true) { 406 while (true) {
392 if (file_sec->data > eof) { 407 if (file_sec->data > eof) {
diff --git a/drivers/net/wireless/iwlwifi/mvm/offloading.c b/drivers/net/wireless/iwlwifi/mvm/offloading.c
index adcbf4c8edd8..68b0169c8892 100644
--- a/drivers/net/wireless/iwlwifi/mvm/offloading.c
+++ b/drivers/net/wireless/iwlwifi/mvm/offloading.c
@@ -67,7 +67,7 @@
67#include "mvm.h" 67#include "mvm.h"
68 68
69void iwl_mvm_set_wowlan_qos_seq(struct iwl_mvm_sta *mvm_ap_sta, 69void iwl_mvm_set_wowlan_qos_seq(struct iwl_mvm_sta *mvm_ap_sta,
70 struct iwl_wowlan_config_cmd_v2 *cmd) 70 struct iwl_wowlan_config_cmd *cmd)
71{ 71{
72 int i; 72 int i;
73 73
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index b3ae094db907..97dfba50c682 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -325,11 +325,9 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
325 CMD(WOWLAN_KEK_KCK_MATERIAL), 325 CMD(WOWLAN_KEK_KCK_MATERIAL),
326 CMD(WOWLAN_GET_STATUSES), 326 CMD(WOWLAN_GET_STATUSES),
327 CMD(WOWLAN_TX_POWER_PER_DB), 327 CMD(WOWLAN_TX_POWER_PER_DB),
328 CMD(NET_DETECT_CONFIG_CMD), 328 CMD(SCAN_OFFLOAD_PROFILES_QUERY_CMD),
329 CMD(NET_DETECT_PROFILES_QUERY_CMD), 329 CMD(SCAN_OFFLOAD_HOTSPOTS_CONFIG_CMD),
330 CMD(NET_DETECT_PROFILES_CMD), 330 CMD(SCAN_OFFLOAD_HOTSPOTS_QUERY_CMD),
331 CMD(NET_DETECT_HOTSPOTS_CMD),
332 CMD(NET_DETECT_HOTSPOTS_QUERY_CMD),
333 CMD(CARD_STATE_NOTIFICATION), 331 CMD(CARD_STATE_NOTIFICATION),
334 CMD(MISSED_BEACONS_NOTIFICATION), 332 CMD(MISSED_BEACONS_NOTIFICATION),
335 CMD(BT_COEX_PRIO_TABLE), 333 CMD(BT_COEX_PRIO_TABLE),
@@ -498,6 +496,10 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
498 496
499 trans->rx_mpdu_cmd = REPLY_RX_MPDU_CMD; 497 trans->rx_mpdu_cmd = REPLY_RX_MPDU_CMD;
500 trans->rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start); 498 trans->rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start);
499 trans->dbg_dest_tlv = mvm->fw->dbg_dest_tlv;
500 trans->dbg_dest_reg_num = mvm->fw->dbg_dest_reg_num;
501 memcpy(trans->dbg_conf_tlv, mvm->fw->dbg_conf_tlv,
502 sizeof(trans->dbg_conf_tlv));
501 503
502 /* set up notification wait support */ 504 /* set up notification wait support */
503 iwl_notification_wait_init(&mvm->notif_wait); 505 iwl_notification_wait_init(&mvm->notif_wait);
@@ -1002,7 +1004,7 @@ static void iwl_mvm_enter_d0i3_iterator(void *_data, u8 *mac,
1002} 1004}
1003 1005
1004static void iwl_mvm_set_wowlan_data(struct iwl_mvm *mvm, 1006static void iwl_mvm_set_wowlan_data(struct iwl_mvm *mvm,
1005 struct iwl_wowlan_config_cmd_v3 *cmd, 1007 struct iwl_wowlan_config_cmd *cmd,
1006 struct iwl_d0i3_iter_data *iter_data) 1008 struct iwl_d0i3_iter_data *iter_data)
1007{ 1009{
1008 struct ieee80211_sta *ap_sta; 1010 struct ieee80211_sta *ap_sta;
@@ -1018,14 +1020,14 @@ static void iwl_mvm_set_wowlan_data(struct iwl_mvm *mvm,
1018 goto out; 1020 goto out;
1019 1021
1020 mvm_ap_sta = iwl_mvm_sta_from_mac80211(ap_sta); 1022 mvm_ap_sta = iwl_mvm_sta_from_mac80211(ap_sta);
1021 cmd->common.is_11n_connection = ap_sta->ht_cap.ht_supported; 1023 cmd->is_11n_connection = ap_sta->ht_cap.ht_supported;
1022 cmd->offloading_tid = iter_data->offloading_tid; 1024 cmd->offloading_tid = iter_data->offloading_tid;
1023 1025
1024 /* 1026 /*
1025 * The d0i3 uCode takes care of the nonqos counters, 1027 * The d0i3 uCode takes care of the nonqos counters,
1026 * so configure only the qos seq ones. 1028 * so configure only the qos seq ones.
1027 */ 1029 */
1028 iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, &cmd->common); 1030 iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, cmd);
1029out: 1031out:
1030 rcu_read_unlock(); 1032 rcu_read_unlock();
1031} 1033}
@@ -1037,14 +1039,11 @@ static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
1037 struct iwl_d0i3_iter_data d0i3_iter_data = { 1039 struct iwl_d0i3_iter_data d0i3_iter_data = {
1038 .mvm = mvm, 1040 .mvm = mvm,
1039 }; 1041 };
1040 struct iwl_wowlan_config_cmd_v3 wowlan_config_cmd = { 1042 struct iwl_wowlan_config_cmd wowlan_config_cmd = {
1041 .common = { 1043 .wakeup_filter = cpu_to_le32(IWL_WOWLAN_WAKEUP_RX_FRAME |
1042 .wakeup_filter = 1044 IWL_WOWLAN_WAKEUP_BEACON_MISS |
1043 cpu_to_le32(IWL_WOWLAN_WAKEUP_RX_FRAME | 1045 IWL_WOWLAN_WAKEUP_LINK_CHANGE |
1044 IWL_WOWLAN_WAKEUP_BEACON_MISS | 1046 IWL_WOWLAN_WAKEUP_BCN_FILTERING),
1045 IWL_WOWLAN_WAKEUP_LINK_CHANGE |
1046 IWL_WOWLAN_WAKEUP_BCN_FILTERING),
1047 },
1048 }; 1047 };
1049 struct iwl_d3_manager_config d3_cfg_cmd = { 1048 struct iwl_d3_manager_config d3_cfg_cmd = {
1050 .min_sleep_time = cpu_to_le32(1000), 1049 .min_sleep_time = cpu_to_le32(1000),
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index a3b63b77b4ba..5d79a1f44b8e 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -78,6 +78,7 @@
78#include "iwl-agn-hw.h" 78#include "iwl-agn-hw.h"
79#include "iwl-fw-error-dump.h" 79#include "iwl-fw-error-dump.h"
80#include "internal.h" 80#include "internal.h"
81#include "iwl-fh.h"
81 82
82/* extended range in FW SRAM */ 83/* extended range in FW SRAM */
83#define IWL_FW_MEM_EXTENDED_START 0x40000 84#define IWL_FW_MEM_EXTENDED_START 0x40000
@@ -665,14 +666,14 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num,
665 return ret; 666 return ret;
666} 667}
667 668
668static int iwl_pcie_load_cpu_secured_sections(struct iwl_trans *trans, 669static int iwl_pcie_load_cpu_sections_8000b(struct iwl_trans *trans,
669 const struct fw_img *image, 670 const struct fw_img *image,
670 int cpu, 671 int cpu,
671 int *first_ucode_section) 672 int *first_ucode_section)
672{ 673{
673 int shift_param; 674 int shift_param;
674 int i, ret = 0; 675 int i, ret = 0, sec_num = 0x1;
675 u32 last_read_idx = 0; 676 u32 val, last_read_idx = 0;
676 677
677 if (cpu == 1) { 678 if (cpu == 1) {
678 shift_param = 0; 679 shift_param = 0;
@@ -693,21 +694,16 @@ static int iwl_pcie_load_cpu_secured_sections(struct iwl_trans *trans,
693 break; 694 break;
694 } 695 }
695 696
696 if (i == (*first_ucode_section) + 1)
697 /* set CPU to started */
698 iwl_set_bits_prph(trans,
699 CSR_UCODE_LOAD_STATUS_ADDR,
700 LMPM_CPU_HDRS_LOADING_COMPLETED
701 << shift_param);
702
703 ret = iwl_pcie_load_section(trans, i, &image->sec[i]); 697 ret = iwl_pcie_load_section(trans, i, &image->sec[i]);
704 if (ret) 698 if (ret)
705 return ret; 699 return ret;
700
701 /* Notify the ucode of the loaded section number and status */
702 val = iwl_read_direct32(trans, FH_UCODE_LOAD_STATUS);
703 val = val | (sec_num << shift_param);
704 iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, val);
705 sec_num = (sec_num << 1) | 0x1;
706 } 706 }
707 /* image loading complete */
708 iwl_set_bits_prph(trans,
709 CSR_UCODE_LOAD_STATUS_ADDR,
710 LMPM_CPU_UCODE_LOADING_COMPLETED << shift_param);
711 707
712 *first_ucode_section = last_read_idx; 708 *first_ucode_section = last_read_idx;
713 709
@@ -760,46 +756,78 @@ static int iwl_pcie_load_cpu_sections(struct iwl_trans *trans,
760 return 0; 756 return 0;
761} 757}
762 758
763static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, 759static void iwl_pcie_apply_destination(struct iwl_trans *trans)
764 const struct fw_img *image)
765{ 760{
766 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 761 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
767 int ret = 0; 762 const struct iwl_fw_dbg_dest_tlv *dest = trans->dbg_dest_tlv;
768 int first_ucode_section; 763 int i;
769 764
770 IWL_DEBUG_FW(trans, 765 if (dest->version)
771 "working with %s CPU\n", 766 IWL_ERR(trans,
772 image->is_dual_cpus ? "Dual" : "Single"); 767 "DBG DEST version is %d - expect issues\n",
768 dest->version);
773 769
774 /* configure the ucode to be ready to get the secured image */ 770 IWL_INFO(trans, "Applying debug destination %s\n",
775 if (iwl_has_secure_boot(trans->hw_rev, trans->cfg->device_family)) { 771 get_fw_dbg_mode_string(dest->monitor_mode));
776 /* set secure boot inspector addresses */
777 iwl_write_prph(trans,
778 LMPM_SECURE_INSPECTOR_CODE_ADDR,
779 LMPM_SECURE_INSPECTOR_CODE_MEM_SPACE);
780 772
781 iwl_write_prph(trans, 773 if (dest->monitor_mode == EXTERNAL_MODE)
782 LMPM_SECURE_INSPECTOR_DATA_ADDR, 774 iwl_pcie_alloc_fw_monitor(trans);
783 LMPM_SECURE_INSPECTOR_DATA_MEM_SPACE); 775 else
776 IWL_WARN(trans, "PCI should have external buffer debug\n");
784 777
785 /* set CPU1 header address */ 778 for (i = 0; i < trans->dbg_dest_reg_num; i++) {
786 iwl_write_prph(trans, 779 u32 addr = le32_to_cpu(dest->reg_ops[i].addr);
787 LMPM_SECURE_UCODE_LOAD_CPU1_HDR_ADDR, 780 u32 val = le32_to_cpu(dest->reg_ops[i].val);
788 LMPM_SECURE_CPU1_HDR_MEM_SPACE);
789 781
790 /* load to FW the binary Secured sections of CPU1 */ 782 switch (dest->reg_ops[i].op) {
791 ret = iwl_pcie_load_cpu_secured_sections(trans, image, 1, 783 case CSR_ASSIGN:
792 &first_ucode_section); 784 iwl_write32(trans, addr, val);
793 if (ret) 785 break;
794 return ret; 786 case CSR_SETBIT:
787 iwl_set_bit(trans, addr, BIT(val));
788 break;
789 case CSR_CLEARBIT:
790 iwl_clear_bit(trans, addr, BIT(val));
791 break;
792 case PRPH_ASSIGN:
793 iwl_write_prph(trans, addr, val);
794 break;
795 case PRPH_SETBIT:
796 iwl_set_bits_prph(trans, addr, BIT(val));
797 break;
798 case PRPH_CLEARBIT:
799 iwl_clear_bits_prph(trans, addr, BIT(val));
800 break;
801 default:
802 IWL_ERR(trans, "FW debug - unknown OP %d\n",
803 dest->reg_ops[i].op);
804 break;
805 }
806 }
795 807
796 } else { 808 if (dest->monitor_mode == EXTERNAL_MODE && trans_pcie->fw_mon_size) {
797 /* load to FW the binary Non secured sections of CPU1 */ 809 iwl_write_prph(trans, le32_to_cpu(dest->base_reg),
798 ret = iwl_pcie_load_cpu_sections(trans, image, 1, 810 trans_pcie->fw_mon_phys >> dest->base_shift);
799 &first_ucode_section); 811 iwl_write_prph(trans, le32_to_cpu(dest->end_reg),
800 if (ret) 812 (trans_pcie->fw_mon_phys +
801 return ret; 813 trans_pcie->fw_mon_size) >> dest->end_shift);
802 } 814 }
815}
816
817static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
818 const struct fw_img *image)
819{
820 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
821 int ret = 0;
822 int first_ucode_section;
823
824 IWL_DEBUG_FW(trans, "working with %s CPU\n",
825 image->is_dual_cpus ? "Dual" : "Single");
826
827 /* load to FW the binary non secured sections of CPU1 */
828 ret = iwl_pcie_load_cpu_sections(trans, image, 1, &first_ucode_section);
829 if (ret)
830 return ret;
803 831
804 if (image->is_dual_cpus) { 832 if (image->is_dual_cpus) {
805 /* set CPU2 header address */ 833 /* set CPU2 header address */
@@ -808,14 +836,8 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
808 LMPM_SECURE_CPU2_HDR_MEM_SPACE); 836 LMPM_SECURE_CPU2_HDR_MEM_SPACE);
809 837
810 /* load to FW the binary sections of CPU2 */ 838 /* load to FW the binary sections of CPU2 */
811 if (iwl_has_secure_boot(trans->hw_rev, 839 ret = iwl_pcie_load_cpu_sections(trans, image, 2,
812 trans->cfg->device_family)) 840 &first_ucode_section);
813 ret = iwl_pcie_load_cpu_secured_sections(
814 trans, image, 2,
815 &first_ucode_section);
816 else
817 ret = iwl_pcie_load_cpu_sections(trans, image, 2,
818 &first_ucode_section);
819 if (ret) 841 if (ret)
820 return ret; 842 return ret;
821 } 843 }
@@ -832,6 +854,8 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
832 (trans_pcie->fw_mon_phys + 854 (trans_pcie->fw_mon_phys +
833 trans_pcie->fw_mon_size) >> 4); 855 trans_pcie->fw_mon_size) >> 4);
834 } 856 }
857 } else if (trans->dbg_dest_tlv) {
858 iwl_pcie_apply_destination(trans);
835 } 859 }
836 860
837 /* release CPU reset */ 861 /* release CPU reset */
@@ -840,18 +864,50 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
840 else 864 else
841 iwl_write32(trans, CSR_RESET, 0); 865 iwl_write32(trans, CSR_RESET, 0);
842 866
843 if (iwl_has_secure_boot(trans->hw_rev, trans->cfg->device_family)) { 867 return 0;
844 /* wait for image verification to complete */ 868}
845 ret = iwl_poll_prph_bit(trans,
846 LMPM_SECURE_BOOT_CPU1_STATUS_ADDR,
847 LMPM_SECURE_BOOT_STATUS_SUCCESS,
848 LMPM_SECURE_BOOT_STATUS_SUCCESS,
849 LMPM_SECURE_TIME_OUT);
850 869
851 if (ret < 0) { 870static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans,
852 IWL_ERR(trans, "Time out on secure boot process\n"); 871 const struct fw_img *image)
853 return ret; 872{
854 } 873 int ret = 0;
874 int first_ucode_section;
875 u32 reg;
876
877 IWL_DEBUG_FW(trans, "working with %s CPU\n",
878 image->is_dual_cpus ? "Dual" : "Single");
879
880 /* configure the ucode to be ready to get the secured image */
881 /* release CPU reset */
882 iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT);
883
884 /* load to FW the binary Secured sections of CPU1 */
885 ret = iwl_pcie_load_cpu_sections_8000b(trans, image, 1,
886 &first_ucode_section);
887 if (ret)
888 return ret;
889
890 /* load to FW the binary sections of CPU2 */
891 ret = iwl_pcie_load_cpu_sections_8000b(trans, image, 2,
892 &first_ucode_section);
893 if (ret)
894 return ret;
895
896 /* Notify FW loading is done */
897 iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, 0xFFFFFFFF);
898
899 /* wait for image verification to complete */
900 ret = iwl_poll_prph_bit(trans, LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0,
901 LMPM_SECURE_BOOT_STATUS_SUCCESS,
902 LMPM_SECURE_BOOT_STATUS_SUCCESS,
903 LMPM_SECURE_TIME_OUT);
904 if (ret < 0) {
905 reg = iwl_read_prph(trans,
906 LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0);
907
908 IWL_ERR(trans, "Timeout on secure boot process, reg = %x\n",
909 reg);
910 return ret;
855 } 911 }
856 912
857 return 0; 913 return 0;
@@ -903,7 +959,11 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
903 iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); 959 iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
904 960
905 /* Load the given image to the HW */ 961 /* Load the given image to the HW */
906 return iwl_pcie_load_given_ucode(trans, fw); 962 if ((trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) &&
963 (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_B_STEP))
964 return iwl_pcie_load_given_ucode_8000b(trans, fw);
965 else
966 return iwl_pcie_load_given_ucode(trans, fw);
907} 967}
908 968
909static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr) 969static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr)
@@ -994,6 +1054,9 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
994 clear_bit(STATUS_RFKILL, &trans->status); 1054 clear_bit(STATUS_RFKILL, &trans->status);
995 if (hw_rfkill != was_hw_rfkill) 1055 if (hw_rfkill != was_hw_rfkill)
996 iwl_trans_pcie_rf_kill(trans, hw_rfkill); 1056 iwl_trans_pcie_rf_kill(trans, hw_rfkill);
1057
1058 /* re-take ownership to prevent other users from stealing the deivce */
1059 iwl_pcie_prepare_card_hw(trans);
997} 1060}
998 1061
999void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state) 1062void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state)
@@ -1968,6 +2031,31 @@ static u32 iwl_trans_pcie_dump_csr(struct iwl_trans *trans,
1968 return csr_len; 2031 return csr_len;
1969} 2032}
1970 2033
2034static u32 iwl_trans_pcie_fh_regs_dump(struct iwl_trans *trans,
2035 struct iwl_fw_error_dump_data **data)
2036{
2037 u32 fh_regs_len = FH_MEM_UPPER_BOUND - FH_MEM_LOWER_BOUND;
2038 unsigned long flags;
2039 __le32 *val;
2040 int i;
2041
2042 if (!iwl_trans_grab_nic_access(trans, false, &flags))
2043 return 0;
2044
2045 (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_FH_REGS);
2046 (*data)->len = cpu_to_le32(fh_regs_len);
2047 val = (void *)(*data)->data;
2048
2049 for (i = FH_MEM_LOWER_BOUND; i < FH_MEM_UPPER_BOUND; i += sizeof(u32))
2050 *val++ = cpu_to_le32(iwl_trans_pcie_read32(trans, i));
2051
2052 iwl_trans_release_nic_access(trans, &flags);
2053
2054 *data = iwl_fw_error_next_data(*data);
2055
2056 return sizeof(**data) + fh_regs_len;
2057}
2058
1971static 2059static
1972struct iwl_trans_dump_data *iwl_trans_pcie_dump_data(struct iwl_trans *trans) 2060struct iwl_trans_dump_data *iwl_trans_pcie_dump_data(struct iwl_trans *trans)
1973{ 2061{
@@ -1977,6 +2065,7 @@ struct iwl_trans_dump_data *iwl_trans_pcie_dump_data(struct iwl_trans *trans)
1977 struct iwl_fw_error_dump_txcmd *txcmd; 2065 struct iwl_fw_error_dump_txcmd *txcmd;
1978 struct iwl_trans_dump_data *dump_data; 2066 struct iwl_trans_dump_data *dump_data;
1979 u32 len; 2067 u32 len;
2068 u32 monitor_len;
1980 int i, ptr; 2069 int i, ptr;
1981 2070
1982 /* transport dump header */ 2071 /* transport dump header */
@@ -1999,10 +2088,34 @@ struct iwl_trans_dump_data *iwl_trans_pcie_dump_data(struct iwl_trans *trans)
1999 num_bytes_in_chunk; 2088 num_bytes_in_chunk;
2000 } 2089 }
2001 2090
2091 /* FH registers */
2092 len += sizeof(*data) + (FH_MEM_UPPER_BOUND - FH_MEM_LOWER_BOUND);
2093
2002 /* FW monitor */ 2094 /* FW monitor */
2003 if (trans_pcie->fw_mon_page) 2095 if (trans_pcie->fw_mon_page) {
2004 len += sizeof(*data) + sizeof(struct iwl_fw_error_dump_fw_mon) + 2096 len += sizeof(*data) + sizeof(struct iwl_fw_error_dump_fw_mon) +
2005 trans_pcie->fw_mon_size; 2097 trans_pcie->fw_mon_size;
2098 monitor_len = trans_pcie->fw_mon_size;
2099 } else if (trans->dbg_dest_tlv) {
2100 u32 base, end;
2101
2102 base = le32_to_cpu(trans->dbg_dest_tlv->base_reg);
2103 end = le32_to_cpu(trans->dbg_dest_tlv->end_reg);
2104
2105 base = iwl_read_prph(trans, base) <<
2106 trans->dbg_dest_tlv->base_shift;
2107 end = iwl_read_prph(trans, end) <<
2108 trans->dbg_dest_tlv->end_shift;
2109
2110 /* Make "end" point to the actual end */
2111 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
2112 end += (1 << trans->dbg_dest_tlv->end_shift);
2113 monitor_len = end - base;
2114 len += sizeof(*data) + sizeof(struct iwl_fw_error_dump_fw_mon) +
2115 monitor_len;
2116 } else {
2117 monitor_len = 0;
2118 }
2006 2119
2007 dump_data = vzalloc(len); 2120 dump_data = vzalloc(len);
2008 if (!dump_data) 2121 if (!dump_data)
@@ -2039,36 +2152,71 @@ struct iwl_trans_dump_data *iwl_trans_pcie_dump_data(struct iwl_trans *trans)
2039 2152
2040 len += iwl_trans_pcie_dump_prph(trans, &data); 2153 len += iwl_trans_pcie_dump_prph(trans, &data);
2041 len += iwl_trans_pcie_dump_csr(trans, &data); 2154 len += iwl_trans_pcie_dump_csr(trans, &data);
2155 len += iwl_trans_pcie_fh_regs_dump(trans, &data);
2042 /* data is already pointing to the next section */ 2156 /* data is already pointing to the next section */
2043 2157
2044 if (trans_pcie->fw_mon_page) { 2158 if ((trans_pcie->fw_mon_page &&
2159 trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) ||
2160 trans->dbg_dest_tlv) {
2045 struct iwl_fw_error_dump_fw_mon *fw_mon_data; 2161 struct iwl_fw_error_dump_fw_mon *fw_mon_data;
2162 u32 base, write_ptr, wrap_cnt;
2163
2164 /* If there was a dest TLV - use the values from there */
2165 if (trans->dbg_dest_tlv) {
2166 write_ptr =
2167 le32_to_cpu(trans->dbg_dest_tlv->write_ptr_reg);
2168 wrap_cnt = le32_to_cpu(trans->dbg_dest_tlv->wrap_count);
2169 base = le32_to_cpu(trans->dbg_dest_tlv->base_reg);
2170 } else {
2171 base = MON_BUFF_BASE_ADDR;
2172 write_ptr = MON_BUFF_WRPTR;
2173 wrap_cnt = MON_BUFF_CYCLE_CNT;
2174 }
2046 2175
2047 data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_FW_MONITOR); 2176 data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_FW_MONITOR);
2048 data->len = cpu_to_le32(trans_pcie->fw_mon_size +
2049 sizeof(*fw_mon_data));
2050 fw_mon_data = (void *)data->data; 2177 fw_mon_data = (void *)data->data;
2051 fw_mon_data->fw_mon_wr_ptr = 2178 fw_mon_data->fw_mon_wr_ptr =
2052 cpu_to_le32(iwl_read_prph(trans, MON_BUFF_WRPTR)); 2179 cpu_to_le32(iwl_read_prph(trans, write_ptr));
2053 fw_mon_data->fw_mon_cycle_cnt = 2180 fw_mon_data->fw_mon_cycle_cnt =
2054 cpu_to_le32(iwl_read_prph(trans, MON_BUFF_CYCLE_CNT)); 2181 cpu_to_le32(iwl_read_prph(trans, wrap_cnt));
2055 fw_mon_data->fw_mon_base_ptr = 2182 fw_mon_data->fw_mon_base_ptr =
2056 cpu_to_le32(iwl_read_prph(trans, MON_BUFF_BASE_ADDR)); 2183 cpu_to_le32(iwl_read_prph(trans, base));
2057 2184
2058 /* 2185 len += sizeof(*data) + sizeof(*fw_mon_data);
2059 * The firmware is now asserted, it won't write anything to 2186 if (trans_pcie->fw_mon_page) {
2060 * the buffer. CPU can take ownership to fetch the data. 2187 data->len = cpu_to_le32(trans_pcie->fw_mon_size +
2061 * The buffer will be handed back to the device before the 2188 sizeof(*fw_mon_data));
2062 * firmware will be restarted. 2189
2063 */ 2190 /*
2064 dma_sync_single_for_cpu(trans->dev, trans_pcie->fw_mon_phys, 2191 * The firmware is now asserted, it won't write anything
2065 trans_pcie->fw_mon_size, 2192 * to the buffer. CPU can take ownership to fetch the
2066 DMA_FROM_DEVICE); 2193 * data. The buffer will be handed back to the device
2067 memcpy(fw_mon_data->data, page_address(trans_pcie->fw_mon_page), 2194 * before the firmware will be restarted.
2068 trans_pcie->fw_mon_size); 2195 */
2069 2196 dma_sync_single_for_cpu(trans->dev,
2070 len += sizeof(*data) + sizeof(*fw_mon_data) + 2197 trans_pcie->fw_mon_phys,
2071 trans_pcie->fw_mon_size; 2198 trans_pcie->fw_mon_size,
2199 DMA_FROM_DEVICE);
2200 memcpy(fw_mon_data->data,
2201 page_address(trans_pcie->fw_mon_page),
2202 trans_pcie->fw_mon_size);
2203
2204 len += trans_pcie->fw_mon_size;
2205 } else {
2206 /* If we are here then the buffer is internal */
2207
2208 /*
2209 * Update pointers to reflect actual values after
2210 * shifting
2211 */
2212 base = iwl_read_prph(trans, base) <<
2213 trans->dbg_dest_tlv->base_shift;
2214 iwl_trans_read_mem(trans, base, fw_mon_data->data,
2215 monitor_len / sizeof(u32));
2216 data->len = cpu_to_le32(sizeof(*fw_mon_data) +
2217 monitor_len);
2218 len += monitor_len;
2219 }
2072 } 2220 }
2073 2221
2074 dump_data->len = len; 2222 dump_data->len = len;
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 4a4104eda9b8..8a6c7a084aa1 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -989,6 +989,65 @@ out:
989 spin_unlock_bh(&txq->lock); 989 spin_unlock_bh(&txq->lock);
990} 990}
991 991
992static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans)
993{
994 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
995 int ret;
996
997 lockdep_assert_held(&trans_pcie->reg_lock);
998
999 if (trans_pcie->cmd_in_flight)
1000 return 0;
1001
1002 trans_pcie->cmd_in_flight = true;
1003
1004 /*
1005 * wake up the NIC to make sure that the firmware will see the host
1006 * command - we will let the NIC sleep once all the host commands
1007 * returned. This needs to be done only on NICs that have
1008 * apmg_wake_up_wa set.
1009 */
1010 if (trans->cfg->base_params->apmg_wake_up_wa) {
1011 __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
1012 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1013 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
1014 udelay(2);
1015
1016 ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
1017 CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
1018 (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
1019 CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP),
1020 15000);
1021 if (ret < 0) {
1022 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
1023 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1024 trans_pcie->cmd_in_flight = false;
1025 IWL_ERR(trans, "Failed to wake NIC for hcmd\n");
1026 return -EIO;
1027 }
1028 }
1029
1030 return 0;
1031}
1032
1033static int iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans)
1034{
1035 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1036
1037 lockdep_assert_held(&trans_pcie->reg_lock);
1038
1039 if (WARN_ON(!trans_pcie->cmd_in_flight))
1040 return 0;
1041
1042 trans_pcie->cmd_in_flight = false;
1043
1044 if (trans->cfg->base_params->apmg_wake_up_wa)
1045 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
1046 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1047
1048 return 0;
1049}
1050
992/* 1051/*
993 * iwl_pcie_cmdq_reclaim - Reclaim TX command queue entries already Tx'd 1052 * iwl_pcie_cmdq_reclaim - Reclaim TX command queue entries already Tx'd
994 * 1053 *
@@ -1024,14 +1083,9 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
1024 } 1083 }
1025 } 1084 }
1026 1085
1027 if (trans->cfg->base_params->apmg_wake_up_wa && 1086 if (q->read_ptr == q->write_ptr) {
1028 q->read_ptr == q->write_ptr) {
1029 spin_lock_irqsave(&trans_pcie->reg_lock, flags); 1087 spin_lock_irqsave(&trans_pcie->reg_lock, flags);
1030 WARN_ON(!trans_pcie->cmd_in_flight); 1088 iwl_pcie_clear_cmd_in_flight(trans);
1031 trans_pcie->cmd_in_flight = false;
1032 __iwl_trans_pcie_clear_bit(trans,
1033 CSR_GP_CNTRL,
1034 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1035 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); 1089 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
1036 } 1090 }
1037 1091
@@ -1419,35 +1473,11 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1419 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); 1473 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout);
1420 1474
1421 spin_lock_irqsave(&trans_pcie->reg_lock, flags); 1475 spin_lock_irqsave(&trans_pcie->reg_lock, flags);
1422 1476 ret = iwl_pcie_set_cmd_in_flight(trans);
1423 /* 1477 if (ret < 0) {
1424 * wake up the NIC to make sure that the firmware will see the host 1478 idx = ret;
1425 * command - we will let the NIC sleep once all the host commands 1479 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
1426 * returned. This needs to be done only on NICs that have 1480 goto out;
1427 * apmg_wake_up_wa set.
1428 */
1429 if (trans->cfg->base_params->apmg_wake_up_wa &&
1430 !trans_pcie->cmd_in_flight) {
1431 trans_pcie->cmd_in_flight = true;
1432 __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
1433 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1434 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
1435 udelay(2);
1436
1437 ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
1438 CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
1439 (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
1440 CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP),
1441 15000);
1442 if (ret < 0) {
1443 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
1444 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1445 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
1446 trans_pcie->cmd_in_flight = false;
1447 IWL_ERR(trans, "Failed to wake NIC for hcmd\n");
1448 idx = -EIO;
1449 goto out;
1450 }
1451 } 1481 }
1452 1482
1453 /* Increment and update queue's write index */ 1483 /* Increment and update queue's write index */