diff options
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 102 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_phy.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 4 |
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 | ||
4803 | static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah, | 4816 | static 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 | } |
31 | EXPORT_SYMBOL(ar9003_paprd_enable); | 31 | EXPORT_SYMBOL(ar9003_paprd_enable); |
32 | 32 | ||
33 | static void ar9003_paprd_setup_single_table(struct ath_hw *ah) | 33 | static 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 | |||
53 | static int get_streams(int mask) | ||
54 | { | ||
55 | return !!(mask & BIT(0)) + !!(mask & BIT(1)) + !!(mask & BIT(2)); | ||
56 | } | ||
57 | |||
58 | static 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 | |||
92 | static 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 | ||
146 | static void ar9003_paprd_get_gain_table(struct ath_hw *ah) | 222 | static 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 | ||
644 | int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain) | 715 | int 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 | ||
717 | int ar9003_paprd_init_table(struct ath_hw *ah) | 782 | int 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 | |||
1093 | void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx); | 1101 | void 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; |