diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/ar9003_paprd.c')
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_paprd.c | 87 |
1 files changed, 64 insertions, 23 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 0ed3846f9cbb..09c1f9da67a0 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c | |||
| @@ -74,15 +74,23 @@ static int ar9003_get_training_power_2g(struct ath_hw *ah) | |||
| 74 | unsigned int power, scale, delta; | 74 | unsigned int power, scale, delta; |
| 75 | 75 | ||
| 76 | scale = ar9003_get_paprd_scale_factor(ah, chan); | 76 | scale = ar9003_get_paprd_scale_factor(ah, chan); |
| 77 | power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5, | ||
| 78 | AR_PHY_POWERTX_RATE5_POWERTXHT20_0); | ||
| 79 | 77 | ||
| 80 | delta = abs((int) ah->paprd_target_power - (int) power); | 78 | if (AR_SREV_9330(ah) || AR_SREV_9340(ah) || |
| 81 | if (delta > scale) | 79 | AR_SREV_9462(ah) || AR_SREV_9565(ah)) { |
| 82 | return -1; | 80 | power = ah->paprd_target_power + 2; |
| 83 | 81 | } else if (AR_SREV_9485(ah)) { | |
| 84 | if (delta < 4) | 82 | power = 25; |
| 85 | power -= 4 - delta; | 83 | } else { |
| 84 | power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5, | ||
| 85 | AR_PHY_POWERTX_RATE5_POWERTXHT20_0); | ||
| 86 | |||
| 87 | delta = abs((int) ah->paprd_target_power - (int) power); | ||
| 88 | if (delta > scale) | ||
| 89 | return -1; | ||
| 90 | |||
| 91 | if (delta < 4) | ||
| 92 | power -= 4 - delta; | ||
| 93 | } | ||
| 86 | 94 | ||
| 87 | return power; | 95 | return power; |
| 88 | } | 96 | } |
| @@ -169,6 +177,9 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) | |||
| 169 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, | 177 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, |
| 170 | ah->paprd_ratemask_ht40); | 178 | ah->paprd_ratemask_ht40); |
| 171 | 179 | ||
| 180 | ath_dbg(common, CALIBRATE, "PAPRD HT20 mask: 0x%x, HT40 mask: 0x%x\n", | ||
| 181 | ah->paprd_ratemask, ah->paprd_ratemask_ht40); | ||
| 182 | |||
| 172 | for (i = 0; i < ah->caps.max_txchains; i++) { | 183 | for (i = 0; i < ah->caps.max_txchains; i++) { |
| 173 | REG_RMW_FIELD(ah, ctrl0[i], | 184 | REG_RMW_FIELD(ah, ctrl0[i], |
| 174 | AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK, 1); | 185 | AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK, 1); |
| @@ -204,7 +215,20 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) | |||
| 204 | AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING, 28); | 215 | AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING, 28); |
| 205 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, | 216 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, |
| 206 | AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE, 1); | 217 | AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE, 1); |
| 207 | val = AR_SREV_9462(ah) ? 0x91 : 147; | 218 | |
| 219 | if (AR_SREV_9485(ah)) { | ||
| 220 | val = 148; | ||
| 221 | } else { | ||
| 222 | if (IS_CHAN_2GHZ(ah->curchan)) { | ||
| 223 | if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) | ||
| 224 | val = 145; | ||
| 225 | else | ||
| 226 | val = 147; | ||
| 227 | } else { | ||
| 228 | val = 137; | ||
| 229 | } | ||
| 230 | } | ||
| 231 | |||
| 208 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL2, | 232 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL2, |
| 209 | AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, val); | 233 | AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, val); |
| 210 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, | 234 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, |
| @@ -215,15 +239,24 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) | |||
| 215 | AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES, 7); | 239 | AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES, 7); |
| 216 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, | 240 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, |
| 217 | AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL, 1); | 241 | AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL, 1); |
| 218 | if (AR_SREV_9485(ah) || AR_SREV_9462(ah) || AR_SREV_9550(ah)) | 242 | |
| 243 | if (AR_SREV_9485(ah) || | ||
| 244 | AR_SREV_9462(ah) || | ||
| 245 | AR_SREV_9565(ah) || | ||
| 246 | AR_SREV_9550(ah) || | ||
| 247 | AR_SREV_9330(ah) || | ||
| 248 | AR_SREV_9340(ah)) | ||
| 219 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, | 249 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, |
| 220 | AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, | 250 | AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -3); |
| 221 | -3); | ||
| 222 | else | 251 | else |
| 223 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, | 252 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, |
| 224 | AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, | 253 | AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -6); |
| 225 | -6); | 254 | |
| 226 | val = AR_SREV_9462(ah) ? -10 : -15; | 255 | val = -10; |
| 256 | |||
| 257 | if (IS_CHAN_2GHZ(ah->curchan) && !AR_SREV_9462(ah) && !AR_SREV_9565(ah)) | ||
| 258 | val = -15; | ||
| 259 | |||
| 227 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, | 260 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, |
| 228 | AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE, | 261 | AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE, |
| 229 | val); | 262 | val); |
| @@ -262,9 +295,6 @@ static void ar9003_paprd_get_gain_table(struct ath_hw *ah) | |||
| 262 | u32 reg = AR_PHY_TXGAIN_TABLE; | 295 | u32 reg = AR_PHY_TXGAIN_TABLE; |
| 263 | int i; | 296 | int i; |
| 264 | 297 | ||
| 265 | memset(entry, 0, sizeof(ah->paprd_gain_table_entries)); | ||
| 266 | memset(index, 0, sizeof(ah->paprd_gain_table_index)); | ||
| 267 | |||
| 268 | for (i = 0; i < PAPRD_GAIN_TABLE_ENTRIES; i++) { | 298 | for (i = 0; i < PAPRD_GAIN_TABLE_ENTRIES; i++) { |
| 269 | entry[i] = REG_READ(ah, reg); | 299 | entry[i] = REG_READ(ah, reg); |
| 270 | index[i] = (entry[i] >> 24) & 0xff; | 300 | index[i] = (entry[i] >> 24) & 0xff; |
| @@ -763,7 +793,7 @@ void ar9003_paprd_populate_single_table(struct ath_hw *ah, | |||
| 763 | } | 793 | } |
| 764 | EXPORT_SYMBOL(ar9003_paprd_populate_single_table); | 794 | EXPORT_SYMBOL(ar9003_paprd_populate_single_table); |
| 765 | 795 | ||
| 766 | int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain) | 796 | void ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain) |
| 767 | { | 797 | { |
| 768 | unsigned int i, desired_gain, gain_index; | 798 | unsigned int i, desired_gain, gain_index; |
| 769 | unsigned int train_power = ah->paprd_training_power; | 799 | unsigned int train_power = ah->paprd_training_power; |
| @@ -781,8 +811,6 @@ int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain) | |||
| 781 | 811 | ||
| 782 | REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, | 812 | REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, |
| 783 | AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); | 813 | AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); |
| 784 | |||
| 785 | return 0; | ||
| 786 | } | 814 | } |
| 787 | EXPORT_SYMBOL(ar9003_paprd_setup_gain_table); | 815 | EXPORT_SYMBOL(ar9003_paprd_setup_gain_table); |
| 788 | 816 | ||
| @@ -894,7 +922,7 @@ int ar9003_paprd_create_curve(struct ath_hw *ah, | |||
| 894 | 922 | ||
| 895 | memset(caldata->pa_table[chain], 0, sizeof(caldata->pa_table[chain])); | 923 | memset(caldata->pa_table[chain], 0, sizeof(caldata->pa_table[chain])); |
| 896 | 924 | ||
| 897 | buf = kmalloc(2 * 48 * sizeof(u32), GFP_ATOMIC); | 925 | buf = kmalloc(2 * 48 * sizeof(u32), GFP_KERNEL); |
| 898 | if (!buf) | 926 | if (!buf) |
| 899 | return -ENOMEM; | 927 | return -ENOMEM; |
| 900 | 928 | ||
| @@ -945,9 +973,13 @@ EXPORT_SYMBOL(ar9003_paprd_init_table); | |||
| 945 | bool ar9003_paprd_is_done(struct ath_hw *ah) | 973 | bool ar9003_paprd_is_done(struct ath_hw *ah) |
| 946 | { | 974 | { |
| 947 | int paprd_done, agc2_pwr; | 975 | int paprd_done, agc2_pwr; |
| 976 | |||
| 948 | paprd_done = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1, | 977 | paprd_done = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1, |
| 949 | AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); | 978 | AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); |
| 950 | 979 | ||
| 980 | if (AR_SREV_9485(ah)) | ||
| 981 | goto exit; | ||
| 982 | |||
| 951 | if (paprd_done == 0x1) { | 983 | if (paprd_done == 0x1) { |
| 952 | agc2_pwr = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1, | 984 | agc2_pwr = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1, |
| 953 | AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR); | 985 | AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR); |
| @@ -963,7 +995,16 @@ bool ar9003_paprd_is_done(struct ath_hw *ah) | |||
| 963 | if (agc2_pwr <= PAPRD_IDEAL_AGC2_PWR_RANGE) | 995 | if (agc2_pwr <= PAPRD_IDEAL_AGC2_PWR_RANGE) |
| 964 | paprd_done = 0; | 996 | paprd_done = 0; |
| 965 | } | 997 | } |
| 966 | 998 | exit: | |
| 967 | return !!paprd_done; | 999 | return !!paprd_done; |
| 968 | } | 1000 | } |
| 969 | EXPORT_SYMBOL(ar9003_paprd_is_done); | 1001 | EXPORT_SYMBOL(ar9003_paprd_is_done); |
| 1002 | |||
| 1003 | bool ar9003_is_paprd_enabled(struct ath_hw *ah) | ||
| 1004 | { | ||
| 1005 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->config.enable_paprd) | ||
| 1006 | return true; | ||
| 1007 | |||
| 1008 | return false; | ||
| 1009 | } | ||
| 1010 | EXPORT_SYMBOL(ar9003_is_paprd_enabled); | ||
