2012-12-07 10:02:41

by Sujith Manoharan

[permalink] [raw]
Subject: [RFC 0/8] PAPRD for ath9k

From: Sujith Manoharan <[email protected]>

This patch series enables PAPRD functionality for AR9485,
AR9462 and AR9565. Please review !

Sujith Manoharan (8):
ath9k_hw: Fix PAPRD registers for AR9485
ath9k_hw: Fix PAPRD training
ath9k: Add a few debug messages for PAPRD
ath9k: Fix redundant PS wrappers
ath9k_hw: Various trivial fixes for PAPRD
ath9k_hw: Fix PAPRD retraining for AR9485
ath9k_hw: Calculate the correct training power for PAPRD
ath9k_hw: Enable PAPRD for AR9485, AR9462 and AR9565

drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 49 +++++++++------
drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 87 +++++++++++++++++++-------
drivers/net/wireless/ath/ath9k/ar9003_phy.h | 29 +++++----
drivers/net/wireless/ath/ath9k/hw.c | 11 ++++
drivers/net/wireless/ath/ath9k/hw.h | 4 +-
drivers/net/wireless/ath/ath9k/link.c | 22 ++++---
6 files changed, 137 insertions(+), 65 deletions(-)

--
1.8.0.1



2012-12-07 15:00:18

by Sujith Manoharan

[permalink] [raw]
Subject: Re: [RFC 7/8] ath9k_hw: Calculate the correct training power for PAPRD

Rajkumar Manoharan wrote:
> Can you reorder the patch series as ar9003_is_paprd_enabled is not defined in
> previous patches?

Will do.

Sujith

2012-12-07 10:27:16

by Rajkumar Manoharan

[permalink] [raw]
Subject: Re: [RFC 7/8] ath9k_hw: Calculate the correct training power for PAPRD

On Fri, Dec 07, 2012 at 03:32:00PM +0530, Sujith Manoharan wrote:
> From: Sujith Manoharan <[email protected]>
>
> Assign the training power for PAPRD based on the chip.
>
> Signed-off-by: Sujith Manoharan <[email protected]>
> ---
> drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 41 ++++++++++++++++++--------
> drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 22 +++++++++-----
> 2 files changed, 43 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
> index c86cb640..0f38895 100644
> --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
> +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
> @@ -5076,6 +5076,33 @@ static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
> return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
> }
>
> +static void ar9003_paprd_set_txpower(struct ath_hw *ah,
> + struct ath9k_channel *chan,
> + u8 *targetPowerValT2)
> +{
> + int i;
> +
> + if (!ar9003_is_paprd_enabled(ah))
> + return;
> +
Can you reorder the patch series as ar9003_is_paprd_enabled is not defined in
previous patches?

-Rajkumar

2012-12-07 10:02:45

by Sujith Manoharan

[permalink] [raw]
Subject: [RFC 4/8] ath9k: Fix redundant PS wrappers

From: Sujith Manoharan <[email protected]>

Move the PowerSave wrappers outside ath_paprd_activate(),
since they are already being used in ath_paprd_calibrate().

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

diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index 3c996ff..c70b31a 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -188,7 +188,6 @@ static void ath_paprd_activate(struct ath_softc *sc)
return;
}

- ath9k_ps_wakeup(sc);
ar9003_paprd_enable(ah, false);
for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
if (!(ah->txchainmask & BIT(chain)))
@@ -199,7 +198,6 @@ static void ath_paprd_activate(struct ath_softc *sc)

ath_dbg(common, CALIBRATE, "Activating PAPRD\n");
ar9003_paprd_enable(ah, true);
- ath9k_ps_restore(sc);
}

static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int chain)
@@ -436,11 +434,15 @@ set_timer:
cal_interval = min(cal_interval, (u32)short_cal_interval);

mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
+
if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD) && ah->caldata) {
- if (!ah->caldata->paprd_done)
+ if (!ah->caldata->paprd_done) {
ieee80211_queue_work(sc->hw, &sc->paprd_work);
- else if (!ah->paprd_table_write_done)
+ } else if (!ah->paprd_table_write_done) {
+ ath9k_ps_wakeup(sc);
ath_paprd_activate(sc);
+ ath9k_ps_restore(sc);
+ }
}
}

