diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c index 003a546571d4772ba568d388acec485c1443f67f..c42d80c710e77c32f3b9804d23a5c6495765608e 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 = { .max_event_log_size = 512, .shadow_reg_enable = true, .pcie_l1_allowed = true, + .apmg_wake_up_wa = true, }; 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 3f17dc3f2c8a9fdde83bddb254efb8cc8d33502f..8c167302a4cfb7760d3eddbc3637fb7c19aa5f4d 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) * @wd_timeout: TX queues watchdog timeout * @max_event_log_size: size of event log buffer size for ucode event logging * @shadow_reg_enable: HW shadow register support + * @apmg_wake_up_wa: should the MAC access REQ be asserted when a command + * is in flight. This is due to a HW bug in 7260, 3160 and 7265. */ struct iwl_base_params { int eeprom_size; @@ -160,6 +162,7 @@ struct iwl_base_params { u32 max_event_log_size; const bool shadow_reg_enable; const bool pcie_l1_allowed; + const bool apmg_wake_up_wa; }; /* diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 3b0c72c1005446d2d93f7eb15ed6d3207e1c3ea1..03686090d5f7140e7525e7f1d192104f507e4477 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) } } - if (q->read_ptr == q->write_ptr) { + if (trans->cfg->base_params->apmg_wake_up_wa && + q->read_ptr == q->write_ptr) { spin_lock_irqsave(&trans_pcie->reg_lock, flags); WARN_ON(!trans_pcie->cmd_in_flight); trans_pcie->cmd_in_flight = false; @@ -1405,9 +1406,11 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, /* * wake up the NIC to make sure that the firmware will see the host * command - we will let the NIC sleep once all the host commands - * returned. + * returned. This needs to be done only on NICs that have + * apmg_wake_up_wa set. */ - if (!trans_pcie->cmd_in_flight) { + if (trans->cfg->base_params->apmg_wake_up_wa && + !trans_pcie->cmd_in_flight) { trans_pcie->cmd_in_flight = true; __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);