+--- a/drivers/net/wireless/ath/ath9k/ani.c
++++ b/drivers/net/wireless/ath/ath9k/ani.c
+@@ -176,16 +176,26 @@ static void ath9k_hw_set_ofdm_nil(struct
+ if (ah->opmode == NL80211_IFTYPE_STATION &&
+ BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_HIGH)
+ weak_sig = true;
+-
+ /*
+- * OFDM Weak signal detection is always enabled for AP mode.
++ * Newer chipsets are better at dealing with high PHY error counts -
++ * keep weak signal detection enabled when no RSSI threshold is
++ * available to determine if it is needed (mode != STA)
+ */
+- if (ah->opmode != NL80211_IFTYPE_AP &&
+- aniState->ofdmWeakSigDetect != weak_sig) {
+- ath9k_hw_ani_control(ah,
+- ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+- entry_ofdm->ofdm_weak_signal_on);
+- }
++ else if (AR_SREV_9300_20_OR_LATER(ah) &&
++ ah->opmode != NL80211_IFTYPE_STATION)
++ weak_sig = true;
++
++ /* Older chipsets are more sensitive to high PHY error counts */
++ else if (!AR_SREV_9300_20_OR_LATER(ah) &&
++ aniState->ofdmNoiseImmunityLevel >= 8)
++ weak_sig = false;
++
++ if (aniState->ofdmWeakSigDetect != weak_sig)
++ ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
++ weak_sig);
++
++ if (!AR_SREV_9300_20_OR_LATER(ah))
++ return;
+
+ if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) {
+ ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
+@@ -483,10 +493,17 @@ void ath9k_hw_ani_init(struct ath_hw *ah
+
+ ath_dbg(common, ANI, "Initialize ANI\n");
+
+- ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
+- ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
+- ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH;
+- ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW;
++ if (AR_SREV_9300_20_OR_LATER(ah)) {
++ ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
++ ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
++ ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH;
++ ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW;
++ } else {
++ ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
++ ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
++ ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
++ ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD;
++ }
+
+ ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
+ ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
+--- a/drivers/net/wireless/ath/ath9k/ani.h
++++ b/drivers/net/wireless/ath/ath9k/ani.h
+@@ -22,12 +22,16 @@
+ /* units are errors per second */
+ #define ATH9K_ANI_OFDM_TRIG_HIGH 3500
+ #define ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI 1000
++#define ATH9K_ANI_OFDM_TRIG_HIGH_OLD 500
+
+ #define ATH9K_ANI_OFDM_TRIG_LOW 400
+ #define ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI 900
++#define ATH9K_ANI_OFDM_TRIG_LOW_OLD 200
+
+ #define ATH9K_ANI_CCK_TRIG_HIGH 600
++#define ATH9K_ANI_CCK_TRIG_HIGH_OLD 200
+ #define ATH9K_ANI_CCK_TRIG_LOW 300
++#define ATH9K_ANI_CCK_TRIG_LOW_OLD 100
+
+ #define ATH9K_ANI_SPUR_IMMUNE_LVL 3
+ #define ATH9K_ANI_FIRSTEP_LVL 2