--
1.8.0.1


2012-12-07 15:00:41

by Sujith Manoharan

[permalink] [raw]
Subject: Re: [RFC 2/8] ath9k_hw: Fix PAPRD training

Rajkumar Manoharan wrote:
> > +
> > + if (AR_SREV_9485(ah)) {
> > + val = 148;
> > + } else {
> > + if (IS_CHAN_2GHZ(ah->curchan)) {
> > + if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
> > + val = 0x91;
> Please change the hex to decimal for the sake of uniformity

Ok. :)

Sujith

2012-12-07 10:02:49

by Sujith Manoharan

[permalink] [raw]
Subject: [RFC 6/8] ath9k_hw: Fix PAPRD retraining for AR9485

From: Sujith Manoharan <[email protected]>

Retraining of PAPRD based on agc2_pwr is required for
chips other than AR9485.

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

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index cd8727b..3eca9bd 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -965,9 +965,13 @@ EXPORT_SYMBOL(ar9003_paprd_init_table);
bool ar9003_paprd_is_done(struct ath_hw *ah)
{
int paprd_done, agc2_pwr;
+
paprd_done = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1,
AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);

+ if (AR_SREV_9485(ah))
+ goto exit;
+
if (paprd_done == 0x1) {
agc2_pwr = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1,
AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR);
@@ -983,7 +987,7 @@ bool ar9003_paprd_is_done(struct ath_hw *ah)
if (agc2_pwr <= PAPRD_IDEAL_AGC2_PWR_RANGE)
paprd_done = 0;
}
-
+exit:
return !!paprd_done;
}
EXPORT_SYMBOL(ar9003_paprd_is_done);
--
1.8.0.1


2012-12-07 10:28:17

by Rajkumar Manoharan

[permalink] [raw]
Subject: Re: [RFC 2/8] ath9k_hw: Fix PAPRD training

On Fri, Dec 07, 2012 at 03:31:55PM +0530, Sujith Manoharan wrote:
> From: Sujith Manoharan <[email protected]>
>
> The PAPRD training control registers have to be
> programmed with values that depend on the chip. This patch
> ensures that the correct values are chosen for the chip
> in use.
>
> Signed-off-by: Sujith Manoharan <[email protected]>
> ---
> drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 36 +++++++++++++++++++++------
> 1 file changed, 29 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
> index 0ed3846..2cd23e5 100644
> --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
> +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
> @@ -204,7 +204,20 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
> AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING, 28);
> REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
> AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE, 1);
> - val = AR_SREV_9462(ah) ? 0x91 : 147;
> +
> + if (AR_SREV_9485(ah)) {
> + val = 148;
> + } else {
> + if (IS_CHAN_2GHZ(ah->curchan)) {
> + if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
> + val = 0x91;
Please change the hex to decimal for the sake of uniformity

> + else
> + val = 147;
> + } else {
> + val = 137;
> + }
> + }

-Rajkumar

2012-12-07 10:02:51

by Sujith Manoharan

[permalink] [raw]
Subject: [RFC 7/8] ath9k_hw: Calculate the correct training power for PAPRD

From: Sujith Manoharan <[email protected]>

Assign the training power for PAPRD based on the chip.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 41 ++++++++++++++++++--------
drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 22 +++++++++-----
2 files changed, 43 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index c86cb640..0f38895 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -5076,6 +5076,33 @@ static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
}

