aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k
diff options
context:
space:
mode:
authorSujith Manoharan <c_manoha@qca.qualcomm.com>2013-09-11 12:00:27 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-09-26 15:13:46 -0400
commit1e516ca7c9ceeeec4ed87f549a14bc3b73427f83 (patch)
treeb5d5744a4e834e6d580c4254e84f290eef93827e /drivers/net/wireless/ath/ath9k
parent9ef48932344a8ea9d6d1628d92afc2c5d6958336 (diff)
ath9k: Handle abnormal NAV in AP mode
Beacon transmission would get stuck if the NAV is an invalid value for some reason. Check and correct the NAV value in the HW when this happens. Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h1
3 files changed, 16 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index b5c16b3a37b9..17be35392bb4 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -334,6 +334,8 @@ void ath9k_beacon_tasklet(unsigned long data)
334 if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) { 334 if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
335 sc->beacon.bmisscnt++; 335 sc->beacon.bmisscnt++;
336 336
337 ath9k_hw_check_nav(ah);
338
337 if (!ath9k_hw_check_alive(ah)) 339 if (!ath9k_hw_check_alive(ah))
338 ieee80211_queue_work(sc->hw, &sc->hw_check_work); 340 ieee80211_queue_work(sc->hw, &sc->hw_check_work);
339 341
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 525ac984eafd..d3206ab40297 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1656,6 +1656,19 @@ hang_check_iter:
1656 return true; 1656 return true;
1657} 1657}
1658 1658
1659void ath9k_hw_check_nav(struct ath_hw *ah)
1660{
1661 struct ath_common *common = ath9k_hw_common(ah);
1662 u32 val;
1663
1664 val = REG_READ(ah, AR_NAV);
1665 if (val != 0xdeadbeef && val > 0x7fff) {
1666 ath_dbg(common, BSTUCK, "Abnormal NAV: 0x%x\n", val);
1667 REG_WRITE(ah, AR_NAV, 0);
1668 }
1669}
1670EXPORT_SYMBOL(ath9k_hw_check_nav);
1671
1659bool ath9k_hw_check_alive(struct ath_hw *ah) 1672bool ath9k_hw_check_alive(struct ath_hw *ah)
1660{ 1673{
1661 int count = 50; 1674 int count = 50;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 5e564c788813..5376011d5200 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -1031,6 +1031,7 @@ void ath9k_hw_set11nmac2040(struct ath_hw *ah);
1031void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); 1031void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
1032void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, 1032void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
1033 const struct ath9k_beacon_state *bs); 1033 const struct ath9k_beacon_state *bs);
1034void ath9k_hw_check_nav(struct ath_hw *ah);
1034bool ath9k_hw_check_alive(struct ath_hw *ah); 1035bool ath9k_hw_check_alive(struct ath_hw *ah);
1035 1036
1036bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); 1037bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);