aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2015-02-10 08:26:57 -0500
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2015-03-02 01:20:31 -0500
commit5a756c20c44fe8b41d8adce090a2cdc95f10ab49 (patch)
tree1903a7a89975885ef6808f42f75b9e0d809c3d15
parent945d4202d95ed75c4af2968a02e58625d0558896 (diff)
iwlwifi: mvm: add trigger for firmware dump upon statistics
It can be very useful to monitor the statistics and trigger a firmware dump when a certain value hits a certain offset. Since the statistics are huge, add a generic trigger. When the DWORD at offset X reaches value Y. Since there is another trigger before this one I can't add right now because of a dependency on mac80211, add a reserved entry to keep the enum in place. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h14
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c30
3 files changed, 48 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
index 1d5195b4aad2..95bef179ddc1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
@@ -246,6 +246,8 @@ iwl_fw_error_next_data(struct iwl_fw_error_dump_data *data)
246 * @FW_DBG_TRIGGER_CHANNEL_SWITCH: trigger log collection upon channel switch. 246 * @FW_DBG_TRIGGER_CHANNEL_SWITCH: trigger log collection upon channel switch.
247 * @FW_DBG_TRIGGER_FW_NOTIF: trigger log collection when the firmware sends a 247 * @FW_DBG_TRIGGER_FW_NOTIF: trigger log collection when the firmware sends a
248 * command response or a notification. 248 * command response or a notification.
249 * @FW_DB_TRIGGER_RESERVED: reserved
250 * @FW_DBG_TRIGGER_STATS: trigger log collection upon statistics threshold.
249 */ 251 */
250enum iwl_fw_dbg_trigger { 252enum iwl_fw_dbg_trigger {
251 FW_DBG_TRIGGER_INVALID = 0, 253 FW_DBG_TRIGGER_INVALID = 0,
@@ -254,6 +256,8 @@ enum iwl_fw_dbg_trigger {
254 FW_DBG_TRIGGER_MISSED_BEACONS, 256 FW_DBG_TRIGGER_MISSED_BEACONS,
255 FW_DBG_TRIGGER_CHANNEL_SWITCH, 257 FW_DBG_TRIGGER_CHANNEL_SWITCH,
256 FW_DBG_TRIGGER_FW_NOTIF, 258 FW_DBG_TRIGGER_FW_NOTIF,
259 FW_DB_TRIGGER_RESERVED,
260 FW_DBG_TRIGGER_STATS,
257 261
258 /* must be last */ 262 /* must be last */
259 FW_DBG_TRIGGER_MAX, 263 FW_DBG_TRIGGER_MAX,
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
index 49388c290704..de0e96d76fa3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
@@ -552,6 +552,20 @@ struct iwl_fw_dbg_trigger_cmd {
552} __packed; 552} __packed;
553 553
554/** 554/**
555 * iwl_fw_dbg_trigger_stats - configures trigger for statistics
556 * @stop_offset: the offset of the value to be monitored
557 * @stop_threshold: the threshold above which to collect
558 * @start_offset: the offset of the value to be monitored
559 * @start_threshold: the threshold above which to start recording
560 */
561struct iwl_fw_dbg_trigger_stats {
562 __le32 stop_offset;
563 __le32 stop_threshold;
564 __le32 start_offset;
565 __le32 start_threshold;
566} __packed;
567
568/**
555 * struct iwl_fw_dbg_conf_tlv - a TLV that describes a debug configuration. 569 * struct iwl_fw_dbg_conf_tlv - a TLV that describes a debug configuration.
556 * @id: conf id 570 * @id: conf id
557 * @usniffer: should the uSniffer image be used 571 * @usniffer: should the uSniffer image be used
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index b86ff66ee0ce..9b2c537b5e95 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -508,6 +508,34 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
508 } 508 }
509} 509}
510 510
511static inline void
512iwl_mvm_rx_stats_check_trigger(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt)
513{
514 struct iwl_fw_dbg_trigger_tlv *trig;
515 struct iwl_fw_dbg_trigger_stats *trig_stats;
516 u32 trig_offset, trig_thold;
517
518 if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_STATS))
519 return;
520
521 trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_STATS);
522 trig_stats = (void *)trig->data;
523
524 if (!iwl_fw_dbg_trigger_check_stop(mvm, NULL, trig))
525 return;
526
527 trig_offset = le32_to_cpu(trig_stats->stop_offset);
528 trig_thold = le32_to_cpu(trig_stats->stop_threshold);
529
530 if (WARN_ON_ONCE(trig_offset >= iwl_rx_packet_payload_len(pkt)))
531 return;
532
533 if (le32_to_cpup((__le32 *) (pkt->data + trig_offset)) < trig_thold)
534 return;
535
536 iwl_mvm_fw_dbg_collect_trig(mvm, trig, NULL, 0);
537}
538
511void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm, 539void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
512 struct iwl_rx_packet *pkt) 540 struct iwl_rx_packet *pkt)
513{ 541{
@@ -553,6 +581,8 @@ void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
553 iwl_mvm_update_rx_statistics(mvm, &stats->rx); 581 iwl_mvm_update_rx_statistics(mvm, &stats->rx);
554 } 582 }
555 583
584 iwl_mvm_rx_stats_check_trigger(mvm, pkt);
585
556 /* Only handle rx statistics temperature changes if async temp 586 /* Only handle rx statistics temperature changes if async temp
557 * notifications are not supported 587 * notifications are not supported
558 */ 588 */