+static void ar9003_paprd_set_txpower(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ u8 *targetPowerValT2)
+{
+ int i;
+
+ if (!ar9003_is_paprd_enabled(ah))
+ return;
+
+ if (IS_CHAN_HT40(chan))
+ i = ALL_TARGET_HT40_7;
+ else
+ i = ALL_TARGET_HT20_7;
+
+ if (IS_CHAN_2GHZ(chan)) {
+ if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) &&
+ !AR_SREV_9462(ah) && !AR_SREV_9565(ah)) {
+ if (IS_CHAN_HT40(chan))
+ i = ALL_TARGET_HT40_0_8_16;
+ else
+ i = ALL_TARGET_HT20_0_8_16;
+ }
+ }
+
+ ah->paprd_target_power = targetPowerValT2[i];
+}
+
static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
struct ath9k_channel *chan, u16 cfgCtl,
u8 twiceAntennaReduction,
@@ -5170,19 +5197,7 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
/* Write target power array to registers */
ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
ar9003_hw_calibration_apply(ah, chan->channel);
-
- if (IS_CHAN_2GHZ(chan)) {
- if (IS_CHAN_HT40(chan))
- i = ALL_TARGET_HT40_0_8_16;
- else
- i = ALL_TARGET_HT20_0_8_16;
- } else {
- if (IS_CHAN_HT40(chan))
- i = ALL_TARGET_HT40_7;
- else
- i = ALL_TARGET_HT20_7;
- }
- ah->paprd_target_power = targetPowerValT2[i];
+ ar9003_paprd_set_txpower(ah, chan, targetPowerValT2);
}

static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index 3eca9bd..548b451 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -74,15 +74,23 @@ static int ar9003_get_training_power_2g(struct ath_hw *ah)
unsigned int power, scale, delta;

scale = ar9003_get_paprd_scale_factor(ah, chan);
- power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
- AR_PHY_POWERTX_RATE5_POWERTXHT20_0);

- delta = abs((int) ah->paprd_target_power - (int) power);
- if (delta > scale)
- return -1;
+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah) ||
+ AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
+ power = ah->paprd_target_power + 2;
+ } else if (AR_SREV_9485(ah)) {
+ power = 25;
+ } else {
+ power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
+ AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
+
+ delta = abs((int) ah->paprd_target_power - (int) power);
+ if (delta > scale)
+ return -1;

- if (delta < 4)
- power -= 4 - delta;
+ if (delta < 4)
+ power -= 4 - delta;
+ }

return power;
}
--
1.8.0.1


2012-12-07 10:02:41

by Sujith Manoharan

[permalink] [raw]
Subject: [RFC 1/8] ath9k_hw: Fix PAPRD registers for AR9485

From: Sujith Manoharan <[email protected]>

Various PAPRD registers are at addresses that are different
from those for the rest of the chips in the AR9003 family.
Fix them.

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

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 4c3d06d..1079562 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -1145,9 +1145,8 @@
#define AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT 0x0ffe0000
#define AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT_S 17

-#define AR_PHY_PAPRD_TRAINER_CNTL1 (AR_SM_BASE + \
- (AR_SREV_9485(ah) ? \
- 0x580 : 0x490))
+#define AR_PHY_PAPRD_TRAINER_CNTL1 (AR_SM_BASE + (AR_SREV_9485(ah) ? 0x580 : 0x490))
+
#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE 0x00000001
#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE_S 0
#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING 0x0000007e
@@ -1163,15 +1162,13 @@
#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP 0x0003f000
#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP_S 12

-#define AR_PHY_PAPRD_TRAINER_CNTL2 (AR_SM_BASE + \
- (AR_SREV_9485(ah) ? \
- 0x584 : 0x494))
+#define AR_PHY_PAPRD_TRAINER_CNTL2 (AR_SM_BASE + (AR_SREV_9485(ah) ? 0x584 : 0x494))
+
#define AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN 0xFFFFFFFF
#define AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN_S 0

-#define AR_PHY_PAPRD_TRAINER_CNTL3 (AR_SM_BASE + \
- (AR_SREV_9485(ah) ? \
- 0x588 : 0x498))
+#define AR_PHY_PAPRD_TRAINER_CNTL3 (AR_SM_BASE + (AR_SREV_9485(ah) ? 0x588 : 0x498))
+
#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE 0x0000003f
#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE_S 0
#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP 0x00000fc0
@@ -1187,9 +1184,8 @@
#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE 0x20000000
#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE_S 29

