* [PATCH 1/7] ath9k_hw: Remove delay during regwrite of analog shift registers
@ 2010-12-15 15:30 Vasanthakumar Thiagarajan
2010-12-15 15:30 ` [PATCH 2/7] ath9k_hw: Remove unnecessary Rx IQ cal register configuration in ar9003_hw_tx_iq_cal() Vasanthakumar Thiagarajan
` (5 more replies)
0 siblings, 6 replies; 8+ messages in thread
From: Vasanthakumar Thiagarajan @ 2010-12-15 15:30 UTC (permalink / raw)
To: linville; +Cc: linux-wireless
This is not needed for AR9003.
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
drivers/net/wireless/ath/ath9k/ar9003_phy.c | 5 +----
1 files changed, 1 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index da4a571..07b44ce 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -578,10 +578,7 @@ static void ar9003_hw_prog_ini(struct ath_hw *ah,
u32 reg = INI_RA(iniArr, i, 0);
u32 val = INI_RA(iniArr, i, column);
- if (reg >= 0x16000 && reg < 0x17000)
- ath9k_hw_analog_shift_regwrite(ah, reg, val);
- else
- REG_WRITE(ah, reg, val);
+ REG_WRITE(ah, reg, val);
DO_DELAY(regWrites);
}
--
1.7.0.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/7] ath9k_hw: Remove unnecessary Rx IQ cal register configuration in ar9003_hw_tx_iq_cal()
2010-12-15 15:30 [PATCH 1/7] ath9k_hw: Remove delay during regwrite of analog shift registers Vasanthakumar Thiagarajan
@ 2010-12-15 15:30 ` Vasanthakumar Thiagarajan
2010-12-15 15:30 ` [PATCH 3/7] ath9k_hw: Move get_streams() to hw.h Vasanthakumar Thiagarajan
` (4 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Vasanthakumar Thiagarajan @ 2010-12-15 15:30 UTC (permalink / raw)
To: linville; +Cc: linux-wireless
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
drivers/net/wireless/ath/ath9k/ar9003_calib.c | 13 -------------
1 files changed, 0 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 7c3334b..75a1c6e 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -616,11 +616,6 @@ static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
AR_PHY_TX_IQCAL_STATUS_B1,
AR_PHY_TX_IQCAL_STATUS_B2,
};
- static const u32 rx_corr[AR9300_MAX_CHAINS] = {
- AR_PHY_RX_IQCAL_CORR_B0,
- AR_PHY_RX_IQCAL_CORR_B1,
- AR_PHY_RX_IQCAL_CORR_B2,
- };
static const u_int32_t chan_info_tab[] = {
AR_PHY_CHAN_INFO_TAB_0,
AR_PHY_CHAN_INFO_TAB_1,
@@ -703,18 +698,10 @@ static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
REG_RMW_FIELD(ah, tx_corr_coeff[i],
AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
iqc_coeff[0]);
- REG_RMW_FIELD(ah, rx_corr[i],
- AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF,
- iqc_coeff[1] >> 7);
- REG_RMW_FIELD(ah, rx_corr[i],
- AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF,
- iqc_coeff[1]);
}
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
- REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
- AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
return;
--
1.7.0.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/7] ath9k_hw: Move get_streams() to hw.h
2010-12-15 15:30 [PATCH 1/7] ath9k_hw: Remove delay during regwrite of analog shift registers Vasanthakumar Thiagarajan
2010-12-15 15:30 ` [PATCH 2/7] ath9k_hw: Remove unnecessary Rx IQ cal register configuration in ar9003_hw_tx_iq_cal() Vasanthakumar Thiagarajan
@ 2010-12-15 15:30 ` Vasanthakumar Thiagarajan
2010-12-15 15:30 ` [PATCH 4/7] ath9k_hw: Tx IQ cal changes for AR9003 Vasanthakumar Thiagarajan
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Vasanthakumar Thiagarajan @ 2010-12-15 15:30 UTC (permalink / raw)
To: linville; +Cc: linux-wireless
This helper can be used in multiple places. Also make
it inline returning u8.
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 5 -----
drivers/net/wireless/ath/ath9k/hw.h | 5 +++++
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index 69f7792..4c74479 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -50,11 +50,6 @@ static int ar9003_get_training_power_2g(struct ath_hw *ah)
return power;
}
-static int get_streams(int mask)
-{
- return !!(mask & BIT(0)) + !!(mask & BIT(1)) + !!(mask & BIT(2));
-}
-
static int ar9003_get_training_power_5g(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 97f22c4..fb64ab8 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -868,6 +868,11 @@ static inline struct ath_hw_ops *ath9k_hw_ops(struct ath_hw *ah)
return &ah->ops;
}
+static inline u8 get_streams(int mask)
+{
+ return !!(mask & BIT(0)) + !!(mask & BIT(1)) + !!(mask & BIT(2));
+}
+
/* Initialization, Detach, Reset */
const char *ath9k_hw_probe(u16 vendorid, u16 devid);
void ath9k_hw_deinit(struct ath_hw *ah);
--
1.7.0.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/7] ath9k_hw: Tx IQ cal changes for AR9003
2010-12-15 15:30 [PATCH 1/7] ath9k_hw: Remove delay during regwrite of analog shift registers Vasanthakumar Thiagarajan
2010-12-15 15:30 ` [PATCH 2/7] ath9k_hw: Remove unnecessary Rx IQ cal register configuration in ar9003_hw_tx_iq_cal() Vasanthakumar Thiagarajan
2010-12-15 15:30 ` [PATCH 3/7] ath9k_hw: Move get_streams() to hw.h Vasanthakumar Thiagarajan
@ 2010-12-15 15:30 ` Vasanthakumar Thiagarajan
2010-12-15 15:30 ` [PATCH 5/7] ath9k_hw: Add a helper to get paprd scale factor Vasanthakumar Thiagarajan
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Vasanthakumar Thiagarajan @ 2010-12-15 15:30 UTC (permalink / raw)
To: linville; +Cc: linux-wireless
Add multiple Tx IQ cal support to improve EVM accross
different power levels.
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
drivers/net/wireless/ath/ath9k/ar9003_calib.c | 212 +++++++++++++------------
1 files changed, 108 insertions(+), 104 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 75a1c6e..4a4cd88 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -608,107 +608,6 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
return true;
}
-static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
-{
- struct ath_common *common = ath9k_hw_common(ah);
- static const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
- AR_PHY_TX_IQCAL_STATUS_B0,
- AR_PHY_TX_IQCAL_STATUS_B1,
- AR_PHY_TX_IQCAL_STATUS_B2,
- };
- static const u_int32_t chan_info_tab[] = {
- AR_PHY_CHAN_INFO_TAB_0,
- AR_PHY_CHAN_INFO_TAB_1,
- AR_PHY_CHAN_INFO_TAB_2,
- };
- u32 tx_corr_coeff[AR9300_MAX_CHAINS];
- s32 iq_res[6];
- s32 iqc_coeff[2];
- s32 i, j;
- u32 num_chains = 0;
-
- tx_corr_coeff[0] = AR_PHY_TX_IQCAL_CORR_COEFF_B0(0);
- tx_corr_coeff[1] = AR_PHY_TX_IQCAL_CORR_COEFF_B1(0);
- tx_corr_coeff[2] = AR_PHY_TX_IQCAL_CORR_COEFF_B2(0);
-
- for (i = 0; i < AR9300_MAX_CHAINS; i++) {
- if (ah->txchainmask & (1 << i))
- num_chains++;
- }
-
- REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
- AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
- DELPT);
- REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
- AR_PHY_TX_IQCAL_START_DO_CAL,
- AR_PHY_TX_IQCAL_START_DO_CAL);
-
- if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
- AR_PHY_TX_IQCAL_START_DO_CAL,
- 0, AH_WAIT_TIMEOUT)) {
- ath_dbg(common, ATH_DBG_CALIBRATE,
- "Tx IQ Cal not complete.\n");
- goto TX_IQ_CAL_FAILED;
- }
-
- for (i = 0; i < num_chains; i++) {
- ath_dbg(common, ATH_DBG_CALIBRATE,
- "Doing Tx IQ Cal for chain %d.\n", i);
-
- if (REG_READ(ah, txiqcal_status[i]) &
- AR_PHY_TX_IQCAL_STATUS_FAILED) {
- ath_dbg(common, ATH_DBG_CALIBRATE,
- "Tx IQ Cal failed for chain %d.\n", i);
- goto TX_IQ_CAL_FAILED;
- }
-
- for (j = 0; j < 3; j++) {
- u_int8_t idx = 2 * j,
- offset = 4 * j;
-
- REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
- AR_PHY_CHAN_INFO_TAB_S2_READ, 0);
-
- /* 32 bits */
- iq_res[idx] = REG_READ(ah, chan_info_tab[i] + offset);
-
- REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
- AR_PHY_CHAN_INFO_TAB_S2_READ, 1);
-
- /* 16 bits */
- iq_res[idx+1] = 0xffff & REG_READ(ah,
- chan_info_tab[i] +
- offset);
-
- ath_dbg(common, ATH_DBG_CALIBRATE,
- "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
- idx, iq_res[idx], idx+1, iq_res[idx+1]);
- }
-
- if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, iqc_coeff)) {
- ath_dbg(common, ATH_DBG_CALIBRATE,
- "Failed in calculation of IQ correction.\n");
- goto TX_IQ_CAL_FAILED;
- }
-
- ath_dbg(common, ATH_DBG_CALIBRATE,
- "IQ_COEFF[0] = 0x%x IQ_COEFF[1] = 0x%x\n",
- iqc_coeff[0], iqc_coeff[1]);
-
- REG_RMW_FIELD(ah, tx_corr_coeff[i],
- AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
- iqc_coeff[0]);
- }
-
- REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
- AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
-
- return;
-
-TX_IQ_CAL_FAILED:
- ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
-}
-
static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg)
{
int diff[MPASS];
@@ -717,9 +616,9 @@ static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg)
diff[1] = abs(mp_coeff[1] - mp_coeff[2]);
diff[2] = abs(mp_coeff[2] - mp_coeff[0]);
- if (diff[0] > MAX_MEASUREMENT &&
- diff[1] > MAX_MEASUREMENT &&
- diff[2] > MAX_MEASUREMENT)
+ if (diff[0] > MAX_DIFFERENCE &&
+ diff[1] > MAX_DIFFERENCE &&
+ diff[2] > MAX_DIFFERENCE)
return false;
if (diff[0] <= diff[1] && diff[0] <= diff[2])
@@ -817,6 +716,111 @@ disable_txiqcal:
ath_dbg(common, ATH_DBG_CALIBRATE, "TX IQ Cal disabled\n");
}
+static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
+{
+ struct ath_common *common = ath9k_hw_common(ah);
+ static const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
+ AR_PHY_TX_IQCAL_STATUS_B0,
+ AR_PHY_TX_IQCAL_STATUS_B1,
+ AR_PHY_TX_IQCAL_STATUS_B2,
+ };
+ static const u32 chan_info_tab[] = {
+ AR_PHY_CHAN_INFO_TAB_0,
+ AR_PHY_CHAN_INFO_TAB_1,
+ AR_PHY_CHAN_INFO_TAB_2,
+ };
+ struct coeff coeff;
+ s32 iq_res[6];
+ s32 i, j, ip, im, nmeasurement;
+ u8 nchains = get_streams(common->tx_chainmask);
+
+ for (ip = 0; ip < MPASS; ip++) {
+ REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
+ AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
+ DELPT);
+ REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
+ AR_PHY_TX_IQCAL_START_DO_CAL,
+ AR_PHY_TX_IQCAL_START_DO_CAL);
+
+ if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
+ AR_PHY_TX_IQCAL_START_DO_CAL,
+ 0, AH_WAIT_TIMEOUT)) {
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Tx IQ Cal not complete.\n");
+ goto TX_IQ_CAL_FAILED;
+ }
+
+ nmeasurement = REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_STATUS_B0,
+ AR_PHY_CALIBRATED_GAINS_0);
+ if (nmeasurement > MAX_MEASUREMENT)
+ nmeasurement = MAX_MEASUREMENT;
+
+ for (i = 0; i < nchains; i++) {
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Doing Tx IQ Cal for chain %d.\n", i);
+ for (im = 0; im < nmeasurement; im++) {
+ if (REG_READ(ah, txiqcal_status[i]) &
+ AR_PHY_TX_IQCAL_STATUS_FAILED) {
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Tx IQ Cal failed for chain %d.\n", i);
+ goto TX_IQ_CAL_FAILED;
+ }
+
+ for (j = 0; j < 3; j++) {
+ u8 idx = 2 * j,
+ offset = 4 * (3 * im + j);
+
+ REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
+ AR_PHY_CHAN_INFO_TAB_S2_READ,
+ 0);
+
+ /* 32 bits */
+ iq_res[idx] = REG_READ(ah,
+ chan_info_tab[i] +
+ offset);
+
+ REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
+ AR_PHY_CHAN_INFO_TAB_S2_READ,
+ 1);
+
+ /* 16 bits */
+ iq_res[idx+1] = 0xffff & REG_READ(ah,
+ chan_info_tab[i] +
+ offset);
+
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
+ idx, iq_res[idx], idx+1, iq_res[idx+1]);
+ }
+
+ if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
+ coeff.iqc_coeff)) {
+ ath_dbg(common, ATH_DBG_CALIBRATE,
+ "Failed in calculation of IQ correction.\n");
+ goto TX_IQ_CAL_FAILED;
+ }
+ coeff.mag_coeff[i][im][ip] =
+ coeff.iqc_coeff[0] & 0x7f;
+ coeff.phs_coeff[i][im][ip] =
+ (coeff.iqc_coeff[0] >> 7) & 0x7f;
+
+ if (coeff.mag_coeff[i][im][ip] > 63)
+ coeff.mag_coeff[i][im][ip] -= 128;
+ if (coeff.phs_coeff[i][im][ip] > 63)
+ coeff.phs_coeff[i][im][ip] -= 128;
+
+ }
+ }
+ }
+
+ ar9003_hw_tx_iqcal_load_avg_2_passes(ah, nchains, &coeff);
+
+ return;
+
+TX_IQ_CAL_FAILED:
+ ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
+}
+
static void ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
{
u8 tx_gain_forced;
--
1.7.0.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5/7] ath9k_hw: Add a helper to get paprd scale factor
2010-12-15 15:30 [PATCH 1/7] ath9k_hw: Remove delay during regwrite of analog shift registers Vasanthakumar Thiagarajan
` (2 preceding siblings ...)
2010-12-15 15:30 ` [PATCH 4/7] ath9k_hw: Tx IQ cal changes for AR9003 Vasanthakumar Thiagarajan
@ 2010-12-15 15:30 ` Vasanthakumar Thiagarajan
2010-12-15 15:30 ` [PATCH 6/7] ath9k_hw: Disable PAPRD for rates with low Tx power Vasanthakumar Thiagarajan
2010-12-15 15:30 ` [PATCH 7/7] ath9k_hw: Configure appropriate Tx power when PAPRD fails Vasanthakumar Thiagarajan
5 siblings, 0 replies; 8+ messages in thread
From: Vasanthakumar Thiagarajan @ 2010-12-15 15:30 UTC (permalink / raw)
To: linville; +Cc: linux-wireless
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 21 +++++++++++++++++++++
drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 3 +++
2 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 4149ffb..9fa5793 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -4843,6 +4843,27 @@ u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz)
return eep->modalHeader5G.spurChans;
}
+unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
+ struct ath9k_channel *chan)
+{
+ struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
+
+ if (IS_CHAN_2GHZ(chan))
+ return MS(le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20),
+ AR9300_PAPRD_SCALE_1);
+ else {
+ if (chan->channel >= 5700)
+ return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20),
+ AR9300_PAPRD_SCALE_1);
+ else if (chan->channel >= 5400)
+ return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
+ AR9300_PAPRD_SCALE_2);
+ else
+ return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
+ AR9300_PAPRD_SCALE_1);
+ }
+}
+
const struct eeprom_ops eep_ar9300_ops = {
.check_eeprom = ath9k_hw_ar9300_check_eeprom,
.get_eeprom = ath9k_hw_ar9300_get_eeprom,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
index efb6a02..afb0b5e 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -315,4 +315,7 @@ s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah);
s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah);
u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz);
+
+unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
+ struct ath9k_channel *chan);
#endif
--
1.7.0.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6/7] ath9k_hw: Disable PAPRD for rates with low Tx power
2010-12-15 15:30 [PATCH 1/7] ath9k_hw: Remove delay during regwrite of analog shift registers Vasanthakumar Thiagarajan
` (3 preceding siblings ...)
2010-12-15 15:30 ` [PATCH 5/7] ath9k_hw: Add a helper to get paprd scale factor Vasanthakumar Thiagarajan
@ 2010-12-15 15:30 ` Vasanthakumar Thiagarajan
2010-12-15 15:30 ` [PATCH 7/7] ath9k_hw: Configure appropriate Tx power when PAPRD fails Vasanthakumar Thiagarajan
5 siblings, 0 replies; 8+ messages in thread
From: Vasanthakumar Thiagarajan @ 2010-12-15 15:30 UTC (permalink / raw)
To: linville; +Cc: linux-wireless
When the drop in Tx power for a particular mcs rate exceeds
the paprd scale factor, paprd may not work properly. Disable
paprd for any such rates.
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 39 +++++++++++++++++++++++-
drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 20 ++++--------
drivers/net/wireless/ath/ath9k/hw.h | 1 +
3 files changed, 45 insertions(+), 15 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 9fa5793..0e9ea35 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -4751,16 +4751,53 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
{
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
struct ath_common *common = ath9k_hw_common(ah);
+ struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
u8 targetPowerValT2[ar9300RateSize];
- unsigned int i = 0;
+ u8 target_power_val_t2_eep[ar9300RateSize];
+ unsigned int i = 0, paprd_scale_factor = 0;
+ u8 pwr_idx, min_pwridx;
ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2);
+
+ if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
+ if (IS_CHAN_2GHZ(chan))
+ ah->paprd_ratemask = (IS_CHAN_HT40(chan) ?
+ le32_to_cpu(eep->modalHeader2G.papdRateMaskHt40) :
+ le32_to_cpu(eep->modalHeader2G.papdRateMaskHt20))
+ & AR9300_PAPRD_RATE_MASK;
+ else
+ ah->paprd_ratemask = (IS_CHAN_HT40(chan) ?
+ le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40) :
+ le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20))
+ & AR9300_PAPRD_RATE_MASK;
+
+ memcpy(target_power_val_t2_eep, targetPowerValT2,
+ sizeof(targetPowerValT2));
+ }
+
ar9003_hw_set_power_per_rate_table(ah, chan,
targetPowerValT2, cfgCtl,
twiceAntennaReduction,
twiceMaxRegulatoryPower,
powerLimit);
+ if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
+ paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
+ min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
+ ALL_TARGET_HT20_0_8_16;
+
+ for (i = 0; i < ar9300RateSize; i++) {
+ if ((ah->paprd_ratemask & (1 << i)) &&
+ (abs(targetPowerValT2[i] -
+ target_power_val_t2_eep[i]) >
+ paprd_scale_factor)) {
+ ah->paprd_ratemask &= ~(1 << i);
+ ath_dbg(common, ATH_DBG_EEPROM,
+ "paprd disabled for mcs %d\n", i);
+ }
+ }
+ }
+
regulatory->max_power_level = 0;
for (i = 0; i < ar9300RateSize; i++) {
if (targetPowerValT2[i] > regulatory->max_power_level)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index 4c74479..26cf31c 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -87,8 +87,6 @@ static int ar9003_get_training_power_5g(struct ath_hw *ah)
static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
- struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
- struct ar9300_modal_eep_header *hdr;
static const u32 ctrl0[3] = {
AR_PHY_PAPRD_CTRL0_B0,
AR_PHY_PAPRD_CTRL0_B1,
@@ -99,18 +97,9 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
AR_PHY_PAPRD_CTRL1_B1,
AR_PHY_PAPRD_CTRL1_B2
};
- u32 am_mask, ht40_mask;
int training_power;
int i;
- if (ah->curchan && IS_CHAN_5GHZ(ah->curchan))
- hdr = &eep->modalHeader5G;
- else
- hdr = &eep->modalHeader2G;
-
- am_mask = le32_to_cpu(hdr->papdRateMaskHt20) & AR9300_PAPRD_RATE_MASK;
- ht40_mask = le32_to_cpu(hdr->papdRateMaskHt40) & AR9300_PAPRD_RATE_MASK;
-
if (IS_CHAN_2GHZ(ah->curchan))
training_power = ar9003_get_training_power_2g(ah);
else
@@ -126,9 +115,12 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
"Training power: %d, Target power: %d\n",
ah->paprd_training_power, ah->paprd_target_power);
- REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, am_mask);
- REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask);
- REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, ht40_mask);
+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK,
+ ah->paprd_ratemask);
+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK,
+ ah->paprd_ratemask);
+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK,
+ AR_PHY_PAPRD_HT40_MASK);
for (i = 0; i < ah->caps.max_txchains; i++) {
REG_RMW_FIELD(ah, ctrl0[i],
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index fb64ab8..3a6101b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -835,6 +835,7 @@ struct ath_hw {
unsigned int paprd_target_power;
unsigned int paprd_training_power;
+ unsigned int paprd_ratemask;
u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES];
u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES];
/*
--
1.7.0.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 7/7] ath9k_hw: Configure appropriate Tx power when PAPRD fails
2010-12-15 15:30 [PATCH 1/7] ath9k_hw: Remove delay during regwrite of analog shift registers Vasanthakumar Thiagarajan
` (4 preceding siblings ...)
2010-12-15 15:30 ` [PATCH 6/7] ath9k_hw: Disable PAPRD for rates with low Tx power Vasanthakumar Thiagarajan
@ 2010-12-15 15:30 ` Vasanthakumar Thiagarajan
2010-12-15 17:45 ` Luis R. Rodriguez
5 siblings, 1 reply; 8+ messages in thread
From: Vasanthakumar Thiagarajan @ 2010-12-15 15:30 UTC (permalink / raw)
To: linville; +Cc: linux-wireless
Target Tx power available in eeprom is for PAPRD. If PAPRD
fails, paprd scale factor needs to be detected from this
target tx power.
Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
---
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 34 ++++++++++++++++++++---
drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 14 ++++++++++
drivers/net/wireless/ath/ath9k/hw.c | 2 +
drivers/net/wireless/ath/ath9k/hw.h | 1 +
drivers/net/wireless/ath/ath9k/main.c | 2 +-
5 files changed, 47 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 0e9ea35..f80ec74 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -4743,6 +4743,16 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
} /* end ctl mode checking */
}
+static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
+{
+ u8 mod_idx = mcs_idx % 8;
+
+ if (mod_idx <= 3)
+ return mod_idx ? (base_pwridx + 1) : base_pwridx;
+ else
+ return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
+}
+
static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
struct ath9k_channel *chan, u16 cfgCtl,
u8 twiceAntennaReduction,
@@ -4755,7 +4765,7 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
u8 targetPowerValT2[ar9300RateSize];
u8 target_power_val_t2_eep[ar9300RateSize];
unsigned int i = 0, paprd_scale_factor = 0;
- u8 pwr_idx, min_pwridx;
+ u8 pwr_idx, min_pwridx = 0;
ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2);
@@ -4771,6 +4781,24 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20))
& AR9300_PAPRD_RATE_MASK;
+ paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
+ min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
+ ALL_TARGET_HT20_0_8_16;
+
+ if (!ah->paprd_table_write_done) {
+ memcpy(target_power_val_t2_eep, targetPowerValT2,
+ sizeof(targetPowerValT2));
+ for (i = 0; i < 24; i++) {
+ pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx);
+ if (ah->paprd_ratemask & (1 << i)) {
+ if (targetPowerValT2[pwr_idx] &&
+ targetPowerValT2[pwr_idx] ==
+ target_power_val_t2_eep[pwr_idx])
+ targetPowerValT2[pwr_idx] -=
+ paprd_scale_factor;
+ }
+ }
+ }
memcpy(target_power_val_t2_eep, targetPowerValT2,
sizeof(targetPowerValT2));
}
@@ -4782,10 +4810,6 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
powerLimit);
if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
- paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
- min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
- ALL_TARGET_HT20_0_8_16;
-
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 26cf31c..79554c5 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -19,6 +19,20 @@
void ar9003_paprd_enable(struct ath_hw *ah, bool val)
{
+ struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+ struct ath9k_channel *chan = ah->curchan;
+
+ if (val) {
+ ah->paprd_table_write_done = true;
+
+ ah->eep_ops->set_txpower(ah, chan,
+ ath9k_regd_get_ctl(regulatory, chan),
+ chan->chan->max_antenna_gain * 2,
+ chan->chan->max_power * 2,
+ min((u32) MAX_RATE_POWER,
+ (u32) regulatory->power_limit), false);
+ }
+
REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0,
AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
if (ah->caps.tx_chainmask & BIT(1))
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 0f373be..ddda76f 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1272,6 +1272,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
ath9k_hw_mark_phy_inactive(ah);
+ ah->paprd_table_write_done = false;
+
/* Only required on the first reset */
if (AR_SREV_9271(ah) && ah->htc_reset_init) {
REG_WRITE(ah,
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 3a6101b..21e37d1 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -836,6 +836,7 @@ struct ath_hw {
unsigned int paprd_target_power;
unsigned int paprd_training_power;
unsigned int paprd_ratemask;
+ bool paprd_table_write_done;
u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES];
u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES];
/*
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index c68205d..d5fd9d1 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -533,7 +533,7 @@ set_timer:
if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) {
if (!ah->caldata->paprd_done)
ieee80211_queue_work(sc->hw, &sc->paprd_work);
- else
+ else if (!ah->paprd_table_write_done)
ath_paprd_activate(sc);
}
}
--
1.7.0.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 7/7] ath9k_hw: Configure appropriate Tx power when PAPRD fails
2010-12-15 15:30 ` [PATCH 7/7] ath9k_hw: Configure appropriate Tx power when PAPRD fails Vasanthakumar Thiagarajan
@ 2010-12-15 17:45 ` Luis R. Rodriguez
0 siblings, 0 replies; 8+ messages in thread
From: Luis R. Rodriguez @ 2010-12-15 17:45 UTC (permalink / raw)
To: Vasanthakumar Thiagarajan; +Cc: linville, linux-wireless
On Wed, Dec 15, 2010 at 7:30 AM, Vasanthakumar Thiagarajan
<vasanth@atheros.com> wrote:
> Target Tx power available in eeprom is for PAPRD. If PAPRD
> fails, paprd scale factor needs to be detected from this
> target tx power.
>
> Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com>
> ---
> drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 34 ++++++++++++++++++++---
> drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 14 ++++++++++
> drivers/net/wireless/ath/ath9k/hw.c | 2 +
> drivers/net/wireless/ath/ath9k/hw.h | 1 +
> drivers/net/wireless/ath/ath9k/main.c | 2 +-
> 5 files changed, 47 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
> index 0e9ea35..f80ec74 100644
> --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
> +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
> @@ -4743,6 +4743,16 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
> } /* end ctl mode checking */
> }
>
> +static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
> +{
No need to inline as its used only once so gcc will do that for you anyway.
Luis
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-12-15 17:46 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-15 15:30 [PATCH 1/7] ath9k_hw: Remove delay during regwrite of analog shift registers Vasanthakumar Thiagarajan
2010-12-15 15:30 ` [PATCH 2/7] ath9k_hw: Remove unnecessary Rx IQ cal register configuration in ar9003_hw_tx_iq_cal() Vasanthakumar Thiagarajan
2010-12-15 15:30 ` [PATCH 3/7] ath9k_hw: Move get_streams() to hw.h Vasanthakumar Thiagarajan
2010-12-15 15:30 ` [PATCH 4/7] ath9k_hw: Tx IQ cal changes for AR9003 Vasanthakumar Thiagarajan
2010-12-15 15:30 ` [PATCH 5/7] ath9k_hw: Add a helper to get paprd scale factor Vasanthakumar Thiagarajan
2010-12-15 15:30 ` [PATCH 6/7] ath9k_hw: Disable PAPRD for rates with low Tx power Vasanthakumar Thiagarajan
2010-12-15 15:30 ` [PATCH 7/7] ath9k_hw: Configure appropriate Tx power when PAPRD fails Vasanthakumar Thiagarajan
2010-12-15 17:45 ` Luis R. Rodriguez
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.