iwlwifi: mvm: add trigger for firmware dump upon command response
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Tue, 10 Feb 2015 08:49:20 +0000 (10:49 +0200)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Mon, 2 Mar 2015 06:20:30 +0000 (08:20 +0200)
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>
drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
drivers/net/wireless/iwlwifi/iwl-fw-file.h
drivers/net/wireless/iwlwifi/mvm/ops.c

index 1ee58b3dca1d565bcb6b9ff891cd1ac574451142..1d5195b4aad24297582212866e6750498d28f6fd 100644 (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,
index 85745dcb0e22563c6bcbe9cb70365f1ed41cc8f3..49388c2907047811917f919aad322cf744cf9a6d 100644 (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
index f1c5751934d50352814b9e015ce24c6a648b07a9..fe40922a6b0d467c86da151e2c786a265e46a1e2 100644 (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