2013-06-04 10:14:22

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 1/6] ath9k: Fix OFDM weak signal detection for AP mode

From: Sujith Manoharan <[email protected]>

The commit "ath9k_hw: improve ANI processing and rx desensitizing parameters"
changed the OFDM weak signal detection logic to disable it
for AP mode, which is not allowed. Fix this and enable it always
for AP mode.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ani.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index e91725b..3ec4c53 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -177,10 +177,15 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel,
BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_HIGH)
weak_sig = true;

- if (aniState->ofdmWeakSigDetect != weak_sig)
- ath9k_hw_ani_control(ah,
- ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
- entry_ofdm->ofdm_weak_signal_on);
+ /*
+ * OFDM Weak signal detection is always enabled for AP mode.
+ */
+ 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);
+ }

if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) {
ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
--
1.8.3



2013-06-04 11:49:51

by Sujith Manoharan

[permalink] [raw]
Subject: Re: [PATCH 2/6] ath9k: Fix ANI monitoring

Felix Fietkau wrote:
> With this patch, the raise-limit is always 3500, you should change it to
> 1000 when removing the above-/below-INI distinction.

Thanks, I'll fix this and send a v2.

Sujith

2013-06-04 10:14:28

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 4/6] ath9k: Fix ofdm weak signal configuration

From: Sujith Manoharan <[email protected]>

The commit, "ath9k_hw: improve ANI processing and rx desensitizing parameters"
removed code setting various phy registers holding threshold values.

This is likely required for OFDM weak signal detection to function
correctly, so add them, but skip AR9462 and AR9565.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar9003_phy.c | 60 +++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 83e0385..bc48312 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -906,6 +906,11 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_channel *chan = ah->curchan;
struct ar5416AniState *aniState = &ah->ani;
+ int m1ThreshLow, m2ThreshLow;
+ int m1Thresh, m2Thresh;
+ int m2CountThr, m2CountThrLow;
+ int m1ThreshLowExt, m2ThreshLowExt;
+ int m1ThreshExt, m2ThreshExt;
s32 value, value2;

switch (cmd & ah->ani_function) {
@@ -919,6 +924,61 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
*/
u32 on = param ? 1 : 0;

+ if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
+ goto skip_ws_det;
+
+ m1ThreshLow = on ?
+ aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
+ m2ThreshLow = on ?
+ aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
+ m1Thresh = on ?
+ aniState->iniDef.m1Thresh : m1Thresh_off;
+ m2Thresh = on ?
+ aniState->iniDef.m2Thresh : m2Thresh_off;
+ m2CountThr = on ?
+ aniState->iniDef.m2CountThr : m2CountThr_off;
+ m2CountThrLow = on ?
+ aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
+ m1ThreshLowExt = on ?
+ aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
+ m2ThreshLowExt = on ?
+ aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
+ m1ThreshExt = on ?
+ aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
+ m2ThreshExt = on ?
+ aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
+
+ REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+ AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
+ m1ThreshLow);
+ REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+ AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
+ m2ThreshLow);
+ REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+ AR_PHY_SFCORR_M1_THRESH,
+ m1Thresh);
+ REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+ AR_PHY_SFCORR_M2_THRESH,
+ m2Thresh);
+ REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+ AR_PHY_SFCORR_M2COUNT_THR,
+ m2CountThr);
+ REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+ AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
+ m2CountThrLow);
+ REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+ AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
+ m1ThreshLowExt);
+ REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+ AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
+ m2ThreshLowExt);
+ REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+ AR_PHY_SFCORR_EXT_M1_THRESH,
+ m1ThreshExt);
+ REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+ AR_PHY_SFCORR_EXT_M2_THRESH,
+ m2ThreshExt);
+skip_ws_det:
if (on)
REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
--
1.8.3


2013-06-04 12:07:42

by Sujith Manoharan

[permalink] [raw]
Subject: Re: [PATCH 2/6] ath9k: Fix ANI monitoring

Sujith Manoharan wrote:
> Actually, the changes appear to have been merged internally, for QCA988x.
> So, I am not sure if we can keep the ANI tweaks.

Let's see if there is any improvement in this bug with
these patches: https://bugzilla.kernel.org/show_bug.cgi?id=49201

Sujith

2013-06-04 10:14:30

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 5/6] ath9k: Remove redundant code

From: Sujith Manoharan <[email protected]>

