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

Commit 36fb9017 authored by Oren Givon's avatar Oren Givon Committed by Emmanuel Grumbach
Browse files

iwlwifi: mvm: add the ability to trigger only monitor dumps



Change the FW debug trigger tlv to include a monitor only
option. Setting this option to true will cause fw dump triggers
to only collect monitor data and skip other dumps such as
SMEM, SRAM, CSR, PRPH, etc.
This option is used when accessing the different parts of the
firmware memory is not wanted and can cause unwanted behavior
like when debugging TX latency.

Signed-off-by: default avatarOren Givon <oren.givon@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 206eea78
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -498,10 +498,13 @@ struct iwl_fw_dbg_conf_hcmd {
 *
 * @IWL_FW_DBG_TRIGGER_START: when trigger occurs re-conf the dbg mechanism
 * @IWL_FW_DBG_TRIGGER_STOP: when trigger occurs pull the dbg data
 * @IWL_FW_DBG_TRIGGER_MONITOR_ONLY: when trigger occurs trigger is set to
 *	collect only monitor data
 */
enum iwl_fw_dbg_trigger_mode {
	IWL_FW_DBG_TRIGGER_START = BIT(0),
	IWL_FW_DBG_TRIGGER_STOP = BIT(1),
	IWL_FW_DBG_TRIGGER_MONITOR_ONLY = BIT(2),
};

/**
+6 −3
Original line number Diff line number Diff line
@@ -608,7 +608,9 @@ struct iwl_trans_ops {
	int  (*suspend)(struct iwl_trans *trans);
	void (*resume)(struct iwl_trans *trans);

	struct iwl_trans_dump_data *(*dump_data)(struct iwl_trans *trans);
	struct iwl_trans_dump_data *(*dump_data)(struct iwl_trans *trans,
						 struct iwl_fw_dbg_trigger_tlv
						 *trigger);
};

/**
@@ -832,11 +834,12 @@ static inline void iwl_trans_resume(struct iwl_trans *trans)
}

static inline struct iwl_trans_dump_data *
iwl_trans_dump_data(struct iwl_trans *trans)
iwl_trans_dump_data(struct iwl_trans *trans,
		    struct iwl_fw_dbg_trigger_tlv *trigger)
{
	if (!trans->ops->dump_data)
		return NULL;
	return trans->ops->dump_data(trans);
	return trans->ops->dump_data(trans, trigger);
}

static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
+1 −1
Original line number Diff line number Diff line
@@ -974,7 +974,7 @@ static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
	if (ret)
		return ret;

	iwl_mvm_fw_dbg_collect(mvm, FW_DBG_TRIGGER_USER, NULL, 0, 0);
	iwl_mvm_fw_dbg_collect(mvm, FW_DBG_TRIGGER_USER, NULL, 0, NULL);

	iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE);

+13 −6
Original line number Diff line number Diff line
@@ -735,8 +735,13 @@ static void iwl_mvm_get_shared_mem_conf(struct iwl_mvm *mvm)

int iwl_mvm_fw_dbg_collect_desc(struct iwl_mvm *mvm,
				struct iwl_mvm_dump_desc *desc,
				unsigned int delay)
				struct iwl_fw_dbg_trigger_tlv *trigger)
{
	unsigned int delay = 0;

	if (trigger)
		delay = msecs_to_jiffies(le32_to_cpu(trigger->stop_delay));

	if (test_and_set_bit(IWL_MVM_STATUS_DUMPING_FW_LOG, &mvm->status))
		return -EBUSY;

@@ -747,6 +752,7 @@ int iwl_mvm_fw_dbg_collect_desc(struct iwl_mvm *mvm,
		 le32_to_cpu(desc->trig_desc.type));

	mvm->fw_dump_desc = desc;
	mvm->fw_dump_trig = trigger;

	queue_delayed_work(system_wq, &mvm->fw_dump_wk, delay);

@@ -754,7 +760,8 @@ int iwl_mvm_fw_dbg_collect_desc(struct iwl_mvm *mvm,
}

int iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm, enum iwl_fw_dbg_trigger trig,
			   const char *str, size_t len, unsigned int delay)
			   const char *str, size_t len,
			   struct iwl_fw_dbg_trigger_tlv *trigger)
{
	struct iwl_mvm_dump_desc *desc;

@@ -766,14 +773,13 @@ int iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm, enum iwl_fw_dbg_trigger trig,
	desc->trig_desc.type = cpu_to_le32(trig);
	memcpy(desc->trig_desc.data, str, len);

	return iwl_mvm_fw_dbg_collect_desc(mvm, desc, delay);
	return iwl_mvm_fw_dbg_collect_desc(mvm, desc, trigger);
}

int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm,
				struct iwl_fw_dbg_trigger_tlv *trigger,
				const char *fmt, ...)
{
	unsigned int delay = msecs_to_jiffies(le32_to_cpu(trigger->stop_delay));
	u16 occurrences = le16_to_cpu(trigger->occurrences);
	int ret, len = 0;
	char buf[64];
@@ -797,8 +803,9 @@ int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm,
		len = strlen(buf) + 1;
	}

	ret = iwl_mvm_fw_dbg_collect(mvm, le32_to_cpu(trigger->id), buf,
				     len, delay);
	ret = iwl_mvm_fw_dbg_collect(mvm, le32_to_cpu(trigger->id), buf, len,
				     trigger);

	if (ret)
		return ret;

+27 −9
Original line number Diff line number Diff line
@@ -1124,9 +1124,14 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
	u32 file_len, fifo_data_len = 0;
	u32 smem_len = mvm->cfg->smem_len;
	u32 sram2_len = mvm->cfg->dccm2_len;
	bool monitor_dump_only = false;

	lockdep_assert_held(&mvm->mutex);

	if (mvm->fw_dump_trig &&
	    mvm->fw_dump_trig->mode & IWL_FW_DBG_TRIGGER_MONITOR_ONLY)
		monitor_dump_only = true;

	fw_error_dump = kzalloc(sizeof(*fw_error_dump), GFP_KERNEL);
	if (!fw_error_dump)
		return;
@@ -1178,6 +1183,20 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
		   fifo_data_len +
		   sizeof(*dump_info);

	/* Make room for the SMEM, if it exists */
	if (smem_len)
		file_len += sizeof(*dump_data) + sizeof(*dump_mem) + smem_len;

	/* Make room for the secondary SRAM, if it exists */
	if (sram2_len)
		file_len += sizeof(*dump_data) + sizeof(*dump_mem) + sram2_len;

	/* If we only want a monitor dump, reset the file length */
	if (monitor_dump_only) {
		file_len = sizeof(*dump_file) + sizeof(*dump_data) +
			   sizeof(*dump_info);
	}

	/*
	 * In 8000 HW family B-step include the ICCM (which resides separately)
	 */
@@ -1190,14 +1209,6 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
		file_len += sizeof(*dump_data) + sizeof(*dump_trig) +
			    mvm->fw_dump_desc->len;

	/* Make room for the SMEM, if it exists */
	if (smem_len)
		file_len += sizeof(*dump_data) + sizeof(*dump_mem) + smem_len;

	/* Make room for the secondary SRAM, if it exists */
	if (sram2_len)
		file_len += sizeof(*dump_data) + sizeof(*dump_mem) + sram2_len;

	dump_file = vzalloc(file_len);
	if (!dump_file) {
		kfree(fw_error_dump);
@@ -1243,6 +1254,10 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
		dump_data = iwl_fw_error_next_data(dump_data);
	}

	/* In case we only want monitor dump, skip to dump trasport data */
	if (monitor_dump_only)
		goto dump_trans_data;

	dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
	dump_data->len = cpu_to_le32(sram_len + sizeof(*dump_mem));
	dump_mem = (void *)dump_data->data;
@@ -1286,7 +1301,9 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
					 dump_mem->data, IWL8260_ICCM_LEN);
	}

	fw_error_dump->trans_ptr = iwl_trans_dump_data(mvm->trans);
dump_trans_data:
	fw_error_dump->trans_ptr = iwl_trans_dump_data(mvm->trans,
						       mvm->fw_dump_trig);
	fw_error_dump->op_mode_len = file_len;
	if (fw_error_dump->trans_ptr)
		file_len += fw_error_dump->trans_ptr->len;
@@ -1295,6 +1312,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
	dev_coredumpm(mvm->trans->dev, THIS_MODULE, fw_error_dump, 0,
		      GFP_KERNEL, iwl_mvm_read_coredump, iwl_mvm_free_coredump);

	mvm->fw_dump_trig = NULL;
	clear_bit(IWL_MVM_STATUS_DUMPING_FW_LOG, &mvm->status);
}

Loading