iwlwifi: mvm: Support setting continuous recording debug mode
authorGolan Ben Ami <golan.ben.ami@intel.com>
Mon, 27 Jul 2015 14:02:35 +0000 (17:02 +0300)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Tue, 1 Dec 2015 19:17:50 +0000 (21:17 +0200)
Add ability to set the continuous recording mode of the FW, while
the FW debug data is configured to be stored on the NIC.
This could be useful for storing large segments of FW usniffer
debug data on the host, while having small store space on the NIC.
The host receives the usniffer data through the regular RX path, and
the data can get extracted using trace-cmd.

Signed-off-by: Golan Ben-Ami <golan.ben.ami@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
drivers/net/wireless/intel/iwlwifi/mvm/ops.c

index 3f7682da99e7fb20bc5f9faeecacc8fb552266d1..7e2a8149411c35c67680abb3a64ed381749586e8 100644 (file)
@@ -961,6 +961,44 @@ static ssize_t iwl_dbgfs_fw_dbg_conf_read(struct file *file,
        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 }
 
+/*
+ * Enable / Disable continuous recording.
+ * Cause the FW to start continuous recording, by sending the relevant hcmd.
+ * Enable: input of every integer larger than 0, ENABLE_CONT_RECORDING.
+ * Disable: for 0 as input, DISABLE_CONT_RECORDING.
+ */
+static ssize_t iwl_dbgfs_cont_recording_write(struct iwl_mvm *mvm,
+                                             char *buf, size_t count,
+                                             loff_t *ppos)
+{
+       struct iwl_trans *trans = mvm->trans;
+       const struct iwl_fw_dbg_dest_tlv *dest = trans->dbg_dest_tlv;
+       struct iwl_continuous_record_cmd cont_rec = {};
+       int ret, rec_mode;
+
+       if (!dest)
+               return -EOPNOTSUPP;
+
+       if (dest->monitor_mode != SMEM_MODE ||
+           trans->cfg->device_family != IWL_DEVICE_FAMILY_8000)
+               return -EOPNOTSUPP;
+
+       ret = kstrtouint(buf, 0, &rec_mode);
+       if (ret)
+               return ret;
+
+       cont_rec.record_mode.enable_recording = rec_mode ?
+               cpu_to_le16(ENABLE_CONT_RECORDING) :
+               cpu_to_le16(DISABLE_CONT_RECORDING);
+
+       mutex_lock(&mvm->mutex);
+       ret = iwl_mvm_send_cmd_pdu(mvm, LDBG_CONFIG_CMD, 0,
+                                  sizeof(cont_rec), &cont_rec);
+       mutex_unlock(&mvm->mutex);
+
+       return ret ?: count;
+}
+
 static ssize_t iwl_dbgfs_fw_dbg_conf_write(struct iwl_mvm *mvm,
                                           char *buf, size_t count,
                                           loff_t *ppos)
@@ -1413,6 +1451,7 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
 MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8);
 MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8);
 MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 8);
+MVM_DEBUGFS_WRITE_FILE_OPS(cont_recording, 8);
 
 #ifdef CONFIG_IWLWIFI_BCAST_FILTERING
 MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256);
@@ -1456,6 +1495,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
        MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, S_IRUSR | S_IWUSR);
        MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, S_IWUSR);
        MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, S_IWUSR);
+       MVM_DEBUGFS_ADD_FILE(cont_recording, mvm->debugfs_dir, S_IWUSR);
        if (!debugfs_create_bool("enable_scan_iteration_notif",
                                 S_IRUSR | S_IWUSR,
                                 mvm->debugfs_dir,
index 181590fbd3b340c712d3f0d1edb70b118a7c9b89..68dfa2848d3e05dabbd2d5087e499d516026bc50 100644 (file)
@@ -239,6 +239,7 @@ enum {
        DTS_MEASUREMENT_NOTIFICATION = 0xdd,
 
        REPLY_DEBUG_CMD = 0xf0,
+       LDBG_CONFIG_CMD = 0xf6,
        DEBUG_LOG_MSG = 0xf7,
 
        BCAST_FILTER_CMD = 0xcf,
@@ -426,6 +427,26 @@ struct iwl_fw_get_item_cmd {
        __le32 item_id;
 } __packed; /* FW_GET_ITEM_CMD_API_S_VER_1 */
 
+#define CONT_REC_COMMAND_SIZE  80
+#define ENABLE_CONT_RECORDING  0x15
+#define DISABLE_CONT_RECORDING 0x16
+
+/*
+ * struct iwl_continuous_record_mode - recording mode
+ */
+struct iwl_continuous_record_mode {
+       __le16 enable_recording;
+} __packed;
+
+/*
+ * struct iwl_continuous_record_cmd - enable/disable continuous recording
+ */
+struct iwl_continuous_record_cmd {
+       struct iwl_continuous_record_mode record_mode;
+       u8 pad[CONT_REC_COMMAND_SIZE -
+               sizeof(struct iwl_continuous_record_mode)];
+} __packed;
+
 struct iwl_fw_get_item_resp {
        __le32 item_id;
        __le32 item_byte_cnt;
index f96ed5577c5e6939d19177060d787d807c2da95a..fa849a284e1ced5d9e346c77bc521c320a982d05 100644 (file)
@@ -363,6 +363,7 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX + 1] = {
        CMD(TDLS_CONFIG_CMD),
        CMD(MCC_UPDATE_CMD),
        CMD(SCAN_ITERATION_COMPLETE_UMAC),
+       CMD(LDBG_CONFIG_CMD),
 };
 #undef CMD