The phy error mask registers are programmed already
in ath9k_ani_restart(), so there is no need to set them
in ath9k_ani_reset().

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ani.c | 11 -----------
1 file changed, 11 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index c8595f4..a68beb1 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -360,18 +360,7 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
ath9k_hw_set_ofdm_nil(ah, ofdm_nil, is_scanning);
ath9k_hw_set_cck_nil(ah, cck_nil, is_scanning);

- /*
- * enable phy counters if hw supports or if not, enable phy
- * interrupts (so we can count each one)
- */
ath9k_ani_restart(ah);
-
- ENABLE_REGWRITE_BUFFER(ah);
-
- REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
- REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
-
- REGWRITE_BUFFER_FLUSH(ah);
}

static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
--
1.8.3


2013-06-04 11:59:38

by Sujith Manoharan

[permalink] [raw]
Subject: Re: [PATCH 2/6] ath9k: Fix ANI monitoring

Sujith Manoharan wrote:
> > With this patch, the raise-limit is always 3500, you should change it to
> > 1000 when removing the above-/below-INI distinction.
>
> Thanks, I'll fix this and send a v2.

Actually, the changes appear to have been merged internally, for QCA988x.
So, I am not sure if we can keep the ANI tweaks.

Sujith

2013-06-04 11:32:45

by Felix Fietkau

[permalink] [raw]
Subject: Re: [PATCH 2/6] ath9k: Fix ANI monitoring

On 2013-06-04 12:11 PM, Sujith Manoharan wrote:
> From: Sujith Manoharan <[email protected]>
>
> The commit "ath9k_hw: improve ANI processing and rx desensitizing parameters"
> changed various ANI operational parameters to address a specific
> card/environment. This is not really applicable for other cards
> in general usage.
>
> As per internal documentation, lowering the immunity level can be
> done only after 5 periods have passed and the CCK/OFDM errors are
> below the low watermak threshold - which have been fixed at 300 and
> 400 respectively by the sytems team.
>
> Raising the immunity level can be done when CCK/OFDM errors exceed
> 600 and 1000 (per second).
>
> Set these values once during attach.
> ---
> diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
> index 78b9fa9..1088472 100644
> --- a/drivers/net/wireless/ath/ath9k/ani.h
> +++ b/drivers/net/wireless/ath/ath9k/ani.h
> @@ -21,11 +21,9 @@
>
> /* units are errors per second */
> #define ATH9K_ANI_OFDM_TRIG_HIGH 3500
> -#define ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI 1000
>
> /* units are errors per second */
> #define ATH9K_ANI_OFDM_TRIG_LOW 400
> -#define ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI 900
>
> /* units are errors per second */
> #define ATH9K_ANI_CCK_TRIG_HIGH 600
>
With this patch, the raise-limit is always 3500, you should change it to
1000 when removing the above-/below-INI distinction.

- Felix

2013-06-04 10:14:26

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 3/6] ath9k: Fix ANI levels

From: Sujith Manoharan <[email protected]>

The commit, "ath9k_hw: improve ANI processing and rx desensitizing parameters"
modified the immunity level tables for both CCK and OFDM. Fix them
so that the tables are in sync with the internal driver/codebase.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ani.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 1520e55..c8595f4 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -46,8 +46,8 @@ static const struct ani_ofdm_level_entry ofdm_level_table[] = {
{ 5, 4, 1 }, /* lvl 5 */
{ 6, 5, 1 }, /* lvl 6 */
{ 7, 6, 1 }, /* lvl 7 */
- { 7, 6, 0 }, /* lvl 8 */
- { 7, 7, 0 } /* lvl 9 */
+ { 7, 7, 1 }, /* lvl 8 */
+ { 7, 8, 0 } /* lvl 9 */
};
#define ATH9K_ANI_OFDM_NUM_LEVEL \
ARRAY_SIZE(ofdm_level_table)
@@ -91,8 +91,8 @@ static const struct ani_cck_level_entry cck_level_table[] = {
{ 4, 0 }, /* lvl 4 */
{ 5, 0 }, /* lvl 5 */
{ 6, 0 }, /* lvl 6 */
- { 6, 0 }, /* lvl 7 (only for high rssi) */
- { 7, 0 } /* lvl 8 (only for high rssi) */
+ { 7, 0 }, /* lvl 7 (only for high rssi) */
+ { 8, 0 } /* lvl 8 (only for high rssi) */
};

#define ATH9K_ANI_CCK_NUM_LEVEL \
--
1.8.3


