| Index: chromeos/compat-wireless/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
|
| diff --git a/chromeos/compat-wireless/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/chromeos/compat-wireless/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
|
| index 716db414c258f254263a47238f45aa9fd6c2d813..22938f673e9a231f4fa4c85405f32e4240074ff0 100644
|
| --- a/chromeos/compat-wireless/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
|
| +++ b/chromeos/compat-wireless/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));
|
| + }
|
| +
|
| REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0,
|
| AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
|
| REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B1,
|
| @@ -28,10 +42,63 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val)
|
| }
|
| EXPORT_SYMBOL(ar9003_paprd_enable);
|
|
|
| -static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
|
| +static int ar9003_get_training_power_2g(struct ath_hw *ah)
|
| +{
|
| + struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
|
| + struct ar9300_modal_eep_header *hdr = &eep->modalHeader2G;
|
| + unsigned int power, scale, delta;
|
| +
|
| + scale = MS(le32_to_cpu(hdr->papdRateMaskHt20), AR9300_PAPRD_SCALE_1);
|
| + 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;
|
| +
|
| + return power;
|
| +}
|
| +
|
| +static int ar9003_get_training_power_5g(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;
|
| + struct ar9300_modal_eep_header *hdr = &eep->modalHeader5G;
|
| + struct ath9k_channel *chan = ah->curchan;
|
| + unsigned int power, scale, delta;
|
| +
|
| + if (chan->channel >= 5700)
|
| + scale = MS(le32_to_cpu(hdr->papdRateMaskHt20),
|
| + AR9300_PAPRD_SCALE_1);
|
| + else if (chan->channel >= 5400)
|
| + scale = MS(le32_to_cpu(hdr->papdRateMaskHt40),
|
| + AR9300_PAPRD_SCALE_2);
|
| + else
|
| + scale = MS(le32_to_cpu(hdr->papdRateMaskHt40),
|
| + AR9300_PAPRD_SCALE_1);
|
| +
|
| + if (IS_CHAN_HT40(chan))
|
| + power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE8,
|
| + AR_PHY_POWERTX_RATE8_POWERTXHT40_5);
|
| + else
|
| + power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE6,
|
| + AR_PHY_POWERTX_RATE6_POWERTXHT20_5);
|
| +
|
| + power += scale;
|
| + delta = abs((int) ah->paprd_target_power - (int) power);
|
| + if (delta > scale)
|
| + return -1;
|
| +
|
| + power += 2 * get_streams(common->tx_chainmask);
|
| + return power;
|
| +}
|
| +
|
| +static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
|
| +{
|
| + struct ath_common *common = ath9k_hw_common(ah);
|
| const u32 ctrl0[3] = {
|
| AR_PHY_PAPRD_CTRL0_B0,
|
| AR_PHY_PAPRD_CTRL0_B1,
|
| @@ -42,20 +109,30 @@ static void 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;
|
| + if (IS_CHAN_2GHZ(ah->curchan))
|
| + training_power = ar9003_get_training_power_2g(ah);
|
| else
|
| - hdr = &eep->modalHeader2G;
|
| + training_power = ar9003_get_training_power_5g(ah);
|
|
|
| - am_mask = le32_to_cpu(hdr->papdRateMaskHt20);
|
| - ht40_mask = le32_to_cpu(hdr->papdRateMaskHt40);
|
| -
|
| - 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);
|
| + if (training_power < 0) {
|
| + ath_print(common, ATH_DBG_CALIBRATE,
|
| + "PAPRD target power delta out of range");
|
| + return -ERANGE;
|
| + }
|
| + ah->paprd_training_power = training_power;
|
| + ath_print(common, ATH_DBG_CALIBRATE,
|
| + "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,
|
| + 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,
|
| + ah->paprd_ratemask_ht40);
|
|
|
| for (i = 0; i < 3; i++) {
|
| REG_RMW_FIELD(ah, ctrl0[i],
|
| @@ -132,6 +209,7 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
|
| AR_PHY_PAPRD_PRE_POST_SCALING, 185706);
|
| REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_7_B0,
|
| AR_PHY_PAPRD_PRE_POST_SCALING, 175487);
|
| + return 0;
|
| }
|
|
|
| static void ar9003_paprd_get_gain_table(struct ath_hw *ah)
|
| @@ -586,15 +664,10 @@ void ar9003_paprd_populate_single_table(struct ath_hw *ah,
|
| {
|
| u32 *paprd_table_val = caldata->pa_table[chain];
|
| u32 small_signal_gain = caldata->small_signal_gain[chain];
|
| - u32 training_power;
|
| + u32 training_power = ah->paprd_training_power;
|
| u32 reg = 0;
|
| int i;
|
|
|
| - training_power =
|
| - REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
|
| - AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
|
| - training_power -= 4;
|
| -
|
| if (chain == 0)
|
| reg = AR_PHY_PAPRD_MEM_TAB_B0;
|
| else if (chain == 1)
|
| @@ -632,14 +705,8 @@ EXPORT_SYMBOL(ar9003_paprd_populate_single_table);
|
|
|
| int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain)
|
| {
|
| -
|
| unsigned int i, desired_gain, gain_index;
|
| - unsigned int train_power;
|
| -
|
| - train_power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
|
| - AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
|
| -
|
| - train_power = train_power - 4;
|
| + unsigned int train_power = ah->paprd_training_power;
|
|
|
| desired_gain = ar9003_get_desired_gain(ah, chain, train_power);
|
|
|
| @@ -705,7 +772,12 @@ EXPORT_SYMBOL(ar9003_paprd_create_curve);
|
|
|
| int ar9003_paprd_init_table(struct ath_hw *ah)
|
| {
|
| - ar9003_paprd_setup_single_table(ah);
|
| + int ret;
|
| +
|
| + ret = ar9003_paprd_setup_single_table(ah);
|
| + if (ret < 0)
|
| + return ret;
|
| +
|
| ar9003_paprd_get_gain_table(ah);
|
| return 0;
|
| }
|
|
|