| Index: chromeos/compat-wireless/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
|
| diff --git a/chromeos/compat-wireless/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/chromeos/compat-wireless/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
|
| index 7a84e1e57b8a0d7c0f9a59a7cd002585d7956b00..654b4f3443f02c2cf5c25f0ea0b8790f1d3571a7 100644
|
| --- a/chromeos/compat-wireless/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
|
| +++ b/chromeos/compat-wireless/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
|
| @@ -4650,6 +4650,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,
|
| @@ -4657,16 +4667,70 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
|
| u8 powerLimit)
|
| {
|
| struct ath_common *common = ath9k_hw_common(ah);
|
| + struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
|
| + struct ar9300_modal_eep_header *modal_hdr;
|
| 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 = 0;
|
|
|
| ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2);
|
| +
|
| + if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
|
| + if (IS_CHAN_2GHZ(chan))
|
| + modal_hdr = &eep->modalHeader2G;
|
| + else
|
| + modal_hdr = &eep->modalHeader5G;
|
| +
|
| + ah->paprd_ratemask =
|
| + le32_to_cpu(modal_hdr->papdRateMaskHt20) &
|
| + AR9300_PAPRD_RATE_MASK;
|
| +
|
| + ah->paprd_ratemask_ht40 =
|
| + le32_to_cpu(modal_hdr->papdRateMaskHt40) &
|
| + 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));
|
| + }
|
| +
|
| ar9003_hw_set_power_per_rate_table(ah, chan,
|
| targetPowerValT2, cfgCtl,
|
| twiceAntennaReduction,
|
| twiceMaxRegulatoryPower,
|
| powerLimit);
|
|
|
| + if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
|
| + 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_print(common, ATH_DBG_EEPROM,
|
| + "paprd disabled for mcs %d\n", i);
|
| + }
|
| + }
|
| + }
|
| +
|
| while (i < ar9300RateSize) {
|
| ath_print(common, ATH_DBG_EEPROM,
|
| "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
|
| @@ -4705,6 +4769,19 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
|
| ah->txpower_limit = targetPowerValT2[i];
|
|
|
| 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];
|
| }
|
|
|
| static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
|
| @@ -4727,6 +4804,27 @@ s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
|
| return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
|
| }
|
|
|
| +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,
|
|
|