aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-core.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-04-12 19:16:02 -0400
committerDavid S. Miller <davem@davemloft.net>2011-04-12 19:16:02 -0400
commita7e70158884629898d79709622a66b8ef99e4018 (patch)
treebd0cd03816f85f5bcef84000e01b0f9701f063ed /drivers/net/wireless/iwlwifi/iwl-core.c
parent24743537d3f784a8b3014e934fad0a9c45e4e789 (diff)
parent252f4bf400df1712408fe83ba199a66a1b57ab1d (diff)
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-core.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c114
1 files changed, 54 insertions, 60 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index bafbe57c9602..45ec5cfe3fcf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2,7 +2,7 @@
2 * 2 *
3 * GPL LICENSE SUMMARY 3 * GPL LICENSE SUMMARY
4 * 4 *
5 * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. 5 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as 8 * it under the terms of version 2 of the GNU General Public License as
@@ -890,10 +890,8 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv,
890 IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id)); 890 IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
891} 891}
892#endif 892#endif
893/** 893
894 * iwl_irq_handle_error - called for HW or SW error interrupt from card 894void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
895 */
896void iwl_irq_handle_error(struct iwl_priv *priv)
897{ 895{
898 unsigned int reload_msec; 896 unsigned int reload_msec;
899 unsigned long reload_jiffies; 897 unsigned long reload_jiffies;
@@ -904,18 +902,62 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
904 /* Cancel currently queued command. */ 902 /* Cancel currently queued command. */
905 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 903 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
906 904
905 /* Keep the restart process from trying to send host
906 * commands by clearing the ready bit */
907 clear_bit(STATUS_READY, &priv->status);
908
909 wake_up_interruptible(&priv->wait_command_queue);
910
911 if (!ondemand) {
912 /*
913 * If firmware keep reloading, then it indicate something
914 * serious wrong and firmware having problem to recover
915 * from it. Instead of keep trying which will fill the syslog
916 * and hang the system, let's just stop it
917 */
918 reload_jiffies = jiffies;
919 reload_msec = jiffies_to_msecs((long) reload_jiffies -
920 (long) priv->reload_jiffies);
921 priv->reload_jiffies = reload_jiffies;
922 if (reload_msec <= IWL_MIN_RELOAD_DURATION) {
923 priv->reload_count++;
924 if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) {
925 IWL_ERR(priv, "BUG_ON, Stop restarting\n");
926 return;
927 }
928 } else
929 priv->reload_count = 0;
930 }
931
932 if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
933 if (priv->cfg->mod_params->restart_fw) {
934 IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
935 "Restarting adapter due to uCode error.\n");
936 queue_work(priv->workqueue, &priv->restart);
937 } else
938 IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
939 "Detected FW error, but not restarting\n");
940 }
941}
942
943/**
944 * iwl_irq_handle_error - called for HW or SW error interrupt from card
945 */
946void iwl_irq_handle_error(struct iwl_priv *priv)
947{
907 /* W/A for WiFi/WiMAX coex and WiMAX own the RF */ 948 /* W/A for WiFi/WiMAX coex and WiMAX own the RF */
908 if (priv->cfg->internal_wimax_coex && 949 if (priv->cfg->internal_wimax_coex &&
909 (!(iwl_read_prph(priv, APMG_CLK_CTRL_REG) & 950 (!(iwl_read_prph(priv, APMG_CLK_CTRL_REG) &
910 APMS_CLK_VAL_MRB_FUNC_MODE) || 951 APMS_CLK_VAL_MRB_FUNC_MODE) ||
911 (iwl_read_prph(priv, APMG_PS_CTRL_REG) & 952 (iwl_read_prph(priv, APMG_PS_CTRL_REG) &
912 APMG_PS_CTRL_VAL_RESET_REQ))) { 953 APMG_PS_CTRL_VAL_RESET_REQ))) {
913 wake_up_interruptible(&priv->wait_command_queue);
914 /* 954 /*
915 *Keep the restart process from trying to send host 955 * Keep the restart process from trying to send host
916 * commands by clearing the INIT status bit 956 * commands by clearing the ready bit.
917 */ 957 */
918 clear_bit(STATUS_READY, &priv->status); 958 clear_bit(STATUS_READY, &priv->status);
959 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
960 wake_up_interruptible(&priv->wait_command_queue);
919 IWL_ERR(priv, "RF is used by WiMAX\n"); 961 IWL_ERR(priv, "RF is used by WiMAX\n");
920 return; 962 return;
921 } 963 }
@@ -935,38 +977,7 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
935 &priv->contexts[IWL_RXON_CTX_BSS]); 977 &priv->contexts[IWL_RXON_CTX_BSS]);
936#endif 978#endif
937 979
938 wake_up_interruptible(&priv->wait_command_queue); 980 iwlagn_fw_error(priv, false);
939
940 /* Keep the restart process from trying to send host
941 * commands by clearing the INIT status bit */
942 clear_bit(STATUS_READY, &priv->status);
943
944 /*
945 * If firmware keep reloading, then it indicate something
946 * serious wrong and firmware having problem to recover
947 * from it. Instead of keep trying which will fill the syslog
948 * and hang the system, let's just stop it
949 */
950 reload_jiffies = jiffies;
951 reload_msec = jiffies_to_msecs((long) reload_jiffies -
952 (long) priv->reload_jiffies);
953 priv->reload_jiffies = reload_jiffies;
954 if (reload_msec <= IWL_MIN_RELOAD_DURATION) {
955 priv->reload_count++;
956 if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) {
957 IWL_ERR(priv, "BUG_ON, Stop restarting\n");
958 return;
959 }
960 } else
961 priv->reload_count = 0;
962
963 if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
964 IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
965 "Restarting adapter due to uCode error.\n");
966
967 if (priv->cfg->mod_params->restart_fw)
968 queue_work(priv->workqueue, &priv->restart);
969 }
970} 981}
971 982
972static int iwl_apm_stop_master(struct iwl_priv *priv) 983static int iwl_apm_stop_master(struct iwl_priv *priv)
@@ -1094,21 +1105,13 @@ int iwl_apm_init(struct iwl_priv *priv)
1094 } 1105 }
1095 1106
1096 /* 1107 /*
1097 * Enable DMA and BSM (if used) clocks, wait for them to stabilize. 1108 * Enable DMA clock and wait for it to stabilize.
1098 * BSM (Boostrap State Machine) is only in 3945 and 4965;
1099 * later devices (i.e. 5000 and later) have non-volatile SRAM,
1100 * and don't need BSM to restore data after power-saving sleep.
1101 * 1109 *
1102 * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits 1110 * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits
1103 * do not disable clocks. This preserves any hardware bits already 1111 * do not disable clocks. This preserves any hardware bits already
1104 * set by default in "CLK_CTRL_REG" after reset. 1112 * set by default in "CLK_CTRL_REG" after reset.
1105 */ 1113 */
1106 if (priv->cfg->base_params->use_bsm) 1114 iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
1107 iwl_write_prph(priv, APMG_CLK_EN_REG,
1108 APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT);
1109 else
1110 iwl_write_prph(priv, APMG_CLK_EN_REG,
1111 APMG_CLK_VAL_DMA_CLK_RQT);
1112 udelay(20); 1115 udelay(20);
1113 1116
1114 /* Disable L1-Active */ 1117 /* Disable L1-Active */
@@ -1430,7 +1433,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
1430 1433
1431 iwl_teardown_interface(priv, vif, false); 1434 iwl_teardown_interface(priv, vif, false);
1432 1435
1433 memset(priv->bssid, 0, ETH_ALEN);
1434 mutex_unlock(&priv->mutex); 1436 mutex_unlock(&priv->mutex);
1435 1437
1436 IWL_DEBUG_MAC80211(priv, "leave\n"); 1438 IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -1756,15 +1758,7 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
1756 break; 1758 break;
1757 } 1759 }
1758 IWL_ERR(priv, "On demand firmware reload\n"); 1760 IWL_ERR(priv, "On demand firmware reload\n");
1759 /* Set the FW error flag -- cleared on iwl_down */ 1761 iwlagn_fw_error(priv, true);
1760 set_bit(STATUS_FW_ERROR, &priv->status);
1761 wake_up_interruptible(&priv->wait_command_queue);
1762 /*
1763 * Keep the restart process from trying to send host
1764 * commands by clearing the INIT status bit
1765 */
1766 clear_bit(STATUS_READY, &priv->status);
1767 queue_work(priv->workqueue, &priv->restart);
1768 break; 1762 break;
1769 } 1763 }
1770 return 0; 1764 return 0;