summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/iwlwifi/mvm/fw.c
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2015-01-29 15:58:06 +0300
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2015-03-02 09:20:28 +0300
commitd2709ad723ff2ae22013978ed6ec29cf1b9b8332 (patch)
tree057dadfcb68f72846b90f2112bfe3bee205c24f9 /drivers/net/wireless/iwlwifi/mvm/fw.c
parentef17708e174fdc1ed5d10887ec2f3fc6f6c98d69 (diff)
downloadlinux-d2709ad723ff2ae22013978ed6ec29cf1b9b8332.tar.xz
iwlwifi: mvm: add framework for triggers for fw dump
Most of the time, the issues we want to debug with the firmware dump mechanism are transient. It is then very hard to stop the recording on time and get meaningful data. In order to solve this, I add here an infrastucture of triggers. The user will supply a list of triggers that will start / stop the recording. We have two types of triggers: start and stop. Start triggers can start a specific configuration. The stop triggers will be able to kick the collection of the data with the currently running configuration. These triggers are given to the driver by the .ucode file - just like the configuration. In the next patches, I'll add triggers in the code. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/fw.c')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index 7426bb0811be..8d684d5da964 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -217,8 +217,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
struct iwl_sf_region st_fwrd_space;
if (ucode_type == IWL_UCODE_REGULAR &&
- iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_CUSTOM) &&
- iwl_fw_dbg_conf_enabled(mvm->fw, FW_DBG_CUSTOM))
+ iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_START_FROM_ALIVE))
fw = iwl_get_ucode_image(mvm, IWL_UCODE_REGULAR_USNIFFER);
else
fw = iwl_get_ucode_image(mvm, ucode_type);
@@ -480,8 +479,14 @@ exit:
iwl_free_resp(&cmd);
}
-void iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm)
+int iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm, enum iwl_fw_dbg_trigger trig,
+ unsigned int delay)
{
+ if (test_and_set_bit(IWL_MVM_STATUS_DUMPING_FW_LOG, &mvm->status))
+ return -EBUSY;
+
+ IWL_WARN(mvm, "Collecting data: trigger %d fired.\n", trig);
+
/* stop recording */
if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
@@ -491,10 +496,30 @@ void iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm)
udelay(100);
}
- schedule_work(&mvm->fw_error_dump_wk);
+ queue_delayed_work(system_wq, &mvm->fw_dump_wk, delay);
+
+ return 0;
+}
+
+int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm,
+ struct iwl_fw_dbg_trigger_tlv *trigger)
+{
+ unsigned int delay = msecs_to_jiffies(le32_to_cpu(trigger->stop_delay));
+ u16 occurrences = le16_to_cpu(trigger->occurrences);
+ int ret;
+
+ if (!occurrences)
+ return 0;
+
+ ret = iwl_mvm_fw_dbg_collect(mvm, le32_to_cpu(trigger->id), delay);
+ if (ret)
+ return ret;
+
+ trigger->occurrences = cpu_to_le16(occurrences - 1);
+ return 0;
}
-int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, enum iwl_fw_dbg_conf conf_id)
+int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id)
{
u8 *ptr;
int ret;
@@ -613,7 +638,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
IWL_ERR(mvm, "Failed to initialize Smart Fifo\n");
mvm->fw_dbg_conf = FW_DBG_INVALID;
- iwl_mvm_start_fw_dbg_conf(mvm, FW_DBG_CUSTOM);
+ iwl_mvm_start_fw_dbg_conf(mvm, FW_DBG_START_FROM_ALIVE);
ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
if (ret)