diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2014-03-25 04:00:31 -0400 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2014-04-06 03:18:47 -0400 |
commit | e7f7634092d73d86846e8d8a85d417b5707ffb29 (patch) | |
tree | 0b5edaad948d99983ed67f72a95f71631339e206 | |
parent | 749f1fe1bb49135e62cd64133f9e3875f2840d66 (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.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-config.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/tx.c | 9 |
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 | ||
112 | static const struct iwl_ht_params iwl7000_ht_params = { | 113 | static 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 | */ |
150 | struct iwl_base_params { | 152 | struct 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); |