2013-06-04 10:14:32

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 6/6] ath9k: Remove unused ANI macros

From: Sujith Manoharan <[email protected]>

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ani.h | 11 -----------
1 file changed, 11 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index 1088472..b75aea2 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -21,17 +21,10 @@

/* units are errors per second */
#define ATH9K_ANI_OFDM_TRIG_HIGH 3500
-
-/* units are errors per second */
#define ATH9K_ANI_OFDM_TRIG_LOW 400
-
-/* units are errors per second */
#define ATH9K_ANI_CCK_TRIG_HIGH 600
-
-/* units are errors per second */
#define ATH9K_ANI_CCK_TRIG_LOW 300

-#define ATH9K_ANI_NOISE_IMMUNE_LVL 4
#define ATH9K_ANI_SPUR_IMMUNE_LVL 3
#define ATH9K_ANI_FIRSTEP_LVL 2

@@ -43,10 +36,6 @@
/* in ms */
#define ATH9K_ANI_POLLINTERVAL 1000

-#define HAL_NOISE_IMMUNE_MAX 4
-#define HAL_SPUR_IMMUNE_MAX 7
-#define HAL_FIRST_STEP_MAX 2
-
#define ATH9K_SIG_FIRSTEP_SETTING_MIN 0
#define ATH9K_SIG_FIRSTEP_SETTING_MAX 20
#define ATH9K_SIG_SPUR_IMM_SETTING_MIN 0
--
1.8.3


2013-06-04 10:14:24

by Sujith Manoharan

[permalink] [raw]
Subject: [PATCH 2/6] ath9k: Fix ANI monitoring

From: Sujith Manoharan <[email protected]>

The commit "ath9k_hw: improve ANI processing and rx desensitizing parameters"
changed various ANI operational parameters to address a specific
card/environment. This is not really applicable for other cards
in general usage.

As per internal documentation, lowering the immunity level can be
done only after 5 periods have passed and the CCK/OFDM errors are
below the low watermak threshold - which have been fixed at 300 and
400 respectively by the sytems team.

Raising the immunity level can be done when CCK/OFDM errors exceed
600 and 1000 (per second).

Set these values once during attach.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ani.c | 29 +++++++++++++++++------------
drivers/net/wireless/ath/ath9k/ani.h | 2 --
2 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 3ec4c53..1520e55 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -186,14 +186,6 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel,
ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
entry_ofdm->ofdm_weak_signal_on);
}
-
- if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) {
- ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH;
- ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI;
- } else {
- ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI;
- ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW;
- }
}

static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
@@ -439,12 +431,25 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
ofdmPhyErrRate, aniState->cckNoiseImmunityLevel,
cckPhyErrRate, aniState->ofdmsTurn);

- if (aniState->listenTime > ah->aniperiod) {
- if (cckPhyErrRate < ah->config.cck_trig_low &&
- ofdmPhyErrRate < ah->config.ofdm_trig_low) {
+ if (aniState->listenTime > 5 * ah->aniperiod) {
+ /*
+ * Check if we need to lower immunity if
+ * 5 ani_periods have passed.
+ */
+ if (ofdmPhyErrRate <= ah->config.ofdm_trig_low &&
+ cckPhyErrRate <= ah->config.cck_trig_low) {
ath9k_hw_ani_lower_immunity(ah);
aniState->ofdmsTurn = !aniState->ofdmsTurn;
- } else if (ofdmPhyErrRate > ah->config.ofdm_trig_high) {
+ }
+ ath9k_ani_restart(ah);
+ } else if (aniState->listenTime > ah->aniperiod) {
+ /*
+ * Check if immunity has to be raised,
+ * (either OFDM or CCK).
+ */
+ if (ofdmPhyErrRate > ah->config.ofdm_trig_high &&
+ (cckPhyErrRate <= ah->config.cck_trig_high ||
+ aniState->ofdmsTurn)) {
ath9k_hw_ani_ofdm_err_trigger(ah);
aniState->ofdmsTurn = false;
} else if (cckPhyErrRate > ah->config.cck_trig_high) {
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index 78b9fa9..1088472 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -21,11 +21,9 @@

/* units are errors per second */
#define ATH9K_ANI_OFDM_TRIG_HIGH 3500
-#define ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI 1000

/* units are errors per second */
#define ATH9K_ANI_OFDM_TRIG_LOW 400
-#define ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI 900

/* units are errors per second */
#define ATH9K_ANI_CCK_TRIG_HIGH 600
--
1.8.3