aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-03-25 04:00:31 -0400
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-04-06 03:18:47 -0400
commite7f7634092d73d86846e8d8a85d417b5707ffb29 (patch)
tree0b5edaad948d99983ed67f72a95f71631339e206
parent749f1fe1bb49135e62cd64133f9e3875f2840d66 (diff)
iwlwifi: pcie: don't leave the new NICs awake for commands
A hardware bug had been discovered on 7260 / 3160 and 7265 and the workaround for this bug is to force the NIC to stay awake as long as we have host commands in flight. This workaround has been introduced for all NICs in a previous patch: b9439491055a ("iwlwifi: pcie: keep the NIC awake when commands are in flight") In newer NICs, this bug is solved, so we can let the NIC go to sleep even when we send commands. The hardware will wake up when we increment the scheduler write pointer. Make the workaround conditional to only use it on affected hardware. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h3
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c9
3 files changed, 10 insertions, 3 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index 003a546571d4..c42d80c710e7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -107,6 +107,7 @@ static const struct iwl_base_params iwl7000_base_params = {
107 .max_event_log_size = 512, 107 .max_event_log_size = 512,
108 .shadow_reg_enable = true, 108 .shadow_reg_enable = true,
109 .pcie_l1_allowed = true, 109 .pcie_l1_allowed = true,
110 .apmg_wake_up_wa = true,
110}; 111};
111 112
112static const struct iwl_ht_params iwl7000_ht_params = { 113static const struct iwl_ht_params iwl7000_ht_params = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index 3f17dc3f2c8a..8c167302a4cf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -146,6 +146,8 @@ static inline u8 num_of_ant(u8 mask)
146 * @wd_timeout: TX queues watchdog timeout 146 * @wd_timeout: TX queues watchdog timeout
147 * @max_event_log_size: size of event log buffer size for ucode event logging 147 * @max_event_log_size: size of event log buffer size for ucode event logging
148 * @shadow_reg_enable: HW shadow register support 148 * @shadow_reg_enable: HW shadow register support
149 * @apmg_wake_up_wa: should the MAC access REQ be asserted when a command
150 * is in flight. This is due to a HW bug in 7260, 3160 and 7265.
149 */ 151 */
150struct iwl_base_params { 152struct iwl_base_params {
151 int eeprom_size; 153 int eeprom_size;
@@ -160,6 +162,7 @@ struct iwl_base_params {
160 u32 max_event_log_size; 162 u32 max_event_log_size;
161 const bool shadow_reg_enable; 163 const bool shadow_reg_enable;
162 const bool pcie_l1_allowed; 164 const bool pcie_l1_allowed;
165 const bool apmg_wake_up_wa;
163}; 166};
164 167
165/* 168/*
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 3b0c72c10054..03686090d5f7 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -1028,7 +1028,8 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
1028 } 1028 }
1029 } 1029 }
1030 1030
1031 if (q->read_ptr == q->write_ptr) { 1031 if (trans->cfg->base_params->apmg_wake_up_wa &&
1032 q->read_ptr == q->write_ptr) {
1032 spin_lock_irqsave(&trans_pcie->reg_lock, flags); 1033 spin_lock_irqsave(&trans_pcie->reg_lock, flags);
1033 WARN_ON(!trans_pcie->cmd_in_flight); 1034 WARN_ON(!trans_pcie->cmd_in_flight);
1034 trans_pcie->cmd_in_flight = false; 1035 trans_pcie->cmd_in_flight = false;
@@ -1405,9 +1406,11 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1405 /* 1406 /*
1406 * wake up the NIC to make sure that the firmware will see the host 1407 * wake up the NIC to make sure that the firmware will see the host
1407 * command - we will let the NIC sleep once all the host commands 1408 * command - we will let the NIC sleep once all the host commands
1408 * returned. 1409 * returned. This needs to be done only on NICs that have
1410 * apmg_wake_up_wa set.
1409 */ 1411 */
1410 if (!trans_pcie->cmd_in_flight) { 1412 if (trans->cfg->base_params->apmg_wake_up_wa &&
1413 !trans_pcie->cmd_in_flight) {
1411 trans_pcie->cmd_in_flight = true; 1414 trans_pcie->cmd_in_flight = true;
1412 __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, 1415 __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
1413 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 1416 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);