2014-09-29 18:45:48

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 1/3] Revert "ath9k_hw: reduce ANI firstep range for older chips"

This reverts commit 09efc56345be4146ab9fc87a55c837ed5d6ea1ab

I've received reports that this change is decreasing throughput in some
rare conditions on an AR9280 based device

Cc: [email protected]
Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar5008_phy.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 00fb8ba..3b3e910 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -1004,9 +1004,11 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
case ATH9K_ANI_FIRSTEP_LEVEL:{
u32 level = param;

- value = level;
+ value = level * 2;
REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
AR_PHY_FIND_SIG_FIRSTEP, value);
+ REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW,
+ AR_PHY_FIND_SIG_FIRSTEP_LOW, value);

if (level != aniState->firstepLevel) {
ath_dbg(common, ANI,
--
2.0.4



2014-09-30 08:30:41

by Felix Fietkau

[permalink] [raw]
Subject: Re: [PATCH 1/3] Revert "ath9k_hw: reduce ANI firstep range for older chips"

On 2014-09-30 03:20, Sujith Manoharan wrote:
> Felix Fietkau wrote:
>> This reverts commit 09efc56345be4146ab9fc87a55c837ed5d6ea1ab
>>
>> I've received reports that this change is decreasing throughput in some
>> rare conditions on an AR9280 based device
>
> Wasn't the original patch for improving stability ? Won't reverting it
> reintroduce the earlier situation ?
The issues that were slightly improved by this patch were fixed in a
different way later. This change has been tested in OpenWrt for 3 weeks now.

> If ANI issues/regressions for pre-AR9003 chips are still arising,
> I wonder what we have gained by the switch and if the new algorithm
> is a good fit for the older chips.
After switching to the new algorithm, a large number of users reported a
very significant increase in stability. Back then, overall stability of
ath9k was a lot worse than it is now, and a much larger number of users
were having trouble with it.

Additionally, the new algorithm is much easier to understand and tune -
the old code (especially the one with both algorithms combined) was an
incomprehensible mess of spaghetti code. I still believe the new
algorithm is better for pre-AR9003 than the old one, just the callback
that applies the settings needs a bit more fine tuning.

The ANI issues that I'm finding these days affect a *much* smaller
number of users, and are less severe than what we've been dealing with
during the time of the switch.

> At least for SoC chips, people will report it to OpenWrt. For PC-OEM
> cards, users will just say that the card sucks and move on...
For pre-AR9003, most devices used with OpenWrt actually use exactly the
same chips as PC-OEM cards.

- Felix

2014-09-29 18:45:48

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 2/3] ath9k_hw: reduce ANI spur immunity setting on HT40 extension channel

The cycpwr_thr1 value needs to be lower on the extension channel than on
the control channel, similar to how the register settings are programmed
in the initvals.

Also drop the unnecessary check for HT40 - this register can always be
written. This patch has been reported to improve HT40 stability and
throughput in some environments.

Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar5008_phy.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 3b3e910..b72d0be 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -1042,9 +1042,8 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah,
REG_RMW_FIELD(ah, AR_PHY_TIMING5,
AR_PHY_TIMING5_CYCPWR_THR1, value);

- if (IS_CHAN_HT40(ah->curchan))
- REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
- AR_PHY_EXT_TIMING5_CYCPWR_THR1, value);
+ REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
+ AR_PHY_EXT_TIMING5_CYCPWR_THR1, value - 1);

