2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
20 #include "ah_internal.h"
21 #include "ar9300paprd.h"
22 #include "ar9300reg.h"
27 static struct ar9300_paprd_pwr_adjust ar9300_paprd_pwr_adj_array
[] = {
28 /* rate index , register offset , mask of register , */
29 {ALL_TARGET_HT20_5
, AR_PHY_POWERTX_RATE5
, AR_PHY_POWERTX_RATE5_POWERTXHT20_3
,
30 /* mask offset of register , offset dB*/
31 AR_PHY_POWERTX_RATE5_POWERTXHT20_3_S
, 1},
32 {ALL_TARGET_HT20_6
, AR_PHY_POWERTX_RATE6
, AR_PHY_POWERTX_RATE6_POWERTXHT20_4
,
33 AR_PHY_POWERTX_RATE6_POWERTXHT20_4_S
, 2},
34 {ALL_TARGET_HT20_7
, AR_PHY_POWERTX_RATE6
, AR_PHY_POWERTX_RATE6_POWERTXHT20_5
,
35 AR_PHY_POWERTX_RATE6_POWERTXHT20_5_S
, 2},
36 {ALL_TARGET_HT40_5
, AR_PHY_POWERTX_RATE7
, AR_PHY_POWERTX_RATE7_POWERTXHT40_3
,
37 AR_PHY_POWERTX_RATE7_POWERTXHT40_3_S
, 1},
38 {ALL_TARGET_HT40_6
, AR_PHY_POWERTX_RATE8
, AR_PHY_POWERTX_RATE8_POWERTXHT40_4
,
39 AR_PHY_POWERTX_RATE8_POWERTXHT40_4_S
, 2},
40 {ALL_TARGET_HT40_7
, AR_PHY_POWERTX_RATE8
, AR_PHY_POWERTX_RATE8_POWERTXHT40_5
,
41 AR_PHY_POWERTX_RATE8_POWERTXHT40_5_S
, 2},
42 {ALL_TARGET_LEGACY_54
, AR_PHY_POWERTX_RATE2
, AR_PHY_POWERTX_RATE2_POWERTX54M_7
,
43 AR_PHY_POWERTX_RATE2_POWERTX54M_7_S
, 2},
46 HAL_BOOL
create_pa_curve(u_int32_t
* paprd_train_data_l
,
47 u_int32_t
*paprd_train_data_u
, u_int32_t
*pa_table
, u_int32_t
*g_fxp_ext
,
51 ar9300_paprd_setup_single_table(struct ath_hal
*ah
, struct ieee80211_channel
* chan
)
53 int is_2g
= IEEE80211_IS_CHAN_2GHZ(chan
);
54 HAL_CHANNEL_INTERNAL
*ichan
= ath_hal_checkchannel(ah
, chan
);
55 struct ath_hal_9300
*ahp
= AH9300(ah
);
57 u_int32_t am_mask
= 0;
58 u_int32_t val
= OS_REG_READ(ah
, AR_2040_MODE
);
59 u_int8_t target_power_val_t2
[ar9300_rate_size
];
60 int power_tblindex
= 0, power_delta
= 0;
61 int paprd_scale_factor
= 5;
63 const u_int8_t mask2num
[8] = {
74 ar9300_eeprom_t
*eep
= &AH9300(ah
)->ah_eeprom
;
76 #define ABS(_x, _y) ((int)_x > (int)_y ? (int)_x - (int)_y : (int)_y - (int)_x)
78 ar9300_set_target_power_from_eeprom(ah
, ichan
->channel
, target_power_val_t2
);
79 if (val
& HAL_HT_MACMODE_2040
) {
84 * Note on paprd_scale_factor
85 * This factor is saved in eeprom as 3 bit fields in following fashion.
86 * In 5G there are 3 scale factors -- upper, mid and lower band.
87 * Upper band scale factor is coded in bits 25-27 of
88 * modal_header_5g.paprd_rate_mask_ht20.
89 * Mid band scale factor is coded in bits 28-30 of
90 * modal_header_5g.paprd_rate_mask_ht40.
91 * Lower band scale factor is coded in bits 25-27 of
92 * modal_header_5g.paprd_rate_mask_ht40.
93 * For 2G there is only one scale factor. It is saved in bits 25-27 of
94 * modal_header_2g.paprd_rate_mask_ht20.
96 AH_PAPRD_GET_SCALE_FACTOR(paprd_scale_factor
, eep
, is_2g
, ichan
->channel
);
99 am_mask
= ahp
->ah_2g_paprd_rate_mask_ht40
& AH_PAPRD_AM_PM_MASK
;
100 power_tblindex
= ALL_TARGET_HT40_0_8_16
;
102 am_mask
= ahp
->ah_2g_paprd_rate_mask_ht20
& AH_PAPRD_AM_PM_MASK
;
103 power_tblindex
= ALL_TARGET_HT20_0_8_16
;
105 if (AR_SREV_HORNET(ah
) || AR_SREV_WASP(ah
) || AR_SREV_JUPITER(ah
) || AR_SREV_APHRODITE(ah
)) {
107 ahp
->paprd_training_power
=
108 target_power_val_t2
[ALL_TARGET_HT40_7
] + 2;
110 ahp
->paprd_training_power
=
111 target_power_val_t2
[ALL_TARGET_HT20_7
] + 2;
113 } else if (AR_SREV_POSEIDON(ah
)) {
114 ahp
->paprd_training_power
= 25;
116 ahp
->paprd_training_power
=
117 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_POWERTX_RATE5
,
118 AR_PHY_POWERTX_RATE5_POWERTXHT20_0
);
119 if (ABS(target_power_val_t2
[power_tblindex
],
120 ahp
->paprd_training_power
) > paprd_scale_factor
)
122 HALDEBUG(ah
, HAL_DEBUG_CALIBRATE
,
123 "%s[%d]: Chan %d paprd failing EEP PWR 0x%08x"
124 "TGT PWR 0x%08x\n", __func__
, __LINE__
, ichan
->channel
,
125 target_power_val_t2
[power_tblindex
],
126 ahp
->paprd_training_power
);
131 ABS(ahp
->paprd_training_power
,
132 target_power_val_t2
[power_tblindex
]);
134 power_delta
= power_delta
> 4 ? 0 : 4 - power_delta
;
135 ahp
->paprd_training_power
=
136 ahp
->paprd_training_power
- power_delta
;
142 ahp
->paprd_training_power
=
143 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_POWERTX_RATE8
,
144 AR_PHY_POWERTX_RATE8_POWERTXHT40_5
);
145 am_mask
= ahp
->ah_5g_paprd_rate_mask_ht40
& AH_PAPRD_AM_PM_MASK
;
146 switch (mask2num
[ahp
->ah_tx_chainmask
])
161 power_tblindex
= ALL_TARGET_HT40_7
;
163 ahp
->paprd_training_power
=
164 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_POWERTX_RATE6
,
165 AR_PHY_POWERTX_RATE6_POWERTXHT20_5
);
166 am_mask
= ahp
->ah_5g_paprd_rate_mask_ht20
& AH_PAPRD_AM_PM_MASK
;
167 switch (mask2num
[ahp
->ah_tx_chainmask
])
182 power_tblindex
= ALL_TARGET_HT20_7
;
184 /* Adjust for scale factor */
185 ahp
->paprd_training_power
+= paprd_scale_factor
;
187 ath_hal_printf(ah, "%s[%d] paprd_scale_factor %d power_delta %d\n",
188 __func__, __LINE__, paprd_scale_factor, power_delta);
190 if (ABS(target_power_val_t2
[power_tblindex
], ahp
->paprd_training_power
)
191 > paprd_scale_factor
)
193 HALDEBUG(ah
, HAL_DEBUG_CALIBRATE
,
194 "%s[%d]: Chan %d paprd failing EEP PWR 0x%08x TGT PWR 0x%08x\n",
195 __func__
, __LINE__
, ichan
->channel
,
196 target_power_val_t2
[power_tblindex
], ahp
->paprd_training_power
);
199 ahp
->paprd_training_power
= ahp
->paprd_training_power
+ power_delta
;
202 HALDEBUG(ah
, HAL_DEBUG_CALIBRATE
, "%s 2G %d HT40 %d am_mask 0x%08x\n",
203 __func__
, is_2g
, is_ht40
, am_mask
);
204 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_AM2AM
, AR_PHY_PAPRD_AM2AM_MASK
,
206 if (AR_SREV_HORNET(ah
)) {
207 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_AM2PM
, AR_PHY_PAPRD_AM2PM_MASK
,
211 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_AM2PM
, AR_PHY_PAPRD_AM2PM_MASK
,
215 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_HT40
, AR_PHY_PAPRD_HT40_MASK
,
216 AR_PHY_PAPRD_HT40_MASK
);
218 if (AH9300(ah
)->ah_tx_chainmask
& AR9300_CHAIN0_MASK
) {
219 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B0
,
220 AR_PHY_PAPRD_CTRL0_B0_USE_SINGLE_TABLE_MASK
, 1);
221 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B0
,
222 AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_AM2PM_ENABLE_0
, 1);
223 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B0
,
224 AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_AM2AM_ENABLE_0
, 1);
225 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B0
,
226 AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_SCALING_ENA
, 0);
227 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B0
,
228 AR_PHY_PAPRD_CTRL1_B0_PA_GAIN_SCALE_FACT_0_MASK
, 181);
229 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B0
,
230 AR_PHY_PAPRD_CTRL1_B0_PAPRD_MAG_SCALE_FACT_0
, 361);
231 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B0
,
232 AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_SCALING_ENA
, 0);
233 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B0
,
234 AR_PHY_PAPRD_CTRL0_B0_PAPRD_MAG_THRSH_0
, 3);
238 if (AH9300(ah
)->ah_tx_chainmask
& AR9300_CHAIN1_MASK
) {
239 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B1
,
240 AR_PHY_PAPRD_CTRL0_B1_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_1
, 1);
241 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B1
,
242 AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_AM2PM_ENABLE_1
, 1);
243 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B1
,
244 AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_AM2AM_ENABLE_1
, 1);
245 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B1
,
246 AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_SCALING_ENA
, 0);
247 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B1
,
248 AR_PHY_PAPRD_CTRL1_B1_PA_GAIN_SCALE_FACT_1_MASK
, 181);
249 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B1
,
250 AR_PHY_PAPRD_CTRL1_B1_PAPRD_MAG_SCALE_FACT_1
, 361);
251 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B1
,
252 AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_SCALING_ENA
, 0);
253 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B1
,
254 AR_PHY_PAPRD_CTRL0_B1_PAPRD_MAG_THRSH_1
, 3);
258 if (AH9300(ah
)->ah_tx_chainmask
& AR9300_CHAIN2_MASK
) {
259 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B2
,
260 AR_PHY_PAPRD_CTRL0_B2_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_2
, 1);
261 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B2
,
262 AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_AM2PM_ENABLE_2
, 1);
263 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B2
,
264 AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_AM2AM_ENABLE_2
, 1);
265 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B2
,
266 AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_SCALING_ENA
, 0);
267 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B2
,
268 AR_PHY_PAPRD_CTRL1_B2_PA_GAIN_SCALE_FACT_2_MASK
, 181);
269 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B2
,
270 AR_PHY_PAPRD_CTRL1_B2_PAPRD_MAG_SCALE_FACT_2
, 361);
271 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B2
,
272 AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_SCALING_ENA
, 0);
273 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B2
,
274 AR_PHY_PAPRD_CTRL0_B2_PAPRD_MAG_THRSH_2
, 3);
277 ar9300_enable_paprd(ah
, AH_FALSE
, chan
);
278 if (AR_SREV_POSEIDON(ah
)) {
279 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON
,
280 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP
, 0x30);
281 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON
,
282 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE
, 1);
283 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON
,
284 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE
, 1);
285 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON
,
286 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE
, 0);
287 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON
,
288 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE
, 0);
289 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON
,
290 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING
, 28);
291 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON
,
292 AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE
, 1);
293 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL2_POSEIDON
,
294 AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN
, 148);
295 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON
,
296 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN
, 4);
297 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON
,
298 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN
, 4);
299 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON
,
300 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES
, 7);
301 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON
,
302 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL
, 1);
303 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON
,
304 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP
, -3);
305 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON
,
306 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE
, -15);
307 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON
,
308 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE
, 1);
309 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL4_POSEIDON
,
310 AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA
, 0);
311 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL4_POSEIDON
,
312 AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR
, 400);
313 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL4_POSEIDON
,
314 AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES
, 100);
316 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1
,
317 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP
, 0x30);
318 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1
,
319 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE
, 1);
320 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1
,
321 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE
, 1);
322 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1
,
323 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE
, 0);
324 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1
,
325 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE
, 0);
326 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1
,
327 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING
, 28);
328 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1
,
329 AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE
, 1);
331 if(AR_SREV_JUPITER(ah
) || AR_SREV_APHRODITE(ah
)){
332 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL2
,
333 AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN
, 0x91);
335 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL2
,
336 AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN
, 147);
339 else if (AR_SREV_WASP(ah
) && !is_2g
) {
340 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL2
,
341 AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN
, 137);
343 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL2
,
344 AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN
, 147);
346 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3
,
347 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN
, 4);
348 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3
,
349 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN
, 4);
350 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3
,
351 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES
, 7);
352 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3
,
353 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL
, 1);
354 if (AR_SREV_HORNET(ah
) || AR_SREV_WASP(ah
) || AR_SREV_JUPITER(ah
) || AR_SREV_APHRODITE(ah
)) {
355 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3
,
356 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP
, -3);
358 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3
,
359 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP
, -6);
362 if(AR_SREV_JUPITER(ah
) || AR_SREV_APHRODITE(ah
)){
363 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3
,
364 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE
, -10);
366 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3
,
367 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE
, -15);
371 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3
,
372 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE
, -10);
374 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3
,
375 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE
, 1);
376 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL4
,
377 AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA
, 0);
378 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL4
,
379 AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR
, 400);
380 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL4
,
381 AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES
, 100);
384 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_PRE_POST_SCALE_0_B0
,
385 AR_PHY_PAPRD_PRE_POST_SCALE_0_B0_PAPRD_PRE_POST_SCALING_0_0
, 261376);
386 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_PRE_POST_SCALE_1_B0
,
387 AR_PHY_PAPRD_PRE_POST_SCALE_1_B0_PAPRD_PRE_POST_SCALING_1_0
, 248079);
388 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_PRE_POST_SCALE_2_B0
,
389 AR_PHY_PAPRD_PRE_POST_SCALE_2_B0_PAPRD_PRE_POST_SCALING_2_0
, 233759);
390 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_PRE_POST_SCALE_3_B0
,
391 AR_PHY_PAPRD_PRE_POST_SCALE_3_B0_PAPRD_PRE_POST_SCALING_3_0
, 220464);
392 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_PRE_POST_SCALE_4_B0
,
393 AR_PHY_PAPRD_PRE_POST_SCALE_4_B0_PAPRD_PRE_POST_SCALING_4_0
, 208194);
394 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_PRE_POST_SCALE_5_B0
,
395 AR_PHY_PAPRD_PRE_POST_SCALE_5_B0_PAPRD_PRE_POST_SCALING_5_0
, 196949);
396 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_PRE_POST_SCALE_6_B0
,
397 AR_PHY_PAPRD_PRE_POST_SCALE_6_B0_PAPRD_PRE_POST_SCALING_6_0
, 185706);
398 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_PRE_POST_SCALE_7_B0
,
399 AR_PHY_PAPRD_PRE_POST_SCALE_7_B0_PAPRD_PRE_POST_SCALING_7_0
, 175487);
408 * XXX There's another copy of this in ar9300_reset.c, use that!
411 static inline HAL_CHANNEL_INTERNAL
*
412 ar9300_check_chan(struct ath_hal
*ah
, HAL_CHANNEL
*chan
)
414 if ((AR9300_IS_CHAN(chan
, CHANNEL_2GHZ
) ^
415 AR9300_IS_CHAN(chan
, CHANNEL_5GHZ
)) == 0)
417 HALDEBUG(ah
, HAL_DEBUG_CHANNEL
,
418 "%s: invalid channel %u/0x%x; not marked as 2GHz or 5GHz\n",
419 __func__
, chan
->channel
, chan
->channel_flags
);
423 if ((AR9300_IS_CHAN(chan
, CHANNEL_OFDM
) ^
424 AR9300_IS_CHAN(chan
, CHANNEL_CCK
) ^
425 AR9300_IS_CHAN(chan
, CHANNEL_HT20
) ^
426 AR9300_IS_CHAN(chan
, CHANNEL_HT40PLUS
) ^
427 AR9300_IS_CHAN(chan
, CHANNEL_HT40MINUS
)) == 0)
429 HALDEBUG(ah
, HAL_DEBUG_CHANNEL
,
430 "%s: invalid channel %u/0x%x; not marked as "
431 "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n", __func__
,
432 chan
->channel
, chan
->channel_flags
);
436 return (ath_hal_checkchannel(ah
, chan
));
440 void ar9300_enable_paprd(struct ath_hal
*ah
, HAL_BOOL enable_flag
,
441 struct ieee80211_channel
* chan
)
443 HAL_BOOL enable
= enable_flag
;
444 u_int32_t am_mask
= 0;
445 u_int32_t val
= OS_REG_READ(ah
, AR_2040_MODE
);
446 int is_2g
= IEEE80211_IS_CHAN_2GHZ(chan
);
447 HAL_CHANNEL_INTERNAL
*ichan
= ath_hal_checkchannel(ah
, chan
);
449 struct ath_hal_9300
*ahp
= AH9300(ah
);
451 if (val
& HAL_HT_MACMODE_2040
) {
454 if (enable_flag
== AH_TRUE
) {
455 ar9300_eeprom_t
*eep
= &AH9300(ah
)->ah_eeprom
;
459 * 3 bits for modal_header_5g.paprd_rate_mask_ht20
460 * is used for sub band disabling of paprd.
461 * 5G band is divided into 3 sub bands -- upper, mid, lower.
462 * If bit 30 of modal_header_5g.paprd_rate_mask_ht20 is set
463 * to one -- disable paprd for upper 5G
464 * If bit 29 of modal_header_5g.paprd_rate_mask_ht20 is set
465 * to one -- disable paprd for mid 5G
466 * If bit 28 of modal_header_5g.paprd_rate_mask_ht20 is set
467 * to one -- disable paprd for lower 5G
468 * u_int32_t am_mask = eep->modal_header_5g.paprd_rate_mask_ht20;
470 if (ichan
->channel
>= UPPER_5G_SUB_BANDSTART
) {
471 if (eep
->modal_header_5g
.paprd_rate_mask_ht20
& (1 << 30)) {
474 } else if (ichan
->channel
>= MID_5G_SUB_BANDSTART
) {
475 if (eep
->modal_header_5g
.paprd_rate_mask_ht20
& (1 << 29)) {
478 } else { /* must be in the lower 5G subband */
479 if (eep
->modal_header_5g
.paprd_rate_mask_ht20
& (1 << 28)) {
485 if (ahp
->ah_paprd_broken
) {
486 ahp
->ah_paprd_broken
= AH_FALSE
;
489 HALDEBUG(ah
, HAL_DEBUG_UNMASKABLE
,
490 "%s: PAPRD is in bad state. Don't enable PAPRD\n",
495 HAL_CHANNEL_INTERNAL
*ichan
;
498 am_mask
= ahp
->ah_2g_paprd_rate_mask_ht40
& AH_PAPRD_AM_PM_MASK
;
500 am_mask
= ahp
->ah_2g_paprd_rate_mask_ht20
& AH_PAPRD_AM_PM_MASK
;
504 am_mask
= ahp
->ah_5g_paprd_rate_mask_ht40
& AH_PAPRD_AM_PM_MASK
;
506 am_mask
= ahp
->ah_5g_paprd_rate_mask_ht20
& AH_PAPRD_AM_PM_MASK
;
509 /* Earlier we promgrammed TGT Power with Scaled down value, since
510 * PAPRD CAL was not done.
511 * Now we finish PAPRD CAL, so bump up the TGT PWR to original
512 * EEPROM Power. CTLs calc and Maverickd in
513 * "ar9300_eeprom_set_transmit_power"
515 ichan
= ar9300_check_chan(ah
, chan
);
516 ichan
->paprd_table_write_done
= 1;
517 // chan->paprd_table_write_done = 1;
519 ath_hal_printf(ah, "%s[%d] eeprom_set_transmit_power PAPRD\n",
522 if (ar9300_eeprom_set_transmit_power(ah
, &ahp
->ah_eeprom
, chan
,
523 ath_hal_getctl(ah
, chan
), ath_hal_getantennaallowed(ah
, chan
),
524 ath_hal_get_twice_max_regpower(AH_PRIVATE(ah
), ichan
, chan
),
525 AH_MIN(MAX_RATE_POWER
, AH_PRIVATE(ah
)->ah_powerLimit
)) != HAL_OK
) {
526 ichan
->paprd_table_write_done
= 0;
527 // chan->paprd_table_write_done = 0;
528 /* Intentional print */
530 "%s[%d] eeprom_set_transmit_power failed ABORT PAPRD\n",
533 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B0
,
534 AR_PHY_PAPRD_CTRL0_B0_PAPRD_ENABLE_0
, 0);
535 if (!AR_SREV_POSEIDON(ah
) && !AR_SREV_HORNET(ah
)) {
536 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B1
,
537 AR_PHY_PAPRD_CTRL0_B1_PAPRD_ENABLE_1
, 0);
538 if (!AR_SREV_JUPITER(ah
) || (AH9300(ah
)->ah_tx_chainmask
& AR9300_CHAIN2_MASK
)) {
539 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B2
,
540 AR_PHY_PAPRD_CTRL0_B2_PAPRD_ENABLE_2
, 0);
547 HALDEBUG(ah
, HAL_DEBUG_CALIBRATE
, "%s 2G %d HT40 %d am_mask 0x%08x\n",
548 __func__
, is_2g
, is_ht40
, am_mask
);
549 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_AM2AM
, AR_PHY_PAPRD_AM2AM_MASK
,
551 if (AR_SREV_HORNET(ah
)) {
552 OS_REG_RMW_FIELD_ALT(ah
,
553 AR_PHY_PAPRD_AM2PM
, AR_PHY_PAPRD_AM2PM_MASK
, 0);
555 OS_REG_RMW_FIELD_ALT(ah
,
556 AR_PHY_PAPRD_AM2PM
, AR_PHY_PAPRD_AM2PM_MASK
, am_mask
);
559 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_HT40
, AR_PHY_PAPRD_HT40_MASK
,
560 AR_PHY_PAPRD_HT40_MASK
);
562 if (AH9300(ah
)->ah_tx_chainmask
& AR9300_CHAIN0_MASK
) {
563 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B0
,
564 AR_PHY_PAPRD_CTRL0_B0_USE_SINGLE_TABLE_MASK
, 1);
565 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B0
,
566 AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_AM2PM_ENABLE_0
, 1);
567 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B0
,
568 AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_AM2AM_ENABLE_0
, 1);
569 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B0
,
570 AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_SCALING_ENA
, 0);
571 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B0
,
572 AR_PHY_PAPRD_CTRL1_B0_PA_GAIN_SCALE_FACT_0_MASK
, 181);
573 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B0
,
574 AR_PHY_PAPRD_CTRL1_B0_PAPRD_MAG_SCALE_FACT_0
, 361);
575 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B0
,
576 AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_SCALING_ENA
, 0);
577 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B0
,
578 AR_PHY_PAPRD_CTRL0_B0_PAPRD_MAG_THRSH_0
, 3);
581 if (AH9300(ah
)->ah_tx_chainmask
& AR9300_CHAIN1_MASK
) {
582 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B1
,
583 AR_PHY_PAPRD_CTRL0_B1_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_1
, 1);
584 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B1
,
585 AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_AM2PM_ENABLE_1
, 1);
586 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B1
,
587 AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_AM2AM_ENABLE_1
, 1);
588 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B1
,
589 AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_SCALING_ENA
, 0);
590 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B1
,
591 AR_PHY_PAPRD_CTRL1_B1_PA_GAIN_SCALE_FACT_1_MASK
, 181);
592 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B1
,
593 AR_PHY_PAPRD_CTRL1_B1_PAPRD_MAG_SCALE_FACT_1
, 361);
594 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B1
,
595 AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_SCALING_ENA
, 0);
596 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B1
,
597 AR_PHY_PAPRD_CTRL0_B1_PAPRD_MAG_THRSH_1
, 3);
600 if (AH9300(ah
)->ah_tx_chainmask
& AR9300_CHAIN2_MASK
) {
601 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B2
,
602 AR_PHY_PAPRD_CTRL0_B2_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_2
, 1);
603 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B2
,
604 AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_AM2PM_ENABLE_2
, 1);
605 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B2
,
606 AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_AM2AM_ENABLE_2
, 1);
607 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B2
,
608 AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_SCALING_ENA
, 0);
609 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B2
,
610 AR_PHY_PAPRD_CTRL1_B2_PA_GAIN_SCALE_FACT_2_MASK
, 181);
611 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B2
,
612 AR_PHY_PAPRD_CTRL1_B2_PAPRD_MAG_SCALE_FACT_2
, 361);
613 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B2
,
614 AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_SCALING_ENA
, 0);
615 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B2
,
616 AR_PHY_PAPRD_CTRL0_B2_PAPRD_MAG_THRSH_2
, 3);
619 if (AH9300(ah
)->ah_tx_chainmask
& AR9300_CHAIN0_MASK
) {
620 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B0
,
621 AR_PHY_PAPRD_CTRL0_B0_PAPRD_ENABLE_0
, 1);
624 if (AH9300(ah
)->ah_tx_chainmask
& AR9300_CHAIN1_MASK
) {
625 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B1
,
626 AR_PHY_PAPRD_CTRL0_B1_PAPRD_ENABLE_1
, 1);
629 if (AH9300(ah
)->ah_tx_chainmask
& AR9300_CHAIN2_MASK
) {
630 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B2
,
631 AR_PHY_PAPRD_CTRL0_B2_PAPRD_ENABLE_2
, 1);
635 if (AH9300(ah
)->ah_tx_chainmask
& AR9300_CHAIN0_MASK
) {
636 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B0
,
637 AR_PHY_PAPRD_CTRL0_B0_PAPRD_ENABLE_0
, 0);
640 if (AH9300(ah
)->ah_tx_chainmask
& AR9300_CHAIN1_MASK
) {
641 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B1
,
642 AR_PHY_PAPRD_CTRL0_B1_PAPRD_ENABLE_1
, 0);
645 if (AH9300(ah
)->ah_tx_chainmask
& AR9300_CHAIN2_MASK
) {
646 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B2
,
647 AR_PHY_PAPRD_CTRL0_B2_PAPRD_ENABLE_2
, 0);
652 static void ar9300_gain_table_entries(struct ath_hal
*ah
)
656 u_int32_t
*gain_table_entries
= AH9300(ah
)->paprd_gain_table_entries
;
657 u_int32_t
*gain_vs_table_index
= AH9300(ah
)->paprd_gain_table_index
;
659 reg
= AR_PHY_TXGAIN_TAB(1);
661 for (i
= 0; i
< 32; i
++) {
662 gain_table_entries
[i
] = OS_REG_READ(ah
, reg
);
663 gain_vs_table_index
[i
] = (gain_table_entries
[i
] >> 24) & 0xff;
666 * ah, "+++reg 0x%08x gain_table_entries[%d] = 0x%08x \n",
667 * reg, i, gain_table_entries[i]);
673 /* Get gain index for Target power */
674 static unsigned int ar9300_get_desired_gain_for_chain(struct ath_hal
*ah
,
675 int chain_num
, int target_power
)
677 int olpc_gain_delta
= 0;
678 int alpha_therm
= 0, alpha_volt
= 0;
679 int therm_cal_value
= 0, volt_cal_value
= 0;
680 int latest_therm_value
= 0, latest_volt_value
= 0, olpc_gain_delta_tmp
= 0;
681 int thermal_gain_corr
= 0, voltage_gain_corr
= 0, desired_scale
= 0;
682 int desired_gain
= 0;
685 /* Clear the training done bit */
686 if (AR_SREV_POSEIDON(ah
)) {
687 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON
,
688 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE
, 0);
690 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1
,
691 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE
, 0);
693 /*field_read("BB_tpc_12.desired_scale_ht40_5", &desired_scale);*/
695 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_TPC_12
,
696 AR_PHY_TPC_12_DESIRED_SCALE_HT40_5
);
697 /*field_read("BB_tpc_19.alpha_therm", &alpha_therm);*/
699 OS_REG_READ_FIELD(ah
, AR_PHY_TPC_19
, AR_PHY_TPC_19_ALPHA_THERM
);
700 /*field_read("BB_tpc_19.alpha_volt", &alpha_volt);*/
702 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_TPC_19
, AR_PHY_TPC_19_ALT_ALPHA_VOLT
);
704 /*field_read("BB_tpc_18.therm_cal_value", &therm_cal_value);*/
706 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_TPC_18
,
707 AR_PHY_TPC_18_ALT_THERM_CAL_VALUE
);
708 /*field_read("BB_tpc_18.volt_cal_value", &volt_cal_value);*/
710 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_TPC_18
,
711 AR_PHY_TPC_18_ALT_VOLT_CAL_VALUE
);
713 /*field_read("BB_therm_adc_4.latest_therm_value", &latest_therm_value);*/
715 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_THERM_ADC_4
,
716 AR_PHY_THERM_ADC_4_LATEST_THERM_VALUE
);
717 /*field_read("BB_therm_adc_4.latest_volt_value", &latest_volt_value);*/
719 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_THERM_ADC_4
,
720 AR_PHY_THERM_ADC_4_LATEST_VOLT_VALUE
);
724 * field_name, "%s%d%s%d\0", "BB_tpc_11_b",
725 * chain_num, ".olpc_gain_delta_", chain_num);
727 /*field_read(field_name, &olpc_gain_delta_tmp);*/
730 if (chain_num
== 0) {
731 olpc_gain_delta_tmp
=
732 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_TPC_11_B0
,
733 AR_PHY_TPC_11_B0_OLPC_GAIN_DELTA_0
);
734 cl_gain_mod
= OS_REG_READ_FIELD_ALT(ah
, AR_PHY_CL_TAB_0
,
735 AR_PHY_CL_TAB_0_CL_GAIN_MOD
);
736 } else if (chain_num
== 1) {
737 if (!AR_SREV_POSEIDON(ah
)) {
738 olpc_gain_delta_tmp
=
739 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_TPC_11_B1
,
740 AR_PHY_TPC_11_B1_OLPC_GAIN_DELTA_1
);
741 cl_gain_mod
= OS_REG_READ_FIELD_ALT(ah
, AR_PHY_CL_TAB_1
,
742 AR_PHY_CL_TAB_1_CL_GAIN_MOD
);
744 } else if (chain_num
== 2) {
745 if (!AR_SREV_POSEIDON(ah
)) {
746 olpc_gain_delta_tmp
=
747 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_TPC_11_B2
,
748 AR_PHY_TPC_11_B2_OLPC_GAIN_DELTA_2
);
749 cl_gain_mod
= OS_REG_READ_FIELD_ALT(ah
, AR_PHY_CL_TAB_2
,
750 AR_PHY_CL_TAB_2_CL_GAIN_MOD
);
753 /* invalid chain_num */
756 if (olpc_gain_delta_tmp
< 128) {
757 olpc_gain_delta
= olpc_gain_delta_tmp
;
759 olpc_gain_delta
= olpc_gain_delta_tmp
- 256;
763 (int) (alpha_therm
* (latest_therm_value
- therm_cal_value
) +
766 (int) (alpha_volt
* (latest_volt_value
- volt_cal_value
) + 64) >> 7;
768 target_power
- olpc_gain_delta
- thermal_gain_corr
-
769 voltage_gain_corr
+ desired_scale
+ cl_gain_mod
;
772 * "olpc_gain_delta %d, desired_gain %d\n",
773 * olpc_gain_delta, desired_gain);
777 "+++ target_power %d olpc_gain_delta %d, cl_gain_mod %d,"
778 "thermal_gain_corr %d voltage_gain_corr %d desired_scale %d"
780 target_power
, olpc_gain_delta
, cl_gain_mod
, thermal_gain_corr
,
782 desired_scale
, desired_gain
);
784 return (unsigned int) desired_gain
;
787 static void ar9300_tx_force_gain(struct ath_hal
*ah
, unsigned int gain_index
)
789 int selected_gain_entry
, txbb1dbgain
, txbb6dbgain
, txmxrgain
;
790 int padrvgn_a
, padrvgn_b
, padrvgn_c
, padrvgn_d
;
791 u_int32_t
*gain_table_entries
= AH9300(ah
)->paprd_gain_table_entries
;
793 /*u_int32_t *gain_vs_table_index = ah->paprd_gain_table_index;*/
794 selected_gain_entry
= gain_table_entries
[gain_index
];
795 txbb1dbgain
= selected_gain_entry
& 0x7;
796 txbb6dbgain
= (selected_gain_entry
>> 3) & 0x3;
797 txmxrgain
= (selected_gain_entry
>> 5) & 0xf;
798 padrvgn_a
= (selected_gain_entry
>> 9) & 0xf;
799 padrvgn_b
= (selected_gain_entry
>> 13) & 0xf;
800 padrvgn_c
= (selected_gain_entry
>> 17) & 0xf;
801 padrvgn_d
= (selected_gain_entry
>> 21) & 0x3;
803 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_TX_FORCED_GAIN
,
804 AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN
, txbb1dbgain
);
805 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_TX_FORCED_GAIN
,
806 AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN
, txbb6dbgain
);
807 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_TX_FORCED_GAIN
,
808 AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN
, txmxrgain
);
809 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_TX_FORCED_GAIN
,
810 AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA
, padrvgn_a
);
811 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_TX_FORCED_GAIN
,
812 AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB
, padrvgn_b
);
813 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_TX_FORCED_GAIN
,
814 AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC
, padrvgn_c
);
815 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_TX_FORCED_GAIN
,
816 AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND
, padrvgn_d
);
817 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_TX_FORCED_GAIN
,
818 AR_PHY_TX_FORCED_GAIN_FORCED_ENABLE_PAL
, 0);
819 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_TX_FORCED_GAIN
,
820 AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN
, 0);
822 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_TPC_1
, AR_PHY_TPC_1_FORCED_DAC_GAIN
, 0);
823 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_TPC_1
, AR_PHY_TPC_1_FORCE_DAC_GAIN
, 0);
826 #define HAL_DEBUG_PAPRD HAL_DEBUG_CALIBRATE /* driver: conditionally print */
828 #if defined(ART_PAPRD_DEBUG) || defined(AH_DEBUG)
829 static void ar9300_paprd_debug_print(struct ath_hal
*ah
)
832 int txbb1dbgain
, txbb6dbgain
, txmxrgain
;
833 int padrvgn_a
, padrvgn_b
, padrvgn_c
, padrvgn_d
;
835 if (AR_SREV_POSEIDON(ah
)) {
836 /*field_read("BB_paprd_trainer_cntl1.cf_paprd_lb_skip", &temp);*/
838 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON
,
839 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP
);
840 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
841 "BB_paprd_trainer_cntl1.cf_paprd_lb_skip=0x%x\n", temp
);
842 /*field_read("BB_paprd_trainer_cntl1.cf_paprd_lb_enable", &temp);*/
844 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON
,
845 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE
);
846 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
847 "BB_paprd_trainer_cntl1.cf_paprd_lb_enable=0x%x\n", temp
);
848 /*field_read("BB_paprd_trainer_cntl1.cf_paprd_tx_gain_force", &temp);*/
850 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON
,
851 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE
);
852 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
853 "BB_paprd_trainer_cntl1.cf_paprd_tx_gain_force=0x%x\n", temp
);
856 * "BB_paprd_trainer_cntl1.cf_paprd_rx_bb_gain_force", &temp);
859 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON
,
860 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE
);
861 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
862 "BB_paprd_trainer_cntl1.cf_paprd_rx_bb_gain_force=0x%x\n", temp
);
863 /*field_read("BB_paprd_trainer_cntl1.cf_paprd_iqcorr_enable", &temp);*/
865 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON
,
866 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE
);
867 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
868 "BB_paprd_trainer_cntl1.cf_paprd_iqcorr_enable=0x%x\n", temp
);
869 /*field_read("BB_paprd_trainer_cntl1.cf_paprd_agc2_settling", &temp);*/
871 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON
,
872 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING
);
873 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
874 "BB_paprd_trainer_cntl1.cf_paprd_agc2_settling=0x%x\n", temp
);
875 /*field_read("BB_paprd_trainer_cntl1.cf_paprd_train_enable", &temp);*/
877 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON
,
878 AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE
);
879 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
880 "BB_paprd_trainer_cntl1.cf_paprd_train_enable=0x%x\n", temp
);
882 * field_read("BB_paprd_trainer_cntl2.cf_paprd_init_rx_bb_gain", &temp);
885 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL2_POSEIDON
,
886 AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN
);
887 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
888 "BB_paprd_trainer_cntl2.cf_paprd_init_rx_bb_gain=0x%x\n", temp
);
889 /*field_read("BB_paprd_trainer_cntl3.cf_paprd_fine_corr_len", &temp);*/
891 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON
,
892 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN
);
893 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
894 "BB_paprd_trainer_cntl3.cf_paprd_fine_corr_len=0x%x\n", temp
);
896 * field_read("BB_paprd_trainer_cntl3.cf_paprd_coarse_corr_len", &temp);
899 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON
,
900 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN
);
901 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
902 "BB_paprd_trainer_cntl3.cf_paprd_coarse_corr_len=0x%x\n", temp
);
904 * field_read("BB_paprd_trainer_cntl3.cf_paprd_num_corr_stages", &temp);
907 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON
,
908 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES
);
909 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
910 "BB_paprd_trainer_cntl3.cf_paprd_num_corr_stages=0x%x\n", temp
);
913 * "BB_paprd_trainer_cntl3.cf_paprd_min_loopback_del", &temp);
916 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON
,
917 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL
);
918 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
919 "BB_paprd_trainer_cntl3.cf_paprd_min_loopback_del=0x%x\n", temp
);
920 /*field_read("BB_paprd_trainer_cntl3.cf_paprd_quick_drop", &temp);*/
922 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON
,
923 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP
);
924 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
925 "BB_paprd_trainer_cntl3.cf_paprd_quick_drop=0x%x\n", temp
);
928 * "BB_paprd_trainer_cntl3.cf_paprd_adc_desired_size", &temp);
931 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON
,
932 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE
);
933 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
934 "BB_paprd_trainer_cntl3.cf_paprd_adc_desired_size=0x%x\n", temp
);
936 * field_read("BB_paprd_trainer_cntl3.cf_paprd_bbtxmix_disable", &temp);
939 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON
,
940 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE
);
941 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
942 "BB_paprd_trainer_cntl3.cf_paprd_bbtxmix_disable=0x%x\n", temp
);
943 /*field_read("BB_paprd_trainer_cntl4.cf_paprd_safety_delta", &temp);*/
945 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL4_POSEIDON
,
946 AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA
);
947 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
948 "BB_paprd_trainer_cntl4.cf_paprd_safety_delta=0x%x\n", temp
);
949 /*field_read("BB_paprd_trainer_cntl4.cf_paprd_min_corr", &temp);*/
951 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL4_POSEIDON
,
952 AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR
);
953 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
954 "BB_paprd_trainer_cntl4.cf_paprd_min_corr=0x%x\n", temp
);
955 /*field_read("BB_paprd_trainer_stat1.paprd_agc2_pwr", &temp);*/
957 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON
,
958 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR
);
959 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
960 " paprd_agc2_pwr = 0x%02x\n", temp
);
961 /*field_read("BB_paprd_trainer_stat1.paprd_rx_gain_idx", &temp);*/
963 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON
,
964 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX
);
965 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
966 " paprd_rx_gain_idx = 0x%02x\n", temp
);
967 /*field_read("BB_paprd_trainer_stat1.paprd_train_active", &temp);*/
969 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON
,
970 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE
);
971 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
972 " paprd_train_active = 0x%08x\n", temp
);
973 /*field_read("BB_paprd_trainer_stat1.paprd_corr_err", &temp);*/
975 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON
,
976 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR
);
977 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
978 " paprd_corr_err = 0x%08x\n", temp
);
979 /*field_read("BB_paprd_trainer_stat1.paprd_train_incomplete", &temp);*/
981 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON
,
982 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE
);
983 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
984 " paprd_train_incomplete = 0x%08x\n", temp
);
985 /*field_read("BB_paprd_trainer_stat1.paprd_train_done", &temp);*/
987 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON
,
988 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE
);
989 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
990 " paprd_train_done = 0x%08x\n", temp
);
991 /*field_read("BB_paprd_trainer_stat2.paprd_fine_idx", &temp);*/
993 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT2_POSEIDON
,
994 AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX
);
995 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
996 " paprd_fine_idx = 0x%08x\n", temp
);
997 /*field_read("BB_paprd_trainer_stat2.paprd_coarse_idx", &temp);*/
999 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT2_POSEIDON
,
1000 AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX
);
1001 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1002 " paprd_coarse_idx = 0x%08x\n", temp
);
1003 /*field_read("BB_paprd_trainer_stat2.paprd_fine_val", &temp);*/
1005 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT2_POSEIDON
,
1006 AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL
);
1007 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1008 " paprd_fine_val = 0x%08x\n", temp
);
1009 /*field_read("BB_paprd_trainer_stat3.paprd_train_samples_cnt", &temp);*/
1011 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT3_POSEIDON
,
1012 AR_PHY_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT
);
1013 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1014 " paprd_train_samples_cnt = 0x%08x\n", temp
);
1016 /*field_read("BB_paprd_trainer_cntl1.cf_paprd_lb_skip", &temp);*/
1018 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1
,
1019 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP
);
1020 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1021 "BB_paprd_trainer_cntl1.cf_paprd_lb_skip=0x%x\n", temp
);
1022 /*field_read("BB_paprd_trainer_cntl1.cf_paprd_lb_enable", &temp);*/
1024 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1
,
1025 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE
);
1026 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1027 "BB_paprd_trainer_cntl1.cf_paprd_lb_enable=0x%x\n", temp
);
1028 /*field_read("BB_paprd_trainer_cntl1.cf_paprd_tx_gain_force", &temp);*/
1030 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1
,
1031 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE
);
1032 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1033 "BB_paprd_trainer_cntl1.cf_paprd_tx_gain_force=0x%x\n", temp
);
1036 * "BB_paprd_trainer_cntl1.cf_paprd_rx_bb_gain_force", &temp);
1039 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1
,
1040 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE
);
1041 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1042 "BB_paprd_trainer_cntl1.cf_paprd_rx_bb_gain_force=0x%x\n", temp
);
1043 /*field_read("BB_paprd_trainer_cntl1.cf_paprd_iqcorr_enable", &temp);*/
1045 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1
,
1046 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE
);
1047 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1048 "BB_paprd_trainer_cntl1.cf_paprd_iqcorr_enable=0x%x\n", temp
);
1049 /*field_read("BB_paprd_trainer_cntl1.cf_paprd_agc2_settling", &temp);*/
1051 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1
,
1052 AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING
);
1053 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1054 "BB_paprd_trainer_cntl1.cf_paprd_agc2_settling=0x%x\n", temp
);
1055 /*field_read("BB_paprd_trainer_cntl1.cf_paprd_train_enable", &temp);*/
1057 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL1
,
1058 AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE
);
1059 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1060 "BB_paprd_trainer_cntl1.cf_paprd_train_enable=0x%x\n", temp
);
1062 * field_read("BB_paprd_trainer_cntl2.cf_paprd_init_rx_bb_gain", &temp);
1065 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL2
,
1066 AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN
);
1067 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1068 "BB_paprd_trainer_cntl2.cf_paprd_init_rx_bb_gain=0x%x\n", temp
);
1069 /*field_read("BB_paprd_trainer_cntl3.cf_paprd_fine_corr_len", &temp);*/
1071 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3
,
1072 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN
);
1073 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1074 "BB_paprd_trainer_cntl3.cf_paprd_fine_corr_len=0x%x\n", temp
);
1076 * field_read("BB_paprd_trainer_cntl3.cf_paprd_coarse_corr_len", &temp);
1079 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3
,
1080 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN
);
1081 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1082 "BB_paprd_trainer_cntl3.cf_paprd_coarse_corr_len=0x%x\n", temp
);
1084 * field_read("BB_paprd_trainer_cntl3.cf_paprd_num_corr_stages", &temp);
1087 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3
,
1088 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES
);
1089 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1090 "BB_paprd_trainer_cntl3.cf_paprd_num_corr_stages=0x%x\n", temp
);
1093 * "BB_paprd_trainer_cntl3.cf_paprd_min_loopback_del", &temp);
1096 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3
,
1097 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL
);
1098 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1099 "BB_paprd_trainer_cntl3.cf_paprd_min_loopback_del=0x%x\n", temp
);
1100 /*field_read("BB_paprd_trainer_cntl3.cf_paprd_quick_drop", &temp);*/
1102 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3
,
1103 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP
);
1104 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1105 "BB_paprd_trainer_cntl3.cf_paprd_quick_drop=0x%x\n", temp
);
1108 * "BB_paprd_trainer_cntl3.cf_paprd_adc_desired_size", &temp);
1111 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3
,
1112 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE
);
1113 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1114 "BB_paprd_trainer_cntl3.cf_paprd_adc_desired_size=0x%x\n", temp
);
1117 * "BB_paprd_trainer_cntl3.cf_paprd_bbtxmix_disable", &temp);
1120 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3
,
1121 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE
);
1122 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1123 "BB_paprd_trainer_cntl3.cf_paprd_bbtxmix_disable=0x%x\n", temp
);
1124 /*field_read("BB_paprd_trainer_cntl4.cf_paprd_safety_delta", &temp);*/
1126 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL4
,
1127 AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA
);
1128 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1129 "BB_paprd_trainer_cntl4.cf_paprd_safety_delta=0x%x\n", temp
);
1130 /*field_read("BB_paprd_trainer_cntl4.cf_paprd_min_corr", &temp);*/
1132 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL4
,
1133 AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR
);
1134 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1135 "BB_paprd_trainer_cntl4.cf_paprd_min_corr=0x%x\n", temp
);
1136 /*field_read("BB_paprd_trainer_stat1.paprd_agc2_pwr", &temp);*/
1138 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1
,
1139 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR
);
1140 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1141 " paprd_agc2_pwr = 0x%02x\n", temp
);
1142 /*field_read("BB_paprd_trainer_stat1.paprd_rx_gain_idx", &temp);*/
1144 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1
,
1145 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX
);
1146 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1147 " paprd_rx_gain_idx = 0x%02x\n", temp
);
1148 /*field_read("BB_paprd_trainer_stat1.paprd_train_active", &temp);*/
1150 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1
,
1151 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE
);
1152 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1153 " paprd_train_active = 0x%08x\n", temp
);
1154 /*field_read("BB_paprd_trainer_stat1.paprd_corr_err", &temp);*/
1156 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1
,
1157 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR
);
1158 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1159 " paprd_corr_err = 0x%08x\n", temp
);
1160 /*field_read("BB_paprd_trainer_stat1.paprd_train_incomplete", &temp);*/
1162 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1
,
1163 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE
);
1164 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1165 " paprd_train_incomplete = 0x%08x\n", temp
);
1166 /*field_read("BB_paprd_trainer_stat1.paprd_train_done", &temp);*/
1168 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1
,
1169 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE
);
1170 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1171 " paprd_train_done = 0x%08x\n", temp
);
1172 /*field_read("BB_paprd_trainer_stat2.paprd_fine_idx", &temp);*/
1174 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT2
,
1175 AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX
);
1176 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1177 " paprd_fine_idx = 0x%08x\n", temp
);
1178 /*field_read("BB_paprd_trainer_stat2.paprd_coarse_idx", &temp);*/
1180 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT2
,
1181 AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX
);
1182 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1183 " paprd_coarse_idx = 0x%08x\n", temp
);
1184 /*field_read("BB_paprd_trainer_stat2.paprd_fine_val", &temp);*/
1186 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT2
,
1187 AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL
);
1188 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1189 " paprd_fine_val = 0x%08x\n", temp
);
1190 /*field_read("BB_paprd_trainer_stat3.paprd_train_samples_cnt", &temp);*/
1192 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT3
,
1193 AR_PHY_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT
);
1194 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1195 " paprd_train_samples_cnt = 0x%08x\n", temp
);
1198 /*field_read("BB_tpc_1.force_dac_gain", &temp);*/
1200 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_TPC_1
, AR_PHY_TPC_1_FORCE_DAC_GAIN
);
1201 HALDEBUG(ah
, HAL_DEBUG_PAPRD
, " dac_gain_forced = 0x%08x\n",
1203 /*field_read("BB_tpc_1.forced_dac_gain", &temp);*/
1205 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_TPC_1
, AR_PHY_TPC_1_FORCED_DAC_GAIN
);
1206 HALDEBUG(ah
, HAL_DEBUG_PAPRD
, " forced_dac_gain = 0x%08x\n",
1209 /*field_read("BB_paprd_ctrl0_b0.paprd_enable_0", &temp);*/
1211 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B0
,
1212 AR_PHY_PAPRD_CTRL0_B0_PAPRD_ENABLE_0
);
1213 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1214 " BB_paprd_ctrl0_b0.paprd_enable_0 = 0x%08x\n", temp
);
1215 if (!AR_SREV_POSEIDON(ah
)) {
1216 /*field_read("BB_paprd_ctrl0_b1.paprd_enable_1", &temp);*/
1218 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B1
,
1219 AR_PHY_PAPRD_CTRL0_B1_PAPRD_ENABLE_1
);
1220 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1221 " BB_paprd_ctrl0_b1.paprd_enable_1 = 0x%08x\n", temp
);
1222 if (AH9300(ah
)->ah_tx_chainmask
& AR9300_CHAIN2_MASK
) {
1223 /*field_read("BB_paprd_ctrl0_b2.paprd_enable_2", &temp);*/
1225 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL0_B2
,
1226 AR_PHY_PAPRD_CTRL0_B2_PAPRD_ENABLE_2
);
1227 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1228 " BB_paprd_ctrl0_b2.paprd_enable_2 = 0x%08x\n", temp
);
1232 /*field_read("BB_tx_forced_gain.forced_txbb1dbgain", &txbb1dbgain);*/
1234 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_TX_FORCED_GAIN
,
1235 AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN
);
1236 /*field_read("BB_tx_forced_gain.forced_txbb6dbgain", &txbb6dbgain);*/
1238 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_TX_FORCED_GAIN
,
1239 AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN
);
1240 /*field_read("BB_tx_forced_gain.forced_txmxrgain", &txmxrgain);*/
1242 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_TX_FORCED_GAIN
,
1243 AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN
);
1244 /*field_read("BB_tx_forced_gain.forced_padrvgn_a", &padrvgn_a);*/
1246 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_TX_FORCED_GAIN
,
1247 AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA
);
1248 /*field_read("BB_tx_forced_gain.forced_padrvgn_b", &padrvgn_b);*/
1250 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_TX_FORCED_GAIN
,
1251 AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB
);
1252 /*field_read("BB_tx_forced_gain.forced_padrvgn_c", &padrvgn_c);*/
1254 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_TX_FORCED_GAIN
,
1255 AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC
);
1256 /*field_read("BB_tx_forced_gain.forced_padrvgn_d", &padrvgn_d);*/
1258 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_TX_FORCED_GAIN
,
1259 AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND
);
1261 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1262 "txbb1dbgain=0x%x, txbb6dbgain=0x%x, txmxrgain=0x%x\n",
1263 txbb1dbgain
, txbb6dbgain
, txmxrgain
);
1264 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1265 "padrvgn_a=0x%x, padrvgn_b=0x%x\n", padrvgn_a
, padrvgn_b
);
1266 HALDEBUG(ah
, HAL_DEBUG_PAPRD
,
1267 "padrvgn_c=0x%x, padrvgn_d=0x%x\n", padrvgn_c
, padrvgn_d
);
1270 #define ar9300_paprd_debug_print(ah) /* dummy macro */
1271 #endif /* defined(ART_PAPRD_DEBUG) || defined(AH_DEBUG) */
1273 static int ar9300_create_pa_curve(struct ath_hal
*ah
, u_int32_t
* pa_table
,
1274 u_int32_t
* small_signal_gain
, int * pa_in
)
1278 /*char field_name[100];*/
1279 u_int32_t paprd_train_data_l
[48], paprd_train_data_u
[48];
1282 ar9300_paprd_debug_print(ah
);
1283 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_CHAN_INFO_MEMORY
,
1284 AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ
, 0);
1285 reg
= AR_PHY_CHAN_INFO_TAB_0
;
1287 for (i
= 0; i
< 48; i
++) {
1290 * field_name, "%s%d%s\0", "BB_chan_info_chan_tab_b0[",
1291 * i, "].chaninfo_word");
1293 /*field_read(field_name, &paprd_train_data_l[i]);*/
1294 paprd_train_data_l
[i
] = OS_REG_READ(ah
, reg
);
1298 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_CHAN_INFO_MEMORY
,
1299 AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ
, 1);
1300 reg
= AR_PHY_CHAN_INFO_TAB_0
;
1302 for (i
= 0; i
< 48; i
++) {
1305 * field_name, "%s%d%s\0", "BB_chan_info_chan_tab_b0[",
1306 * i, "].chaninfo_word");
1308 /*field_read(field_name, &paprd_train_data_u[i]);*/
1309 paprd_train_data_u
[i
] = OS_REG_READ(ah
, reg
);
1314 * for(i=0; i<48; i++)
1316 * ah, "%08x%08x\n", paprd_train_data_u[i], paprd_train_data_l[i]);
1319 if (create_pa_curve(
1320 paprd_train_data_l
, paprd_train_data_u
,
1321 pa_table
, small_signal_gain
, pa_in
) ==
1326 /* Clear the training done bit */
1327 if (AR_SREV_POSEIDON(ah
)) {
1328 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON
,
1329 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE
, 0);
1331 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1
,
1332 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE
, 0);
1337 static int find_expn(int num
)
1352 static int find_proper_scale(int expn
, int n
)
1356 q_pw
= (expn
> n
) ? expn
- 10 : 0;
1360 static int find_max(int *array
, int length
)
1366 for (i
= 0; i
< length
; i
++) {
1367 if (array
[i
] > loc_max
) {
1375 static int paprd_abs(int num
)
1385 HAL_BOOL
create_pa_curve(u_int32_t
* paprd_train_data_l
,
1386 u_int32_t
* paprd_train_data_u
, u_int32_t
* pa_table
,
1387 u_int32_t
* g_fxp_ext
, int *pa_in
)
1389 unsigned int accum_cnt
[NUM_BIN
+ 1];
1390 unsigned int accum_tx
[NUM_BIN
+ 1];
1391 unsigned int accum_rx
[NUM_BIN
+ 1];
1392 unsigned int accum_ang
[NUM_BIN
+ 1];
1393 unsigned int thresh_accum_cnt
;
1398 int x_est
[NUM_BIN
+ 1];
1400 int theta
[NUM_BIN
+ 1];
1401 int y_sqr
[NUM_BIN
+ 1];
1402 int y_quad
[NUM_BIN
+ 1];
1403 int theta_tilde
[NUM_BIN
+ 1];
1404 int pa_angle
[NUM_BIN
+ 1];
1406 int b1_tmp
[NUM_BIN
+ 1];
1407 int b2_tmp
[NUM_BIN
+ 1];
1408 int b1_abs
[NUM_BIN
+ 1];
1409 int b2_abs
[NUM_BIN
+ 1];
1411 int y_lin
[NUM_BIN
+ 1];
1412 int y_est
[NUM_BIN
+ 1];
1413 int x_est_fxp1_nonlin
[NUM_BIN
+ 1];
1414 int x_tilde
[NUM_BIN
+ 1];
1415 int x_tilde_abs
[NUM_BIN
+ 1];
1420 int m
, half_lo
, half_hi
;
1423 int q_x
, q_b1
, q_b2
;
1424 int beta_raw
, alpha_raw
, scale_b
;
1425 int q_scale_b
, q_beta
, q_alpha
;
1427 int order_1
, order_2
;
1428 int order1_5x
, order2_3x
;
1429 int order1_5x_rem
, order2_3x_rem
;
1432 int theta_low_bin
= 0;
1435 * [15:00] u16, accum_cnt[15:00]: number of samples in the bin
1436 * [42:16] u27, accum_tx[26:00]: sum(tx amplitude) of the bin
1437 * [63:43] u21, accum_rx[20:00]:
1438 * sum(rx amplitude distance to lower bin edge) of the bin
1439 * [90:64] s27, accum_ang[26:00]: sum(angles) of the bin
1443 * Disregard any bin that contains less than
1444 * or equal to 16 counts of samples
1446 thresh_accum_cnt
= 16;
1449 for (bin
= 0; bin
< NUM_BIN
; bin
++) {
1450 accum_cnt
[bin
] = paprd_train_data_l
[bin
] & 0xffff;
1451 /* lower 16 bit OR-ed upper 11 bits */
1453 ((paprd_train_data_l
[bin
] >> 16) & 0xffff) |
1454 ((paprd_train_data_u
[bin
] & 0x7ff) << 16);
1456 ((paprd_train_data_u
[bin
] >> 11) & 0x1f) |
1457 ((paprd_train_data_l
[bin
+ 23] & 0xffff) << 5);
1459 ((paprd_train_data_l
[bin
+ 23] >> 16) & 0xffff) |
1460 ((paprd_train_data_u
[bin
+ 23] & 0x7ff) << 16);
1463 * "%d\t%d\t%d\t%d\n", accum_cnt[bin], accum_tx[bin],
1464 * accum_rx[bin], accum_ang[bin]);
1466 if (accum_cnt
[bin
] > thresh_accum_cnt
) {
1467 /* accum_cnt[i] will be non-zero at this point */
1469 ((((accum_tx
[bin
] << scale_factor
) +
1470 accum_cnt
[bin
]) / accum_cnt
[bin
]) + 32) >> scale_factor
;
1472 (((((accum_rx
[bin
] << scale_factor
) +
1473 accum_cnt
[bin
]) / accum_cnt
[bin
]) + 32) >> scale_factor
) +
1474 (1 << scale_factor
) * max_index
+ 16;
1475 if (accum_ang
[bin
] >= (1 << 26)) {
1477 ((accum_ang
[bin
] - (1 << 27)) * (1 << scale_factor
) +
1479 theta
[bin
+ 1] = theta
[bin
+ 1] / (int) accum_cnt
[bin
];
1482 * ((accum_ang[i] - (1 << 27)) *
1483 * (1 << scale_factor) + zz) / zz;
1487 ((accum_ang
[bin
] * (1 << scale_factor
)) +
1488 accum_cnt
[bin
]) / accum_cnt
[bin
];
1494 * "i=%d, theta[i+1]=%d\t%d\t%d\t%d\t%d\n",
1495 * i, theta[i+1], accum_cnt[i],
1496 * accum_tx[i], accum_rx[i], accum_ang[i]);
1501 * Find average theta of first 5 bin and all of those to same value.
1502 * Curve is linear at that range.
1504 for (bin
= 1; bin
< 6; bin
++) {
1505 theta_low_bin
+= theta
[bin
];
1507 theta_low_bin
= theta_low_bin
/ 5;
1508 for (bin
= 1; bin
< 6; bin
++) {
1509 theta
[bin
] = theta_low_bin
;
1512 /* Set values at origin */
1513 theta
[0] = theta_low_bin
;
1515 for (bin
= 0; bin
<= max_index
; bin
++) {
1516 theta
[bin
] = theta
[bin
] - theta_low_bin
;
1517 /*printf("bin=%d, theta[bin] = %d\n", bin, theta[bin]);*/
1523 /* low signal gain */
1524 if (x_est
[6] == x_est
[3]) {
1528 (((y
[6] - y
[3]) * 1 << scale_factor
) + (x_est
[6] - x_est
[3])) /
1529 (x_est
[6] - x_est
[3]);
1533 * NULL, "%s[%d] Potential divide by zero error\n",
1534 * __func__, __LINE__);
1539 for (bin
= 0; bin
<= max_index
; bin
++) {
1541 (g_fxp
* (x_est
[bin
] - x_est
[3]) + (1 << scale_factor
)) /
1542 (1 << scale_factor
) + y
[3];
1544 y_intercept
= y_lin
[0];
1546 for (bin
= 0; bin
<= max_index
; bin
++) {
1547 y_est
[bin
] = y
[bin
] - y_intercept
;
1548 y_lin
[bin
] = y_lin
[bin
] - y_intercept
;
1551 for (bin
= 0; bin
<= 3; bin
++) {
1552 y_est
[bin
] = bin
* 32;
1553 /* g_fxp was checked for zero already */
1554 x_est
[bin
] = ((y_est
[bin
] * 1 << scale_factor
) + g_fxp
) / g_fxp
;
1558 * for (bin = 0; bin <= max_index; bin++) {
1559 * printf("y_est[%d] = %d, x_est[%d]=%d\n",
1560 * bin, y_est[bin], bin, x_est[bin]);
1563 for (bin
= 0; bin
<= max_index
; bin
++) {
1564 x_est_fxp1_nonlin
[bin
] =
1565 x_est
[bin
] - ((1 << scale_factor
) * y_est
[bin
] + g_fxp
) / g_fxp
;
1566 /*printf("x_est_fxp1_nonlin[%d] = %d\n", bin, x_est_fxp1_nonlin[bin]);*/
1569 /* Check for divide by 0 */
1570 if (y_est
[max_index
] == 0) {
1574 (x_est_fxp1_nonlin
[max_index
] + y_est
[max_index
]) / y_est
[max_index
];
1575 if (order_x_by_y
== 0) {
1577 } else if (order_x_by_y
== 1) {
1583 half_lo
= (max_index
> 15) ? 7 : max_index
>> 1;
1584 half_hi
= max_index
- half_lo
;
1589 for (bin
= 0; bin
<= half_hi
; bin
++) {
1590 if (y_est
[bin
+ half_lo
] == 0) {
1593 * NULL, "%s Potential divide by zero error\n", __func__);
1599 (x_est_fxp1_nonlin
[bin
+ half_lo
] * (1 << m
) +
1600 y_est
[bin
+ half_lo
]) / y_est
[bin
+ half_lo
];
1601 x_tilde
[bin
] = (x_tilde
[bin
] * (1 << m
) + y_est
[bin
+ half_lo
]) /
1602 y_est
[bin
+ half_lo
];
1603 x_tilde
[bin
] = (x_tilde
[bin
] * (1 << m
) + y_est
[bin
+ half_lo
]) /
1604 y_est
[bin
+ half_lo
];
1607 (y_est
[bin
+ half_lo
] * y_est
[bin
+ half_lo
] +
1608 (scale_factor
* scale_factor
)) / (scale_factor
* scale_factor
);
1609 x_tilde_abs
[bin
] = paprd_abs(x_tilde
[bin
]);
1610 y_quad
[bin
] = y_sqr
[bin
] * y_sqr
[bin
];
1611 sum_y_sqr
= sum_y_sqr
+ y_sqr
[bin
];
1612 sum_y_quad
= sum_y_quad
+ y_quad
[bin
];
1615 /*printf("sum_y_sqr = %d, sum_y_quad=%d\n", sum_y_sqr, sum_y_quad);*/
1617 for (bin
= 0; bin
<= half_hi
; bin
++) {
1618 b1_tmp
[bin
] = y_sqr
[bin
] * (half_hi
+ 1) - sum_y_sqr
;
1619 b2_tmp
[bin
] = sum_y_quad
- sum_y_sqr
* y_sqr
[bin
];
1620 b1_abs
[bin
] = paprd_abs(b1_tmp
[bin
]);
1621 b2_abs
[bin
] = paprd_abs(b2_tmp
[bin
]);
1625 * "bin=%d, b1_tmp[bin] = %d, b2_tmp[bin] = %d\n",
1626 * bin, b1_tmp[bin], b2_tmp[bin]);
1630 q_x
= find_proper_scale(find_expn(find_max(x_tilde_abs
, half_hi
+ 1)), 10);
1631 q_b1
= find_proper_scale(find_expn(find_max(b1_abs
, half_hi
+ 1)), 10);
1632 q_b2
= find_proper_scale(find_expn(find_max(b2_abs
, half_hi
+ 1)), 10);
1637 for (bin
= 0; bin
<= half_hi
; bin
++) {
1638 x_tilde
[bin
] = x_tilde
[bin
] / (1 << q_x
);
1639 b1_tmp
[bin
] = b1_tmp
[bin
] / (1 << q_b1
);
1640 b2_tmp
[bin
] = b2_tmp
[bin
] / (1 << q_b2
);
1644 * "bin=%d, b1_tmp[bin]=%d b2_tmp[bin]=%d x_tilde[bin] = %d\n",
1645 * bin, b1_tmp[bin], b2_tmp[bin], x_tilde[bin]);
1647 beta_raw
= beta_raw
+ b1_tmp
[bin
] * x_tilde
[bin
];
1648 alpha_raw
= alpha_raw
+ b2_tmp
[bin
] * x_tilde
[bin
];
1652 ((sum_y_quad
/ scale_factor
) * (half_hi
+ 1) -
1653 (sum_y_sqr
/ scale_factor
) * sum_y_sqr
) * scale_factor
;
1654 q_scale_b
= find_proper_scale(find_expn(paprd_abs(scale_b
)), 10);
1655 scale_b
= scale_b
/ (1 << q_scale_b
);
1656 /* Check for divide by 0 */
1660 q_beta
= find_proper_scale(find_expn(paprd_abs(beta_raw
)), 10);
1661 q_alpha
= find_proper_scale(find_expn(paprd_abs(alpha_raw
)), 10);
1663 beta_raw
= beta_raw
/ (1 << q_beta
);
1664 alpha_raw
= alpha_raw
/ (1 << q_alpha
);
1665 alpha
= (alpha_raw
<< 10) / scale_b
;
1666 beta
= (beta_raw
<< 10) / scale_b
;
1667 order_1
= 3 * m
- q_x
- q_b1
- q_beta
+ 10 + q_scale_b
;
1668 order_2
= 3 * m
- q_x
- q_b2
- q_alpha
+ 10 + q_scale_b
;
1670 order1_5x
= order_1
/ 5;
1671 order2_3x
= order_2
/ 3;
1673 order1_5x_rem
= order_1
- 5 * order1_5x
;
1674 order2_3x_rem
= order_2
- 3 * order2_3x
;
1676 for (idx
= 0; idx
< AR9300_PAPRD_TABLE_SZ
; idx
++) {
1678 y5
= ((beta
* tmp
) >> 6) >> order1_5x
;
1679 y5
= (y5
* tmp
) >> order1_5x
;
1680 y5
= (y5
* tmp
) >> order1_5x
;
1681 y5
= (y5
* tmp
) >> order1_5x
;
1682 y5
= (y5
* tmp
) >> order1_5x
;
1684 y5
= y5
>> order1_5x_rem
;
1685 y3
= (alpha
* tmp
) >> order2_3x
;
1686 y3
= (y3
* tmp
) >> order2_3x
;
1687 y3
= (y3
* tmp
) >> order2_3x
;
1689 y3
= y3
>> order2_3x_rem
;
1690 /* g_fxp was checked for zero already */
1691 pa_in
[idx
] = y5
+ y3
+ (256 * tmp
) / g_fxp
;
1694 for (idx
= 1; idx
< 23; idx
++) {
1695 tmp
= pa_in
[idx
+ 1] - pa_in
[idx
];
1697 pa_in
[idx
+ 1] = pa_in
[idx
] + (pa_in
[idx
] - pa_in
[idx
- 1]);
1701 for (idx
= 0; idx
< AR9300_PAPRD_TABLE_SZ
; idx
++) {
1702 pa_in
[idx
] = (pa_in
[idx
] < 1400) ? pa_in
[idx
] : 1400;
1703 /*printf("idx=%d, pa_in[idx]=%d\n", i, pa_in[idx]);*/
1709 for (bin
= 0; bin
<= half_hi
; bin
++) {
1712 * "bin=%d half_lo=%d m=%d theta[bin+half_lo]=%d "
1713 * "y_est[bin+half_lo]=%d\n",
1714 * bin, half_lo, m, theta[bin+half_lo], y_est[bin+half_lo]);
1716 /* y_est[] was already checked for zero */
1718 ((theta
[bin
+ half_lo
] << m
) + y_est
[bin
+ half_lo
]) /
1719 y_est
[bin
+ half_lo
];
1720 theta_tilde
[bin
] = ((theta_tilde
[bin
] << m
) + y_est
[bin
+ half_lo
]) /
1721 y_est
[bin
+ half_lo
];
1722 theta_tilde
[bin
] = ((theta_tilde
[bin
] << m
) + y_est
[bin
+ half_lo
]) /
1723 y_est
[bin
+ half_lo
];
1725 /*printf("bin=%d theta_tilde[bin]=%d\n", bin, theta_tilde[bin]);*/
1726 beta_raw
= beta_raw
+ b1_tmp
[bin
] * theta_tilde
[bin
];
1727 alpha_raw
= alpha_raw
+ b2_tmp
[bin
] * theta_tilde
[bin
];
1730 printf("bin=%d, alpha_raw=%d, beta_raw=%d\n", bin, alpha_raw, beta_raw);
1734 q_beta
= find_proper_scale(find_expn(paprd_abs(beta_raw
)), 10);
1735 q_alpha
= find_proper_scale(find_expn(paprd_abs(alpha_raw
)), 10);
1737 beta_raw
= beta_raw
/ (1 << q_beta
);
1738 alpha_raw
= alpha_raw
/ (1 << q_alpha
);
1739 /* scale_b checked for zero previously */
1740 alpha
= (alpha_raw
<< 10) / scale_b
;
1741 beta
= (beta_raw
<< 10) / scale_b
;
1742 order_1
= 3 * m
- q_x
- q_b1
- q_beta
+ 10 + q_scale_b
+ 5;
1743 order_2
= 3 * m
- q_x
- q_b2
- q_alpha
+ 10 + q_scale_b
+ 5;
1745 order1_5x
= order_1
/ 5;
1746 order2_3x
= order_2
/ 3;
1748 order1_5x_rem
= order_1
- 5 * order1_5x
;
1749 order2_3x_rem
= order_2
- 3 * order2_3x
;
1751 for (idx
= 0; idx
< AR9300_PAPRD_TABLE_SZ
; idx
++) {
1755 y5
= (((beta
* tmp
- 64) >> 6) -
1756 (1 << order1_5x
)) / (1 << order1_5x
);
1758 y5
= ((((beta
* tmp
- 64) >> 6) +
1759 (1 << order1_5x
)) / (1 << order1_5x
));
1762 y5
= (y5
* tmp
) / (1 << order1_5x
);
1763 y5
= (y5
* tmp
) / (1 << order1_5x
);
1764 y5
= (y5
* tmp
) / (1 << order1_5x
);
1765 y5
= (y5
* tmp
) / (1 << order1_5x
);
1767 y5
= y5
/ (1 << order1_5x_rem
);
1770 y3
= (alpha
* tmp
- (1 << order2_3x
)) / (1 << order2_3x
);
1772 y3
= (alpha
* tmp
+ (1 << order2_3x
)) / (1 << order2_3x
);
1775 y3
= (y3
* tmp
) / (1 << order2_3x
);
1776 y3
= (y3
* tmp
) / (1 << order2_3x
);
1778 y3
= y3
/ (1 << order2_3x_rem
);
1779 pa_angle
[idx
] = y5
+ y3
;
1780 /*printf("idx=%d, y5 = %d, y3=%d\n", idx, y5, y3);*/
1782 (pa_angle
[idx
] < -150) ? -150 : ((pa_angle
[idx
] >
1783 150) ? 150 : pa_angle
[idx
]);
1791 pa_angle
[4] = (pa_angle
[5] + 2) >> 1;
1793 for (idx
= 0; idx
< AR9300_PAPRD_TABLE_SZ
; idx
++) {
1794 pa_table
[idx
] = ((pa_in
[idx
] & 0x7ff) << 11) + (pa_angle
[idx
] & 0x7ff);
1797 * NULL, HAL_DEBUG_UNMASKABLE,"%d\t%d\t0x%x\n",
1798 * pa_in[idx], pa_angle[idx], pa_table[idx]);
1802 /*HALDEBUG(NULL, HAL_DEBUG_UNMASKABLE, "g_fxp = %d\n", g_fxp);*/
1807 // Due to a hardware bug, when transmitting with just one chain the papd
1808 // data for chain 0 is always used. So when using chain 2 or 4, the
1809 // corresponding data must be copied into the chain 0 area.
1810 void ar9300_swizzle_paprd_entries(struct ath_hal
*ah
, unsigned int txchain
)
1813 u_int32_t
*paprd_table_val
= NULL
;
1814 u_int32_t small_signal_gain
= 0;
1817 reg
= AR_PHY_PAPRD_MEM_TAB_B0
;
1822 paprd_table_val
= &AH9300(ah
)->pa_table
[0][0];
1823 small_signal_gain
= AH9300(ah
)->small_signal_gain
[0];
1826 paprd_table_val
= &AH9300(ah
)->pa_table
[1][0];
1827 small_signal_gain
= AH9300(ah
)->small_signal_gain
[1];
1830 paprd_table_val
= &AH9300(ah
)->pa_table
[2][0];
1831 small_signal_gain
= AH9300(ah
)->small_signal_gain
[2];
1835 ath_hal_printf(ah
, "YAK! Bad chain mask %x\n", txchain
);
1838 for (i
= 0; i
< AR9300_PAPRD_TABLE_SZ
; i
++) {
1839 OS_REG_WRITE(ah
, reg
, paprd_table_val
[i
]);
1840 HALDEBUG(ah
, HAL_DEBUG_CALIBRATE
, "%s[%d] reg %08x = 0x%08x\n", __func__
,
1841 __LINE__
, reg
, paprd_table_val
[i
]);
1845 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PA_GAIN123_B0
,AR_PHY_PA_GAIN123_B0_PA_GAIN1_0
, small_signal_gain
);
1846 HALDEBUG(ah
, HAL_DEBUG_CALIBRATE
, "%s[%d] reg %08x small_signal_gain 0x%08x\n", __func__
, __LINE__
,
1847 (unsigned) AR_PHY_PA_GAIN123_B0
, OS_REG_READ(ah
, AR_PHY_PA_GAIN123_B0
));
1849 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B0
, AR_PHY_PAPRD_CTRL1_B0_PAPRD_POWER_AT_AM2AM_CAL_0
,
1850 AH9300(ah
)->paprd_training_power
);
1851 HALDEBUG(ah
, HAL_DEBUG_CALIBRATE
, "%s[%d] reg %08x = 0x%08x\n", __func__
, __LINE__
,
1852 (unsigned) AR_PHY_PAPRD_CTRL1_B0
, OS_REG_READ(ah
, AR_PHY_PAPRD_CTRL1_B0
));
1856 void ar9300_populate_paprd_single_table(struct ath_hal
*ah
,
1857 struct ieee80211_channel
*chan
, int chain_num
)
1859 int i
, j
, bad_read
= 0;
1861 HAL_CHANNEL_INTERNAL
*ichan
= ath_hal_checkchannel(ah
, chan
);
1863 u_int32_t
*paprd_table_val
= &AH9300(ah
)->pa_table
[chain_num
][0];
1864 u_int32_t small_signal_gain
= AH9300(ah
)->small_signal_gain
[chain_num
];
1867 HALDEBUG(ah
, HAL_DEBUG_CALIBRATE
,
1868 "%s[%d]: channel %d paprd_done %d write %d\n", __func__
, __LINE__
,
1869 ichan
->channel
, ichan
->paprd_done
, ichan
->paprd_table_write_done
);
1871 if (chain_num
== 0) {
1872 reg
= AR_PHY_PAPRD_MEM_TAB_B0
;
1873 } else if (chain_num
== 1) {
1874 reg
= AR_PHY_PAPRD_MEM_TAB_B1
;
1875 } else if (chain_num
== 2) {
1876 reg
= AR_PHY_PAPRD_MEM_TAB_B2
;
1879 for (i
= 0; i
< AR9300_PAPRD_TABLE_SZ
; i
++) {
1880 if (AR_SREV_POSEIDON(ah
)) {
1881 HALASSERT(chain_num
== 0x1);
1882 if ((reg
== AR_PHY_PAPRD_MEM_TAB_B1
) ||
1883 (reg
== AR_PHY_PAPRD_MEM_TAB_B2
)) {
1889 * field_name, "%s%d[%d]%s\0", "BB_paprd_mem_tab_b",
1890 * chain_num, i, ".paprd_mem");
1892 OS_REG_WRITE(ah
, reg
, paprd_table_val
[i
]);
1893 HALDEBUG(ah
, HAL_DEBUG_CALIBRATE
, "%s[%d] reg %08x = 0x%08x\n", __func__
,
1894 __LINE__
, reg
, paprd_table_val
[i
]);
1897 * "%s[%d] reg %08x = 0x%08x\n",
1898 * __func__, __LINE__, reg, paprd_table_val[i]);
1900 if (OS_REG_READ(ah
, reg
) == 0xdeadbeef) {
1901 HALDEBUG(ah
, HAL_DEBUG_UNMASKABLE
,
1902 "%s: Reg0x%x = 0xdeadbeef\n", __func__
, reg
);
1904 for (j
= AR_PHY_PAPRD_MEM_TAB_B0
; j
< (AR_PHY_PAPRD_MEM_TAB_B0
+ 0x10); j
+=4)
1906 if (OS_REG_READ(ah
, j
) == 0xdeadbeef) {
1907 HALDEBUG(ah
, HAL_DEBUG_UNMASKABLE
,
1908 "%s: Reg0x%x = 0xdeadbeef\n", __func__
, j
);
1912 for (j
= AR_PHY_PAPRD_MEM_TAB_B1
; j
< (AR_PHY_PAPRD_MEM_TAB_B1
+ 0x10); j
+=4)
1914 if (OS_REG_READ(ah
, j
) == 0xdeadbeef) {
1915 HALDEBUG(ah
, HAL_DEBUG_UNMASKABLE
,
1916 "%s: Reg0x%x = 0xdeadbeef\n", __func__
, j
);
1926 HALDEBUG(ah
, HAL_DEBUG_UNMASKABLE
,
1927 "%s: Get %d 0xdeadbeef. Mark PAPRD as broken.\n",
1928 __func__
, bad_read
);
1929 AH9300(ah
)->ah_paprd_broken
= AH_TRUE
;
1932 if (chain_num
== 0) {
1933 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PA_GAIN123_B0
,
1934 AR_PHY_PA_GAIN123_B0_PA_GAIN1_0
, small_signal_gain
);
1935 HALDEBUG(ah
, HAL_DEBUG_CALIBRATE
,
1936 "%s[%d] reg %08x small_signal_gain 0x%08x\n", __func__
, __LINE__
,
1937 (unsigned) AR_PHY_PA_GAIN123_B0
,
1938 OS_REG_READ(ah
, AR_PHY_PA_GAIN123_B0
));
1939 } else if (chain_num
== 1) {
1940 if (!AR_SREV_POSEIDON(ah
) && !AR_SREV_HORNET(ah
) && !AR_SREV_APHRODITE(ah
)) {
1941 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PA_GAIN123_B1
,
1942 AR_PHY_PA_GAIN123_B1_PA_GAIN1_1
, small_signal_gain
);
1943 HALDEBUG(ah
, HAL_DEBUG_CALIBRATE
,
1944 "%s[%d] reg %08x small_signal_gain 0x%08x\n",
1946 (unsigned) AR_PHY_PA_GAIN123_B1
,
1947 OS_REG_READ(ah
, AR_PHY_PA_GAIN123_B1
));
1949 } else if (chain_num
== 2) {
1950 if (!AR_SREV_POSEIDON(ah
) && !AR_SREV_HORNET(ah
) && !AR_SREV_APHRODITE(ah
)) {
1951 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PA_GAIN123_B2
,
1952 AR_PHY_PA_GAIN123_B2_PA_GAIN1_2
, small_signal_gain
);
1953 HALDEBUG(ah
, HAL_DEBUG_CALIBRATE
,
1954 "%s[%d] reg %08x small_signal_gain 0x%08x\n",
1956 (unsigned) AR_PHY_PA_GAIN123_B2
,
1957 OS_REG_READ(ah
, AR_PHY_PA_GAIN123_B2
));
1960 /* invalid channel number */
1963 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B0
,
1964 AR_PHY_PAPRD_CTRL1_B0_PAPRD_POWER_AT_AM2AM_CAL_0
,
1965 AH9300(ah
)->paprd_training_power
);
1966 HALDEBUG(ah
, HAL_DEBUG_CALIBRATE
, "%s[%d] reg %08x = 0x%08x\n", __func__
,
1967 __LINE__
, (unsigned) AR_PHY_PAPRD_CTRL1_B0
,
1968 OS_REG_READ(ah
, AR_PHY_PAPRD_CTRL1_B0
));
1969 if (!AR_SREV_POSEIDON(ah
) && !AR_SREV_HORNET(ah
) && !AR_SREV_APHRODITE(ah
)) {
1970 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B1
,
1971 AR_PHY_PAPRD_CTRL1_B1_PAPRD_POWER_AT_AM2AM_CAL_1
,
1972 AH9300(ah
)->paprd_training_power
);
1973 HALDEBUG(ah
, HAL_DEBUG_CALIBRATE
, "%s[%d] reg %08x = 0x%08x\n", __func__
,
1974 __LINE__
, (unsigned) AR_PHY_PAPRD_CTRL1_B1
,
1975 OS_REG_READ(ah
, AR_PHY_PAPRD_CTRL1_B1
));
1976 if (!AR_SREV_WASP(ah
) && !AR_SREV_JUPITER(ah
)) {
1977 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_CTRL1_B2
,
1978 AR_PHY_PAPRD_CTRL1_B2_PAPRD_POWER_AT_AM2AM_CAL_2
,
1979 AH9300(ah
)->paprd_training_power
);
1980 HALDEBUG(ah
, HAL_DEBUG_CALIBRATE
,
1981 "%s[%d] reg %08x = 0x%08x\n", __func__
,
1982 __LINE__
, (unsigned) AR_PHY_PAPRD_CTRL1_B2
,
1983 OS_REG_READ(ah
, AR_PHY_PAPRD_CTRL1_B2
));
1986 /*ar9300_enable_paprd(ah, AH_TRUE);*/
1989 HAL_STATUS
ar9300_paprd_setup_gain_table(struct ath_hal
*ah
, int chain_num
)
1991 unsigned int i
, desired_gain
, gain_index
;
1992 HALDEBUG(ah
, HAL_DEBUG_CALIBRATE
,
1993 "Run papredistortion single table algorithm:: Training power = %d\n",
1994 AH9300(ah
)->paprd_training_power
/ 2);
1996 if (AH9300(ah
)->ah_tx_chainmask
& (1 << chain_num
)) {
1997 /* this is an active chain */
1998 desired_gain
= ar9300_get_desired_gain_for_chain(
1999 ah
, chain_num
, AH9300(ah
)->paprd_training_power
);
2000 /* find out gain index */
2003 for (i
= 0; i
< 32; i
++) {
2004 if (AH9300(ah
)->paprd_gain_table_index
[i
] < desired_gain
) {
2005 gain_index
= gain_index
+ 1;
2011 /*printf("gain_index = %d\n", gain_index);*/
2012 /*ath_hal_printf(ah, "++++ gain_index = %d\n", gain_index);*/
2013 ar9300_tx_force_gain(ah
, gain_index
);
2014 if (AR_SREV_POSEIDON(ah
)) {
2015 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON
,
2016 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE
, 0);
2018 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1
,
2019 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE
, 0);
2026 static HAL_BOOL
ar9300_paprd_retrain_pain(struct ath_hal
* ah
, int * pa_in
)
2029 int capdiv_offset
= 0, quick_drop_offset
;
2030 int capdiv2g
, quick_drop
;
2032 capdiv2g
= (OS_REG_READ(ah
, AR_PHY_65NM_CH0_TXRF3
) >> 1) & 0xF;
2033 if (!AR_SREV_POSEIDON(ah
)) {
2035 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3
,
2036 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP
);
2039 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON
,
2040 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP
);
2043 if ( quick_drop
!= 0 ) {
2046 for (i
= 0; i
< (NUM_BIN
+ 1); i
++) {
2047 if (pa_in
[i
] == 1400) {
2052 if (AR_SREV_POSEIDON(ah
)) {
2053 if ((pa_in
[23] < 800) || (pa_in
[23] == 1400)) {
2054 if (pa_in
[23] < 800) {
2055 capdiv_offset
= (int)((1000 - pa_in
[23] + 75) / 150);
2056 capdiv2g
= capdiv2g
+ capdiv_offset
;
2059 if (pa_in
[23] < 600) {
2060 quick_drop
= quick_drop
+ 1;
2061 if (quick_drop
> 0) {
2067 OS_REG_RMW_FIELD(ah
,
2068 AR_PHY_65NM_CH0_TXRF3
,
2069 AR_PHY_65NM_CH0_TXRF3_CAPDIV2G
,
2072 OS_REG_RMW_FIELD_ALT(ah
,
2073 AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON
,
2074 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP
,
2078 } /* end of if (pa_in[23] < 800) */
2079 else if (pa_in
[23] == 1400) {
2080 quick_drop_offset
= (int)(count
/ 3);
2081 if (quick_drop_offset
> 2) {
2082 quick_drop_offset
= 2;
2084 quick_drop
= quick_drop
+ quick_drop_offset
;
2085 capdiv2g
= capdiv2g
+ (int)(quick_drop_offset
/ 2);
2089 if (quick_drop
> 0) {
2091 capdiv2g
= capdiv2g
- (int)(quick_drop_offset
/ 1);
2096 OS_REG_RMW_FIELD(ah
,
2097 AR_PHY_65NM_CH0_TXRF3
,
2098 AR_PHY_65NM_CH0_TXRF3_CAPDIV2G
,
2101 OS_REG_RMW_FIELD_ALT(ah
,
2102 AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON
,
2103 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP
,
2108 } /* end of if (pa_in[23] == 1400)*/
2109 } /* end of if ((pa_in[23] < 800) || (pa_in[23] == 1400)) */
2110 }else if (AR_SREV_HORNET(ah
)) {
2111 if ((pa_in
[23] < 1000) || (pa_in
[23] == 1400)) {
2112 if (pa_in
[23] < 1000) {
2113 capdiv_offset
= ((1000 - pa_in
[23]) / 100);
2114 capdiv2g
= capdiv2g
+ capdiv_offset
;
2115 if (capdiv_offset
> 3) {
2116 quick_drop_offset
= 1;
2117 quick_drop
= quick_drop
- quick_drop_offset
;
2118 capdiv2g
= capdiv2g
+ 1;
2122 if (quick_drop
< -4) {
2125 OS_REG_RMW_FIELD(ah
,
2126 AR_PHY_65NM_CH0_TXRF3
,
2127 AR_PHY_65NM_CH0_TXRF3_CAPDIV2G
,
2129 OS_REG_RMW_FIELD_ALT(ah
,
2130 AR_PHY_PAPRD_TRAINER_CNTL3
,
2131 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP
,
2135 capdiv2g
= capdiv2g
+ capdiv_offset
;
2139 if (quick_drop
< -4) {
2142 OS_REG_RMW_FIELD(ah
,
2143 AR_PHY_65NM_CH0_TXRF3
,
2144 AR_PHY_65NM_CH0_TXRF3_CAPDIV2G
,
2146 OS_REG_RMW_FIELD_ALT(ah
,
2147 AR_PHY_PAPRD_TRAINER_CNTL3
,
2148 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP
,
2152 } /* end of if (PA_in[23] < 1000) */
2153 else if (pa_in
[23] == 1400) {
2155 quick_drop_offset
= 1;
2156 quick_drop
= quick_drop
+ quick_drop_offset
;
2157 capdiv2g
= capdiv2g
- (count
/ 4);
2161 if (quick_drop
> -2) {
2164 OS_REG_RMW_FIELD(ah
, AR_PHY_65NM_CH0_TXRF3
,
2165 AR_PHY_65NM_CH0_TXRF3_CAPDIV2G
,
2167 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3
,
2168 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP
,
2172 capdiv2g
= capdiv2g
- 1;
2176 OS_REG_RMW_FIELD(ah
, AR_PHY_65NM_CH0_TXRF3
,
2177 AR_PHY_65NM_CH0_TXRF3_CAPDIV2G
,
2179 OS_REG_RMW_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_CNTL3
,
2180 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP
,
2184 } /* end of if (PA_in[23] == 1400)*/
2185 } /* end of if ((PA_in[23] < 1000) || (PA_in[23] == 1400)) */
2191 HAL_STATUS
ar9300_paprd_create_curve(struct ath_hal
* ah
,
2192 struct ieee80211_channel
* chan
, int chain_num
)
2195 u_int32_t
*pa_table
, small_signal_gain
;
2196 int pa_in
[NUM_BIN
+ 1];
2198 if (AH9300(ah
)->ah_tx_chainmask
& (1 << chain_num
)) {
2199 pa_table
= &AH9300(ah
)->pa_table
[chain_num
][0];
2200 /* Compute PA table and gain index */
2201 small_signal_gain
= 0; /* avoid gcc warnings */
2202 status
= ar9300_create_pa_curve(ah
, &pa_table
[0], &small_signal_gain
,
2205 if (AR_SREV_WASP(ah
)) {
2210 ath_hal_printf(ah
, "ERROR:: paprd failed with error code = %d\n",
2214 AH9300(ah
)->small_signal_gain
[chain_num
] = small_signal_gain
;
2216 if (AR_SREV_POSEIDON(ah
) || AR_SREV_HORNET(ah
)) {
2217 if (ar9300_paprd_retrain_pain(ah
, pa_in
)) {
2218 /* need re-train PAPRD */
2219 return HAL_EINPROGRESS
;
2226 int ar9300_paprd_init_table(struct ath_hal
*ah
, struct ieee80211_channel
* chan
)
2228 HAL_CHANNEL_INTERNAL
*ichan
= ath_hal_checkchannel(ah
, chan
);
2230 if ((AR_SREV_WASP(ah
) && IS_CHAN_5GHZ(ichan
)) ||
2231 ar9300_paprd_setup_single_table(ah
, chan
)) {
2234 OS_MEMZERO(AH9300(ah
)->paprd_gain_table_entries
,
2235 sizeof(AH9300(ah
)->paprd_gain_table_entries
));
2236 OS_MEMZERO(AH9300(ah
)->paprd_gain_table_index
,
2237 sizeof(AH9300(ah
)->paprd_gain_table_index
));
2239 ar9300_gain_table_entries(ah
);
2245 int ar9300_paprd_is_done(struct ath_hal
*ah
)
2249 /*field_read("BB_paprd_trainer_stat1.paprd_train_done", &temp);*/
2250 if (!AR_SREV_POSEIDON(ah
)) {
2252 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1
,
2253 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE
);
2257 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1
,
2258 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR
);
2260 HALDEBUG(ah
, HAL_DEBUG_CALIBRATE
,
2261 "%s AGC2_PWR=0x%2x Training done=0x%2x\n",
2262 __func__
, agc2_pwr
, temp
);
2264 /* Retrain if agc2_pwr is not in ideal range */
2265 if (agc2_pwr
<= AH_PAPRD_IDEAL_AGC2_PWR_RANGE
) {
2271 OS_REG_READ_FIELD_ALT(ah
, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON
,
2272 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE
);
2275 /*ath_hal_printf(ah, "%s[%d] PAPRD TEMp Error\n", __func__, __LINE__);*/
2282 * ar9300_paprd_dec_tx_pwr
2284 * This function do decrease tx power if Paprd is off or train failed.
2287 ar9300_paprd_dec_tx_pwr(struct ath_hal
*ah
)
2289 u_int32_t pwr_temp
, pwr_reg
;
2291 struct ar9300_paprd_pwr_adjust
*p_item
;
2292 struct ath_hal_9300
*ahp
= AH9300(ah
);
2294 if (AR_SREV_POSEIDON(ah
)) {
2296 (sizeof(ar9300_paprd_pwr_adj_array
) /
2297 sizeof(struct ar9300_paprd_pwr_adjust
));
2298 for (i
= 0; i
< loop_cnt
; i
++ )
2300 p_item
= &ar9300_paprd_pwr_adj_array
[i
];
2301 pwr_reg
= OS_REG_READ(ah
, p_item
->reg_addr
);
2302 pwr_temp
= ahp
->ah_default_tx_power
[p_item
->target_rate
];
2303 pwr_temp
-= (p_item
->sub_db
* 2);
2304 pwr_temp
= pwr_temp
<< p_item
->reg_mask_offset
;
2305 pwr_temp
|= (pwr_reg
&~(p_item
->reg_mask
<<p_item
->reg_mask_offset
));
2307 if (pwr_temp
!= pwr_reg
)
2309 OS_REG_WRITE(ah
, p_item
->reg_addr
, pwr_temp
);
2316 int ar9300_paprd_thermal_send(struct ath_hal
*ah
)
2318 if (AR_SREV_HORNET(ah
)) {
2319 return OS_REG_READ(ah
, AR_TFCNT
);
2326 void ar9300_paprd_test_prints(struct ath_hal
*ah
)
2328 u_int32_t i
, reg
= 0;
2330 HALDEBUG(NULL
, HAL_DEBUG_CALIBRATE
, "=====ar9300_paprd_test_prints=======\n");
2331 /*printf("=====ar9300_paprd_test_prints=======\n");*/
2332 HALDEBUG(NULL
, HAL_DEBUG_CALIBRATE
, "BB_paprd_ctrl0_b0 = 0x%08x\n",
2333 OS_REG_READ(ah
, AR_PHY_PAPRD_CTRL0_B0
));
2336 * "BB_paprd_ctrl0_b0 = 0x%08x\n",
2337 * OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B0));
2339 if (!AR_SREV_POSEIDON(ah
) && !AR_SREV_HORNET(ah
)) {
2340 HALDEBUG(NULL
, HAL_DEBUG_CALIBRATE
, "BB_paprd_ctrl0_b1 = 0x%08x\n",
2341 OS_REG_READ(ah
, AR_PHY_PAPRD_CTRL0_B1
));
2344 * "BB_paprd_ctrl0_b1 = 0x%08x\n",
2345 * OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B1));
2347 HALDEBUG(NULL
, HAL_DEBUG_CALIBRATE
, "BB_paprd_ctrl0_b2 = 0x%08x\n",
2348 OS_REG_READ(ah
, AR_PHY_PAPRD_CTRL0_B2
));
2351 * "BB_paprd_ctrl0_b2 = 0x%08x\n",
2352 * OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B2));
2356 reg
= AR_PHY_PAPRD_MEM_TAB_B0
;
2357 HALDEBUG(NULL
, HAL_DEBUG_CALIBRATE
,
2358 "%s[%d] reg %08lx small_signal_gain ch0 0x%08x\n", __func__
, __LINE__
,
2359 AR_PHY_PA_GAIN123_B0
, OS_REG_READ(ah
, AR_PHY_PA_GAIN123_B0
));
2362 * "%s[%d] reg %08lx small_signal_gain ch0 0x%08x\n",
2363 * __func__, __LINE__, AR_PHY_PA_GAIN123_B0,
2364 * OS_REG_READ(ah, AR_PHY_PA_GAIN123_B0));
2367 for (i
= 0; i
< 24; i
++) {
2368 HALDEBUG(NULL
, HAL_DEBUG_CALIBRATE
, "%s[%d] reg %08x = 0x%08x\n",
2369 __func__
, __LINE__
, reg
, OS_REG_READ(ah
, reg
));
2372 * "%s[%d] reg %08x = 0x%08x\n", __func__, __LINE__,
2373 * reg, OS_REG_READ(ah, reg));
2378 ar9300_paprd_debug_print(ah
);
2379 HALDEBUG(NULL
, HAL_DEBUG_CALIBRATE
,
2380 "=====ar9300_paprd_test_prints end=======\n");
2381 /*printf("=====ar9300_paprd_test_prints end=======\n");*/
2383 if (!AR_SREV_POSEIDON(ah
)) {
2384 reg
= AR_PHY_PAPRD_MEM_TAB_B1
;
2385 printf("%s[%d] reg %08lx small_signal_gain ch1 0x%08x\n",
2387 AR_PHY_PA_GAIN123_B1
, OS_REG_READ(ah
, AR_PHY_PA_GAIN123_B1
));
2388 for (i
= 0; i
< 24; i
++) {
2389 OS_REG_WRITE(ah
, reg
, paprd_table_val
[i
]);
2390 HALDEBUG(NULL
, HAL_DEBUG_CALIBRATE
, "%s[%d] reg %08x = 0x%08x\n",
2391 __func__
, __LINE__
, reg
, OS_REG_READ(ah
, reg
));
2392 printf("%s[%d] reg %08x = 0x%08x\n", __func__
, __LINE__
, reg
,
2393 OS_REG_READ(ah
, reg
));
2397 reg
= AR_PHY_PAPRD_MEM_TAB_B2
;
2398 printf("%s[%d] reg %08lx small_signal_gain ch2 0x%08x\n",
2400 AR_PHY_PA_GAIN123_B2
, OS_REG_READ(ah
, AR_PHY_PA_GAIN123_B2
));
2407 ar9300_paprd_init_table(struct ath_hal
*ah
, HAL_CHANNEL
* chan
)
2413 ar9300_paprd_setup_gain_table(struct ath_hal
* ah
, int chain_num
)
2419 ar9300_paprd_create_curve(struct ath_hal
* ah
, HAL_CHANNEL
* chan
,
2426 ar9300_paprd_is_done(struct ath_hal
*ah
)
2432 ar9300_enable_paprd(struct ath_hal
*ah
, HAL_BOOL enable_flag
, HAL_CHANNEL
* chan
)
2438 ar9300_populate_paprd_single_table(struct ath_hal
*ah
, HAL_CHANNEL
* chan
,
2445 ar9300_paprd_dec_tx_pwr(struct ath_hal
*ah
)
2450 int ar9300_paprd_thermal_send(struct ath_hal
*ah
)
2454 #endif /* ATH_SUPPORT_PAPRD */