aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorIlan Peer <ilan.peer@intel.com>2015-05-13 07:34:07 -0400
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2015-05-28 06:27:51 -0400
commitfc8a350d0b8df744fd6d3c55907b3886979d2638 (patch)
treec862522f942b54f96f649fb764a1fce6c95d0db7 /drivers
parent292208914d8ca5a41cf68c2f1d2810a2ea2044e9 (diff)
iwlwifi: pcie: fix tracking of cmd_in_flight
The cmd_in_flight tracking was introduced to workaround faulty power management hardware, by having the driver keep the NIC awake as long as there are commands in flight. However, some of the code handling this workaround was unconditionally executed, which resulted with an inconsistent state where the driver assumed that the NIC was awake although it wasn't. Fix this by renaming 'cmd_in_flight' to 'cmd_hold_nic_awake' and handling the NIC requested awake state only for hardwares for which the workaround is needed. Signed-off-by: Ilan Peer <ilan.peer@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h6
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c4
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c23
3 files changed, 14 insertions, 19 deletions
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index 01996c9d98a7..376b84e54ad7 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -1,7 +1,7 @@
1/****************************************************************************** 1/******************************************************************************
2 * 2 *
3 * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. 3 * Copyright(c) 2003 - 2015 Intel Corporation. All rights reserved.
4 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 4 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
5 * 5 *
6 * Portions of this file are derived from the ipw3945 project, as well 6 * Portions of this file are derived from the ipw3945 project, as well
7 * as portions of the ieee80211 subsystem header files. 7 * as portions of the ieee80211 subsystem header files.
@@ -320,7 +320,7 @@ struct iwl_trans_pcie {
320 320
321 /*protect hw register */ 321 /*protect hw register */
322 spinlock_t reg_lock; 322 spinlock_t reg_lock;
323 bool cmd_in_flight; 323 bool cmd_hold_nic_awake;
324 bool ref_cmd_in_flight; 324 bool ref_cmd_in_flight;
325 325
326 /* protect ref counter */ 326 /* protect ref counter */
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index d6f6515fe663..dc179094e6a0 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -1372,7 +1372,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent,
1372 1372
1373 spin_lock_irqsave(&trans_pcie->reg_lock, *flags); 1373 spin_lock_irqsave(&trans_pcie->reg_lock, *flags);
1374 1374
1375 if (trans_pcie->cmd_in_flight) 1375 if (trans_pcie->cmd_hold_nic_awake)
1376 goto out; 1376 goto out;
1377 1377
1378 /* this bit wakes up the NIC */ 1378 /* this bit wakes up the NIC */
@@ -1438,7 +1438,7 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans,
1438 */ 1438 */
1439 __acquire(&trans_pcie->reg_lock); 1439 __acquire(&trans_pcie->reg_lock);
1440 1440
1441 if (trans_pcie->cmd_in_flight) 1441 if (trans_pcie->cmd_hold_nic_awake)
1442 goto out; 1442 goto out;
1443 1443
1444 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, 1444 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 06952aadfd7b..5ef8044c2ea3 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -1039,18 +1039,14 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans,
1039 iwl_trans_pcie_ref(trans); 1039 iwl_trans_pcie_ref(trans);
1040 } 1040 }
1041 1041
1042 if (trans_pcie->cmd_in_flight)
1043 return 0;
1044
1045 trans_pcie->cmd_in_flight = true;
1046
1047 /* 1042 /*
1048 * wake up the NIC to make sure that the firmware will see the host 1043 * wake up the NIC to make sure that the firmware will see the host
1049 * command - we will let the NIC sleep once all the host commands 1044 * command - we will let the NIC sleep once all the host commands
1050 * returned. This needs to be done only on NICs that have 1045 * returned. This needs to be done only on NICs that have
1051 * apmg_wake_up_wa set. 1046 * apmg_wake_up_wa set.
1052 */ 1047 */
1053 if (trans->cfg->base_params->apmg_wake_up_wa) { 1048 if (trans->cfg->base_params->apmg_wake_up_wa &&
1049 !trans_pcie->cmd_hold_nic_awake) {
1054 __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, 1050 __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
1055 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 1051 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1056 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) 1052 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
@@ -1064,10 +1060,10 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans,
1064 if (ret < 0) { 1060 if (ret < 0) {
1065 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, 1061 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
1066 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 1062 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1067 trans_pcie->cmd_in_flight = false;
1068 IWL_ERR(trans, "Failed to wake NIC for hcmd\n"); 1063 IWL_ERR(trans, "Failed to wake NIC for hcmd\n");
1069 return -EIO; 1064 return -EIO;
1070 } 1065 }
1066 trans_pcie->cmd_hold_nic_awake = true;
1071 } 1067 }
1072 1068
1073 return 0; 1069 return 0;
@@ -1085,15 +1081,14 @@ static int iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans)
1085 iwl_trans_pcie_unref(trans); 1081 iwl_trans_pcie_unref(trans);
1086 } 1082 }
1087 1083
1088 if (WARN_ON(!trans_pcie->cmd_in_flight)) 1084 if (trans->cfg->base_params->apmg_wake_up_wa) {
1089 return 0; 1085 if (WARN_ON(!trans_pcie->cmd_hold_nic_awake))
1090 1086 return 0;
1091 trans_pcie->cmd_in_flight = false;
1092 1087
1093 if (trans->cfg->base_params->apmg_wake_up_wa) 1088 trans_pcie->cmd_hold_nic_awake = false;
1094 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, 1089 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
1095 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 1090 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1096 1091 }
1097 return 0; 1092 return 0;
1098} 1093}
1099 1094