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

Commit 5a756c20 authored by Emmanuel Grumbach's avatar Emmanuel Grumbach
Browse files

iwlwifi: mvm: add trigger for firmware dump upon statistics



It can be very useful to monitor the statistics and trigger
a firmware dump when a certain value hits a certain offset.
Since the statistics are huge, add a generic trigger. When
the DWORD at offset X reaches value Y.

Since there is another trigger before this one I can't add
right now because of a dependency on mac80211, add a
reserved entry to keep the enum in place.

Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 945d4202
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -246,6 +246,8 @@ iwl_fw_error_next_data(struct iwl_fw_error_dump_data *data)
 * @FW_DBG_TRIGGER_CHANNEL_SWITCH: trigger log collection upon channel switch.
 * @FW_DBG_TRIGGER_FW_NOTIF: trigger log collection when the firmware sends a
 *	command response or a notification.
 * @FW_DB_TRIGGER_RESERVED: reserved
 * @FW_DBG_TRIGGER_STATS: trigger log collection upon statistics threshold.
 */
enum iwl_fw_dbg_trigger {
	FW_DBG_TRIGGER_INVALID = 0,
@@ -254,6 +256,8 @@ enum iwl_fw_dbg_trigger {
	FW_DBG_TRIGGER_MISSED_BEACONS,
	FW_DBG_TRIGGER_CHANNEL_SWITCH,
	FW_DBG_TRIGGER_FW_NOTIF,
	FW_DB_TRIGGER_RESERVED,
	FW_DBG_TRIGGER_STATS,

	/* must be last */
	FW_DBG_TRIGGER_MAX,
+14 −0
Original line number Diff line number Diff line
@@ -551,6 +551,20 @@ struct iwl_fw_dbg_trigger_cmd {
	} __packed cmds[16];
} __packed;

/**
 * iwl_fw_dbg_trigger_stats - configures trigger for statistics
 * @stop_offset: the offset of the value to be monitored
 * @stop_threshold: the threshold above which to collect
 * @start_offset: the offset of the value to be monitored
 * @start_threshold: the threshold above which to start recording
 */
struct iwl_fw_dbg_trigger_stats {
	__le32 stop_offset;
	__le32 stop_threshold;
	__le32 start_offset;
	__le32 start_threshold;
} __packed;

/**
 * struct iwl_fw_dbg_conf_tlv - a TLV that describes a debug configuration.
 * @id: conf id
+30 −0
Original line number Diff line number Diff line
@@ -508,6 +508,34 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
	}
}

static inline void
iwl_mvm_rx_stats_check_trigger(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt)
{
	struct iwl_fw_dbg_trigger_tlv *trig;
	struct iwl_fw_dbg_trigger_stats *trig_stats;
	u32 trig_offset, trig_thold;

	if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_STATS))
		return;

	trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_STATS);
	trig_stats = (void *)trig->data;

	if (!iwl_fw_dbg_trigger_check_stop(mvm, NULL, trig))
		return;

	trig_offset = le32_to_cpu(trig_stats->stop_offset);
	trig_thold = le32_to_cpu(trig_stats->stop_threshold);

	if (WARN_ON_ONCE(trig_offset >= iwl_rx_packet_payload_len(pkt)))
		return;

	if (le32_to_cpup((__le32 *) (pkt->data + trig_offset)) < trig_thold)
		return;

	iwl_mvm_fw_dbg_collect_trig(mvm, trig, NULL, 0);
}

void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
				  struct iwl_rx_packet *pkt)
{
@@ -553,6 +581,8 @@ void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
		iwl_mvm_update_rx_statistics(mvm, &stats->rx);
	}

	iwl_mvm_rx_stats_check_trigger(mvm, pkt);

	/* Only handle rx statistics temperature changes if async temp
	 * notifications are not supported
	 */