]> git.baikalelectronics.ru Git - kernel.git/commitdiff
iwlwifi: add dump collection in case alive flow fails
authorShahar S Matityahu <shahar.s.matityahu@intel.com>
Sun, 27 May 2018 14:17:07 +0000 (17:17 +0300)
committerLuca Coelho <luciano.coelho@intel.com>
Sat, 6 Oct 2018 07:25:50 +0000 (10:25 +0300)
Trigger dump collection if the alive flow fails, regardless of the
reason.

Signed-off-by: Shahar S Matityahu <shahar.s.matityahu@intel.com>
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 146ec50658259be9adfb4c893e8f1a00081f875f..a049367ac08a5e74ff44b1cf27f573a0f2b375b8 100644 (file)
@@ -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))
index 5b087fc4f380c64820a5d343e071b117a4a5d066..0f09a2128ad277287406ac2aa9ad857b33dc2596 100644 (file)
@@ -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__ */
index 6d3ef331b7d5cc58ac4e22f8a0eae3e6c043640e..6fede174c6649cd6395927ad8b2d43373144d882 100644 (file)
@@ -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,
index 9ed5819defaf06bf6cfd5d8a5ebd5610c707e55c..ac6db5e2b3d02251c9f96110eeea5334b100208e 100644 (file)
@@ -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,
 };
 
 /**
index 3fee304cddbb2adb587c40e8db06b6fd067c068e..c5df73231ba37ed8f1cd79bbd2c0c061855b2b7b 100644 (file)
@@ -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;
 }
index b058b7de88be1046f46cadbbe67d003b43088d19..c388e0e758e770d342c29c55cd1c3fe95cfc8978 100644 (file)
@@ -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);