Commit 9d761fd8 authored by Emmanuel Grumbach's avatar Emmanuel Grumbach

iwlwifi: mvm: add trigger for firmware dump upon missed beacons

Missing beacons is a good indication that something is going
wrong in the firmware. Add a trigger to be able to collect
data when we start missing beacons with a configurable
threshold.
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent b6eaa45a
...@@ -241,11 +241,14 @@ iwl_fw_error_next_data(struct iwl_fw_error_dump_data *data) ...@@ -241,11 +241,14 @@ iwl_fw_error_next_data(struct iwl_fw_error_dump_data *data)
* driver should set to indicate that the trigger was initiated by the * driver should set to indicate that the trigger was initiated by the
* user. * user.
* @FW_DBG_TRIGGER_FW_ASSERT: trigger log collection when the firmware asserts * @FW_DBG_TRIGGER_FW_ASSERT: trigger log collection when the firmware asserts
* @FW_DBG_TRIGGER_MISSED_BEACONS: trigger log collection when beacons are
* missed.
*/ */
enum iwl_fw_dbg_trigger { enum iwl_fw_dbg_trigger {
FW_DBG_TRIGGER_INVALID = 0, FW_DBG_TRIGGER_INVALID = 0,
FW_DBG_TRIGGER_USER, FW_DBG_TRIGGER_USER,
FW_DBG_TRIGGER_FW_ASSERT, FW_DBG_TRIGGER_FW_ASSERT,
FW_DBG_TRIGGER_MISSED_BEACONS,
/* must be last */ /* must be last */
FW_DBG_TRIGGER_MAX, FW_DBG_TRIGGER_MAX,
......
...@@ -522,6 +522,24 @@ struct iwl_fw_dbg_trigger_tlv { ...@@ -522,6 +522,24 @@ struct iwl_fw_dbg_trigger_tlv {
#define FW_DBG_CONF_MAX 32 #define FW_DBG_CONF_MAX 32
#define FW_DBG_INVALID 0xff #define FW_DBG_INVALID 0xff
/**
* struct iwl_fw_dbg_trigger_missed_bcon - configures trigger for missed beacons
* @stop_consec_missed_bcon: stop recording if threshold is crossed.
* @stop_consec_missed_bcon_since_rx: stop recording if threshold is crossed.
* @start_consec_missed_bcon: start recording if threshold is crossed.
* @start_consec_missed_bcon_since_rx: start recording if threshold is crossed.
* @reserved1: reserved
* @reserved2: reserved
*/
struct iwl_fw_dbg_trigger_missed_bcon {
__le32 stop_consec_missed_bcon;
__le32 stop_consec_missed_bcon_since_rx;
__le32 reserved2[2];
__le32 start_consec_missed_bcon;
__le32 start_consec_missed_bcon_since_rx;
__le32 reserved1[2];
} __packed;
/** /**
* struct iwl_fw_dbg_conf_tlv - a TLV that describes a debug configuration. * struct iwl_fw_dbg_conf_tlv - a TLV that describes a debug configuration.
* @id: conf id * @id: conf id
......
...@@ -1375,10 +1375,18 @@ static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac, ...@@ -1375,10 +1375,18 @@ static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac,
{ {
struct iwl_missed_beacons_notif *missed_beacons = _data; struct iwl_missed_beacons_notif *missed_beacons = _data;
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm *mvm = mvmvif->mvm;
struct iwl_fw_dbg_trigger_missed_bcon *bcon_trig;
struct iwl_fw_dbg_trigger_tlv *trigger;
u32 stop_trig_missed_bcon, stop_trig_missed_bcon_since_rx;
u32 rx_missed_bcon, rx_missed_bcon_since_rx;
if (mvmvif->id != (u16)le32_to_cpu(missed_beacons->mac_id)) if (mvmvif->id != (u16)le32_to_cpu(missed_beacons->mac_id))
return; return;
rx_missed_bcon = le32_to_cpu(missed_beacons->consec_missed_beacons);
rx_missed_bcon_since_rx =
le32_to_cpu(missed_beacons->consec_missed_beacons_since_last_rx);
/* /*
* TODO: the threshold should be adjusted based on latency conditions, * TODO: the threshold should be adjusted based on latency conditions,
* and/or in case of a CS flow on one of the other AP vifs. * and/or in case of a CS flow on one of the other AP vifs.
...@@ -1386,6 +1394,26 @@ static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac, ...@@ -1386,6 +1394,26 @@ static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac,
if (le32_to_cpu(missed_beacons->consec_missed_beacons_since_last_rx) > if (le32_to_cpu(missed_beacons->consec_missed_beacons_since_last_rx) >
IWL_MVM_MISSED_BEACONS_THRESHOLD) IWL_MVM_MISSED_BEACONS_THRESHOLD)
ieee80211_beacon_loss(vif); ieee80211_beacon_loss(vif);
if (!iwl_fw_dbg_trigger_enabled(mvm->fw,
FW_DBG_TRIGGER_MISSED_BEACONS))
return;
trigger = iwl_fw_dbg_get_trigger(mvm->fw,
FW_DBG_TRIGGER_MISSED_BEACONS);
bcon_trig = (void *)trigger->data;
stop_trig_missed_bcon = le32_to_cpu(bcon_trig->stop_consec_missed_bcon);
stop_trig_missed_bcon_since_rx =
le32_to_cpu(bcon_trig->stop_consec_missed_bcon_since_rx);
/* TODO: implement start trigger */
if (!iwl_fw_dbg_trigger_check_stop(mvm, vif, trigger))
return;
if (rx_missed_bcon_since_rx >= stop_trig_missed_bcon_since_rx ||
rx_missed_bcon >= stop_trig_missed_bcon)
iwl_mvm_fw_dbg_collect_trig(mvm, trigger, NULL, 0);
} }
int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment