diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2015-02-10 07:29:48 -0500 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2015-04-02 02:29:12 -0400 |
commit | d42f53503406d5dcedbad9ea18c964f189f72d84 (patch) | |
tree | 305004215f1dfc09af4926721c55b5976505fd34 /drivers/net/wireless | |
parent | b916693a7731670429609854c32de1a71775d070 (diff) |
iwlwifi: mvm: add trigger for firmware dump upon MLME failures
This will allow to catch failures in MLME and get the
firmware data when this happens.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-fw-file.h | 35 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mac80211.c | 65 |
3 files changed, 102 insertions, 2 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h index 46cbae8f821d..8b926ece0d3a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h | |||
@@ -246,7 +246,7 @@ 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 | 249 | * @FW_DBG_TRIGGER_MLME: trigger log collection upon MLME event. |
250 | * @FW_DBG_TRIGGER_STATS: trigger log collection upon statistics threshold. | 250 | * @FW_DBG_TRIGGER_STATS: trigger log collection upon statistics threshold. |
251 | * @FW_DBG_TRIGGER_RSSI: trigger log collection when the rssi of the beacon | 251 | * @FW_DBG_TRIGGER_RSSI: trigger log collection when the rssi of the beacon |
252 | * goes below a threshold. | 252 | * goes below a threshold. |
@@ -260,7 +260,7 @@ enum iwl_fw_dbg_trigger { | |||
260 | FW_DBG_TRIGGER_MISSED_BEACONS, | 260 | FW_DBG_TRIGGER_MISSED_BEACONS, |
261 | FW_DBG_TRIGGER_CHANNEL_SWITCH, | 261 | FW_DBG_TRIGGER_CHANNEL_SWITCH, |
262 | FW_DBG_TRIGGER_FW_NOTIF, | 262 | FW_DBG_TRIGGER_FW_NOTIF, |
263 | FW_DB_TRIGGER_RESERVED, | 263 | FW_DBG_TRIGGER_MLME, |
264 | FW_DBG_TRIGGER_STATS, | 264 | FW_DBG_TRIGGER_STATS, |
265 | FW_DBG_TRIGGER_RSSI, | 265 | FW_DBG_TRIGGER_RSSI, |
266 | FW_DBG_TRIGGER_TXQ_TIMERS, | 266 | FW_DBG_TRIGGER_TXQ_TIMERS, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 0cfc66d1aef2..823938e3b7ef 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h | |||
@@ -579,6 +579,41 @@ struct iwl_fw_dbg_trigger_low_rssi { | |||
579 | } __packed; | 579 | } __packed; |
580 | 580 | ||
581 | /** | 581 | /** |
582 | * struct iwl_fw_dbg_trigger_mlme - configures trigger for mlme events | ||
583 | * @stop_auth_denied: number of denied authentication to collect | ||
584 | * @stop_auth_timeout: number of authentication timeout to collect | ||
585 | * @stop_rx_deauth: number of Rx deauth before to collect | ||
586 | * @stop_tx_deauth: number of Tx deauth before to collect | ||
587 | * @stop_assoc_denied: number of denied association to collect | ||
588 | * @stop_assoc_timeout: number of association timeout to collect | ||
589 | * @start_auth_denied: number of denied authentication to start recording | ||
590 | * @start_auth_timeout: number of authentication timeout to start recording | ||
591 | * @start_rx_deauth: number of Rx deauth to start recording | ||
592 | * @start_tx_deauth: number of Tx deauth to start recording | ||
593 | * @start_assoc_denied: number of denied association to start recording | ||
594 | * @start_assoc_timeout: number of association timeout to start recording | ||
595 | */ | ||
596 | struct iwl_fw_dbg_trigger_mlme { | ||
597 | u8 stop_auth_denied; | ||
598 | u8 stop_auth_timeout; | ||
599 | u8 stop_rx_deauth; | ||
600 | u8 stop_tx_deauth; | ||
601 | |||
602 | u8 stop_assoc_denied; | ||
603 | u8 stop_assoc_timeout; | ||
604 | __le16 reserved2; | ||
605 | |||
606 | u8 start_auth_denied; | ||
607 | u8 start_auth_timeout; | ||
608 | u8 start_rx_deauth; | ||
609 | u8 start_tx_deauth; | ||
610 | |||
611 | u8 start_assoc_denied; | ||
612 | u8 start_assoc_timeout; | ||
613 | __le16 reserved4; | ||
614 | } __packed; | ||
615 | |||
616 | /** | ||
582 | * struct iwl_fw_dbg_trigger_txq_timer - configures the Tx queue's timer | 617 | * struct iwl_fw_dbg_trigger_txq_timer - configures the Tx queue's timer |
583 | * @command_queue: timeout for the command queue in ms | 618 | * @command_queue: timeout for the command queue in ms |
584 | * @bss: timeout for the queues of a BSS (except for TDLS queues) in ms | 619 | * @bss: timeout for the queues of a BSS (except for TDLS queues) in ms |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 810b6d317b24..fc73cc1bda0d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -3956,6 +3956,69 @@ static void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw, | |||
3956 | mutex_unlock(&mvm->mutex); | 3956 | mutex_unlock(&mvm->mutex); |
3957 | } | 3957 | } |
3958 | 3958 | ||
3959 | static void iwl_mvm_mac_event_callback(struct ieee80211_hw *hw, | ||
3960 | struct ieee80211_vif *vif, | ||
3961 | const struct ieee80211_event *event) | ||
3962 | { | ||
3963 | #define CHECK_MLME_TRIGGER(_mvm, _trig, _buf, _cnt, _str...) \ | ||
3964 | do { \ | ||
3965 | if ((_cnt) && --(_cnt)) \ | ||
3966 | break; \ | ||
3967 | snprintf(_buf, sizeof(_buf), ##_str); \ | ||
3968 | iwl_mvm_fw_dbg_collect_trig(_mvm, _trig, _buf, \ | ||
3969 | sizeof(_buf)); \ | ||
3970 | } while (0) | ||
3971 | |||
3972 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); | ||
3973 | struct iwl_fw_dbg_trigger_tlv *trig; | ||
3974 | struct iwl_fw_dbg_trigger_mlme *trig_mlme; | ||
3975 | char buf[32]; | ||
3976 | |||
3977 | if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_MLME)) | ||
3978 | return; | ||
3979 | |||
3980 | if (event->u.mlme.status == MLME_SUCCESS) | ||
3981 | return; | ||
3982 | |||
3983 | trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_MLME); | ||
3984 | trig_mlme = (void *)trig->data; | ||
3985 | if (!iwl_fw_dbg_trigger_check_stop(mvm, vif, trig)) | ||
3986 | return; | ||
3987 | |||
3988 | memset(buf, 0, sizeof(buf)); | ||
3989 | |||
3990 | if (event->u.mlme.data == ASSOC_EVENT) { | ||
3991 | if (event->u.mlme.status == MLME_DENIED) | ||
3992 | CHECK_MLME_TRIGGER(mvm, trig, buf, | ||
3993 | trig_mlme->stop_assoc_denied, | ||
3994 | "DENIED ASSOC: reason %d", | ||
3995 | event->u.mlme.reason); | ||
3996 | else if (event->u.mlme.status == MLME_TIMEOUT) | ||
3997 | CHECK_MLME_TRIGGER(mvm, trig, buf, | ||
3998 | trig_mlme->stop_assoc_timeout, | ||
3999 | "ASSOC TIMEOUT"); | ||
4000 | } else if (event->u.mlme.data == AUTH_EVENT) { | ||
4001 | if (event->u.mlme.status == MLME_DENIED) | ||
4002 | CHECK_MLME_TRIGGER(mvm, trig, buf, | ||
4003 | trig_mlme->stop_auth_denied, | ||
4004 | "DENIED AUTH: reason %d", | ||
4005 | event->u.mlme.reason); | ||
4006 | else if (event->u.mlme.status == MLME_TIMEOUT) | ||
4007 | CHECK_MLME_TRIGGER(mvm, trig, buf, | ||
4008 | trig_mlme->stop_auth_timeout, | ||
4009 | "AUTH TIMEOUT"); | ||
4010 | } else if (event->u.mlme.data == DEAUTH_RX_EVENT) { | ||
4011 | CHECK_MLME_TRIGGER(mvm, trig, buf, | ||
4012 | trig_mlme->stop_rx_deauth, | ||
4013 | "DEAUTH RX %d", event->u.mlme.reason); | ||
4014 | } else if (event->u.mlme.data == DEAUTH_TX_EVENT) { | ||
4015 | CHECK_MLME_TRIGGER(mvm, trig, buf, | ||
4016 | trig_mlme->stop_tx_deauth, | ||
4017 | "DEAUTH TX %d", event->u.mlme.reason); | ||
4018 | } | ||
4019 | #undef CHECK_MLME_TRIGGER | ||
4020 | } | ||
4021 | |||
3959 | const struct ieee80211_ops iwl_mvm_hw_ops = { | 4022 | const struct ieee80211_ops iwl_mvm_hw_ops = { |
3960 | .tx = iwl_mvm_mac_tx, | 4023 | .tx = iwl_mvm_mac_tx, |
3961 | .ampdu_action = iwl_mvm_mac_ampdu_action, | 4024 | .ampdu_action = iwl_mvm_mac_ampdu_action, |
@@ -4009,6 +4072,8 @@ const struct ieee80211_ops iwl_mvm_hw_ops = { | |||
4009 | .tdls_cancel_channel_switch = iwl_mvm_tdls_cancel_channel_switch, | 4072 | .tdls_cancel_channel_switch = iwl_mvm_tdls_cancel_channel_switch, |
4010 | .tdls_recv_channel_switch = iwl_mvm_tdls_recv_channel_switch, | 4073 | .tdls_recv_channel_switch = iwl_mvm_tdls_recv_channel_switch, |
4011 | 4074 | ||
4075 | .event_callback = iwl_mvm_mac_event_callback, | ||
4076 | |||
4012 | CFG80211_TESTMODE_CMD(iwl_mvm_mac_testmode_cmd) | 4077 | CFG80211_TESTMODE_CMD(iwl_mvm_mac_testmode_cmd) |
4013 | 4078 | ||
4014 | #ifdef CONFIG_PM_SLEEP | 4079 | #ifdef CONFIG_PM_SLEEP |