Commit 6960a059 authored by Emmanuel Grumbach's avatar Emmanuel Grumbach

iwlwifi: pcie: fix interrupt coalescing for 7260 / 3160

We changed the timeout for the interrupt coealescing for
calibration, but that wasn't effective since we changed
that value back before loading the firmware. Since
calibrations are notification from firmware and not Rx
packets, this doesn't change anyway - the firmware will
fire an interrupt straight away regardless of the interrupt
coalescing value.
Also, a HW issue has been discovered in 7000 devices series.
The work around is to disable the new interrupt coalescing
timeout feature - do this by setting bit 31 in
CSR_INT_COALESCING.
This has been fixed in 7265 which means that we can't rely
on the device family and must have a hint in the iwl_cfg
structure.

Cc: stable@vger.kernel.org [3.10+]
Fixes: 99cd4714 ("iwlwifi: add 7000 series device configuration")
Reviewed-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 60765a47
...@@ -130,6 +130,7 @@ const struct iwl_cfg iwl7260_2ac_cfg = { ...@@ -130,6 +130,7 @@ const struct iwl_cfg iwl7260_2ac_cfg = {
.ht_params = &iwl7000_ht_params, .ht_params = &iwl7000_ht_params,
.nvm_ver = IWL7260_NVM_VERSION, .nvm_ver = IWL7260_NVM_VERSION,
.nvm_calib_ver = IWL7260_TX_POWER_VERSION, .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
.host_interrupt_operation_mode = true,
}; };
const struct iwl_cfg iwl7260_2ac_cfg_high_temp = { const struct iwl_cfg iwl7260_2ac_cfg_high_temp = {
...@@ -140,6 +141,7 @@ const struct iwl_cfg iwl7260_2ac_cfg_high_temp = { ...@@ -140,6 +141,7 @@ const struct iwl_cfg iwl7260_2ac_cfg_high_temp = {
.nvm_ver = IWL7260_NVM_VERSION, .nvm_ver = IWL7260_NVM_VERSION,
.nvm_calib_ver = IWL7260_TX_POWER_VERSION, .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
.high_temp = true, .high_temp = true,
.host_interrupt_operation_mode = true,
}; };
const struct iwl_cfg iwl7260_2n_cfg = { const struct iwl_cfg iwl7260_2n_cfg = {
...@@ -149,6 +151,7 @@ const struct iwl_cfg iwl7260_2n_cfg = { ...@@ -149,6 +151,7 @@ const struct iwl_cfg iwl7260_2n_cfg = {
.ht_params = &iwl7000_ht_params, .ht_params = &iwl7000_ht_params,
.nvm_ver = IWL7260_NVM_VERSION, .nvm_ver = IWL7260_NVM_VERSION,
.nvm_calib_ver = IWL7260_TX_POWER_VERSION, .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
.host_interrupt_operation_mode = true,
}; };
const struct iwl_cfg iwl7260_n_cfg = { const struct iwl_cfg iwl7260_n_cfg = {
...@@ -158,6 +161,7 @@ const struct iwl_cfg iwl7260_n_cfg = { ...@@ -158,6 +161,7 @@ const struct iwl_cfg iwl7260_n_cfg = {
.ht_params = &iwl7000_ht_params, .ht_params = &iwl7000_ht_params,
.nvm_ver = IWL7260_NVM_VERSION, .nvm_ver = IWL7260_NVM_VERSION,
.nvm_calib_ver = IWL7260_TX_POWER_VERSION, .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
.host_interrupt_operation_mode = true,
}; };
const struct iwl_cfg iwl3160_2ac_cfg = { const struct iwl_cfg iwl3160_2ac_cfg = {
...@@ -167,6 +171,7 @@ const struct iwl_cfg iwl3160_2ac_cfg = { ...@@ -167,6 +171,7 @@ const struct iwl_cfg iwl3160_2ac_cfg = {
.ht_params = &iwl7000_ht_params, .ht_params = &iwl7000_ht_params,
.nvm_ver = IWL3160_NVM_VERSION, .nvm_ver = IWL3160_NVM_VERSION,
.nvm_calib_ver = IWL3160_TX_POWER_VERSION, .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
.host_interrupt_operation_mode = true,
}; };
const struct iwl_cfg iwl3160_2n_cfg = { const struct iwl_cfg iwl3160_2n_cfg = {
...@@ -176,6 +181,7 @@ const struct iwl_cfg iwl3160_2n_cfg = { ...@@ -176,6 +181,7 @@ const struct iwl_cfg iwl3160_2n_cfg = {
.ht_params = &iwl7000_ht_params, .ht_params = &iwl7000_ht_params,
.nvm_ver = IWL3160_NVM_VERSION, .nvm_ver = IWL3160_NVM_VERSION,
.nvm_calib_ver = IWL3160_TX_POWER_VERSION, .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
.host_interrupt_operation_mode = true,
}; };
const struct iwl_cfg iwl3160_n_cfg = { const struct iwl_cfg iwl3160_n_cfg = {
...@@ -185,6 +191,7 @@ const struct iwl_cfg iwl3160_n_cfg = { ...@@ -185,6 +191,7 @@ const struct iwl_cfg iwl3160_n_cfg = {
.ht_params = &iwl7000_ht_params, .ht_params = &iwl7000_ht_params,
.nvm_ver = IWL3160_NVM_VERSION, .nvm_ver = IWL3160_NVM_VERSION,
.nvm_calib_ver = IWL3160_TX_POWER_VERSION, .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
.host_interrupt_operation_mode = true,
}; };
const struct iwl_cfg iwl7265_2ac_cfg = { const struct iwl_cfg iwl7265_2ac_cfg = {
......
...@@ -207,6 +207,8 @@ struct iwl_eeprom_params { ...@@ -207,6 +207,8 @@ struct iwl_eeprom_params {
* @rx_with_siso_diversity: 1x1 device with rx antenna diversity * @rx_with_siso_diversity: 1x1 device with rx antenna diversity
* @internal_wimax_coex: internal wifi/wimax combo device * @internal_wimax_coex: internal wifi/wimax combo device
* @high_temp: Is this NIC is designated to be in high temperature. * @high_temp: Is this NIC is designated to be in high temperature.
* @host_interrupt_operation_mode: device needs host interrupt operation
* mode set
* *
* We enable the driver to be backward compatible wrt. hardware features. * We enable the driver to be backward compatible wrt. hardware features.
* API differences in uCode shouldn't be handled here but through TLVs * API differences in uCode shouldn't be handled here but through TLVs
...@@ -235,6 +237,7 @@ struct iwl_cfg { ...@@ -235,6 +237,7 @@ struct iwl_cfg {
enum iwl_led_mode led_mode; enum iwl_led_mode led_mode;
const bool rx_with_siso_diversity; const bool rx_with_siso_diversity;
const bool internal_wimax_coex; const bool internal_wimax_coex;
const bool host_interrupt_operation_mode;
bool high_temp; bool high_temp;
}; };
......
...@@ -495,14 +495,11 @@ enum secure_load_status_reg { ...@@ -495,14 +495,11 @@ enum secure_load_status_reg {
* the CSR_INT_COALESCING is an 8 bit register in 32-usec unit * the CSR_INT_COALESCING is an 8 bit register in 32-usec unit
* *
* default interrupt coalescing timer is 64 x 32 = 2048 usecs * default interrupt coalescing timer is 64 x 32 = 2048 usecs
* default interrupt coalescing calibration timer is 16 x 32 = 512 usecs
*/ */
#define IWL_HOST_INT_TIMEOUT_MAX (0xFF) #define IWL_HOST_INT_TIMEOUT_MAX (0xFF)
#define IWL_HOST_INT_TIMEOUT_DEF (0x40) #define IWL_HOST_INT_TIMEOUT_DEF (0x40)
#define IWL_HOST_INT_TIMEOUT_MIN (0x0) #define IWL_HOST_INT_TIMEOUT_MIN (0x0)
#define IWL_HOST_INT_CALIB_TIMEOUT_MAX (0xFF) #define IWL_HOST_INT_OPER_MODE BIT(31)
#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10)
#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0)
/***************************************************************************** /*****************************************************************************
* 7000/3000 series SHR DTS addresses * * 7000/3000 series SHR DTS addresses *
......
...@@ -489,6 +489,10 @@ static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq) ...@@ -489,6 +489,10 @@ static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq)
/* Set interrupt coalescing timer to default (2048 usecs) */ /* Set interrupt coalescing timer to default (2048 usecs) */
iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
/* W/A for interrupt coalescing bug in 7260 and 3160 */
if (trans->cfg->host_interrupt_operation_mode)
iwl_set_bit(trans, CSR_INT_COALESCING, IWL_HOST_INT_OPER_MODE);
} }
static void iwl_pcie_rx_init_rxb_lists(struct iwl_rxq *rxq) static void iwl_pcie_rx_init_rxb_lists(struct iwl_rxq *rxq)
......
...@@ -279,9 +279,6 @@ static int iwl_pcie_nic_init(struct iwl_trans *trans) ...@@ -279,9 +279,6 @@ static int iwl_pcie_nic_init(struct iwl_trans *trans)
spin_lock_irqsave(&trans_pcie->irq_lock, flags); spin_lock_irqsave(&trans_pcie->irq_lock, flags);
iwl_pcie_apm_init(trans); iwl_pcie_apm_init(trans);
/* Set interrupt coalescing calibration timer to default (512 usecs) */
iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF);
spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
iwl_pcie_set_pwr(trans, false); iwl_pcie_set_pwr(trans, false);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment