diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2015-02-10 08:26:57 -0500 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2015-03-02 01:20:31 -0500 |
commit | 5a756c20c44fe8b41d8adce090a2cdc95f10ab49 (patch) | |
tree | 1903a7a89975885ef6808f42f75b9e0d809c3d15 | |
parent | 945d4202d95ed75c4af2968a02e58625d0558896 (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.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-fw-file.h | 14 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/rx.c | 30 |
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 | */ |
250 | enum iwl_fw_dbg_trigger { | 252 | enum 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 | */ | ||
561 | struct 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 | ||
511 | static inline void | ||
512 | iwl_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 | |||
511 | void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm, | 539 | void 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 | */ |