aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/ath9k/beacon.c
diff options
context:
space:
mode:
authorRajkumar Manoharan <rmanohar@qca.qualcomm.com>2011-06-24 17:38:13 +0530
committerJohn W. Linville <linville@tuxdriver.com>2011-06-27 15:09:42 -0400
commitf6b4e4d476b890e1ddebbed8ec4924f9c2750a31 (patch)
treec7b8beed1a1967722f8ce73b072057f7abe82c11 /drivers/net/wireless/ath/ath9k/beacon.c
parent428bc8c3960d2b18cb9f0d90cfe197ec9a822a54 (diff)
ath9k: Fix locking issue during tx completion
The received tx status of aggregated frame without BlockAck may cause deaf state in AR5416 cards. So the driver does a reset to recover. When this happens, we release the pcu_lock before doing a reset as ath_rest acquires pcu_lock. This is ugly and also not atomic. Fixing this addresses the TX DMA failure also. ath_tx_complete_aggr can be called from different paths which takes different variants of spin_lock. This patch also addresses the following warning. WARNING: at kernel/timer.c:1011 del_timer_sync+0x4e/0x50() Call Trace: <IRQ> [<ffffffff8104be3a>] warn_slowpath_common+0x7a/0xb0 [<ffffffff8104be85>] warn_slowpath_null+0x15/0x20 [<ffffffff8105915e>] del_timer_sync+0x4e/0x50 [<ffffffffa03726be>] ath_reset+0x3e/0x210 [ath9k] [<ffffffff8135cdaf>] ? _raw_spin_unlock_bh+0x1f/0x30 [<ffffffffa037760a>] ath_tx_complete_aggr.isra.26+0x54a/0xa40 [ath9k] Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/beacon.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 0b6e3b65bb0..e19a230dfff 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -385,7 +385,9 @@ void ath_beacon_tasklet(unsigned long data)
ath_dbg(common, ATH_DBG_BSTUCK,
"beacon is officially stuck\n");
sc->sc_flags |= SC_OP_TSF_RESET;
+ spin_lock(&sc->sc_pcu_lock);
ath_reset(sc, true);
+ spin_unlock(&sc->sc_pcu_lock);
}
return;