aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVasanthakumar Thiagarajan <vasanth@atheros.com>2010-12-15 10:30:53 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-12-16 15:22:31 -0500
commit45ef6a0bcc9cd8f13004789ec6decb52e1d3045c (patch)
tree6191d717a17f9570658852a41b2f8694c1e6d147
parent7072bf62fb7abe5a91389d6271da520f29c79326 (diff)
ath9k_hw: Configure appropriate Tx power when PAPRD fails
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> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c34
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_paprd.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c2
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 0e9ea35f2fb4..f80ec7497d0f 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,
4743 } /* end ctl mode checking */ 4743 } /* end ctl mode checking */
4744} 4744}
4745 4745
4746static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
4747{
4748 u8 mod_idx = mcs_idx % 8;
4749
4750 if (mod_idx <= 3)
4751 return mod_idx ? (base_pwridx + 1) : base_pwridx;
4752 else
4753 return base_pwridx + 4 * (mcs_idx / 8) + mod_idx - 2;
4754}
4755
4746static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, 4756static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
4747 struct ath9k_channel *chan, u16 cfgCtl, 4757 struct ath9k_channel *chan, u16 cfgCtl,
4748 u8 twiceAntennaReduction, 4758 u8 twiceAntennaReduction,
@@ -4755,7 +4765,7 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
4755 u8 targetPowerValT2[ar9300RateSize]; 4765 u8 targetPowerValT2[ar9300RateSize];
4756 u8 target_power_val_t2_eep[ar9300RateSize]; 4766 u8 target_power_val_t2_eep[ar9300RateSize];
4757 unsigned int i = 0, paprd_scale_factor = 0; 4767 unsigned int i = 0, paprd_scale_factor = 0;
4758 u8 pwr_idx, min_pwridx; 4768 u8 pwr_idx, min_pwridx = 0;
4759 4769
4760 ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2); 4770 ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2);
4761 4771
@@ -4771,6 +4781,24 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
4771 le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20)) 4781 le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20))
4772 & AR9300_PAPRD_RATE_MASK; 4782 & AR9300_PAPRD_RATE_MASK;
4773 4783
4784 paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
4785 min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
4786 ALL_TARGET_HT20_0_8_16;
4787
4788 if (!ah->paprd_table_write_done) {
4789 memcpy(target_power_val_t2_eep, targetPowerValT2,
4790 sizeof(targetPowerValT2));
4791 for (i = 0; i < 24; i++) {
4792 pwr_idx = mcsidx_to_tgtpwridx(i, min_pwridx);
4793 if (ah->paprd_ratemask & (1 << i)) {
4794 if (targetPowerValT2[pwr_idx] &&
4795 targetPowerValT2[pwr_idx] ==
4796 target_power_val_t2_eep[pwr_idx])
4797 targetPowerValT2[pwr_idx] -=
4798 paprd_scale_factor;
4799 }
4800 }
4801 }
4774 memcpy(target_power_val_t2_eep, targetPowerValT2, 4802 memcpy(target_power_val_t2_eep, targetPowerValT2,
4775 sizeof(targetPowerValT2)); 4803 sizeof(targetPowerValT2));
4776 } 4804 }
@@ -4782,10 +4810,6 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
4782 powerLimit); 4810 powerLimit);
4783 4811
4784 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) { 4812 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
4785 paprd_scale_factor = ar9003_get_paprd_scale_factor(ah, chan);
4786 min_pwridx = IS_CHAN_HT40(chan) ? ALL_TARGET_HT40_0_8_16 :
4787 ALL_TARGET_HT20_0_8_16;
4788
4789 for (i = 0; i < ar9300RateSize; i++) { 4813 for (i = 0; i < ar9300RateSize; i++) {
4790 if ((ah->paprd_ratemask & (1 << i)) && 4814 if ((ah->paprd_ratemask & (1 << i)) &&
4791 (abs(targetPowerValT2[i] - 4815 (abs(targetPowerValT2[i] -
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index 26cf31cca3ac..79554c524b68 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -19,6 +19,20 @@
19 19
20void ar9003_paprd_enable(struct ath_hw *ah, bool val) 20void ar9003_paprd_enable(struct ath_hw *ah, bool val)
21{ 21{
22 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
23 struct ath9k_channel *chan = ah->curchan;
24
25 if (val) {
26 ah->paprd_table_write_done = true;
27
28 ah->eep_ops->set_txpower(ah, chan,
29 ath9k_regd_get_ctl(regulatory, chan),
30 chan->chan->max_antenna_gain * 2,
31 chan->chan->max_power * 2,
32 min((u32) MAX_RATE_POWER,
33 (u32) regulatory->power_limit), false);
34 }
35
22 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0, 36 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0,
23 AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val); 37 AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
24 if (ah->caps.tx_chainmask & BIT(1)) 38 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 0f373be9ef8c..ddda76fcd180 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,
1272 1272
1273 ath9k_hw_mark_phy_inactive(ah); 1273 ath9k_hw_mark_phy_inactive(ah);
1274 1274
1275 ah->paprd_table_write_done = false;
1276
1275 /* Only required on the first reset */ 1277 /* Only required on the first reset */
1276 if (AR_SREV_9271(ah) && ah->htc_reset_init) { 1278 if (AR_SREV_9271(ah) && ah->htc_reset_init) {
1277 REG_WRITE(ah, 1279 REG_WRITE(ah,
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 3a6101ba9837..21e37d157d3a 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -836,6 +836,7 @@ struct ath_hw {
836 unsigned int paprd_target_power; 836 unsigned int paprd_target_power;
837 unsigned int paprd_training_power; 837 unsigned int paprd_training_power;
838 unsigned int paprd_ratemask; 838 unsigned int paprd_ratemask;
839 bool paprd_table_write_done;
839 u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES]; 840 u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES];
840 u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES]; 841 u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES];
841 /* 842 /*
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 4d647169439c..cb53fbb951f1 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -533,7 +533,7 @@ set_timer:
533 if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) { 533 if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) {
534 if (!ah->caldata->paprd_done) 534 if (!ah->caldata->paprd_done)
535 ieee80211_queue_work(sc->hw, &sc->paprd_work); 535 ieee80211_queue_work(sc->hw, &sc->paprd_work);
536 else 536 else if (!ah->paprd_table_write_done)
537 ath_paprd_activate(sc); 537 ath_paprd_activate(sc);
538 } 538 }
539} 539}