All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.