Commit 554d1d02 authored by Stanislaw Gruszka's avatar Stanislaw Gruszka Committed by John W. Linville

iwlagn: enable only rfkill interrupt when device is down

Since commit 6cd0b1cb "iwlagn: fix
hw-rfkill while the interface is down", we enable interrupts when
device is not ready to receive them. However hardware, when it is in
some inconsistent state, can generate other than rfkill interrupts
and crash the system. I can reproduce crash with "kernel BUG at
drivers/net/wireless/iwlwifi/iwl-agn.c:1010!" message, when forcing
firmware restarts.

To fix only enable rfkill interrupt when down device and after probe.
I checked patch on laptop with 5100 device, rfkill change is still
passed to user space when device is down.
Signed-off-by: default avatarStanislaw Gruszka <sgruszka@redhat.com>
Cc: stable@kernel.org
Acked-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent b51aff05
...@@ -3530,9 +3530,10 @@ static void iwl_mac_stop(struct ieee80211_hw *hw) ...@@ -3530,9 +3530,10 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)
flush_workqueue(priv->workqueue); flush_workqueue(priv->workqueue);
/* enable interrupts again in order to receive rfkill changes */ /* User space software may expect getting rfkill changes
* even if interface is down */
iwl_write32(priv, CSR_INT, 0xFFFFFFFF); iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
iwl_enable_interrupts(priv); iwl_enable_rfkill_int(priv);
IWL_DEBUG_MAC80211(priv, "leave\n"); IWL_DEBUG_MAC80211(priv, "leave\n");
} }
...@@ -4515,14 +4516,14 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -4515,14 +4516,14 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
* 8. Enable interrupts and read RFKILL state * 8. Enable interrupts and read RFKILL state
*********************************************/ *********************************************/
/* enable interrupts if needed: hw bug w/a */ /* enable rfkill interrupt: hw bug w/a */
pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd); pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd);
} }
iwl_enable_interrupts(priv); iwl_enable_rfkill_int(priv);
/* If platform's RF_KILL switch is NOT set to KILL */ /* If platform's RF_KILL switch is NOT set to KILL */
if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
......
...@@ -163,6 +163,12 @@ static inline void iwl_disable_interrupts(struct iwl_priv *priv) ...@@ -163,6 +163,12 @@ static inline void iwl_disable_interrupts(struct iwl_priv *priv)
IWL_DEBUG_ISR(priv, "Disabled interrupts\n"); IWL_DEBUG_ISR(priv, "Disabled interrupts\n");
} }
static inline void iwl_enable_rfkill_int(struct iwl_priv *priv)
{
IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n");
iwl_write32(priv, CSR_INT_MASK, CSR_INT_BIT_RF_KILL);
}
static inline void iwl_enable_interrupts(struct iwl_priv *priv) static inline void iwl_enable_interrupts(struct iwl_priv *priv)
{ {
IWL_DEBUG_ISR(priv, "Enabling interrupts\n"); IWL_DEBUG_ISR(priv, "Enabling interrupts\n");
......
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