aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c39
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_paprd.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c27
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c33
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c43
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c63
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h9
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c2
13 files changed, 85 insertions, 176 deletions
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 4ed7f248a577..bb71b4f27a9b 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -71,7 +71,6 @@ struct ath_regulatory {
71 char alpha2[2]; 71 char alpha2[2];
72 u16 country_code; 72 u16 country_code;
73 u16 max_power_level; 73 u16 max_power_level;
74 u32 tp_scale;
75 u16 current_rd; 74 u16 current_rd;
76 u16 current_rd_ext; 75 u16 current_rd_ext;
77 int16_t power_limit; 76 int16_t power_limit;
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 0a749c8fa634..f199e9e25149 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -763,10 +763,8 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah,
763static int ar5008_hw_process_ini(struct ath_hw *ah, 763static int ar5008_hw_process_ini(struct ath_hw *ah,
764 struct ath9k_channel *chan) 764 struct ath9k_channel *chan)
765{ 765{
766 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
767 struct ath_common *common = ath9k_hw_common(ah); 766 struct ath_common *common = ath9k_hw_common(ah);
768 int i, regWrites = 0; 767 int i, regWrites = 0;
769 struct ieee80211_channel *channel = chan->chan;
770 u32 modesIndex, freqIndex; 768 u32 modesIndex, freqIndex;
771 769
772 switch (chan->chanmode) { 770 switch (chan->chanmode) {
@@ -903,14 +901,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
903 ar5008_hw_set_channel_regs(ah, chan); 901 ar5008_hw_set_channel_regs(ah, chan);
904 ar5008_hw_init_chain_masks(ah); 902 ar5008_hw_init_chain_masks(ah);
905 ath9k_olc_init(ah); 903 ath9k_olc_init(ah);
906 904 ath9k_hw_apply_txpower(ah, chan);
907 /* Set TX power */
908 ah->eep_ops->set_txpower(ah, chan,
909 ath9k_regd_get_ctl(regulatory, chan),
910 channel->max_antenna_gain * 2,
911 channel->max_power * 2,
912 min((u32) MAX_RATE_POWER,
913 (u32) regulatory->power_limit), false);
914 905
915 /* Write analog registers */ 906 /* Write analog registers */
916 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { 907 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 51398f0063e2..d7a5ca722548 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3021,6 +3021,10 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
3021 return (pBase->miscConfiguration >> 0x3) & 0x1; 3021 return (pBase->miscConfiguration >> 0x3) & 0x1;
3022 case EEP_ANT_DIV_CTL1: 3022 case EEP_ANT_DIV_CTL1:
3023 return eep->base_ext1.ant_div_control; 3023 return eep->base_ext1.ant_div_control;
3024 case EEP_ANTENNA_GAIN_5G:
3025 return eep->modalHeader5G.antennaGain;
3026 case EEP_ANTENNA_GAIN_2G:
3027 return eep->modalHeader2G.antennaGain;
3024 default: 3028 default:
3025 return 0; 3029 return 0;
3026 } 3030 }
@@ -4764,20 +4768,14 @@ static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
4764static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, 4768static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
4765 struct ath9k_channel *chan, 4769 struct ath9k_channel *chan,
4766 u8 *pPwrArray, u16 cfgCtl, 4770 u8 *pPwrArray, u16 cfgCtl,
4767 u8 twiceAntennaReduction, 4771 u8 antenna_reduction,
4768 u8 twiceMaxRegulatoryPower,
4769 u16 powerLimit) 4772 u16 powerLimit)
4770{ 4773{
4771 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
4772 struct ath_common *common = ath9k_hw_common(ah); 4774 struct ath_common *common = ath9k_hw_common(ah);
4773 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep; 4775 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
4774 u16 twiceMaxEdgePower = MAX_RATE_POWER; 4776 u16 twiceMaxEdgePower = MAX_RATE_POWER;
4775 static const u16 tpScaleReductionTable[5] = {
4776 0, 3, 6, 9, MAX_RATE_POWER
4777 };
4778 int i; 4777 int i;
4779 int16_t twiceLargestAntenna; 4778 u16 scaledPower = 0, minCtlPower;
4780 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
4781 static const u16 ctlModesFor11a[] = { 4779 static const u16 ctlModesFor11a[] = {
4782 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 4780 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
4783 }; 4781 };
@@ -4795,28 +4793,7 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
4795 bool is2ghz = IS_CHAN_2GHZ(chan); 4793 bool is2ghz = IS_CHAN_2GHZ(chan);
4796 4794
4797 ath9k_hw_get_channel_centers(ah, chan, &centers); 4795 ath9k_hw_get_channel_centers(ah, chan, &centers);
4798 4796 scaledPower = powerLimit - antenna_reduction;
4799 /* Compute TxPower reduction due to Antenna Gain */
4800 if (is2ghz)
4801 twiceLargestAntenna = pEepData->modalHeader2G.antennaGain;
4802 else
4803 twiceLargestAntenna = pEepData->modalHeader5G.antennaGain;
4804
4805 twiceLargestAntenna = (int16_t)min((twiceAntennaReduction) -
4806 twiceLargestAntenna, 0);
4807
4808 /*
4809 * scaledPower is the minimum of the user input power level
4810 * and the regulatory allowed power level
4811 */
4812 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
4813
4814 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
4815 maxRegAllowedPower -=
4816 (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
4817 }
4818
4819 scaledPower = min(powerLimit, maxRegAllowedPower);
4820 4797
4821 /* 4798 /*
4822 * Reduce scaled Power by number of chains active to get 4799 * Reduce scaled Power by number of chains active to get
@@ -5003,7 +4980,6 @@ static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
5003static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, 4980static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
5004 struct ath9k_channel *chan, u16 cfgCtl, 4981 struct ath9k_channel *chan, u16 cfgCtl,
5005 u8 twiceAntennaReduction, 4982 u8 twiceAntennaReduction,
5006 u8 twiceMaxRegulatoryPower,
5007 u8 powerLimit, bool test) 4983 u8 powerLimit, bool test)
5008{ 4984{
5009 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 4985 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
@@ -5056,7 +5032,6 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
5056 ar9003_hw_set_power_per_rate_table(ah, chan, 5032 ar9003_hw_set_power_per_rate_table(ah, chan,
5057 targetPowerValT2, cfgCtl, 5033 targetPowerValT2, cfgCtl,
5058 twiceAntennaReduction, 5034 twiceAntennaReduction,
5059 twiceMaxRegulatoryPower,
5060 powerLimit); 5035 powerLimit);
5061 5036
5062 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) { 5037 if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index 609acb2b504f..a1a08b31b33d 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -19,7 +19,6 @@
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; 22 struct ath9k_channel *chan = ah->curchan;
24 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 23 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
25 24
@@ -54,13 +53,7 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val)
54 53
55 if (val) { 54 if (val) {
56 ah->paprd_table_write_done = true; 55 ah->paprd_table_write_done = true;
57 56 ath9k_hw_apply_txpower(ah, chan);
58 ah->eep_ops->set_txpower(ah, chan,
59 ath9k_regd_get_ctl(regulatory, chan),
60 chan->chan->max_antenna_gain * 2,
61 chan->chan->max_power * 2,
62 min((u32) MAX_RATE_POWER,
63 (u32) regulatory->power_limit), false);
64 } 57 }
65 58
66 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0, 59 REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 7db6e8647a01..779f407222ed 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -631,9 +631,7 @@ static void ar9003_hw_prog_ini(struct ath_hw *ah,
631static int ar9003_hw_process_ini(struct ath_hw *ah, 631static int ar9003_hw_process_ini(struct ath_hw *ah,
632 struct ath9k_channel *chan) 632 struct ath9k_channel *chan)
633{ 633{
634 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
635 unsigned int regWrites = 0, i; 634 unsigned int regWrites = 0, i;
636 struct ieee80211_channel *channel = chan->chan;
637 u32 modesIndex; 635 u32 modesIndex;
638 636
639 switch (chan->chanmode) { 637 switch (chan->chanmode) {
@@ -693,14 +691,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
693 ar9003_hw_override_ini(ah); 691 ar9003_hw_override_ini(ah);
694 ar9003_hw_set_channel_regs(ah, chan); 692 ar9003_hw_set_channel_regs(ah, chan);
695 ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); 693 ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
696 694 ath9k_hw_apply_txpower(ah, chan);
697 /* Set TX power */
698 ah->eep_ops->set_txpower(ah, chan,
699 ath9k_regd_get_ctl(regulatory, chan),
700 channel->max_antenna_gain * 2,
701 channel->max_power * 2,
702 min((u32) MAX_RATE_POWER,
703 (u32) regulatory->power_limit), false);
704 695
705 return 0; 696 return 0;
706} 697}
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index dc705a224952..905f1b313961 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -161,10 +161,12 @@ EXPORT_SYMBOL(ath9k_cmn_count_streams);
161void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow, 161void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
162 u16 new_txpow, u16 *txpower) 162 u16 new_txpow, u16 *txpower)
163{ 163{
164 if (cur_txpow != new_txpow) { 164 struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
165
166 if (reg->power_limit != new_txpow) {
165 ath9k_hw_set_txpowerlimit(ah, new_txpow, false); 167 ath9k_hw_set_txpowerlimit(ah, new_txpow, false);
166 /* read back in case value is clamped */ 168 /* read back in case value is clamped */
167 *txpower = ath9k_hw_regulatory(ah)->power_limit; 169 *txpower = reg->max_power_level;
168 } 170 }
169} 171}
170EXPORT_SYMBOL(ath9k_cmn_update_txpow); 172EXPORT_SYMBOL(ath9k_cmn_update_txpow);
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 5d92f96980e6..909a224fb650 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -248,7 +248,9 @@ enum eeprom_param {
248 EEP_PAPRD, 248 EEP_PAPRD,
249 EEP_MODAL_VER, 249 EEP_MODAL_VER,
250 EEP_ANT_DIV_CTL1, 250 EEP_ANT_DIV_CTL1,
251 EEP_CHAIN_MASK_REDUCE 251 EEP_CHAIN_MASK_REDUCE,
252 EEP_ANTENNA_GAIN_2G,
253 EEP_ANTENNA_GAIN_5G
252}; 254};
253 255
254enum ar5416_rates { 256enum ar5416_rates {
@@ -652,8 +654,7 @@ struct eeprom_ops {
652 void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan); 654 void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
653 void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan, 655 void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
654 u16 cfgCtl, u8 twiceAntennaReduction, 656 u16 cfgCtl, u8 twiceAntennaReduction,
655 u8 twiceMaxRegulatoryPower, u8 powerLimit, 657 u8 powerLimit, bool test);
656 bool test);
657 u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz); 658 u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
658}; 659};
659 660
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 303560e49ac8..ab6811dc5deb 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -350,6 +350,8 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
350 return pModal->antdiv_ctl1; 350 return pModal->antdiv_ctl1;
351 case EEP_TXGAIN_TYPE: 351 case EEP_TXGAIN_TYPE:
352 return pBase->txGainType; 352 return pBase->txGainType;
353 case EEP_ANTENNA_GAIN_2G:
354 return pModal->antennaGainCh[0];
353 default: 355 default:
354 return 0; 356 return 0;
355 } 357 }
@@ -462,8 +464,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
462 struct ath9k_channel *chan, 464 struct ath9k_channel *chan,
463 int16_t *ratesArray, 465 int16_t *ratesArray,
464 u16 cfgCtl, 466 u16 cfgCtl,
465 u16 AntennaReduction, 467 u16 antenna_reduction,
466 u16 twiceMaxRegulatoryPower,
467 u16 powerLimit) 468 u16 powerLimit)
468{ 469{
469#define CMP_TEST_GRP \ 470#define CMP_TEST_GRP \
@@ -472,20 +473,16 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
472 || (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \ 473 || (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
473 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL)) 474 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))
474 475
475 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
476 int i; 476 int i;
477 int16_t twiceLargestAntenna;
478 u16 twiceMinEdgePower; 477 u16 twiceMinEdgePower;
479 u16 twiceMaxEdgePower = MAX_RATE_POWER; 478 u16 twiceMaxEdgePower = MAX_RATE_POWER;
480 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; 479 u16 scaledPower = 0, minCtlPower;
481 u16 numCtlModes; 480 u16 numCtlModes;
482 const u16 *pCtlMode; 481 const u16 *pCtlMode;
483 u16 ctlMode, freq; 482 u16 ctlMode, freq;
484 struct chan_centers centers; 483 struct chan_centers centers;
485 struct cal_ctl_data_4k *rep; 484 struct cal_ctl_data_4k *rep;
486 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; 485 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
487 static const u16 tpScaleReductionTable[5] =
488 { 0, 3, 6, 9, MAX_RATE_POWER };
489 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = { 486 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
490 0, { 0, 0, 0, 0} 487 0, { 0, 0, 0, 0}
491 }; 488 };
@@ -503,19 +500,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
503 500
504 ath9k_hw_get_channel_centers(ah, chan, &centers); 501 ath9k_hw_get_channel_centers(ah, chan, &centers);
505 502
506 twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0]; 503 scaledPower = powerLimit - antenna_reduction;
507 twiceLargestAntenna = (int16_t)min(AntennaReduction -
508 twiceLargestAntenna, 0);
509
510 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
511 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
512 maxRegAllowedPower -=
513 (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
514 }
515
516 scaledPower = min(powerLimit, maxRegAllowedPower);
517 scaledPower = max((u16)0, scaledPower);
518
519 numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; 504 numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
520 pCtlMode = ctlModesFor11g; 505 pCtlMode = ctlModesFor11g;
521 506
@@ -671,7 +656,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
671 struct ath9k_channel *chan, 656 struct ath9k_channel *chan,
672 u16 cfgCtl, 657 u16 cfgCtl,
673 u8 twiceAntennaReduction, 658 u8 twiceAntennaReduction,
674 u8 twiceMaxRegulatoryPower,
675 u8 powerLimit, bool test) 659 u8 powerLimit, bool test)
676{ 660{
677 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 661 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
@@ -691,7 +675,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
691 ath9k_hw_set_4k_power_per_rate_table(ah, chan, 675 ath9k_hw_set_4k_power_per_rate_table(ah, chan,
692 &ratesArray[0], cfgCtl, 676 &ratesArray[0], cfgCtl,
693 twiceAntennaReduction, 677 twiceAntennaReduction,
694 twiceMaxRegulatoryPower,
695 powerLimit); 678 powerLimit);
696 679
697 ath9k_hw_set_4k_power_cal_table(ah, chan); 680 ath9k_hw_set_4k_power_cal_table(ah, chan);
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index 6698b722b604..90d771fa2dea 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -336,6 +336,9 @@ static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah,
336 return pBase->tempSensSlopePalOn; 336 return pBase->tempSensSlopePalOn;
337 else 337 else
338 return 0; 338 return 0;
339 case EEP_ANTENNA_GAIN_2G:
340 return max_t(u8, pModal->antennaGainCh[0],
341 pModal->antennaGainCh[1]);
339 default: 342 default:
340 return 0; 343 return 0;
341 } 344 }
@@ -554,8 +557,7 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
554 struct ath9k_channel *chan, 557 struct ath9k_channel *chan,
555 int16_t *ratesArray, 558 int16_t *ratesArray,
556 u16 cfgCtl, 559 u16 cfgCtl,
557 u16 AntennaReduction, 560 u16 antenna_reduction,
558 u16 twiceMaxRegulatoryPower,
559 u16 powerLimit) 561 u16 powerLimit)
560{ 562{
561#define CMP_CTL \ 563#define CMP_CTL \
@@ -569,12 +571,8 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
569#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 571#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6
570#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 572#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10
571 573
572 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
573 u16 twiceMaxEdgePower = MAX_RATE_POWER; 574 u16 twiceMaxEdgePower = MAX_RATE_POWER;
574 static const u16 tpScaleReductionTable[5] =
575 { 0, 3, 6, 9, MAX_RATE_POWER };
576 int i; 575 int i;
577 int16_t twiceLargestAntenna;
578 struct cal_ctl_data_ar9287 *rep; 576 struct cal_ctl_data_ar9287 *rep;
579 struct cal_target_power_leg targetPowerOfdm = {0, {0, 0, 0, 0} }, 577 struct cal_target_power_leg targetPowerOfdm = {0, {0, 0, 0, 0} },
580 targetPowerCck = {0, {0, 0, 0, 0} }; 578 targetPowerCck = {0, {0, 0, 0, 0} };
@@ -582,7 +580,7 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
582 targetPowerCckExt = {0, {0, 0, 0, 0} }; 580 targetPowerCckExt = {0, {0, 0, 0, 0} };
583 struct cal_target_power_ht targetPowerHt20, 581 struct cal_target_power_ht targetPowerHt20,
584 targetPowerHt40 = {0, {0, 0, 0, 0} }; 582 targetPowerHt40 = {0, {0, 0, 0, 0} };
585 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; 583 u16 scaledPower = 0, minCtlPower;
586 static const u16 ctlModesFor11g[] = { 584 static const u16 ctlModesFor11g[] = {
587 CTL_11B, CTL_11G, CTL_2GHT20, 585 CTL_11B, CTL_11G, CTL_2GHT20,
588 CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40 586 CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
@@ -597,24 +595,7 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
597 tx_chainmask = ah->txchainmask; 595 tx_chainmask = ah->txchainmask;
598 596
599 ath9k_hw_get_channel_centers(ah, chan, &centers); 597 ath9k_hw_get_channel_centers(ah, chan, &centers);
600 598 scaledPower = powerLimit - antenna_reduction;
601 /* Compute TxPower reduction due to Antenna Gain */
602 twiceLargestAntenna = max(pEepData->modalHeader.antennaGainCh[0],
603 pEepData->modalHeader.antennaGainCh[1]);
604 twiceLargestAntenna = (int16_t)min((AntennaReduction) -
605 twiceLargestAntenna, 0);
606
607 /*
608 * scaledPower is the minimum of the user input power level
609 * and the regulatory allowed power level.
610 */
611 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
612
613 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX)
614 maxRegAllowedPower -=
615 (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
616
617 scaledPower = min(powerLimit, maxRegAllowedPower);
618 599
619 /* 600 /*
620 * Reduce scaled Power by number of chains active 601 * Reduce scaled Power by number of chains active
@@ -815,7 +796,6 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
815static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, 796static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
816 struct ath9k_channel *chan, u16 cfgCtl, 797 struct ath9k_channel *chan, u16 cfgCtl,
817 u8 twiceAntennaReduction, 798 u8 twiceAntennaReduction,
818 u8 twiceMaxRegulatoryPower,
819 u8 powerLimit, bool test) 799 u8 powerLimit, bool test)
820{ 800{
821 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 801 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
@@ -834,7 +814,6 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
834 ath9k_hw_set_ar9287_power_per_rate_table(ah, chan, 814 ath9k_hw_set_ar9287_power_per_rate_table(ah, chan,
835 &ratesArray[0], cfgCtl, 815 &ratesArray[0], cfgCtl,
836 twiceAntennaReduction, 816 twiceAntennaReduction,
837 twiceMaxRegulatoryPower,
838 powerLimit); 817 powerLimit);
839 818
840 ath9k_hw_set_ar9287_power_cal_table(ah, chan); 819 ath9k_hw_set_ar9287_power_cal_table(ah, chan);
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index eda681fc7ba6..e175e2078a39 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -400,6 +400,7 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
400 struct ar5416_eeprom_def *eep = &ah->eeprom.def; 400 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
401 struct modal_eep_header *pModal = eep->modalHeader; 401 struct modal_eep_header *pModal = eep->modalHeader;
402 struct base_eep_header *pBase = &eep->baseEepHeader; 402 struct base_eep_header *pBase = &eep->baseEepHeader;
403 int band = 0;
403 404
404 switch (param) { 405 switch (param) {
405 case EEP_NFTHRESH_5: 406 case EEP_NFTHRESH_5:
@@ -467,6 +468,14 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
467 return pBase->pwr_table_offset; 468 return pBase->pwr_table_offset;
468 else 469 else
469 return AR5416_PWR_TABLE_OFFSET_DB; 470 return AR5416_PWR_TABLE_OFFSET_DB;
471 case EEP_ANTENNA_GAIN_2G:
472 band = 1;
473 /* fall through */
474 case EEP_ANTENNA_GAIN_5G:
475 return max_t(u8, max_t(u8,
476 pModal[band].antennaGainCh[0],
477 pModal[band].antennaGainCh[1]),
478 pModal[band].antennaGainCh[2]);
470 default: 479 default:
471 return 0; 480 return 0;
472 } 481 }
@@ -986,21 +995,15 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
986 struct ath9k_channel *chan, 995 struct ath9k_channel *chan,
987 int16_t *ratesArray, 996 int16_t *ratesArray,
988 u16 cfgCtl, 997 u16 cfgCtl,
989 u16 AntennaReduction, 998 u16 antenna_reduction,
990 u16 twiceMaxRegulatoryPower,
991 u16 powerLimit) 999 u16 powerLimit)
992{ 1000{
993#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ 1001#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
994#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */ 1002#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */
995 1003
996 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
997 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; 1004 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
998 u16 twiceMaxEdgePower = MAX_RATE_POWER; 1005 u16 twiceMaxEdgePower = MAX_RATE_POWER;
999 static const u16 tpScaleReductionTable[5] =
1000 { 0, 3, 6, 9, MAX_RATE_POWER };
1001
1002 int i; 1006 int i;
1003 int16_t twiceLargestAntenna;
1004 struct cal_ctl_data *rep; 1007 struct cal_ctl_data *rep;
1005 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = { 1008 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
1006 0, { 0, 0, 0, 0} 1009 0, { 0, 0, 0, 0}
@@ -1012,7 +1015,7 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
1012 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = { 1015 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
1013 0, {0, 0, 0, 0} 1016 0, {0, 0, 0, 0}
1014 }; 1017 };
1015 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower; 1018 u16 scaledPower = 0, minCtlPower;
1016 static const u16 ctlModesFor11a[] = { 1019 static const u16 ctlModesFor11a[] = {
1017 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 1020 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
1018 }; 1021 };
@@ -1031,27 +1034,7 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
1031 1034
1032 ath9k_hw_get_channel_centers(ah, chan, &centers); 1035 ath9k_hw_get_channel_centers(ah, chan, &centers);
1033 1036
1034 twiceLargestAntenna = max( 1037 scaledPower = powerLimit - antenna_reduction;
1035 pEepData->modalHeader
1036 [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
1037 pEepData->modalHeader
1038 [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
1039
1040 twiceLargestAntenna = max((u8)twiceLargestAntenna,
1041 pEepData->modalHeader
1042 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
1043
1044 twiceLargestAntenna = (int16_t)min(AntennaReduction -
1045 twiceLargestAntenna, 0);
1046
1047 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
1048
1049 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
1050 maxRegAllowedPower -=
1051 (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
1052 }
1053
1054 scaledPower = min(powerLimit, maxRegAllowedPower);
1055 1038
1056 switch (ar5416_get_ntxchains(tx_chainmask)) { 1039 switch (ar5416_get_ntxchains(tx_chainmask)) {
1057 case 1: 1040 case 1:
@@ -1256,7 +1239,6 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1256 struct ath9k_channel *chan, 1239 struct ath9k_channel *chan,
1257 u16 cfgCtl, 1240 u16 cfgCtl,
1258 u8 twiceAntennaReduction, 1241 u8 twiceAntennaReduction,
1259 u8 twiceMaxRegulatoryPower,
1260 u8 powerLimit, bool test) 1242 u8 powerLimit, bool test)
1261{ 1243{
1262#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta) 1244#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
@@ -1278,7 +1260,6 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1278 ath9k_hw_set_def_power_per_rate_table(ah, chan, 1260 ath9k_hw_set_def_power_per_rate_table(ah, chan,
1279 &ratesArray[0], cfgCtl, 1261 &ratesArray[0], cfgCtl,
1280 twiceAntennaReduction, 1262 twiceAntennaReduction,
1281 twiceMaxRegulatoryPower,
1282 powerLimit); 1263 powerLimit);
1283 1264
1284 ath9k_hw_set_def_power_cal_table(ah, chan); 1265 ath9k_hw_set_def_power_cal_table(ah, chan);
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 42ebe8fb053a..949656d928d3 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -433,7 +433,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
433 433
434 regulatory->country_code = CTRY_DEFAULT; 434 regulatory->country_code = CTRY_DEFAULT;
435 regulatory->power_limit = MAX_RATE_POWER; 435 regulatory->power_limit = MAX_RATE_POWER;
436 regulatory->tp_scale = ATH9K_TP_SCALE_MAX;
437 436
438 ah->hw_version.magic = AR5416_MAGIC; 437 ah->hw_version.magic = AR5416_MAGIC;
439 ah->hw_version.subvendorid = 0; 438 ah->hw_version.subvendorid = 0;
@@ -1389,9 +1388,7 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah,
1389static bool ath9k_hw_channel_change(struct ath_hw *ah, 1388static bool ath9k_hw_channel_change(struct ath_hw *ah,
1390 struct ath9k_channel *chan) 1389 struct ath9k_channel *chan)
1391{ 1390{
1392 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
1393 struct ath_common *common = ath9k_hw_common(ah); 1391 struct ath_common *common = ath9k_hw_common(ah);
1394 struct ieee80211_channel *channel = chan->chan;
1395 u32 qnum; 1392 u32 qnum;
1396 int r; 1393 int r;
1397 1394
@@ -1416,14 +1413,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1416 return false; 1413 return false;
1417 } 1414 }
1418 ath9k_hw_set_clockrate(ah); 1415 ath9k_hw_set_clockrate(ah);
1419 1416 ath9k_hw_apply_txpower(ah, chan);
1420 ah->eep_ops->set_txpower(ah, chan,
1421 ath9k_regd_get_ctl(regulatory, chan),
1422 channel->max_antenna_gain * 2,
1423 channel->max_power * 2,
1424 min((u32) MAX_RATE_POWER,
1425 (u32) regulatory->power_limit), false);
1426
1427 ath9k_hw_rfbus_done(ah); 1417 ath9k_hw_rfbus_done(ah);
1428 1418
1429 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) 1419 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
@@ -2498,23 +2488,56 @@ bool ath9k_hw_disable(struct ath_hw *ah)
2498} 2488}
2499EXPORT_SYMBOL(ath9k_hw_disable); 2489EXPORT_SYMBOL(ath9k_hw_disable);
2500 2490
2491static int get_antenna_gain(struct ath_hw *ah, struct ath9k_channel *chan)
2492{
2493 enum eeprom_param gain_param;
2494
2495 if (IS_CHAN_2GHZ(chan))
2496 gain_param = EEP_ANTENNA_GAIN_2G;
2497 else
2498 gain_param = EEP_ANTENNA_GAIN_5G;
2499
2500 return ah->eep_ops->get_eeprom(ah, gain_param);
2501}
2502
2503void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan)
2504{
2505 struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
2506 struct ieee80211_channel *channel;
2507 int chan_pwr, new_pwr, max_gain;
2508 int ant_gain, ant_reduction = 0;
2509
2510 if (!chan)
2511 return;
2512
2513 channel = chan->chan;
2514 chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER);
2515 new_pwr = min_t(int, chan_pwr, reg->power_limit);
2516 max_gain = chan_pwr - new_pwr + channel->max_antenna_gain * 2;
2517
2518 ant_gain = get_antenna_gain(ah, chan);
2519 if (ant_gain > max_gain)
2520 ant_reduction = ant_gain - max_gain;
2521
2522 ah->eep_ops->set_txpower(ah, chan,
2523 ath9k_regd_get_ctl(reg, chan),
2524 ant_reduction, new_pwr, false);
2525}
2526
2501void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) 2527void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
2502{ 2528{
2503 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 2529 struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
2504 struct ath9k_channel *chan = ah->curchan; 2530 struct ath9k_channel *chan = ah->curchan;
2505 struct ieee80211_channel *channel = chan->chan; 2531 struct ieee80211_channel *channel = chan->chan;
2506 int reg_pwr = min_t(int, MAX_RATE_POWER, limit);
2507 int chan_pwr = channel->max_power * 2;
2508 2532
2533 reg->power_limit = min_t(int, limit, MAX_RATE_POWER);
2509 if (test) 2534 if (test)
2510 reg_pwr = chan_pwr = MAX_RATE_POWER; 2535 channel->max_power = MAX_RATE_POWER / 2;
2511 2536
2512 regulatory->power_limit = reg_pwr; 2537 ath9k_hw_apply_txpower(ah, chan);
2513 2538
2514 ah->eep_ops->set_txpower(ah, chan, 2539 if (test)
2515 ath9k_regd_get_ctl(regulatory, chan), 2540 channel->max_power = DIV_ROUND_UP(reg->max_power_level, 2);
2516 channel->max_antenna_gain * 2,
2517 chan_pwr, reg_pwr, test);
2518} 2541}
2519EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit); 2542EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit);
2520 2543
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 24889f78a053..684c33c4897c 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -390,14 +390,6 @@ enum ath9k_power_mode {
390 ATH9K_PM_UNDEFINED 390 ATH9K_PM_UNDEFINED
391}; 391};
392 392
393enum ath9k_tp_scale {
394 ATH9K_TP_SCALE_MAX = 0,
395 ATH9K_TP_SCALE_50,
396 ATH9K_TP_SCALE_25,
397 ATH9K_TP_SCALE_12,
398 ATH9K_TP_SCALE_MIN
399};
400
401enum ser_reg_mode { 393enum ser_reg_mode {
402 SER_REG_MODE_OFF = 0, 394 SER_REG_MODE_OFF = 0,
403 SER_REG_MODE_ON = 1, 395 SER_REG_MODE_ON = 1,
@@ -968,6 +960,7 @@ void ath9k_hw_htc_resetinit(struct ath_hw *ah);
968/* PHY */ 960/* PHY */
969void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, 961void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
970 u32 *coef_mantissa, u32 *coef_exponent); 962 u32 *coef_mantissa, u32 *coef_exponent);
963void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan);
971 964
972/* 965/*
973 * Code Specific to AR5008, AR9001 or AR9002, 966 * Code Specific to AR5008, AR9001 or AR9002,
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 39514de044ef..af1b32549531 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -626,7 +626,6 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
626 struct ieee80211_supported_band *sband; 626 struct ieee80211_supported_band *sband;
627 struct ieee80211_channel *chan; 627 struct ieee80211_channel *chan;
628 struct ath_hw *ah = sc->sc_ah; 628 struct ath_hw *ah = sc->sc_ah;
629 struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
630 int i; 629 int i;
631 630
632 sband = &sc->sbands[band]; 631 sband = &sc->sbands[band];
@@ -635,7 +634,6 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
635 ah->curchan = &ah->channels[chan->hw_value]; 634 ah->curchan = &ah->channels[chan->hw_value];
636 ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20); 635 ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20);
637 ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true); 636 ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
638 chan->max_power = reg->max_power_level / 2;
639 } 637 }
640} 638}
641 639