From: Shahar S Matityahu <shahar.s.matity...@intel.com>

Trigger dump collection if the alive flow fails, regardless of the
reason.

Signed-off-by: Shahar S Matityahu <shahar.s.matity...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/dbg.c   | 27 ++++++++++++++++++-
 drivers/net/wireless/intel/iwlwifi/fw/dbg.h   |  1 +
 .../wireless/intel/iwlwifi/fw/error-dump.h    |  2 ++
 .../net/wireless/intel/iwlwifi/fw/runtime.h   |  1 +
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c   |  2 ++
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c  |  2 ++
 6 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 146ec5065825..a049367ac08a 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -973,6 +973,30 @@ const struct iwl_fw_dump_desc iwl_dump_desc_assert = {
 };
 IWL_EXPORT_SYMBOL(iwl_dump_desc_assert);
 
+void iwl_fw_alive_error_dump(struct iwl_fw_runtime *fwrt)
+{
+       struct iwl_fw_dump_desc *iwl_dump_desc_no_alive =
+               kmalloc(sizeof(*iwl_dump_desc_no_alive), GFP_KERNEL);
+
+       if (!iwl_dump_desc_no_alive)
+               return;
+
+       iwl_dump_desc_no_alive->trig_desc.type =
+               cpu_to_le32(FW_DBG_TRIGGER_NO_ALIVE);
+       iwl_dump_desc_no_alive->len = 0;
+
+       if (WARN_ON(fwrt->dump.desc))
+               iwl_fw_free_dump_desc(fwrt);
+
+       IWL_WARN(fwrt, "Collecting data: trigger %d fired.\n",
+                FW_DBG_TRIGGER_NO_ALIVE);
+
+       fwrt->dump.desc = iwl_dump_desc_no_alive;
+       iwl_fw_error_dump(fwrt);
+       clear_bit(IWL_FWRT_STATUS_WAIT_ALIVE, &fwrt->status);
+}
+IWL_EXPORT_SYMBOL(iwl_fw_alive_error_dump);
+
 int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
                            const struct iwl_fw_dump_desc *desc,
                            const struct iwl_fw_dbg_trigger_tlv *trigger)
@@ -998,7 +1022,8 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
            fwrt->smem_cfg.num_lmacs)
                return -EIO;
 
-       if (test_and_set_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status))
+       if (test_and_set_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status) ||
+           test_bit(IWL_FWRT_STATUS_WAIT_ALIVE, &fwrt->status))
                return -EBUSY;
 
        if (WARN_ON(fwrt->dump.desc))
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h 
b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
index 5b087fc4f380..0f09a2128ad2 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.h
@@ -368,4 +368,5 @@ static inline void iwl_fw_resume_timestamp(struct 
iwl_fw_runtime *fwrt) {}
 
 #endif /* CONFIG_IWLWIFI_DEBUGFS */
 
+void iwl_fw_alive_error_dump(struct iwl_fw_runtime *fwrt);
 #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 6d3ef331b7d5..6fede174c664 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
@@ -328,6 +328,7 @@ iwl_fw_error_next_data(struct iwl_fw_error_dump_data *data)
  * @FW_DBG_TDLS: trigger log collection upon TDLS related events.
  * @FW_DBG_TRIGGER_TX_STATUS: trigger log collection upon tx status when
  *  the firmware sends a tx reply.
+ * @FW_DBG_TRIGGER_NO_ALIVE: trigger log collection if alive flow fails
  */
 enum iwl_fw_dbg_trigger {
        FW_DBG_TRIGGER_INVALID = 0,
@@ -345,6 +346,7 @@ enum iwl_fw_dbg_trigger {
        FW_DBG_TRIGGER_TX_LATENCY,
        FW_DBG_TRIGGER_TDLS,
        FW_DBG_TRIGGER_TX_STATUS,
+       FW_DBG_TRIGGER_NO_ALIVE,
 
        /* must be last */
        FW_DBG_TRIGGER_MAX,
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h 
b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
index 9ed5819defaf..ac6db5e2b3d0 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
@@ -88,6 +88,7 @@ struct iwl_fwrt_shared_mem_cfg {
 
 enum iwl_fw_runtime_status {
        IWL_FWRT_STATUS_DUMPING = 0,
+       IWL_FWRT_STATUS_WAIT_ALIVE,
 };
 
 /**
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 3fee304cddbb..c5df73231ba3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -299,6 +299,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm 
*mvm,
        enum iwl_ucode_type old_type = mvm->fwrt.cur_fw_img;
        static const u16 alive_cmd[] = { MVM_ALIVE };
 
+       set_bit(IWL_FWRT_STATUS_WAIT_ALIVE, &mvm->fwrt.status);
        if (ucode_type == IWL_UCODE_REGULAR &&
            iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_START_FROM_ALIVE) &&
            !(fw_has_capa(&mvm->fw->ucode_capa,
@@ -369,6 +370,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm 
*mvm,
                atomic_set(&mvm->mac80211_queue_stop_count[i], 0);
 
        set_bit(IWL_MVM_STATUS_FIRMWARE_RUNNING, &mvm->status);
+       clear_bit(IWL_FWRT_STATUS_WAIT_ALIVE, &mvm->fwrt.status);
 
        return 0;
 }
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index b058b7de88be..c388e0e758e7 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -788,6 +788,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct 
iwl_cfg *cfg,
        mutex_lock(&mvm->mutex);
        iwl_mvm_ref(mvm, IWL_MVM_REF_INIT_UCODE);
        err = iwl_run_init_mvm_ucode(mvm, true);
+       if (test_bit(IWL_FWRT_STATUS_WAIT_ALIVE, &mvm->fwrt.status))
+               iwl_fw_alive_error_dump(&mvm->fwrt);
        if (!iwlmvm_mod_params.init_dbg || !err)
                iwl_mvm_stop_device(mvm);
        iwl_mvm_unref(mvm, IWL_MVM_REF_INIT_UCODE);
-- 
2.19.0

Reply via email to