]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.4.83/iwlwifi-don-t-handle-masked-interrupt.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.4.83 / iwlwifi-don-t-handle-masked-interrupt.patch
CommitLineData
6f345252
GKH
1From wujianguo@huawei.com Fri Mar 7 16:58:50 2014
2From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
3Date: Thu, 27 Feb 2014 09:52:57 +0800
4Subject: iwlwifi: don't handle masked interrupt
5To: <gregkh@linuxfoundation.org>
6Cc: <stable@vger.kernel.org>, <lizefan@huawei.com>, Emmanuel Grumbach <emmanuel.grumbach@intel.com>, Jianguo Wu <wujianguo@huawei.com>
7Message-ID: <1393465983-10548-4-git-send-email-wujianguo@huawei.com>
8
9
10From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
11
12commit 25a172655f837bdb032e451f95441bb4acec51bb upstream.
13
14This can lead to a panic if the driver isn't ready to
15handle them. Since our interrupt line is shared, we can get
16an interrupt at any time (and CONFIG_DEBUG_SHIRQ checks
17that even when the interrupt is being freed).
18
19If the op_mode has gone away, we musn't call it. To avoid
20this the transport disables the interrupts when the hw is
21stopped and the op_mode is leaving.
22If there is an event that would cause an interrupt the INTA
23register is updated regardless of the enablement of the
24interrupts: even if the interrupts are disabled, the INTA
25will be changed, but the device won't issue an interrupt.
26But the ISR can be called at any time, so we ought ignore
27the value in the INTA otherwise we can call the op_mode
28after it was freed.
29
30I found this bug when the op_mode_start failed, and called
31iwl_trans_stop_hw(trans, true). Then I played with the
32RFKILL button, and removed the module.
33While removing the module, the IRQ is freed, and the ISR is
34called (CONFIG_DEBUG_SHIRQ enabled). Panic.
35
36Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
37Reviewed-by: Gregory Greenman <gregory.greenman@intel.com>
38Signed-off-by: Johannes Berg <johannes.berg@intel.com>
39[bwh: Backported to 3.2:
40 - Adjust context
41 - Pass bus(trans), not trans, to iwl_{read,write}32()]
42Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
43[wujg: Backported to 3.4:
44 - adjust context
45 - Pass trans to iwl_{read,write}32()}]
46Signed-off-by: Jianguo Wu <wujianguo@huawei.com>
47Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
48---
49 drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 12 ++++++++++--
50 1 file changed, 10 insertions(+), 2 deletions(-)
51
52--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
53+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
54@@ -1264,12 +1264,20 @@ static irqreturn_t iwl_isr(int irq, void
55 * back-to-back ISRs and sporadic interrupts from our NIC.
56 * If we have something to service, the tasklet will re-enable ints.
57 * If we *don't* have something, we'll re-enable before leaving here. */
58- inta_mask = iwl_read32(trans, CSR_INT_MASK); /* just for debug */
59+ inta_mask = iwl_read32(trans, CSR_INT_MASK);
60 iwl_write32(trans, CSR_INT_MASK, 0x00000000);
61
62 /* Discover which interrupts are active/pending */
63 inta = iwl_read32(trans, CSR_INT);
64
65+ if (inta & (~inta_mask)) {
66+ IWL_DEBUG_ISR(trans,
67+ "We got a masked interrupt (0x%08x)...Ack and ignore\n",
68+ inta & (~inta_mask));
69+ iwl_write32(trans, CSR_INT, inta & (~inta_mask));
70+ inta &= inta_mask;
71+ }
72+
73 /* Ignore interrupt if there's nothing in NIC to service.
74 * This may be due to IRQ shared with another device,
75 * or due to sporadic interrupts thrown from our NIC. */
76@@ -1353,7 +1361,7 @@ irqreturn_t iwl_isr_ict(int irq, void *d
77 * If we have something to service, the tasklet will re-enable ints.
78 * If we *don't* have something, we'll re-enable before leaving here.
79 */
80- inta_mask = iwl_read32(trans, CSR_INT_MASK); /* just for debug */
81+ inta_mask = iwl_read32(trans, CSR_INT_MASK);
82 iwl_write32(trans, CSR_INT_MASK, 0x00000000);
83
84