aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_paprd.c102
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h8
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c4
5 files changed, 112 insertions, 17 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 5ad37d05a85d..4149ffb6d54a 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -4798,6 +4798,19 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
4798 /* Write target power array to registers */ 4798 /* Write target power array to registers */
4799 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2); 4799 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
4800 ar9003_hw_calibration_apply(ah, chan->channel); 4800 ar9003_hw_calibration_apply(ah, chan->channel);
4801
4802 if (IS_CHAN_2GHZ(chan)) {
4803 if (IS_CHAN_HT40(chan))
4804 i = ALL_TARGET_HT40_0_8_16;
4805 else
4806 i = ALL_TARGET_HT20_0_8_16;
4807 } else {
4808 if (IS_CHAN_HT40(chan))
4809 i = ALL_TARGET_HT40_7;
4810 else
4811 i = ALL_TARGET_HT20_7;
4812 }
4813 ah->paprd_target_power = targetPowerValT2[i];
4801} 4814}
4802 4815
4803static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah, 4816static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index cdca4c3265b9..69f779237d28 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -30,9 +30,69 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val)
30} 30}
31EXPORT_SYMBOL(ar9003_paprd_enable); 31EXPORT_SYMBOL(ar9003_paprd_enable);
32 32
33static void ar9003_paprd_setup_single_table(struct ath_hw *ah) 33static int ar9003_get_training_power_2g(struct ath_hw *ah)
34{ 34{
35 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 35 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
36 struct ar9300_modal_eep_header *hdr = &eep->modalHeader2G;
37 unsigned int power, scale, delta;
38
39 scale = MS(le32_to_cpu(hdr->papdRateMaskHt20), AR9300_PAPRD_SCALE_1);
40 power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
41 AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
42
43 delta = abs((int) ah->paprd_target_power - (int) power);
44 if (delta > scale)
45 return -1;
46
47 if (delta < 4)
48 power -= 4 - delta;
49
50 return power;
51}
52
53static int get_streams(int mask)
54{
55 return !!(mask & BIT(0)) + !!(mask & BIT(1)) + !!(mask & BIT(2));
56}
57
58static int ar9003_get_training_power_5g(struct ath_hw *ah)
59{
60 struct ath_common *common = ath9k_hw_common(ah);
61 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
62 struct ar9300_modal_eep_header *hdr = &eep->modalHeader5G;
63 struct ath9k_channel *chan = ah->curchan;
64 unsigned int power, scale, delta;
65
66 if (chan->channel >= 5700)
67 scale = MS(le32_to_cpu(hdr->papdRateMaskHt20),
68 AR9300_PAPRD_SCALE_1);
69 else if (chan->channel >= 5400)
70 scale = MS(le32_to_cpu(hdr->papdRateMaskHt40),
71 AR9300_PAPRD_SCALE_2);
72 else
73 scale = MS(le32_to_cpu(hdr->papdRateMaskHt40),
74 AR9300_PAPRD_SCALE_1);
75
76 if (IS_CHAN_HT40(chan))
77 power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE8,
78 AR_PHY_POWERTX_RATE8_POWERTXHT40_5);
79 else
80 power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE6,
81 AR_PHY_POWERTX_RATE6_POWERTXHT20_5);
82
83 power += scale;
84 delta = abs((int) ah->paprd_target_power - (int) power);
85 if (delta > scale)
86 return -1;
87
88 power += 2 * get_streams(common->tx_chainmask);
89 return power;
90}
91
92static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
93{
94 struct ath_common *common = ath9k_hw_common(ah);
95 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
36 struct ar9300_modal_eep_header *hdr; 96 struct ar9300_modal_eep_header *hdr;
37 static const u32 ctrl0[3] = { 97 static const u32 ctrl0[3] = {
38 AR_PHY_PAPRD_CTRL0_B0, 98 AR_PHY_PAPRD_CTRL0_B0,
@@ -45,6 +105,7 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
45 AR_PHY_PAPRD_CTRL1_B2 105 AR_PHY_PAPRD_CTRL1_B2
46 }; 106 };
47 u32 am_mask, ht40_mask; 107 u32 am_mask, ht40_mask;
108 int training_power;
48 int i; 109 int i;
49 110
50 if (ah->curchan && IS_CHAN_5GHZ(ah->curchan)) 111 if (ah->curchan && IS_CHAN_5GHZ(ah->curchan))
@@ -55,11 +116,25 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
55 am_mask = le32_to_cpu(hdr->papdRateMaskHt20) & AR9300_PAPRD_RATE_MASK; 116 am_mask = le32_to_cpu(hdr->papdRateMaskHt20) & AR9300_PAPRD_RATE_MASK;
56 ht40_mask = le32_to_cpu(hdr->papdRateMaskHt40) & AR9300_PAPRD_RATE_MASK; 117 ht40_mask = le32_to_cpu(hdr->papdRateMaskHt40) & AR9300_PAPRD_RATE_MASK;
57 118
119 if (IS_CHAN_2GHZ(ah->curchan))
120 training_power = ar9003_get_training_power_2g(ah);
121 else
122 training_power = ar9003_get_training_power_5g(ah);
123
124 if (training_power < 0) {
125 ath_dbg(common, ATH_DBG_CALIBRATE,
126 "PAPRD target power delta out of range");
127 return -ERANGE;
128 }
129 ah->paprd_training_power = training_power;
130 ath_dbg(common, ATH_DBG_CALIBRATE,
131 "Training power: %d, Target power: %d\n",
132 ah->paprd_training_power, ah->paprd_target_power);
133
58 REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, am_mask); 134 REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, am_mask);
59 REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask); 135 REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask);
60 REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, ht40_mask); 136 REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, ht40_mask);
61 137
62
63 for (i = 0; i < ah->caps.max_txchains; i++) { 138 for (i = 0; i < ah->caps.max_txchains; i++) {
64 REG_RMW_FIELD(ah, ctrl0[i], 139 REG_RMW_FIELD(ah, ctrl0[i],
65 AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK, 1); 140 AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK, 1);
@@ -141,6 +216,7 @@ static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
141 AR_PHY_PAPRD_PRE_POST_SCALING, 185706); 216 AR_PHY_PAPRD_PRE_POST_SCALING, 185706);
142 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_7_B0, 217 REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_7_B0,
143 AR_PHY_PAPRD_PRE_POST_SCALING, 175487); 218 AR_PHY_PAPRD_PRE_POST_SCALING, 175487);
219 return 0;
144} 220}
145 221
146static void ar9003_paprd_get_gain_table(struct ath_hw *ah) 222static void ar9003_paprd_get_gain_table(struct ath_hw *ah)
@@ -595,15 +671,10 @@ void ar9003_paprd_populate_single_table(struct ath_hw *ah,
595{ 671{
596 u32 *paprd_table_val = caldata->pa_table[chain]; 672 u32 *paprd_table_val = caldata->pa_table[chain];
597 u32 small_signal_gain = caldata->small_signal_gain[chain]; 673 u32 small_signal_gain = caldata->small_signal_gain[chain];
598 u32 training_power; 674 u32 training_power = ah->paprd_training_power;
599 u32 reg = 0; 675 u32 reg = 0;
600 int i; 676 int i;
601 677
602 training_power =
603 REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
604 AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
605 training_power -= 4;
606
607 if (chain == 0) 678 if (chain == 0)
608 reg = AR_PHY_PAPRD_MEM_TAB_B0; 679 reg = AR_PHY_PAPRD_MEM_TAB_B0;
609 else if (chain == 1) 680 else if (chain == 1)
@@ -643,14 +714,8 @@ EXPORT_SYMBOL(ar9003_paprd_populate_single_table);
643 714
644int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain) 715int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain)
645{ 716{
646
647 unsigned int i, desired_gain, gain_index; 717 unsigned int i, desired_gain, gain_index;
648 unsigned int train_power; 718 unsigned int train_power = ah->paprd_training_power;
649
650 train_power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
651 AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
652
653 train_power = train_power - 4;
654 719
655 desired_gain = ar9003_get_desired_gain(ah, chain, train_power); 720 desired_gain = ar9003_get_desired_gain(ah, chain, train_power);
656 721
@@ -716,7 +781,12 @@ EXPORT_SYMBOL(ar9003_paprd_create_curve);
716 781
717int ar9003_paprd_init_table(struct ath_hw *ah) 782int ar9003_paprd_init_table(struct ath_hw *ah)
718{ 783{
719 ar9003_paprd_setup_single_table(ah); 784 int ret;
785
786 ret = ar9003_paprd_setup_single_table(ah);
787 if (ret < 0)
788 return ret;
789
720 ar9003_paprd_get_gain_table(ah); 790 ar9003_paprd_get_gain_table(ah);
721 return 0; 791 return 0;
722} 792}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 6f811c7ada05..59bab6bd8a74 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -1090,6 +1090,14 @@
1090#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0 0x3F 1090#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0 0x3F
1091#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0_S 0 1091#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0_S 0
1092 1092
1093#define AR_PHY_POWERTX_RATE6 (AR_SM_BASE + 0x1d4)
1094#define AR_PHY_POWERTX_RATE6_POWERTXHT20_5 0x3F00
1095#define AR_PHY_POWERTX_RATE6_POWERTXHT20_5_S 8
1096
1097#define AR_PHY_POWERTX_RATE8 (AR_SM_BASE + 0x1dc)
1098#define AR_PHY_POWERTX_RATE8_POWERTXHT40_5 0x3F00
1099#define AR_PHY_POWERTX_RATE8_POWERTXHT40_5_S 8
1100
1093void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx); 1101void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
1094 1102
1095#endif /* AR9003_PHY_H */ 1103#endif /* AR9003_PHY_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index c20e0476ee44..97f22c428603 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -833,6 +833,8 @@ struct ath_hw {
833 u32 bb_watchdog_last_status; 833 u32 bb_watchdog_last_status;
834 u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */ 834 u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */
835 835
836 unsigned int paprd_target_power;
837 unsigned int paprd_training_power;
836 u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES]; 838 u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES];
837 u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES]; 839 u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES];
838 /* 840 /*
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index d49dacbc96a7..c68205dea1fa 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -373,6 +373,9 @@ void ath_paprd_calibrate(struct work_struct *work)
373 if (!caldata) 373 if (!caldata)
374 return; 374 return;
375 375
376 if (ar9003_paprd_init_table(ah) < 0)
377 return;
378
376 skb = alloc_skb(len, GFP_KERNEL); 379 skb = alloc_skb(len, GFP_KERNEL);
377 if (!skb) 380 if (!skb)
378 return; 381 return;
@@ -388,7 +391,6 @@ void ath_paprd_calibrate(struct work_struct *work)
388 memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); 391 memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
389 392
390 ath9k_ps_wakeup(sc); 393 ath9k_ps_wakeup(sc);
391 ar9003_paprd_init_table(ah);
392 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { 394 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
393 if (!(common->tx_chainmask & BIT(chain))) 395 if (!(common->tx_chainmask & BIT(chain)))
394 continue; 396 continue;