if (level != aniState->spurImmunityLevel) {
ath_dbg(common, ANI,
--
2.0.4


2014-09-30 08:40:26

by Sujith Manoharan

[permalink] [raw]
Subject: Re: [PATCH 1/3] Revert "ath9k_hw: reduce ANI firstep range for older chips"

Felix Fietkau wrote:
> For pre-AR9003, most devices used with OpenWrt actually use exactly the
> same chips as PC-OEM cards.

Yes, that is true. We split the SoC/PC-OEM chip lines in AR9003.
Sorry for the noise. ;)

Sujith

2014-09-29 18:45:48

by Felix Fietkau

[permalink] [raw]
Subject: [PATCH 3/3] ath9k_hw: fix PLL clock initialization for newer SoC

On AR934x and newer SoC devices, the layout of the AR_RTC_PLL_CONTROL
register changed. This currently breaks at least 5/10 MHz operation.
AR933x uses the old layout.

It might also have been causing other stability issues because of the
different location of the PLL_BYPASS bit which needs to be set during
PLL clock initialization.

This patch also removes more instances of hardcoded register values in
favor of properly computed ones with the PLL_BYPASS bit added.

Reported-by: Lorenzo Bianconi <[email protected]>
Signed-off-by: Felix Fietkau <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar9003_phy.c | 24 +++++++++++++++++++++++-
drivers/net/wireless/ath/ath9k/hw.c | 9 ++++++---
drivers/net/wireless/ath/ath9k/reg.h | 11 +++++++++++
3 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 542a8d5..697c4ae 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -517,6 +517,23 @@ static void ar9003_hw_spur_mitigate(struct ath_hw *ah,
ar9003_hw_spur_mitigate_ofdm(ah, chan);
}

+static u32 ar9003_hw_compute_pll_control_soc(struct ath_hw *ah,
+ struct ath9k_channel *chan)
+{
+ u32 pll;
+
+ pll = SM(0x5, AR_RTC_9300_SOC_PLL_REFDIV);
+
+ if (chan && IS_CHAN_HALF_RATE(chan))
+ pll |= SM(0x1, AR_RTC_9300_SOC_PLL_CLKSEL);
+ else if (chan && IS_CHAN_QUARTER_RATE(chan))
+ pll |= SM(0x2, AR_RTC_9300_SOC_PLL_CLKSEL);
+
+ pll |= SM(0x2c, AR_RTC_9300_SOC_PLL_DIV_INT);
+
+ return pll;
+}
+
static u32 ar9003_hw_compute_pll_control(struct ath_hw *ah,
struct ath9k_channel *chan)
{
@@ -1781,7 +1798,12 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)

priv_ops->rf_set_freq = ar9003_hw_set_channel;
priv_ops->spur_mitigate_freq = ar9003_hw_spur_mitigate;
- priv_ops->compute_pll_control = ar9003_hw_compute_pll_control;
+
+ if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah))
+ priv_ops->compute_pll_control = ar9003_hw_compute_pll_control_soc;
+ else
+ priv_ops->compute_pll_control = ar9003_hw_compute_pll_control;
+
priv_ops->set_channel_regs = ar9003_hw_set_channel_regs;
priv_ops->init_bb = ar9003_hw_init_bb;
priv_ops->process_ini = ar9003_hw_process_ini;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 3aed729..f03e283 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -704,6 +704,8 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
{
u32 pll;

+ pll = ath9k_hw_compute_pll_control(ah, chan);
+
if (AR_SREV_9485(ah) || AR_SREV_9565(ah)) {
/* program BB PLL ki and kd value, ki=0x4, kd=0x40 */
REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
@@ -754,7 +756,8 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
REG_RMW_FIELD(ah, AR_CH0_DDR_DPLL3,
AR_CH0_DPLL3_PHASE_SHIFT, 0x1);

- REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
+ REG_WRITE(ah, AR_RTC_PLL_CONTROL,
+ pll | AR_RTC_9300_PLL_BYPASS);
udelay(1000);

/* program refdiv, nint, frac to RTC register */
@@ -770,7 +773,8 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
} else if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah)) {
u32 regval, pll2_divint, pll2_divfrac, refdiv;

- REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
+ REG_WRITE(ah, AR_RTC_PLL_CONTROL,
+ pll | AR_RTC_9300_SOC_PLL_BYPASS);
udelay(1000);

REG_SET_BIT(ah, AR_PHY_PLL_MODE, 0x1 << 16);
@@ -843,7 +847,6 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
udelay(1000);
}

- pll = ath9k_hw_compute_pll_control(ah, chan);
if (AR_SREV_9565(ah))
pll |= 0x40000;
REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index a149970..3747a8a 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1240,12 +1240,23 @@ enum {
#define AR_CH0_DPLL3_PHASE_SHIFT_S 23
#define AR_PHY_CCA_NOM_VAL_2GHZ -118

+#define AR_RTC_9300_SOC_PLL_DIV_INT 0x0000003f
+#define AR_RTC_9300_SOC_PLL_DIV_INT_S 0
+#define AR_RTC_9300_SOC_PLL_DIV_FRAC 0x000fffc0
+#define AR_RTC_9300_SOC_PLL_DIV_FRAC_S 6
+#define AR_RTC_9300_SOC_PLL_REFDIV 0x01f00000
+#define AR_RTC_9300_SOC_PLL_REFDIV_S 20
+#define AR_RTC_9300_SOC_PLL_CLKSEL 0x06000000
+#define AR_RTC_9300_SOC_PLL_CLKSEL_S 25
+#define AR_RTC_9300_SOC_PLL_BYPASS 0x08000000
+
#define AR_RTC_9300_PLL_DIV 0x000003ff
#define AR_RTC_9300_PLL_DIV_S 0
#define AR_RTC_9300_PLL_REFDIV 0x00003C00
#define AR_RTC_9300_PLL_REFDIV_S 10
#define AR_RTC_9300_PLL_CLKSEL 0x0000C000
#define AR_RTC_9300_PLL_CLKSEL_S 14
+#define AR_RTC_9300_PLL_BYPASS 0x00010000

#define AR_RTC_9160_PLL_DIV 0x000003ff
#define AR_RTC_9160_PLL_DIV_S 0
--
2.0.4


2014-09-30 01:20:07

by Sujith Manoharan

[permalink] [raw]
Subject: Re: [PATCH 1/3] Revert "ath9k_hw: reduce ANI firstep range for older chips"

Felix Fietkau wrote:
> This reverts commit 09efc56345be4146ab9fc87a55c837ed5d6ea1ab
>
> I've received reports that this change is decreasing throughput in some
> rare conditions on an AR9280 based device

Wasn't the original patch for improving stability ? Won't reverting it
reintroduce the earlier situation ?

If ANI issues/regressions for pre-AR9003 chips are still arising,
I wonder what we have gained by the switch and if the new algorithm
is a good fit for the older chips.

At least for SoC chips, people will report it to OpenWrt. For PC-OEM
cards, users will just say that the card sucks and move on...

Sujith