aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2010-09-16 15:12:28 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-09-16 15:46:12 -0400
commit48a6a468198aadb54bc5d3fdd065364d43ff5197 (patch)
treecc4a26212a72638dcaffb0191e0f33cf98f1f40a /drivers
parent52b8ac92496e03d6b5619204d7f3bae6ce6eae45 (diff)
ath9k: fix enabling ANI / tx monitor after bg scan
ath9k's entire logic with SC_OP_SCANNING is incorrect due to the way mac80211 currently implements the scan complete callback and we handle it in ath9k. This patch removes the flag completely in preference for the SC_OP_OFFCHANNEL which is really what we wanted. The scanning flag was used to ensure we reset ANI to the old values when we go back to the home channel, but if we are offchannel we use some defaults. The flag was also used to re-enable the TX monitor. Without this patch we simply never re-enabled ANI and the TX monitor after going offchannel. This means that after one background scan we are prone to noise issues and if we had a TX hang we would not recover. To get this to work properly we must enable ANI after we have configured the beacon timers, otherwise hardware acts really oddly. This patch has stable fixes which apply down to [2.6.36+], there *may* be a to fix this on older kernels but requires a bit of work since this patch relies on the new mac80211 flag IEEE80211_CONF_OFFCHANNEL which was introduced as of 2.6.36. Cc: stable@kernel.org Cc: Paul Stewart <pstew@google.com> Cc: Amod Bodas <amod.bodas@atheros.com> Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c4
3 files changed, 5 insertions, 10 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index c8ff417f6c10..98b57e6c614e 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -563,7 +563,6 @@ struct ath_ant_comb {
563#define SC_OP_RXFLUSH BIT(7) 563#define SC_OP_RXFLUSH BIT(7)
564#define SC_OP_LED_ASSOCIATED BIT(8) 564#define SC_OP_LED_ASSOCIATED BIT(8)
565#define SC_OP_LED_ON BIT(9) 565#define SC_OP_LED_ON BIT(9)
566#define SC_OP_SCANNING BIT(10)
567#define SC_OP_TSF_RESET BIT(11) 566#define SC_OP_TSF_RESET BIT(11)
568#define SC_OP_BT_PRIORITY_DETECTED BIT(12) 567#define SC_OP_BT_PRIORITY_DETECTED BIT(12)
569#define SC_OP_BT_SCAN BIT(13) 568#define SC_OP_BT_SCAN BIT(13)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 3295c638f7e3..5056733e6f66 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -255,14 +255,12 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
255 ath_update_txpow(sc); 255 ath_update_txpow(sc);
256 ath9k_hw_set_interrupts(ah, ah->imask); 256 ath9k_hw_set_interrupts(ah, ah->imask);
257 257
258 if (!(sc->sc_flags & (SC_OP_OFFCHANNEL | SC_OP_SCANNING))) { 258 if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) {
259 ath_start_ani(common); 259 ath_beacon_config(sc, NULL);
260 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); 260 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
261 ath_start_ani(common);
261 } 262 }
262 263
263 if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)))
264 ath_beacon_config(sc, NULL);
265
266 ps_restore: 264 ps_restore:
267 ath9k_ps_restore(sc); 265 ath9k_ps_restore(sc);
268 return r; 266 return r;
@@ -2036,7 +2034,6 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
2036 2034
2037 aphy->state = ATH_WIPHY_SCAN; 2035 aphy->state = ATH_WIPHY_SCAN;
2038 ath9k_wiphy_pause_all_forced(sc, aphy); 2036 ath9k_wiphy_pause_all_forced(sc, aphy);
2039 sc->sc_flags |= SC_OP_SCANNING;
2040 mutex_unlock(&sc->mutex); 2037 mutex_unlock(&sc->mutex);
2041} 2038}
2042 2039
@@ -2051,7 +2048,6 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
2051 2048
2052 mutex_lock(&sc->mutex); 2049 mutex_lock(&sc->mutex);
2053 aphy->state = ATH_WIPHY_ACTIVE; 2050 aphy->state = ATH_WIPHY_ACTIVE;
2054 sc->sc_flags &= ~SC_OP_SCANNING;
2055 mutex_unlock(&sc->mutex); 2051 mutex_unlock(&sc->mutex);
2056} 2052}
2057 2053
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 3e7b8fe36044..007df33ab05e 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -300,7 +300,7 @@ static void ath_edma_start_recv(struct ath_softc *sc)
300 300
301 ath_opmode_init(sc); 301 ath_opmode_init(sc);
302 302
303 ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_SCANNING)); 303 ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_OFFCHANNEL));
304} 304}
305 305
306static void ath_edma_stop_recv(struct ath_softc *sc) 306static void ath_edma_stop_recv(struct ath_softc *sc)
@@ -506,7 +506,7 @@ int ath_startrecv(struct ath_softc *sc)
506start_recv: 506start_recv:
507 spin_unlock_bh(&sc->rx.rxbuflock); 507 spin_unlock_bh(&sc->rx.rxbuflock);
508 ath_opmode_init(sc); 508 ath_opmode_init(sc);
509 ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_SCANNING)); 509 ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_OFFCHANNEL));
510 510
511 return 0; 511 return 0;
512} 512}