iwlwifi: mvm: add trigger for firmware dump upon command response

This will allow to collect the data as soon the firmware
sends a specific notification of command response.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
This commit is contained in:
Emmanuel Grumbach 2015-02-10 10:49:20 +02:00
parent f35d9c55cd
commit 917f39bb9a
3 changed files with 48 additions and 0 deletions

View File

@ -244,6 +244,8 @@ iwl_fw_error_next_data(struct iwl_fw_error_dump_data *data)
* @FW_DBG_TRIGGER_MISSED_BEACONS: trigger log collection when beacons are
* missed.
* @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.
*/
enum iwl_fw_dbg_trigger {
FW_DBG_TRIGGER_INVALID = 0,
@ -251,6 +253,7 @@ enum iwl_fw_dbg_trigger {
FW_DBG_TRIGGER_FW_ASSERT,
FW_DBG_TRIGGER_MISSED_BEACONS,
FW_DBG_TRIGGER_CHANNEL_SWITCH,
FW_DBG_TRIGGER_FW_NOTIF,
/* must be last */
FW_DBG_TRIGGER_MAX,

View File

@ -540,6 +540,17 @@ struct iwl_fw_dbg_trigger_missed_bcon {
__le32 reserved1[2];
} __packed;
/**
* struct iwl_fw_dbg_trigger_cmd - configures trigger for messages from FW.
* cmds: the list of commands to trigger the collection on
*/
struct iwl_fw_dbg_trigger_cmd {
struct cmd {
u8 cmd_id;
u8 group_id;
} __packed cmds[16];
} __packed;
/**
* struct iwl_fw_dbg_conf_tlv - a TLV that describes a debug configuration.
* @id: conf id

View File

@ -685,6 +685,38 @@ static void iwl_mvm_async_handlers_wk(struct work_struct *wk)
mutex_unlock(&mvm->mutex);
}
static inline void iwl_mvm_rx_check_trigger(struct iwl_mvm *mvm,
struct iwl_rx_packet *pkt)
{
struct iwl_fw_dbg_trigger_tlv *trig;
struct iwl_fw_dbg_trigger_cmd *cmds_trig;
char buf[32];
int i;
if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_FW_NOTIF))
return;
trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_FW_NOTIF);
cmds_trig = (void *)trig->data;
if (!iwl_fw_dbg_trigger_check_stop(mvm, NULL, trig))
return;
for (i = 0; i < ARRAY_SIZE(cmds_trig->cmds); i++) {
/* don't collect on CMD 0 */
if (!cmds_trig->cmds[i].cmd_id)
break;
if (cmds_trig->cmds[i].cmd_id != pkt->hdr.cmd)
continue;
memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf), "CMD 0x%02x received", pkt->hdr.cmd);
iwl_mvm_fw_dbg_collect_trig(mvm, trig, buf, sizeof(buf));
break;
}
}
static int iwl_mvm_rx_dispatch(struct iwl_op_mode *op_mode,
struct iwl_rx_cmd_buffer *rxb,
struct iwl_device_cmd *cmd)
@ -693,6 +725,8 @@ static int iwl_mvm_rx_dispatch(struct iwl_op_mode *op_mode,
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
u8 i;
iwl_mvm_rx_check_trigger(mvm, pkt);
/*
* Do the notification wait before RX handlers so
* even if the RX handler consumes the RXB we have