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

Commit fe1b7d6c authored by Sara Sharon's avatar Sara Sharon Committed by Luca Coelho
Browse files

iwlwifi: add support for triggering ini triggers



Add support for ini triggers.

Signed-off-by: default avatarSara Sharon <sara.sharon@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent 7a14c23d
Loading
Loading
Loading
Loading
+53 −6
Original line number Diff line number Diff line
@@ -1329,7 +1329,7 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
}
IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect_desc);

int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
int _iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
			enum iwl_fw_dbg_trigger trig,
			const char *str, size_t len,
			struct iwl_fw_dbg_trigger_tlv *trigger)
@@ -1367,6 +1367,47 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,

	return iwl_fw_dbg_collect_desc(fwrt, desc, monitor_only, delay);
}
IWL_EXPORT_SYMBOL(_iwl_fw_dbg_collect);

int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
		       u32 id, const char *str, size_t len)
{
	struct iwl_fw_dump_desc *desc;
	u32 occur, delay;

	if (!fwrt->trans->ini_valid)
		return _iwl_fw_dbg_collect(fwrt, id, str, len, NULL);

	if (id == FW_DBG_TRIGGER_USER)
		id = IWL_FW_TRIGGER_ID_USER_TRIGGER;

	if (WARN_ON(!fwrt->dump.active_trigs[id].active))
		return -EINVAL;

	delay = le32_to_cpu(fwrt->dump.active_trigs[id].conf->ignore_consec);
	occur = le32_to_cpu(fwrt->dump.active_trigs[id].conf->occurrences);
	if (!occur)
		return 0;

	if (le32_to_cpu(fwrt->dump.active_trigs[id].conf->force_restart)) {
		IWL_WARN(fwrt, "Force restart: trigger %d fired.\n", id);
		iwl_force_nmi(fwrt->trans);
		return 0;
	}

	desc = kzalloc(sizeof(*desc) + len, GFP_ATOMIC);
	if (!desc)
		return -ENOMEM;

	occur--;
	fwrt->dump.active_trigs[id].conf->occurrences = cpu_to_le32(occur);

	desc->len = len;
	desc->trig_desc.type = cpu_to_le32(id);
	memcpy(desc->trig_desc.data, str, len);

	return iwl_fw_dbg_collect_desc(fwrt, desc, true, delay);
}
IWL_EXPORT_SYMBOL(iwl_fw_dbg_collect);

int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
@@ -1395,7 +1436,7 @@ int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
		len = strlen(buf) + 1;
	}

	ret = iwl_fw_dbg_collect(fwrt, le32_to_cpu(trigger->id), buf, len,
	ret = _iwl_fw_dbg_collect(fwrt, le32_to_cpu(trigger->id), buf, len,
				  trigger);

	if (ret)
@@ -1668,6 +1709,12 @@ static void iwl_fw_dbg_update_triggers(struct iwl_fw_runtime *fwrt,
			active->conf = trig;
		}

		/* Since zero means infinity - just set to -1 */
		if (!le32_to_cpu(trig->occurrences))
			trig->occurrences = cpu_to_le32(-1);
		if (!le32_to_cpu(trig->ignore_consec))
			trig->ignore_consec = cpu_to_le32(-1);

		iter += sizeof(*trig) +
			le32_to_cpu(trig->num_regions) * sizeof(__le32);

+36 −3
Original line number Diff line number Diff line
@@ -108,10 +108,12 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt);
int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
			    const struct iwl_fw_dump_desc *desc,
			    bool monitor_only, unsigned int delay);
int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
int _iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
			enum iwl_fw_dbg_trigger trig,
			const char *str, size_t len,
			struct iwl_fw_dbg_trigger_tlv *trigger);
int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt,
		       u32 id, const char *str, size_t len);
int iwl_fw_dbg_collect_trig(struct iwl_fw_runtime *fwrt,
			    struct iwl_fw_dbg_trigger_tlv *trigger,
			    const char *fmt, ...) __printf(3, 4);
@@ -213,6 +215,37 @@ _iwl_fw_dbg_trigger_on(struct iwl_fw_runtime *fwrt,
	_iwl_fw_dbg_trigger_on((fwrt), (wdev), (id));		\
})

static inline bool
_iwl_fw_ini_trigger_on(struct iwl_fw_runtime *fwrt,
		       const enum iwl_fw_dbg_trigger id)
{
	struct iwl_fw_ini_active_triggers *trig = &fwrt->dump.active_trigs[id];
	u32 ms;

	if (!fwrt->trans->ini_valid)
		return false;

	if (!trig || !trig->active)
		return false;

	ms = le32_to_cpu(trig->conf->ignore_consec);
	if (ms)
		ms /= USEC_PER_MSEC;

	if (iwl_fw_dbg_no_trig_window(fwrt, id, ms)) {
		IWL_WARN(fwrt, "Trigger %d fired in no-collect window\n", id);
		return false;
	}

	return true;
}

#define iwl_fw_ini_trigger_on(fwrt, wdev, id) ({		\
	BUILD_BUG_ON(!__builtin_constant_p(id));		\
	BUILD_BUG_ON((id) >= IWL_FW_TRIGGER_ID_NUM);		\
	_iwl_fw_ini_trigger_on((fwrt), (wdev), (id));		\
})

static inline void
_iwl_fw_dbg_trigger_simple_stop(struct iwl_fw_runtime *fwrt,
				struct wireless_dev *wdev,
+1 −1
Original line number Diff line number Diff line
@@ -138,7 +138,7 @@ struct iwl_fw_runtime {
		u8 conf;

		/* ts of the beginning of a non-collect fw dbg data period */
		unsigned long non_collect_ts_start[FW_DBG_TRIGGER_MAX - 1];
		unsigned long non_collect_ts_start[IWL_FW_TRIGGER_ID_NUM - 1];
		u32 *d3_debug_data;
		struct iwl_fw_ini_active_regs active_regs[IWL_FW_INI_MAX_REGION_ID];
		struct iwl_fw_ini_active_triggers active_trigs[IWL_FW_TRIGGER_ID_NUM];
+1 −1
Original line number Diff line number Diff line
@@ -1284,7 +1284,7 @@ static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
		return 0;

	iwl_fw_dbg_collect(&mvm->fwrt, FW_DBG_TRIGGER_USER, buf,
			   (count - 1), NULL);
			   (count - 1));

	iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE);