iwlwifi: differentiate between alive timeout and alive flow failure
authorShahar S Matityahu <shahar.s.matityahu@intel.com>
Thu, 22 Nov 2018 07:12:08 +0000 (09:12 +0200)
committerLuca Coelho <luciano.coelho@intel.com>
Mon, 4 Feb 2019 10:27:18 +0000 (12:27 +0200)
There are two cases that can cause the alive flow to fail,
an assert or a timeout.
Currently we mask any incoming asserts when we wait for alive.

Solve this by differentiating between the two cases:
1. Let the regular error handling to handle a received assert
2. Do a dump collection in the case of a timeout

Signed-off-by: Shahar S Matityahu <shahar.s.matityahu@intel.com>
Fixes: f38efdb29389 ("iwlwifi: add dump collection in case alive flow fails")
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/fw/dbg.c
drivers/net/wireless/intel/iwlwifi/fw/dbg.h
drivers/net/wireless/intel/iwlwifi/fw/error-dump.h
drivers/net/wireless/intel/iwlwifi/fw/runtime.h
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
drivers/net/wireless/intel/iwlwifi/mvm/ops.c

index d16a8a4..0edc5bc 100644 (file)
@@ -1373,29 +1373,35 @@ void iwl_fw_assert_error_dump(struct iwl_fw_runtime *fwrt)
 }
 IWL_EXPORT_SYMBOL(iwl_fw_assert_error_dump);
 
-void iwl_fw_alive_error_dump(struct iwl_fw_runtime *fwrt)
+void iwl_fw_alive_timeout_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);
+       struct iwl_fw_dump_desc *iwl_dump_desc_alive_timeout;
 
-       if (!iwl_dump_desc_no_alive)
+       if (test_and_set_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status))
                return;
 
-       iwl_dump_desc_no_alive->trig_desc.type =
-               cpu_to_le32(FW_DBG_TRIGGER_NO_ALIVE);
-       iwl_dump_desc_no_alive->len = 0;
+       iwl_dump_desc_alive_timeout =
+               kmalloc(sizeof(*iwl_dump_desc_alive_timeout), GFP_KERNEL);
+       if (!iwl_dump_desc_alive_timeout)
+               return;
+
+       iwl_dump_desc_alive_timeout->trig_desc.type =
+               cpu_to_le32(FW_DBG_TRIGGER_ALIVE_TIMEOUT);
+       iwl_dump_desc_alive_timeout->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);
+                FW_DBG_TRIGGER_ALIVE_TIMEOUT);
+
+       /* set STATUS_FW_ERROR to collect all memory regions. */
+       set_bit(STATUS_FW_ERROR, &fwrt->trans->status);
 
-       fwrt->dump.desc = iwl_dump_desc_no_alive;
+       fwrt->dump.desc = iwl_dump_desc_alive_timeout;
        iwl_fw_error_dump(fwrt);
-       clear_bit(IWL_FWRT_STATUS_WAIT_ALIVE, &fwrt->status);
 }
-IWL_EXPORT_SYMBOL(iwl_fw_alive_error_dump);
+IWL_EXPORT_SYMBOL(iwl_fw_alive_timeout_dump);
 
 int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
                            const struct iwl_fw_dump_desc *desc,
@@ -1418,8 +1424,7 @@ 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) ||
-           test_bit(IWL_FWRT_STATUS_WAIT_ALIVE, &fwrt->status))
+       if (test_and_set_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status))
                return -EBUSY;
 
        if (WARN_ON(fwrt->dump.desc))
index 330229d..36e0f40 100644 (file)
@@ -435,7 +435,7 @@ static inline void iwl_fw_resume_timestamp(struct iwl_fw_runtime *fwrt) {}
 #endif /* CONFIG_IWLWIFI_DEBUGFS */
 
 void iwl_fw_assert_error_dump(struct iwl_fw_runtime *fwrt);
-void iwl_fw_alive_error_dump(struct iwl_fw_runtime *fwrt);
+void iwl_fw_alive_timeout_dump(struct iwl_fw_runtime *fwrt);
 void iwl_fw_dbg_collect_sync(struct iwl_fw_runtime *fwrt);
 void iwl_fw_dbg_apply_point(struct iwl_fw_runtime *fwrt,
                            enum iwl_fw_ini_apply_point apply_point);
index c02425a..d06707f 100644 (file)
@@ -355,7 +355,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
+ * @FW_DBG_TRIGGER_ALIVE_TIMEOUT: trigger log collection if alive flow timeouts
  */
 enum iwl_fw_dbg_trigger {
        FW_DBG_TRIGGER_INVALID = 0,
@@ -373,7 +373,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,
+       FW_DBG_TRIGGER_ALIVE_TIMEOUT,
 
        /* must be last */
        FW_DBG_TRIGGER_MAX,
index a0fcbb2..9ff04ff 100644 (file)
@@ -90,7 +90,6 @@ struct iwl_fwrt_shared_mem_cfg {
 
 enum iwl_fw_runtime_status {
        IWL_FWRT_STATUS_DUMPING = 0,
-       IWL_FWRT_STATUS_WAIT_ALIVE,
 };
 
 /**
index d3dc9d2..25c8cea 100644 (file)
@@ -299,7 +299,6 @@ 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,
@@ -332,6 +331,9 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
        if (ret) {
                struct iwl_trans *trans = mvm->trans;
 
+               if (ret == -ETIMEDOUT)
+                       iwl_fw_alive_timeout_dump(&mvm->fwrt);
+
                if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22000)
                        IWL_ERR(mvm,
                                "SecBoot CPU1 Status: 0x%x, CPU2 Status: 0x%x\n",
@@ -377,7 +379,6 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
 #ifdef CONFIG_IWLWIFI_DEBUGFS
        iwl_fw_set_dbg_rec_on(&mvm->fwrt);
 #endif
-       clear_bit(IWL_FWRT_STATUS_WAIT_ALIVE, &mvm->fwrt.status);
 
        return 0;
 }
index e56b316..a2719a7 100644 (file)
@@ -818,8 +818,6 @@ 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);