From 317d09f76976c5a0b1e758fe45474a47cbea1aef Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Mon, 10 Oct 2011 07:26:49 -0700 Subject: [PATCH] iwlagn: add "echo" test when command queue stuck When detect command queue stuck, instead of reload the firmware do the "echo" test to make sure it is really stuck before reload Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 23 ++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-core.h | 1 + 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 0725603dbf1d..59d1968e6ae9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1732,10 +1732,31 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, return err; } +int iwl_cmd_echo_test(struct iwl_priv *priv) +{ + struct iwl_host_cmd cmd = { + .id = REPLY_ECHO, + .flags = CMD_SYNC, + }; + + return iwl_trans_send_cmd(trans(priv), &cmd); +} + static inline int iwl_check_stuck_queue(struct iwl_priv *priv, int txq) { if (iwl_trans_check_stuck_queue(trans(priv), txq)) { - int ret = iwl_force_reset(priv, IWL_FW_RESET, false); + int ret; + if (txq == priv->shrd->cmd_queue) { + /* + * validate command queue still working + * by sending "ECHO" command + */ + if (!iwl_cmd_echo_test(priv)) + return 0; + else + IWL_DEBUG_HC(priv, "echo testing fail\n"); + } + ret = iwl_force_reset(priv, IWL_FW_RESET, false); return (ret == -EAGAIN) ? 0 : 1; } return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index db50b650756c..080c35543881 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -266,6 +266,7 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum nl80211_iftype newtype, bool newp2p); +int iwl_cmd_echo_test(struct iwl_priv *priv); #ifdef CONFIG_IWLWIFI_DEBUGFS int iwl_alloc_traffic_mem(struct iwl_priv *priv); void iwl_free_traffic_mem(struct iwl_priv *priv); -- 2.20.1