-#define AR_PHY_PAPRD_TRAINER_CNTL4 (AR_SM_BASE + \
- (AR_SREV_9485(ah) ? \
- 0x58c : 0x49c))
+#define AR_PHY_PAPRD_TRAINER_CNTL4 (AR_SM_BASE + (AR_SREV_9485(ah) ? 0x58c : 0x49c))
+
#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES 0x03ff0000
#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES_S 16
#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA 0x0000f000
@@ -1208,7 +1204,8 @@
#define AR_PHY_PAPRD_PRE_POST_SCALING 0x3FFFF
#define AR_PHY_PAPRD_PRE_POST_SCALING_S 0

-#define AR_PHY_PAPRD_TRAINER_STAT1 (AR_SM_BASE + 0x4a0)
+#define AR_PHY_PAPRD_TRAINER_STAT1 (AR_SM_BASE + (AR_SREV_9485(ah) ? 0x590 : 0x4a0))
+
#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE 0x00000001
#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE_S 0
#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE 0x00000002
@@ -1222,7 +1219,8 @@
#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR 0x0001fe00
#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR_S 9

-#define AR_PHY_PAPRD_TRAINER_STAT2 (AR_SM_BASE + 0x4a4)
+#define AR_PHY_PAPRD_TRAINER_STAT2 (AR_SM_BASE + (AR_SREV_9485(ah) ? 0x594 : 0x4a4))
+
#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL 0x0000ffff
#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL_S 0
#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX 0x001f0000
@@ -1230,7 +1228,8 @@
#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX 0x00600000
#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX_S 21

-#define AR_PHY_PAPRD_TRAINER_STAT3 (AR_SM_BASE + 0x4a8)
+#define AR_PHY_PAPRD_TRAINER_STAT3 (AR_SM_BASE + (AR_SREV_9485(ah) ? 0x598 : 0x4a8))
+
#define AR_PHY_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT 0x000fffff
#define AR_PHY_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT_S 0

--
1.8.0.1


2012-12-07 10:02:47

by Sujith Manoharan

[permalink] [raw]
Subject: [RFC 5/8] ath9k_hw: Various trivial fixes for PAPRD

From: Sujith Manoharan <[email protected]>

* Remove unneeded memset.

All the values in the PAPRD gain table are filled, so there
is no need to zero out the arrays.

* Use GFP_KERNEL in ar9003_paprd_create_curve

This is called from the PAPRD work, so the atomic variant
is not needed.

* Change return type of ar9003_paprd_setup_gain_table

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 9 ++-------
drivers/net/wireless/ath/ath9k/hw.h | 2 +-
2 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index b11a166..cd8727b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -287,9 +287,6 @@ static void ar9003_paprd_get_gain_table(struct ath_hw *ah)
u32 reg = AR_PHY_TXGAIN_TABLE;
int i;

- memset(entry, 0, sizeof(ah->paprd_gain_table_entries));
- memset(index, 0, sizeof(ah->paprd_gain_table_index));
-
for (i = 0; i < PAPRD_GAIN_TABLE_ENTRIES; i++) {
entry[i] = REG_READ(ah, reg);
index[i] = (entry[i] >> 24) & 0xff;
@@ -788,7 +785,7 @@ void ar9003_paprd_populate_single_table(struct ath_hw *ah,
}
EXPORT_SYMBOL(ar9003_paprd_populate_single_table);

-int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain)
+void ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain)
{
unsigned int i, desired_gain, gain_index;
unsigned int train_power = ah->paprd_training_power;
@@ -806,8 +803,6 @@ int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain)

REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
-
- return 0;
}
EXPORT_SYMBOL(ar9003_paprd_setup_gain_table);

@@ -919,7 +914,7 @@ int ar9003_paprd_create_curve(struct ath_hw *ah,

memset(caldata->pa_table[chain], 0, sizeof(caldata->pa_table[chain]));

- buf = kmalloc(2 * 48 * sizeof(u32), GFP_ATOMIC);
+ buf = kmalloc(2 * 48 * sizeof(u32), GFP_KERNEL);
if (!buf)
return -ENOMEM;

diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 3636dab..fe87d0e 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -1058,7 +1058,7 @@ void ar9003_paprd_populate_single_table(struct ath_hw *ah,
int chain);
int ar9003_paprd_create_curve(struct ath_hw *ah,
struct ath9k_hw_cal_data *caldata, int chain);
-int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain);
+void ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain);
int ar9003_paprd_init_table(struct ath_hw *ah);
bool ar9003_paprd_is_done(struct ath_hw *ah);

