aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/pcie/rx.c
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2012-09-09 09:58:07 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-09-10 13:13:20 -0400
commit7439046d9747966bb805ca8bfd1086a876a4b8fd (patch)
tree6c9bbf5171d27632e582cb8bdfa7f60acafc6fb1 /drivers/net/wireless/iwlwifi/pcie/rx.c
parent358a46d47eefadd5be67495682426bd743ce455c (diff)
iwlwifi: don't access the HW when it is not available
When we kill the radio with the RF kill button we could access the HW after having stopped the APM which would result in the warning below. The flow goes like this: * RF kill iwlwifi notifies the stack which stops the driver fw sends CARD_STATE_NOTIFICATION * iwl_trans_pcie_stop_device stops the APM * the tasklet runs and calls to iwl_rx_handle * iwl_rx_handle calls iwl_rx_queue_restock * iwl_rx_queue_restock tries to access the HW... [255908.543823] ------------[ cut here ]------------ [255908.543843] WARNING: at drivers/net/wireless/iwlwifi/iwl-io.c:150 iwl_grab_nic_access+0x79/0xb0 [iwlwifi]() [255908.543849] Hardware name: Latitude E6410 [255908.543852] Timeout waiting for hardware access (CSR_GP_CNTRL 0x000003d8) [255908.543856] Modules linked in: iwlmvm iwlwifi mac80211 [...] [255908.543935] Pid: 0, comm: swapper Tainted: G W 3.1.0 #1 [255908.543939] Call Trace: [255908.543950] [<c1046e42>] warn_slowpath_common+0x72/0xa0 [255908.543980] [<c1046f13>] warn_slowpath_fmt+0x33/0x40 [255908.543992] [<fa4bb3b9>] iwl_grab_nic_access+0x79/0xb0 [iwlwifi] [255908.544004] [<fa4bb9eb>] iwl_write_direct32+0x2b/0xa0 [iwlwifi] [255908.544018] [<fa4c0ff9>] iwl_rx_queue_update_write_ptr+0x89/0x1d0 [iwlwifi] [255908.544054] [<fa4c1250>] iwlagn_rx_queue_restock+0x110/0x140 [iwlwifi] [255908.544067] [<fa4c234d>] iwl_irq_tasklet+0x82d/0xf40 [iwlwifi] [255908.544096] [<c104e11e>] tasklet_action+0xbe/0x100 [255908.544102] [<c104d91e>] __do_softirq+0xae/0x1f0 [255908.544227] ---[ end trace d150f49345d85009 ]--- Prevent this. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Reviewed-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/pcie/rx.c')
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index 7fc38217d76d..6d71f51ef548 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -203,6 +203,17 @@ static void iwl_rx_queue_restock(struct iwl_trans *trans)
203 struct iwl_rx_mem_buffer *rxb; 203 struct iwl_rx_mem_buffer *rxb;
204 unsigned long flags; 204 unsigned long flags;
205 205
206 /*
207 * If the device isn't enabled - not need to try to add buffers...
208 * This can happen when we stop the device and still have an interrupt
209 * pending. We stop the APM before we sync the interrupts / tasklets
210 * because we have to (see comment there). On the other hand, since
211 * the APM is stopped, we cannot access the HW (in particular not prph).
212 * So don't try to restock if the APM has been already stopped.
213 */
214 if (!test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status))
215 return;
216
206 spin_lock_irqsave(&rxq->lock, flags); 217 spin_lock_irqsave(&rxq->lock, flags);
207 while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) { 218 while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
208 /* The overwritten rxb must be a used one */ 219 /* The overwritten rxb must be a used one */