Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 67b8261c authored by Shahar S Matityahu's avatar Shahar S Matityahu Committed by Luca Coelho
Browse files

iwlwifi: differentiate between alive timeout and alive flow failure



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: default avatarShahar S Matityahu <shahar.s.matityahu@intel.com>
Fixes: f38efdb2 ("iwlwifi: add dump collection in case alive flow fails")
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent 74a10252
Loading
Loading
Loading
Loading
+18 −13
Original line number Diff line number Diff line
@@ -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))
+1 −1
Original line number Diff line number Diff line
@@ -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);
+2 −2
Original line number Diff line number Diff line
@@ -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,
+0 −1
Original line number Diff line number Diff line
@@ -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,
};

/**
+3 −2
Original line number Diff line number Diff line
@@ -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;
}
Loading