--
1.8.0.1


2012-12-07 10:02:53

by Sujith Manoharan

[permalink] [raw]
Subject: [RFC 8/8] ath9k_hw: Enable PAPRD for AR9485, AR9462 and AR9565

From: Sujith Manoharan <[email protected]>

Add a HW capability to indicate whether PAPRD is enabled
for the card, since PAPRD could be enabled in the EEPROM, but
disabled in the driver. This makes things clearer.

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 8 ++------
drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 9 +++++++++
drivers/net/wireless/ath/ath9k/hw.c | 11 +++++++++++
drivers/net/wireless/ath/ath9k/hw.h | 2 ++
drivers/net/wireless/ath/ath9k/link.c | 2 +-
5 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 0f38895..11082b4 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -2987,10 +2987,6 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
case EEP_RX_MASK:
return pBase->txrxMask & 0xf;
case EEP_PAPRD:
- if (AR_SREV_9462(ah))
- return false;
- if (!ah->config.enable_paprd)
- return false;
return !!(pBase->featureEnable & BIT(5));
case EEP_CHAIN_MASK_REDUCE:
return (pBase->miscConfiguration >> 0x3) & 0x1;
@@ -5124,7 +5120,7 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
*/
ar9003_hw_get_target_power_eeprom(ah, chan, targetPowerValT2);

- if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
+ if (ar9003_is_paprd_enabled(ah)) {
if (IS_CHAN_2GHZ(chan))
modal_hdr = &eep->modalHeader2G;
else
@@ -5165,7 +5161,7 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
twiceAntennaReduction,
powerLimit);

