aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorShahar S Matityahu <shahar.s.matityahu@intel.com>2018-11-12 06:27:51 -0500
committerLuca Coelho <luciano.coelho@intel.com>2019-02-04 05:27:19 -0500
commit700b3799b398d00320f40ef1a40d3fe341f98678 (patch)
treeedfda78230b08cb3bb8743036e7d7427d1aeefec /drivers/net
parent6032c062723ce5a23eccb7d2bf8c0a2985424f27 (diff)
iwlwifi: Fix pre operational dumping flows
There are several dumping flows in the driver in case of a fail prior to operational. In some cases we get 2 dumps while in others we get none. Fix this by uniting the different flows. Add a different dump type to driver triggered dumps in case we want a dump but did not got assert, and make all dumping go through iwl_fw_dbg_collect_desc to avoid multiple dumps. Signed-off-by: Shahar S Matityahu <shahar.s.matityahu@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/dbg.c89
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/dbg.h5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/error-dump.h3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/init.c3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-trans.h13
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/fw.c6
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mvm.h9
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/ops.c2
8 files changed, 81 insertions, 49 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 0edc5bcdfb82..f8cf12804aee 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -1365,44 +1365,6 @@ const struct iwl_fw_dump_desc iwl_dump_desc_assert = {
1365}; 1365};
1366IWL_EXPORT_SYMBOL(iwl_dump_desc_assert); 1366IWL_EXPORT_SYMBOL(iwl_dump_desc_assert);
1367 1367
1368void iwl_fw_assert_error_dump(struct iwl_fw_runtime *fwrt)
1369{
1370 IWL_INFO(fwrt, "error dump due to fw assert\n");
1371 fwrt->dump.desc = &iwl_dump_desc_assert;
1372 iwl_fw_error_dump(fwrt);
1373}
1374IWL_EXPORT_SYMBOL(iwl_fw_assert_error_dump);
1375
1376void iwl_fw_alive_timeout_dump(struct iwl_fw_runtime *fwrt)
1377{
1378 struct iwl_fw_dump_desc *iwl_dump_desc_alive_timeout;
1379
1380 if (test_and_set_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status))
1381 return;
1382
1383 iwl_dump_desc_alive_timeout =
1384 kmalloc(sizeof(*iwl_dump_desc_alive_timeout), GFP_KERNEL);
1385 if (!iwl_dump_desc_alive_timeout)
1386 return;
1387
1388 iwl_dump_desc_alive_timeout->trig_desc.type =
1389 cpu_to_le32(FW_DBG_TRIGGER_ALIVE_TIMEOUT);
1390 iwl_dump_desc_alive_timeout->len = 0;
1391
1392 if (WARN_ON(fwrt->dump.desc))
1393 iwl_fw_free_dump_desc(fwrt);
1394
1395 IWL_WARN(fwrt, "Collecting data: trigger %d fired.\n",
1396 FW_DBG_TRIGGER_ALIVE_TIMEOUT);
1397
1398 /* set STATUS_FW_ERROR to collect all memory regions. */
1399 set_bit(STATUS_FW_ERROR, &fwrt->trans->status);
1400
1401 fwrt->dump.desc = iwl_dump_desc_alive_timeout;
1402 iwl_fw_error_dump(fwrt);
1403}
1404IWL_EXPORT_SYMBOL(iwl_fw_alive_timeout_dump);
1405
1406int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt, 1368int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
1407 const struct iwl_fw_dump_desc *desc, 1369 const struct iwl_fw_dump_desc *desc,
1408 bool monitor_only, 1370 bool monitor_only,
@@ -1442,6 +1404,33 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
1442} 1404}
1443IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect_desc); 1405IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect_desc);
1444 1406
1407int iwl_fw_dbg_error_collect(struct iwl_fw_runtime *fwrt,
1408 enum iwl_fw_dbg_trigger trig_type)
1409{
1410 int ret;
1411 struct iwl_fw_dump_desc *iwl_dump_error_desc =
1412 kmalloc(sizeof(*iwl_dump_error_desc), GFP_KERNEL);
1413
1414 if (!iwl_dump_error_desc)
1415 return -ENOMEM;
1416
1417 iwl_dump_error_desc->trig_desc.type = cpu_to_le32(trig_type);
1418 iwl_dump_error_desc->len = 0;
1419
1420 ret = iwl_fw_dbg_collect_desc(fwrt, iwl_dump_error_desc, false, 0);
1421 if (ret) {
1422 kfree(iwl_dump_error_desc);
1423 } else {
1424 set_bit(STATUS_FW_WAIT_DUMP, &fwrt->trans->status);
1425
1426 /* trigger nmi to halt the fw */
1427 iwl_force_nmi(fwrt->trans);
1428 }
1429
1430 return ret;
1431}
1432IWL_EXPORT_SYMBOL(iwl_fw_dbg_error_collect);
1433
1445int _iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt, 1434int _iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
1446 enum iwl_fw_dbg_trigger trig, 1435 enum iwl_fw_dbg_trigger trig,
1447 const char *str, size_t len, 1436 const char *str, size_t len,
@@ -1893,3 +1882,27 @@ void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
1893 _iwl_fw_dbg_apply_point(fwrt, data, apply_point, true); 1882 _iwl_fw_dbg_apply_point(fwrt, data, apply_point, true);
1894} 1883}
1895IWL_EXPORT_SYMBOL(iwl_fw_dbg_apply_point); 1884IWL_EXPORT_SYMBOL(iwl_fw_dbg_apply_point);
1885
1886void iwl_fwrt_stop_device(struct iwl_fw_runtime *fwrt)
1887{
1888 /* if the wait event timeout elapses instead of wake up then
1889 * the driver did not receive NMI interrupt and can not assume the FW
1890 * is halted
1891 */
1892 int ret = wait_event_timeout(fwrt->trans->fw_halt_waitq,
1893 !test_bit(STATUS_FW_WAIT_DUMP,
1894 &fwrt->trans->status),
1895 msecs_to_jiffies(2000));
1896 if (!ret) {
1897 /* failed to receive NMI interrupt, assuming the FW is stuck */
1898 set_bit(STATUS_FW_ERROR, &fwrt->trans->status);
1899
1900 clear_bit(STATUS_FW_WAIT_DUMP, &fwrt->trans->status);
1901 }
1902
1903 /* Assuming the op mode mutex is held at this point */
1904 iwl_fw_dbg_collect_sync(fwrt);
1905
1906 iwl_trans_stop_device(fwrt->trans);
1907}
1908IWL_EXPORT_SYMBOL(iwl_fwrt_stop_device);
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
index 36e0f40dab3b..2fa7a19e02b6 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
@@ -112,6 +112,8 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt);
112int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt, 112int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
113 const struct iwl_fw_dump_desc *desc, 113 const struct iwl_fw_dump_desc *desc,
114 bool monitor_only, unsigned int delay); 114 bool monitor_only, unsigned int delay);
115int iwl_fw_dbg_error_collect(struct iwl_fw_runtime *fwrt,
116 enum iwl_fw_dbg_trigger trig_type);
115int _iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt, 117int _iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
116 enum iwl_fw_dbg_trigger trig, 118 enum iwl_fw_dbg_trigger trig,
117 const char *str, size_t len, 119 const char *str, size_t len,
@@ -434,10 +436,9 @@ static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) {}
434 436
435#endif /* CONFIG_IWLWIFI_DEBUGFS */ 437#endif /* CONFIG_IWLWIFI_DEBUGFS */
436 438
437void iwl_fw_assert_error_dump(struct iwl_fw_runtime *fwrt);
438void iwl_fw_alive_timeout_dump(struct iwl_fw_runtime *fwrt);
439void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt); 439void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt);
440void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt, 440void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
441 enum iwl_fw_ini_apply_point apply_point); 441 enum iwl_fw_ini_apply_point apply_point);
442 442
443void iwl_fwrt_stop_device(struct iwl_fw_runtime *fwrt);
443#endif /* __iwl_fw_dbg_h__ */ 444#endif /* __iwl_fw_dbg_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
index d06707f3a2a4..e1c6aa61ab90 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
@@ -356,6 +356,8 @@ iwl_fw_error_next_data(struct iwl_fw_error_dump_data *data)
356 * @FW_DBG_TRIGGER_TX_STATUS: trigger log collection upon tx status when 356 * @FW_DBG_TRIGGER_TX_STATUS: trigger log collection upon tx status when
357 * the firmware sends a tx reply. 357 * the firmware sends a tx reply.
358 * @FW_DBG_TRIGGER_ALIVE_TIMEOUT: trigger log collection if alive flow timeouts 358 * @FW_DBG_TRIGGER_ALIVE_TIMEOUT: trigger log collection if alive flow timeouts
359 * @FW_DBG_TRIGGER_DRIVER: trigger log collection upon a flow failure
360 * in the driver.
359 */ 361 */
360enum iwl_fw_dbg_trigger { 362enum iwl_fw_dbg_trigger {
361 FW_DBG_TRIGGER_INVALID = 0, 363 FW_DBG_TRIGGER_INVALID = 0,
@@ -374,6 +376,7 @@ enum iwl_fw_dbg_trigger {
374 FW_DBG_TRIGGER_TDLS, 376 FW_DBG_TRIGGER_TDLS,
375 FW_DBG_TRIGGER_TX_STATUS, 377 FW_DBG_TRIGGER_TX_STATUS,
376 FW_DBG_TRIGGER_ALIVE_TIMEOUT, 378 FW_DBG_TRIGGER_ALIVE_TIMEOUT,
379 FW_DBG_TRIGGER_DRIVER,
377 380
378 /* must be last */ 381 /* must be last */
379 FW_DBG_TRIGGER_MAX, 382 FW_DBG_TRIGGER_MAX,
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/init.c b/drivers/net/wireless/intel/iwlwifi/fw/init.c
index 2efac307909e..7adf4e4e841a 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/init.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/init.c
@@ -6,6 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2017 Intel Deutschland GmbH 8 * Copyright(c) 2017 Intel Deutschland GmbH
9 * Copyright(c) 2019 Intel Corporation
9 * 10 *
10 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as 12 * it under the terms of version 2 of the GNU General Public License as
@@ -26,6 +27,7 @@
26 * BSD LICENSE 27 * BSD LICENSE
27 * 28 *
28 * Copyright(c) 2017 Intel Deutschland GmbH 29 * Copyright(c) 2017 Intel Deutschland GmbH
30 * Copyright(c) 2019 Intel Corporation
29 * All rights reserved. 31 * All rights reserved.
30 * 32 *
31 * Redistribution and use in source and binary forms, with or without 33 * Redistribution and use in source and binary forms, with or without
@@ -74,6 +76,7 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
74 fwrt->ops_ctx = ops_ctx; 76 fwrt->ops_ctx = ops_ctx;
75 INIT_DELAYED_WORK(&fwrt->dump.wk, iwl_fw_error_dump_wk); 77 INIT_DELAYED_WORK(&fwrt->dump.wk, iwl_fw_error_dump_wk);
76 iwl_fwrt_dbgfs_register(fwrt, dbgfs_dir); 78 iwl_fwrt_dbgfs_register(fwrt, dbgfs_dir);
79 init_waitqueue_head(&fwrt->trans->fw_halt_waitq);
77} 80}
78IWL_EXPORT_SYMBOL(iwl_fw_runtime_init); 81IWL_EXPORT_SYMBOL(iwl_fw_runtime_init);
79 82
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index a7009cd4232d..d79025d663df 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -8,6 +8,7 @@
8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
11 * Copyright(c) 2018 - 2019 Intel Corporation
11 * 12 *
12 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of version 2 of the GNU General Public License as 14 * it under the terms of version 2 of the GNU General Public License as
@@ -30,6 +31,7 @@
30 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 31 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
31 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
32 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
34 * Copyright(c) 2018 - 2019 Intel Corporation
33 * All rights reserved. 35 * All rights reserved.
34 * 36 *
35 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
@@ -330,6 +332,7 @@ enum iwl_d3_status {
330 * are sent 332 * are sent
331 * @STATUS_TRANS_IDLE: the trans is idle - general commands are not to be sent 333 * @STATUS_TRANS_IDLE: the trans is idle - general commands are not to be sent
332 * @STATUS_TRANS_DEAD: trans is dead - avoid any read/write operation 334 * @STATUS_TRANS_DEAD: trans is dead - avoid any read/write operation
335 * @STATUS_FW_WAIT_DUMP: if set, wait until cleared before collecting dump
333 */ 336 */
334enum iwl_trans_status { 337enum iwl_trans_status {
335 STATUS_SYNC_HCMD_ACTIVE, 338 STATUS_SYNC_HCMD_ACTIVE,
@@ -342,6 +345,7 @@ enum iwl_trans_status {
342 STATUS_TRANS_GOING_IDLE, 345 STATUS_TRANS_GOING_IDLE,
343 STATUS_TRANS_IDLE, 346 STATUS_TRANS_IDLE,
344 STATUS_TRANS_DEAD, 347 STATUS_TRANS_DEAD,
348 STATUS_FW_WAIT_DUMP,
345}; 349};
346 350
347static inline int 351static inline int
@@ -796,6 +800,11 @@ struct iwl_trans {
796 bool suspending; 800 bool suspending;
797 bool dbg_rec_on; 801 bool dbg_rec_on;
798 802
803 u32 lmac_error_event_table[2];
804 u32 umac_error_event_table;
805 unsigned int error_event_table_tlv_status;
806 wait_queue_head_t fw_halt_waitq;
807
799 /* pointer to trans specific struct */ 808 /* pointer to trans specific struct */
800 /*Ensure that this pointer will always be aligned to sizeof pointer */ 809 /*Ensure that this pointer will always be aligned to sizeof pointer */
801 char trans_specific[0] __aligned(sizeof(void *)); 810 char trans_specific[0] __aligned(sizeof(void *));
@@ -1202,6 +1211,10 @@ static inline void iwl_trans_fw_error(struct iwl_trans *trans)
1202 /* prevent double restarts due to the same erroneous FW */ 1211 /* prevent double restarts due to the same erroneous FW */
1203 if (!test_and_set_bit(STATUS_FW_ERROR, &trans->status)) 1212 if (!test_and_set_bit(STATUS_FW_ERROR, &trans->status))
1204 iwl_op_mode_nic_error(trans->op_mode); 1213 iwl_op_mode_nic_error(trans->op_mode);
1214
1215 if (test_and_clear_bit(STATUS_FW_WAIT_DUMP, &trans->status))
1216 wake_up(&trans->fw_halt_waitq);
1217
1205} 1218}
1206 1219
1207/***************************************************** 1220/*****************************************************
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 25c8cea1180e..d8ae9561a9b0 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -332,7 +332,8 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
332 struct iwl_trans *trans = mvm->trans; 332 struct iwl_trans *trans = mvm->trans;
333 333
334 if (ret == -ETIMEDOUT) 334 if (ret == -ETIMEDOUT)
335 iwl_fw_alive_timeout_dump(&mvm->fwrt); 335 iwl_fw_dbg_error_collect(&mvm->fwrt,
336 FW_DBG_TRIGGER_ALIVE_TIMEOUT);
336 337
337 if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000) 338 if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000)
338 IWL_ERR(mvm, 339 IWL_ERR(mvm,
@@ -408,7 +409,6 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
408 ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR); 409 ret = iwl_mvm_load_ucode_wait_alive(mvm, IWL_UCODE_REGULAR);
409 if (ret) { 410 if (ret) {
410 IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret); 411 IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret);
411 iwl_fw_assert_error_dump(&mvm->fwrt);
412 goto error; 412 goto error;
413 } 413 }
414 414
@@ -1053,7 +1053,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
1053 ret = iwl_mvm_load_rt_fw(mvm); 1053 ret = iwl_mvm_load_rt_fw(mvm);
1054 if (ret) { 1054 if (ret) {
1055 IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret); 1055 IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret);
1056 iwl_fw_assert_error_dump(&mvm->fwrt); 1056 iwl_fw_dbg_error_collect(&mvm->fwrt, FW_DBG_TRIGGER_DRIVER);
1057 goto error; 1057 goto error;
1058 } 1058 }
1059 1059
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index f7176020139d..ee61f4a00c5e 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -2013,15 +2013,12 @@ static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm)
2013 &mvm->status)) 2013 &mvm->status))
2014 iwl_fw_dbg_collect_desc(&mvm->fwrt, &iwl_dump_desc_assert, 2014 iwl_fw_dbg_collect_desc(&mvm->fwrt, &iwl_dump_desc_assert,
2015 false, 0); 2015 false, 0);
2016 /* calling this function without using dump_start/end since at this 2016
2017 * point we already hold the op mode mutex
2018 */
2019 iwl_fw_dbg_collect_sync(&mvm->fwrt);
2020 iwl_fw_cancel_timestamp(&mvm->fwrt); 2017 iwl_fw_cancel_timestamp(&mvm->fwrt);
2021 iwl_free_fw_paging(&mvm->fwrt);
2022 clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status); 2018 clear_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status);
2019 iwl_fwrt_stop_device(&mvm->fwrt);
2020 iwl_free_fw_paging(&mvm->fwrt);
2023 iwl_fw_dump_conf_clear(&mvm->fwrt); 2021 iwl_fw_dump_conf_clear(&mvm->fwrt);
2024 iwl_trans_stop_device(mvm->trans);
2025} 2022}
2026 2023
2027/* Re-configure the SCD for a queue that has already been configured */ 2024/* Re-configure the SCD for a queue that has already been configured */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index de288962773e..ad816007e546 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -817,6 +817,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
817 mutex_lock(&mvm->mutex); 817 mutex_lock(&mvm->mutex);
818 iwl_mvm_ref(mvm, IWL_MVM_REF_INIT_UCODE); 818 iwl_mvm_ref(mvm, IWL_MVM_REF_INIT_UCODE);
819 err = iwl_run_init_mvm_ucode(mvm, true); 819 err = iwl_run_init_mvm_ucode(mvm, true);
820 if (err)
821 iwl_fw_dbg_error_collect(&mvm->fwrt, FW_DBG_TRIGGER_DRIVER);
820 if (!iwlmvm_mod_params.init_dbg || !err) 822 if (!iwlmvm_mod_params.init_dbg || !err)
821 iwl_mvm_stop_device(mvm); 823 iwl_mvm_stop_device(mvm);
822 iwl_mvm_unref(mvm, IWL_MVM_REF_INIT_UCODE); 824 iwl_mvm_unref(mvm, IWL_MVM_REF_INIT_UCODE);