- if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
+ if (ar9003_is_paprd_enabled(ah)) {
for (i = 0; i < ar9300RateSize; i++) {
if ((ah->paprd_ratemask & (1 << i)) &&
(abs(targetPowerValT2[i] -
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index 548b451..1255b6a 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -999,3 +999,12 @@ exit:
return !!paprd_done;
}
EXPORT_SYMBOL(ar9003_paprd_is_done);
+
+bool ar9003_is_paprd_enabled(struct ath_hw *ah)
+{
+ if ((ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->config.enable_paprd)
+ return true;
+
+ return false;
+}
+EXPORT_SYMBOL(ar9003_is_paprd_enabled);
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index e06bcec..6af86ad 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2599,6 +2599,17 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
pCap->hw_caps |= ATH9K_HW_WOW_PATTERN_MATCH_DWORD;
}

+ if (AR_SREV_9300_20_OR_LATER(ah) &&
+ ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
+ pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
+
+ /* Enable PAPRD for these chips. */
+ if (AR_SREV_9485(ah) ||
+ AR_SREV_9462(ah) ||
+ AR_SREV_9565(ah))
+ ah->config.enable_paprd = 1;
+ }
+
return 0;
}

diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index fe87d0e..eff6759 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -247,6 +247,7 @@ enum ath9k_hw_caps {
ATH9K_HW_WOW_DEVICE_CAPABLE = BIT(17),
ATH9K_HW_WOW_PATTERN_MATCH_EXACT = BIT(18),
ATH9K_HW_WOW_PATTERN_MATCH_DWORD = BIT(19),
+ ATH9K_HW_CAP_PAPRD = BIT(20),
};

/*
@@ -1061,6 +1062,7 @@ int ar9003_paprd_create_curve(struct ath_hw *ah,
void ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain);
int ar9003_paprd_init_table(struct ath_hw *ah);
bool ar9003_paprd_is_done(struct ath_hw *ah);
+bool ar9003_is_paprd_enabled(struct ath_hw *ah);

/* Hardware family op attach helpers */
void ar5008_hw_attach_phy_ops(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index c70b31a..ade3afb 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -435,7 +435,7 @@ set_timer:

mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval));

- if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD) && ah->caldata) {
+ if (ar9003_is_paprd_enabled(ah) && ah->caldata) {
if (!ah->caldata->paprd_done) {
ieee80211_queue_work(sc->hw, &sc->paprd_work);
} else if (!ah->paprd_table_write_done) {
--
1.8.0.1


2012-12-07 10:02:43

by Sujith Manoharan

[permalink] [raw]
Subject: [RFC 3/8] ath9k: Add a few debug messages for PAPRD

From: Sujith Manoharan <[email protected]>

Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 3 +++
drivers/net/wireless/ath/ath9k/link.c | 10 ++++++++--
2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index 2cd23e5..b11a166 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -169,6 +169,9 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK,
ah->paprd_ratemask_ht40);

+ ath_dbg(common, CALIBRATE, "PAPRD HT20 mask: 0x%x, HT40 mask: 0x%x\n",
+ ah->paprd_ratemask, ah->paprd_ratemask_ht40);
+
for (i = 0; i < ah->caps.max_txchains; i++) {
REG_RMW_FIELD(ah, ctrl0[i],
AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK, 1);
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index fc6b075..3c996ff 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -179,11 +179,14 @@ void ath_rx_poll(unsigned long data)
static void ath_paprd_activate(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_hw_cal_data *caldata = ah->caldata;
int chain;

- if (!caldata || !caldata->paprd_done)
+ if (!caldata || !caldata->paprd_done) {
+ ath_dbg(common, CALIBRATE, "Failed to activate PAPRD\n");
return;
+ }

ath9k_ps_wakeup(sc);
ar9003_paprd_enable(ah, false);
@@ -194,6 +197,7 @@ static void ath_paprd_activate(struct ath_softc *sc)
ar9003_paprd_populate_single_table(ah, caldata, chain);
}

+ ath_dbg(common, CALIBRATE, "Activating PAPRD\n");
ar9003_paprd_enable(ah, true);
ath9k_ps_restore(sc);
}
@@ -253,8 +257,10 @@ void ath_paprd_calibrate(struct work_struct *work)
int len = 1800;
int ret;

- if (!caldata || !caldata->paprd_packet_sent || caldata->paprd_done)
+ if (!caldata || !caldata->paprd_packet_sent || caldata->paprd_done) {
+ ath_dbg(common, CALIBRATE, "Skipping PAPRD calibration\n");
return;
+ }

ath9k_ps_wakeup(sc);

--
1.8.0.1


2012-12-07 10:02:42

by Sujith Manoharan

[permalink] [raw]
Subject: [RFC 2/8] ath9k_hw: Fix PAPRD training

From: Sujith Manoharan <[email protected]>

The PAPRD training control registers have to be
programmed with values that depend on the chip. This patch
ensures that the correct values are chosen for the chip
in use.

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

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index 0ed3846..2cd23e5 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -204,7 +204,20 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING, 28);
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE, 1);
- val = AR_SREV_9462(ah) ? 0x91 : 147;
+
+ if (AR_SREV_9485(ah)) {
+ val = 148;
+ } else {
+ if (IS_CHAN_2GHZ(ah->curchan)) {
+ if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
+ val = 0x91;
+ else
+ val = 147;
+ } else {
+ val = 137;
+ }
+ }
+
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL2,
AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, val);
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
@@ -215,15 +228,24 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES, 7);
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL, 1);
- if (AR_SREV_9485(ah) || AR_SREV_9462(ah) || AR_SREV_9550(ah))
+
+ if (AR_SREV_9485(ah) ||
+ AR_SREV_9462(ah) ||
+ AR_SREV_9565(ah) ||
+ AR_SREV_9550(ah) ||
+ AR_SREV_9330(ah) ||
+ AR_SREV_9340(ah))
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
- AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
- -3);
+ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -3);
else
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
- AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
- -6);
- val = AR_SREV_9462(ah) ? -10 : -15;
+ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -6);
+
+ val = -10;
+
+ if (IS_CHAN_2GHZ(ah->curchan) && !AR_SREV_9462(ah) && !AR_SREV_9565(ah))
+ val = -15;
+
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE,
val);
--
1.8.0.1