xref: /freebsd/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_paprd.c (revision 8ddb146abcdf061be9f2c0db7e391697dafad85c)
1 /*
2  * Copyright (c) 2013 Qualcomm Atheros, Inc.
3  *
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.
7  *
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.
15  */
16 
17 #include "opt_ah.h"
18 #include "ah.h"
19 #include "ar9300.h"
20 #include "ah_internal.h"
21 #include "ar9300paprd.h"
22 #include "ar9300reg.h"
23 
24 
25 #if ATH_SUPPORT_PAPRD
26 
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},
44 };
45 
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,
48     int * pa_in);
49 
50 static int
51 ar9300_paprd_setup_single_table(struct ath_hal *ah, struct ieee80211_channel * chan)
52 {
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);
56     int is_ht40 = 0;
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;
62 
63     const u_int8_t mask2num[8] = {
64         0 /* 000 */,
65         1 /* 001 */,
66         1 /* 010 */,
67         2 /* 011 */,
68         1 /* 100 */,
69         2 /* 101 */,
70         2 /* 110 */,
71         3 /* 111 */
72     };
73 
74     ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
75 
76 #define ABS(_x, _y) ((int)_x > (int)_y ? (int)_x - (int)_y : (int)_y - (int)_x)
77 
78     ar9300_set_target_power_from_eeprom(ah, ichan->channel, target_power_val_t2);
79     if (val & HAL_HT_MACMODE_2040) {
80         is_ht40 = 1;
81     }
82 
83     /*
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.
95      */
96     AH_PAPRD_GET_SCALE_FACTOR(paprd_scale_factor, eep, is_2g, ichan->channel);
97     if (is_2g) {
98         if (is_ht40) {
99             am_mask = ahp->ah_2g_paprd_rate_mask_ht40 & AH_PAPRD_AM_PM_MASK;
100             power_tblindex = ALL_TARGET_HT40_0_8_16;
101         } else {
102             am_mask = ahp->ah_2g_paprd_rate_mask_ht20 & AH_PAPRD_AM_PM_MASK;
103             power_tblindex = ALL_TARGET_HT20_0_8_16;
104         }
105         if (AR_SREV_HORNET(ah) || AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
106             if (is_ht40) {
107                 ahp->paprd_training_power =
108                     target_power_val_t2[ALL_TARGET_HT40_7] + 2;
109             } else {
110                 ahp->paprd_training_power =
111                     target_power_val_t2[ALL_TARGET_HT20_7] + 2;
112             }
113 		} else if (AR_SREV_POSEIDON(ah)) {
114             ahp->paprd_training_power = 25;
115         } else {
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)
121             {
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);
127                 goto FAILED;
128             }
129 
130             power_delta =
131                 ABS(ahp->paprd_training_power,
132                     target_power_val_t2[power_tblindex]);
133 
134             power_delta = power_delta > 4 ? 0 : 4 - power_delta;
135             ahp->paprd_training_power =
136                 ahp->paprd_training_power - power_delta;
137         }
138 
139 
140     } else {
141         if (is_ht40) {
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])
147             {
148             case 1:
149                 power_delta = 6;
150                 break;
151             case 2:
152                 power_delta = 4;
153                 break;
154             case 3:
155                 power_delta = 2;
156                 break;
157             default:
158                 goto FAILED;
159                 break;
160             }
161             power_tblindex = ALL_TARGET_HT40_7;
162         } else {
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])
168             {
169             case 1:
170                 power_delta = 6;
171                 break;
172             case 2:
173                 power_delta = 4;
174                 break;
175             case 3:
176                 power_delta = 2;
177                 break;
178             default:
179                 goto FAILED;
180                 break;
181             }
182             power_tblindex = ALL_TARGET_HT20_7;
183         }
184         /* Adjust for scale factor */
185         ahp->paprd_training_power += paprd_scale_factor;
186         /*
187         ath_hal_printf(ah, "%s[%d] paprd_scale_factor %d power_delta %d\n",
188             __func__, __LINE__, paprd_scale_factor, power_delta);
189          */
190         if (ABS(target_power_val_t2[power_tblindex], ahp->paprd_training_power)
191             >  paprd_scale_factor)
192         {
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);
197             goto FAILED;
198         }
199         ahp->paprd_training_power = ahp->paprd_training_power + power_delta;
200     }
201 
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,
205         am_mask);
206     if (AR_SREV_HORNET(ah)) {
207         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK,
208             0);
209     }
210     else {
211         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK,
212             am_mask);
213     }
214 
215     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK,
216         AR_PHY_PAPRD_HT40_MASK);
217     /* chain0 */
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);
235     }
236 
237     /* chain1 */
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);
255     }
256 
257     /* chain2 */
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);
275     }
276 
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);
315     } else {
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);
330         if (is_2g) {
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);
334            }else{
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);
337            }
338         }
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);
342 		} else {
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);
345         }
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);
357         } else {
358             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
359                 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -6);
360         }
361         if (is_2g) {
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);
365             }else{
366                 OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
367                     AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE, -15);
368             }
369         }
370         else {
371              OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
372                  AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE, -10);
373         }
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);
382     }
383 
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);
400     return 0;
401 
402 FAILED:
403     return -1;
404 #undef ABS
405 }
406 
407 /*
408  * XXX There's another copy of this in ar9300_reset.c, use that!
409  */
410 #if 0
411 static inline HAL_CHANNEL_INTERNAL*
412 ar9300_check_chan(struct ath_hal *ah, HAL_CHANNEL *chan)
413 {
414     if ((AR9300_IS_CHAN(chan, CHANNEL_2GHZ) ^
415          AR9300_IS_CHAN(chan, CHANNEL_5GHZ)) == 0)
416     {
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);
420         return AH_NULL;
421     }
422 
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)
428     {
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);
433         return AH_NULL;
434     }
435 
436     return (ath_hal_checkchannel(ah, chan));
437 }
438 #endif
439 
440 void ar9300_enable_paprd(struct ath_hal *ah, HAL_BOOL enable_flag,
441     struct ieee80211_channel * chan)
442 {
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);
448     int is_ht40 = 0;
449     struct ath_hal_9300 *ahp = AH9300(ah);
450 
451     if (val & HAL_HT_MACMODE_2040) {
452         is_ht40 = 1;
453     }
454     if (enable_flag == AH_TRUE) {
455         ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
456 
457         if (!is_2g) {
458             /*
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;
469              */
470             if (ichan->channel >= UPPER_5G_SUB_BANDSTART) {
471                 if (eep->modal_header_5g.paprd_rate_mask_ht20 & (1 << 30)) {
472                     enable = AH_FALSE;
473                 }
474             } else if (ichan->channel >= MID_5G_SUB_BANDSTART) {
475                 if (eep->modal_header_5g.paprd_rate_mask_ht20 & (1 << 29)) {
476                     enable = AH_FALSE;
477                 }
478             } else { /* must be in the lower 5G subband */
479                 if (eep->modal_header_5g.paprd_rate_mask_ht20 & (1 << 28)) {
480                     enable = AH_FALSE;
481                 }
482             }
483         }
484 
485         if (ahp->ah_paprd_broken) {
486             ahp->ah_paprd_broken = AH_FALSE;
487             enable = AH_FALSE;
488 
489             HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
490                      "%s: PAPRD is in bad state. Don't enable PAPRD\n",
491                      __func__);
492         }
493     }
494     if (enable) {
495         HAL_CHANNEL_INTERNAL *ichan;
496         if (is_2g) {
497             if (is_ht40) {
498                 am_mask = ahp->ah_2g_paprd_rate_mask_ht40 & AH_PAPRD_AM_PM_MASK;
499             } else {
500                 am_mask = ahp->ah_2g_paprd_rate_mask_ht20 & AH_PAPRD_AM_PM_MASK;
501             }
502         } else {
503             if (is_ht40) {
504                 am_mask = ahp->ah_5g_paprd_rate_mask_ht40 & AH_PAPRD_AM_PM_MASK;
505             } else {
506                 am_mask = ahp->ah_5g_paprd_rate_mask_ht20 & AH_PAPRD_AM_PM_MASK;
507             }
508         }
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"
514          */
515         ichan = ar9300_check_chan(ah, chan);
516         ichan->paprd_table_write_done = 1;
517 //        chan->paprd_table_write_done = 1;
518         /*
519         ath_hal_printf(ah, "%s[%d] eeprom_set_transmit_power PAPRD\n",
520             __func__, __LINE__);
521          */
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 */
529             ath_hal_printf(ah,
530                 "%s[%d] eeprom_set_transmit_power failed ABORT PAPRD\n",
531                 __func__, __LINE__);
532 
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);
541 
542                 }
543             }
544             return;
545         }
546 
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,
550             am_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);
554         } else {
555             OS_REG_RMW_FIELD_ALT(ah,
556                 AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask);
557         }
558 
559         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK,
560             AR_PHY_PAPRD_HT40_MASK);
561         /* chain0 */
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);
579         }
580         /* chain1 */
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);
598         }
599         /* chain2 */
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);
617         }
618 
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);
622         }
623 
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);
627         }
628 
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);
632         }
633 
634     } else {
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);
638         }
639 
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);
643         }
644 
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);
648         }
649     }
650 }
651 
652 static void ar9300_gain_table_entries(struct ath_hal *ah)
653 {
654     int i;
655     u_int32_t reg;
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;
658 
659     reg = AR_PHY_TXGAIN_TAB(1);
660 
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;
664         /*
665          * ath_hal_printf(
666          *     ah, "+++reg 0x%08x gain_table_entries[%d] = 0x%08x \n",
667          *     reg, i, gain_table_entries[i]);
668          */
669         reg = reg + 4;
670     }
671 }
672 
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)
676 {
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;
683     int cl_gain_mod = 0;
684 
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);
689     } else {
690         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
691             AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE, 0);
692     }
693     /*field_read("BB_tpc_12.desired_scale_ht40_5", &desired_scale);*/
694     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);*/
698     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);*/
701     alpha_volt =
702         OS_REG_READ_FIELD_ALT(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALT_ALPHA_VOLT);
703 
704     /*field_read("BB_tpc_18.therm_cal_value", &therm_cal_value);*/
705     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);*/
709     volt_cal_value =
710         OS_REG_READ_FIELD_ALT(ah, AR_PHY_TPC_18,
711         AR_PHY_TPC_18_ALT_VOLT_CAL_VALUE);
712 
713     /*field_read("BB_therm_adc_4.latest_therm_value", &latest_therm_value);*/
714     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);*/
718     latest_volt_value =
719         OS_REG_READ_FIELD_ALT(ah, AR_PHY_THERM_ADC_4,
720         AR_PHY_THERM_ADC_4_LATEST_VOLT_VALUE);
721 
722     /*
723      * sprintf(
724      *     field_name, "%s%d%s%d\0", "BB_tpc_11_b",
725      *     chain_num, ".olpc_gain_delta_", chain_num);
726      */
727     /*field_read(field_name, &olpc_gain_delta_tmp);*/
728 
729 
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);
743         }
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);
751         }
752     } else {
753         /* invalid chain_num */
754     }
755 
756     if (olpc_gain_delta_tmp < 128) {
757         olpc_gain_delta = olpc_gain_delta_tmp;
758     } else {
759         olpc_gain_delta = olpc_gain_delta_tmp - 256;
760     }
761 
762     thermal_gain_corr =
763         (int) (alpha_therm * (latest_therm_value - therm_cal_value) +
764         128) >> 8;
765     voltage_gain_corr =
766         (int) (alpha_volt * (latest_volt_value - volt_cal_value) + 64) >> 7;
767     desired_gain =
768         target_power - olpc_gain_delta - thermal_gain_corr -
769         voltage_gain_corr + desired_scale + cl_gain_mod;
770     /*
771      * printf(
772      *     "olpc_gain_delta %d, desired_gain %d\n",
773      *     olpc_gain_delta, desired_gain);
774      */
775 #if 0
776     ath_hal_printf(ah,
777         "+++ target_power %d olpc_gain_delta %d, cl_gain_mod %d,"
778         "thermal_gain_corr %d  voltage_gain_corr %d desired_scale %d"
779         "desired_gain %d\n",
780         target_power, olpc_gain_delta, cl_gain_mod, thermal_gain_corr,
781         voltage_gain_corr,
782         desired_scale, desired_gain);
783 #endif
784     return (unsigned int) desired_gain;
785 }
786 
787 static void ar9300_tx_force_gain(struct ath_hal *ah, unsigned int gain_index)
788 {
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;
792 
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;
802 
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);
821 
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);
824 }
825 
826 #define HAL_DEBUG_PAPRD HAL_DEBUG_CALIBRATE  /* driver: conditionally print */
827 
828 #if defined(ART_PAPRD_DEBUG) || defined(AH_DEBUG)
829 static void ar9300_paprd_debug_print(struct ath_hal *ah)
830 {
831     int temp;
832     int txbb1dbgain, txbb6dbgain, txmxrgain;
833     int padrvgn_a, padrvgn_b, padrvgn_c, padrvgn_d;
834 
835     if (AR_SREV_POSEIDON(ah)) {
836         /*field_read("BB_paprd_trainer_cntl1.cf_paprd_lb_skip", &temp);*/
837         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);*/
843         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);*/
849         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);
854         /*
855          * field_read(
856          *     "BB_paprd_trainer_cntl1.cf_paprd_rx_bb_gain_force", &temp);
857          */
858         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);*/
864         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);*/
870         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);*/
876         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);
881         /*
882          * field_read("BB_paprd_trainer_cntl2.cf_paprd_init_rx_bb_gain", &temp);
883          */
884         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);*/
890         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);
895         /*
896          * field_read("BB_paprd_trainer_cntl3.cf_paprd_coarse_corr_len", &temp);
897          */
898         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);
903         /*
904          * field_read("BB_paprd_trainer_cntl3.cf_paprd_num_corr_stages", &temp);
905          */
906         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);
911         /*
912          * field_read(
913          *     "BB_paprd_trainer_cntl3.cf_paprd_min_loopback_del", &temp);
914          */
915         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);*/
921         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);
926         /*
927          * field_read(
928          *     "BB_paprd_trainer_cntl3.cf_paprd_adc_desired_size", &temp);
929          */
930         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);
935         /*
936          * field_read("BB_paprd_trainer_cntl3.cf_paprd_bbtxmix_disable", &temp);
937          */
938         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);*/
944         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);*/
950         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);*/
956         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);*/
962         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);*/
968         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);*/
974         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);*/
980         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);*/
986         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);*/
992         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);*/
998         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);*/
1004         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);*/
1010         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);
1015     } else {
1016         /*field_read("BB_paprd_trainer_cntl1.cf_paprd_lb_skip", &temp);*/
1017         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);*/
1023         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);*/
1029         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);
1034         /*
1035          * field_read(
1036          *     "BB_paprd_trainer_cntl1.cf_paprd_rx_bb_gain_force", &temp);
1037          */
1038         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);*/
1044         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);*/
1050         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);*/
1056         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);
1061         /*
1062          * field_read("BB_paprd_trainer_cntl2.cf_paprd_init_rx_bb_gain", &temp);
1063          */
1064         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);*/
1070         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);
1075         /*
1076          * field_read("BB_paprd_trainer_cntl3.cf_paprd_coarse_corr_len", &temp);
1077          */
1078         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);
1083         /*
1084          * field_read("BB_paprd_trainer_cntl3.cf_paprd_num_corr_stages", &temp);
1085          */
1086         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);
1091         /*
1092          * field_read(
1093          *     "BB_paprd_trainer_cntl3.cf_paprd_min_loopback_del", &temp);
1094          */
1095         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);*/
1101         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);
1106         /*
1107          * field_read(
1108          *     "BB_paprd_trainer_cntl3.cf_paprd_adc_desired_size", &temp);
1109          */
1110         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);
1115         /*
1116          * field_read(
1117          *     "BB_paprd_trainer_cntl3.cf_paprd_bbtxmix_disable", &temp);
1118          */
1119         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);*/
1125         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);*/
1131         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);*/
1137         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);*/
1143         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);*/
1149         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);*/
1155         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);*/
1161         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);*/
1167         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);*/
1173         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);*/
1179         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);*/
1185         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);*/
1191         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);
1196     }
1197 
1198     /*field_read("BB_tpc_1.force_dac_gain", &temp);*/
1199     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",
1202         temp);
1203     /*field_read("BB_tpc_1.forced_dac_gain", &temp);*/
1204     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",
1207         temp);
1208 
1209     /*field_read("BB_paprd_ctrl0_b0.paprd_enable_0", &temp);*/
1210     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);*/
1217         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);*/
1224             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);
1229         }
1230     }
1231 
1232     /*field_read("BB_tx_forced_gain.forced_txbb1dbgain", &txbb1dbgain);*/
1233     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);*/
1237     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);*/
1241     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);*/
1245     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);*/
1249     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);*/
1253     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);*/
1257     padrvgn_d =
1258         OS_REG_READ_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
1259         AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND);
1260 
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);
1268 }
1269 #else
1270 #define ar9300_paprd_debug_print(ah) /* dummy macro */
1271 #endif /* defined(ART_PAPRD_DEBUG) || defined(AH_DEBUG) */
1272 
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)
1275 {
1276     int i;
1277     int status;
1278     /*char field_name[100];*/
1279     u_int32_t paprd_train_data_l[48], paprd_train_data_u[48];
1280     u_int32_t reg;
1281 
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;
1286 
1287     for (i = 0; i < 48; i++) {
1288         /*
1289          * sprintf(
1290          *     field_name, "%s%d%s\0", "BB_chan_info_chan_tab_b0[",
1291          *     i, "].chaninfo_word");
1292          */
1293         /*field_read(field_name, &paprd_train_data_l[i]);*/
1294         paprd_train_data_l[i] = OS_REG_READ(ah, reg);
1295         reg = reg + 4;
1296     }
1297 
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;
1301 
1302     for (i = 0; i < 48; i++) {
1303         /*
1304          * sprintf(
1305          *     field_name, "%s%d%s\0", "BB_chan_info_chan_tab_b0[",
1306          *     i, "].chaninfo_word");
1307          */
1308         /*field_read(field_name, &paprd_train_data_u[i]);*/
1309         paprd_train_data_u[i] = OS_REG_READ(ah, reg);
1310         reg = reg + 4;
1311     }
1312 
1313     /*
1314      * for(i=0; i<48; i++)
1315      *     ath_hal_printf(
1316      *         ah, "%08x%08x\n", paprd_train_data_u[i], paprd_train_data_l[i]);
1317      */
1318     status = 0;
1319     if (create_pa_curve(
1320             paprd_train_data_l, paprd_train_data_u,
1321             pa_table, small_signal_gain, pa_in) ==
1322             AH_FALSE)
1323     {
1324         status = -2;
1325     }
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);
1330     } else {
1331         OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
1332             AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE, 0);
1333     }
1334     return status;
1335 }
1336 
1337 static int find_expn(int num)
1338 {
1339     int tmp, exp;
1340 
1341     exp = 0;
1342     tmp = num >> 1;
1343 
1344     while (tmp != 0) {
1345         tmp = tmp >> 1;
1346         exp++;
1347     }
1348 
1349     return exp;
1350 }
1351 
1352 static int find_proper_scale(int expn, int n)
1353 {
1354     int q_pw;
1355 
1356     q_pw = (expn > n) ? expn - 10 : 0;
1357     return q_pw;
1358 }
1359 
1360 static int find_max(int *array, int length)
1361 {
1362     int i, loc_max;
1363 
1364     loc_max = 0;
1365 
1366     for (i = 0; i < length; i++) {
1367         if (array[i] > loc_max) {
1368             loc_max = array[i];
1369         }
1370     }
1371 
1372     return loc_max;
1373 }
1374 
1375 static int paprd_abs(int num)
1376 {
1377     if (num < 0) {
1378         return -num;
1379     }
1380     return num;
1381 }
1382 
1383 #define NUM_BIN 23
1384 
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)
1388 {
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;
1394 
1395     int max_index;
1396     int scale_factor;
1397 
1398     int x_est[NUM_BIN + 1];
1399     int y[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];
1405 
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];
1410 
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];
1416 
1417     int g_fxp;
1418     int y_intercept;
1419     int order_x_by_y;
1420     int m, half_lo, half_hi;
1421     int sum_y_sqr;
1422     int sum_y_quad;
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;
1426     int alpha, beta;
1427     int order_1, order_2;
1428     int order1_5x, order2_3x;
1429     int order1_5x_rem, order2_3x_rem;
1430     int y5, y3, tmp;
1431     int bin, idx;
1432     int theta_low_bin = 0;
1433 
1434     /*
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
1440      */
1441     max_index = 0;
1442     /*
1443      * Disregard any bin that contains less than
1444      * or equal to 16 counts of samples
1445      */
1446     thresh_accum_cnt = 16;
1447     scale_factor = 5;
1448 
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 */
1452         accum_tx[bin] =
1453             ((paprd_train_data_l[bin] >> 16) & 0xffff) |
1454             ((paprd_train_data_u[bin] & 0x7ff) << 16);
1455         accum_rx[bin] =
1456             ((paprd_train_data_u[bin] >> 11) & 0x1f) |
1457              ((paprd_train_data_l[bin + 23] & 0xffff) << 5);
1458         accum_ang[bin] =
1459             ((paprd_train_data_l[bin + 23] >> 16) & 0xffff) |
1460              ((paprd_train_data_u[bin + 23] & 0x7ff) << 16);
1461         /*
1462          * printf(
1463          *     "%d\t%d\t%d\t%d\n", accum_cnt[bin], accum_tx[bin],
1464          *     accum_rx[bin], accum_ang[bin]);
1465          */
1466         if (accum_cnt[bin] > thresh_accum_cnt) {
1467             /* accum_cnt[i] will be non-zero at this point */
1468             x_est[bin + 1] =
1469                 ((((accum_tx[bin] << scale_factor) +
1470                     accum_cnt[bin]) / accum_cnt[bin]) + 32) >> scale_factor;
1471             y[bin + 1] =
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)) {
1476                 theta[bin + 1] =
1477                     ((accum_ang[bin] - (1 << 27)) * (1 << scale_factor) +
1478                     accum_cnt[bin]);
1479                 theta[bin + 1] = theta[bin + 1] / (int) accum_cnt[bin];
1480                 /*
1481                  *  theta[i+1] =
1482                  *      ((accum_ang[i] - (1 << 27)) *
1483                  *      (1 << scale_factor) + zz) / zz;
1484                  */
1485             } else {
1486                 theta[bin + 1] =
1487                     ((accum_ang[bin] * (1 << scale_factor)) +
1488                     accum_cnt[bin]) / accum_cnt[bin];
1489             }
1490             max_index++;
1491         }
1492         /*
1493          * printf(
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]);
1497          */
1498     }
1499 
1500     /*
1501      * Find average theta of first 5 bin and all of those to same value.
1502      * Curve is linear at that range.
1503      */
1504     for (bin = 1; bin < 6; bin++) {
1505         theta_low_bin += theta[bin];
1506     }
1507     theta_low_bin = theta_low_bin / 5;
1508     for (bin = 1; bin < 6; bin++) {
1509         theta[bin] = theta_low_bin;
1510     }
1511 
1512     /* Set values at origin */
1513     theta[0] = theta_low_bin;
1514 
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]);*/
1518     }
1519 
1520     x_est[0] = 0;
1521     y[0] = 0;
1522     scale_factor = 8;
1523     /* low signal gain */
1524     if (x_est[6] == x_est[3]) {
1525         return AH_FALSE;
1526     }
1527     g_fxp =
1528         (((y[6] - y[3]) * 1 << scale_factor) + (x_est[6] - x_est[3])) /
1529         (x_est[6] - x_est[3]);
1530     if (g_fxp == 0) {
1531         /*
1532          * ath_hal_printf(
1533          *     NULL, "%s[%d] Potential divide by zero error\n",
1534          *     __func__, __LINE__);
1535          */
1536         return AH_FALSE;
1537     }
1538 
1539     for (bin = 0; bin <= max_index; bin++) {
1540         y_lin[bin] =
1541             (g_fxp * (x_est[bin] - x_est[3]) + (1 << scale_factor)) /
1542             (1 << scale_factor) + y[3];
1543     }
1544     y_intercept = y_lin[0];
1545 
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;
1549     }
1550 
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;
1555     }
1556 
1557     /*
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]);
1561      *  }
1562      */
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]);*/
1567     }
1568 
1569     /* Check for divide by 0 */
1570     if (y_est[max_index] == 0) {
1571         return AH_FALSE;
1572     }
1573     order_x_by_y =
1574         (x_est_fxp1_nonlin[max_index] + y_est[max_index]) / y_est[max_index];
1575     if (order_x_by_y == 0) {
1576         m = 10;
1577     } else if (order_x_by_y == 1) {
1578         m = 9;
1579     } else {
1580         m = 8;
1581     }
1582 
1583     half_lo = (max_index > 15) ? 7 : max_index >> 1;
1584     half_hi = max_index - half_lo;
1585     scale_factor = 8;
1586     sum_y_sqr = 0;
1587     sum_y_quad = 0;
1588 
1589     for (bin = 0; bin <= half_hi; bin++) {
1590         if (y_est[bin + half_lo] == 0) {
1591             /*
1592              * ath_hal_printf(
1593              *     NULL, "%s Potential divide by zero error\n", __func__);
1594              */
1595             return AH_FALSE;
1596         }
1597 
1598         x_tilde[bin] =
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];
1605 
1606         y_sqr[bin] =
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];
1613     }
1614 
1615     /*printf("sum_y_sqr = %d, sum_y_quad=%d\n", sum_y_sqr, sum_y_quad);*/
1616 
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]);
1622 
1623         /*
1624          * printf(
1625          *     "bin=%d, b1_tmp[bin] = %d, b2_tmp[bin] = %d\n",
1626          *     bin, b1_tmp[bin], b2_tmp[bin]);
1627          */
1628     }
1629 
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);
1633 
1634     beta_raw = 0;
1635     alpha_raw = 0;
1636 
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);
1641 
1642         /*
1643          * printf(
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]);
1646          */
1647         beta_raw = beta_raw + b1_tmp[bin] * x_tilde[bin];
1648         alpha_raw = alpha_raw + b2_tmp[bin] * x_tilde[bin];
1649     }
1650 
1651     scale_b =
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 */
1657     if (scale_b == 0) {
1658         return AH_FALSE;
1659     }
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);
1662 
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;
1669 
1670     order1_5x = order_1 / 5;
1671     order2_3x = order_2 / 3;
1672 
1673     order1_5x_rem = order_1 - 5 * order1_5x;
1674     order2_3x_rem = order_2 - 3 * order2_3x;
1675 
1676     for (idx = 0; idx < AR9300_PAPRD_TABLE_SZ; idx++) {
1677         tmp = idx * 32;
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;
1683 
1684         y5 = y5 >> order1_5x_rem;
1685         y3 = (alpha * tmp) >> order2_3x;
1686         y3 = (y3 * tmp) >> order2_3x;
1687         y3 = (y3 * tmp) >> order2_3x;
1688 
1689         y3 = y3 >> order2_3x_rem;
1690         /* g_fxp was checked for zero already */
1691         pa_in[idx] = y5 + y3 + (256 * tmp) / g_fxp;
1692     }
1693 
1694     for (idx = 1; idx < 23; idx++) {
1695         tmp = pa_in[idx + 1] - pa_in[idx];
1696         if (tmp < 0) {
1697             pa_in[idx + 1] = pa_in[idx] + (pa_in[idx] - pa_in[idx - 1]);
1698         }
1699     }
1700 
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]);*/
1704     }
1705 
1706     beta_raw = 0;
1707     alpha_raw = 0;
1708 
1709     for (bin = 0; bin <= half_hi; bin++) {
1710         /*
1711          *  printf(
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]);
1715          */
1716         /* y_est[] was already checked for zero */
1717         theta_tilde[bin] =
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];
1724 
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];
1728 
1729         /*
1730         printf("bin=%d, alpha_raw=%d, beta_raw=%d\n", bin, alpha_raw, beta_raw);
1731          */
1732     }
1733 
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);
1736 
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;
1744 
1745     order1_5x = order_1 / 5;
1746     order2_3x = order_2 / 3;
1747 
1748     order1_5x_rem = order_1 - 5 * order1_5x;
1749     order2_3x_rem = order_2 - 3 * order2_3x;
1750 
1751     for (idx = 0; idx < AR9300_PAPRD_TABLE_SZ; idx++) {
1752         tmp = idx * 32;
1753 
1754         if (beta > 0) {
1755             y5 = (((beta * tmp - 64) >> 6) -
1756                 (1 << order1_5x)) / (1 << order1_5x);
1757         } else {
1758             y5 = ((((beta * tmp - 64) >> 6) +
1759                     (1 << order1_5x)) / (1 << order1_5x));
1760         }
1761 
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);
1766 
1767         y5 = y5 / (1 << order1_5x_rem);
1768 
1769         if (beta > 0) {
1770             y3 = (alpha * tmp - (1 << order2_3x)) / (1 << order2_3x);
1771         } else {
1772             y3 = (alpha * tmp + (1 << order2_3x)) / (1 << order2_3x);
1773         }
1774 
1775         y3 = (y3 * tmp) / (1 << order2_3x);
1776         y3 = (y3 * tmp) / (1 << order2_3x);
1777 
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);*/
1781         pa_angle[idx] =
1782             (pa_angle[idx] < -150) ? -150 : ((pa_angle[idx] >
1783                 150) ? 150 : pa_angle[idx]);
1784     }
1785 
1786     pa_angle[0] = 0;
1787     pa_angle[1] = 0;
1788     pa_angle[2] = 0;
1789     pa_angle[3] = 0;
1790 
1791     pa_angle[4] = (pa_angle[5] + 2) >> 1;
1792 
1793     for (idx = 0; idx < AR9300_PAPRD_TABLE_SZ; idx++) {
1794         pa_table[idx] = ((pa_in[idx] & 0x7ff) << 11) + (pa_angle[idx] & 0x7ff);
1795         /*
1796          * HALDEBUG(
1797          *     NULL, HAL_DEBUG_UNMASKABLE,"%d\t%d\t0x%x\n",
1798          *     pa_in[idx], pa_angle[idx], pa_table[idx]);
1799          */
1800     }
1801 
1802     /*HALDEBUG(NULL, HAL_DEBUG_UNMASKABLE, "g_fxp = %d\n", g_fxp);*/
1803     *g_fxp_ext = g_fxp;
1804     return AH_TRUE;
1805 }
1806 
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)
1811 {
1812     int i;
1813     u_int32_t *paprd_table_val = NULL;
1814     u_int32_t small_signal_gain = 0;
1815     u_int32_t reg = 0;
1816 
1817     reg = AR_PHY_PAPRD_MEM_TAB_B0;
1818     switch (txchain) {
1819     case 0x1:
1820     case 0x3:
1821     case 0x7:
1822 	paprd_table_val = &AH9300(ah)->pa_table[0][0];
1823 	small_signal_gain = AH9300(ah)->small_signal_gain[0];
1824 	break;
1825     case 0x2:
1826 	paprd_table_val = &AH9300(ah)->pa_table[1][0];
1827 	small_signal_gain = AH9300(ah)->small_signal_gain[1];
1828 	break;
1829     case 0x4:
1830 	paprd_table_val = &AH9300(ah)->pa_table[2][0];
1831 	small_signal_gain = AH9300(ah)->small_signal_gain[2];
1832 	break;
1833     default:
1834 	// Error out.
1835 	ath_hal_printf(ah, "YAK! Bad chain mask %x\n", txchain);
1836 	return;
1837     }
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]);
1842 
1843         reg = reg + 4;
1844     }
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));
1848 
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));
1853 
1854 }
1855 
1856 void ar9300_populate_paprd_single_table(struct ath_hal *ah,
1857     struct ieee80211_channel *chan, int chain_num)
1858 {
1859     int i, j, bad_read = 0;
1860 #ifdef	AH_DEBUG
1861     HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
1862 #endif
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];
1865     u_int32_t reg = 0;
1866 
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);
1870 
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;
1877     }
1878 
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)) {
1884                 continue;
1885             }
1886         }
1887         /*
1888          * sprintf(
1889          *     field_name, "%s%d[%d]%s\0", "BB_paprd_mem_tab_b",
1890          *     chain_num, i, ".paprd_mem");
1891          */
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]);
1895         /*
1896          * printf(
1897          *     "%s[%d] reg %08x = 0x%08x\n",
1898          *     __func__, __LINE__, reg, paprd_table_val[i]);
1899          */
1900          if (OS_REG_READ(ah, reg) == 0xdeadbeef) {
1901             HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
1902                      "%s: Reg0x%x = 0xdeadbeef\n", __func__, reg);
1903             bad_read++;
1904             for (j = AR_PHY_PAPRD_MEM_TAB_B0; j < (AR_PHY_PAPRD_MEM_TAB_B0 + 0x10); j+=4)
1905             {
1906                 if (OS_REG_READ(ah, j) == 0xdeadbeef) {
1907                     HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
1908                              "%s: Reg0x%x = 0xdeadbeef\n", __func__, j);
1909                     bad_read++;
1910                 }
1911             }
1912             for (j = AR_PHY_PAPRD_MEM_TAB_B1; j < (AR_PHY_PAPRD_MEM_TAB_B1 + 0x10); j+=4)
1913             {
1914                 if (OS_REG_READ(ah, j) == 0xdeadbeef) {
1915                     HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
1916                              "%s: Reg0x%x = 0xdeadbeef\n", __func__, j);
1917                     bad_read++;
1918                 }
1919             }
1920          }
1921 
1922         reg = reg + 4;
1923     }
1924 
1925     if (bad_read > 4) {
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;
1930     }
1931 
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",
1945                 __func__, __LINE__,
1946                 (unsigned) AR_PHY_PA_GAIN123_B1,
1947                 OS_REG_READ(ah, AR_PHY_PA_GAIN123_B1));
1948         }
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",
1955                 __func__, __LINE__,
1956                 (unsigned) AR_PHY_PA_GAIN123_B2,
1957                 OS_REG_READ(ah, AR_PHY_PA_GAIN123_B2));
1958         }
1959     } else {
1960         /* invalid channel number */
1961     }
1962 
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));
1984         }
1985     }
1986     /*ar9300_enable_paprd(ah, AH_TRUE);*/
1987 }
1988 
1989 HAL_STATUS ar9300_paprd_setup_gain_table(struct ath_hal *ah, int chain_num)
1990 {
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);
1995 
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 */
2001         gain_index = 0;
2002 
2003         for (i = 0; i < 32; i++) {
2004             if (AH9300(ah)->paprd_gain_table_index[i] < desired_gain) {
2005                 gain_index = gain_index + 1;
2006             } else {
2007                 break;
2008             }
2009         }
2010 
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);
2017         } else {
2018             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
2019                 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE, 0);
2020         }
2021     }
2022 
2023     return HAL_OK;
2024 }
2025 
2026 static HAL_BOOL ar9300_paprd_retrain_pain(struct ath_hal * ah, int * pa_in)
2027 {
2028     int count = 0, i;
2029     int capdiv_offset = 0, quick_drop_offset;
2030     int capdiv2g, quick_drop;
2031 
2032     capdiv2g = (OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF3) >> 1) & 0xF;
2033     if (!AR_SREV_POSEIDON(ah)) {
2034         quick_drop =
2035             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
2036                 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP);
2037     } else {
2038         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);
2041     }
2042 
2043     if ( quick_drop != 0 ) {
2044         quick_drop -= 0x40;
2045     }
2046     for (i = 0; i < (NUM_BIN + 1); i++) {
2047         if (pa_in[i] == 1400) {
2048             count++;
2049         }
2050     }
2051 
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;
2057                 if (capdiv2g > 7) {
2058                     capdiv2g = 7;
2059                     if (pa_in[23] < 600) {
2060                         quick_drop = quick_drop + 1;
2061                         if (quick_drop > 0) {
2062                             quick_drop = 0;
2063                         }
2064                     }
2065                 }
2066 
2067                 OS_REG_RMW_FIELD(ah,
2068                     AR_PHY_65NM_CH0_TXRF3,
2069     			    AR_PHY_65NM_CH0_TXRF3_CAPDIV2G,
2070     			    capdiv2g);
2071 
2072                 OS_REG_RMW_FIELD_ALT(ah,
2073                     AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
2074                     AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
2075                     quick_drop);
2076 
2077                 return AH_TRUE;
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;
2083                 }
2084                 quick_drop = quick_drop + quick_drop_offset;
2085                 capdiv2g = capdiv2g + (int)(quick_drop_offset / 2);
2086                 if (capdiv2g > 7) {
2087                     capdiv2g = 7;
2088                 }
2089                 if (quick_drop > 0) {
2090                     quick_drop = 0;
2091                     capdiv2g = capdiv2g - (int)(quick_drop_offset / 1);
2092     				if (capdiv2g < 0) {
2093                         capdiv2g = 0;
2094     				}
2095                 }
2096                 OS_REG_RMW_FIELD(ah,
2097                         AR_PHY_65NM_CH0_TXRF3,
2098     			        AR_PHY_65NM_CH0_TXRF3_CAPDIV2G,
2099     			        capdiv2g);
2100 
2101                 OS_REG_RMW_FIELD_ALT(ah,
2102                         AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
2103         			    AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
2104                         quick_drop);
2105 
2106                 return AH_TRUE;
2107                 /* sleep(1); */
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;
2119                     if (capdiv2g > 6) {
2120                         capdiv2g = 6;
2121                     }
2122                     if (quick_drop < -4) {
2123                         quick_drop = -4;
2124                     }
2125                     OS_REG_RMW_FIELD(ah,
2126                         AR_PHY_65NM_CH0_TXRF3,
2127                         AR_PHY_65NM_CH0_TXRF3_CAPDIV2G,
2128                         capdiv2g);
2129                     OS_REG_RMW_FIELD_ALT(ah,
2130                         AR_PHY_PAPRD_TRAINER_CNTL3,
2131                         AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
2132                         quick_drop);
2133                     return AH_TRUE;
2134                 } else {
2135                     capdiv2g = capdiv2g + capdiv_offset;
2136                     if (capdiv2g > 6) {
2137                         capdiv2g = 6;
2138                     }
2139                     if (quick_drop < -4) {
2140                         quick_drop = -4;
2141                     }
2142                     OS_REG_RMW_FIELD(ah,
2143                         AR_PHY_65NM_CH0_TXRF3,
2144                         AR_PHY_65NM_CH0_TXRF3_CAPDIV2G,
2145                         capdiv2g);
2146                     OS_REG_RMW_FIELD_ALT(ah,
2147                         AR_PHY_PAPRD_TRAINER_CNTL3,
2148                         AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
2149                         quick_drop);
2150                     return AH_TRUE;
2151                 }
2152             } /* end of if (PA_in[23] < 1000) */
2153             else if (pa_in[23] == 1400) {
2154                 if (count > 3) {
2155                     quick_drop_offset = 1;
2156                     quick_drop = quick_drop + quick_drop_offset;
2157                     capdiv2g = capdiv2g - (count / 4);
2158                     if (capdiv2g < 0) {
2159                         capdiv2g = 0;
2160                     }
2161                     if (quick_drop > -2) {
2162                         quick_drop = -2;
2163                     }
2164                     OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_TXRF3,
2165                         AR_PHY_65NM_CH0_TXRF3_CAPDIV2G,
2166                         capdiv2g);
2167                     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
2168                         AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
2169                         quick_drop);
2170                     return AH_TRUE;
2171                 } else {
2172                     capdiv2g = capdiv2g - 1;
2173                     if (capdiv2g < 0) {
2174                         capdiv2g = 0;
2175                     }
2176                     OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_TXRF3,
2177                         AR_PHY_65NM_CH0_TXRF3_CAPDIV2G,
2178                         capdiv2g);
2179                     OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
2180                         AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
2181                         quick_drop);
2182                     return AH_TRUE;
2183                 }
2184             } /* end of if (PA_in[23] == 1400)*/
2185         } /* end of if ((PA_in[23] < 1000) || (PA_in[23] == 1400)) */
2186     }
2187 
2188     return AH_FALSE;
2189 }
2190 
2191 HAL_STATUS ar9300_paprd_create_curve(struct ath_hal * ah,
2192   struct ieee80211_channel * chan, int chain_num)
2193 {
2194     int status = 0;
2195     u_int32_t *pa_table, small_signal_gain;
2196     int pa_in[NUM_BIN + 1];
2197 
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         status = ar9300_create_pa_curve(ah, &pa_table[0], &small_signal_gain,
2202                     &pa_in[0]);
2203 
2204 		if (AR_SREV_WASP(ah)) {
2205 			OS_DELAY(1000);
2206 		}
2207 
2208         if (status != 0) {
2209             ath_hal_printf(ah, "ERROR:: paprd failed with error code = %d\n",
2210                 status);
2211             return -1;
2212         }
2213         AH9300(ah)->small_signal_gain[chain_num] = small_signal_gain;
2214 
2215         if (AR_SREV_POSEIDON(ah) || AR_SREV_HORNET(ah)) {
2216             if (ar9300_paprd_retrain_pain(ah, pa_in)) {
2217                 /* need re-train PAPRD */
2218                 return HAL_EINPROGRESS;
2219 		    }
2220         }
2221     }
2222     return HAL_OK;
2223 }
2224 
2225 int ar9300_paprd_init_table(struct ath_hal *ah, struct ieee80211_channel * chan)
2226 {
2227     HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
2228 
2229     if ((AR_SREV_WASP(ah) && IS_CHAN_5GHZ(ichan)) ||
2230          ar9300_paprd_setup_single_table(ah, chan)) {
2231         goto FAIL;
2232     }
2233     OS_MEMZERO(AH9300(ah)->paprd_gain_table_entries,
2234         sizeof(AH9300(ah)->paprd_gain_table_entries));
2235     OS_MEMZERO(AH9300(ah)->paprd_gain_table_index,
2236         sizeof(AH9300(ah)->paprd_gain_table_index));
2237 
2238     ar9300_gain_table_entries(ah);
2239     return 0;
2240 FAIL:
2241     return -1;
2242 }
2243 
2244 int ar9300_paprd_is_done(struct ath_hal *ah)
2245 {
2246     int temp, agc2_pwr;
2247 
2248     /*field_read("BB_paprd_trainer_stat1.paprd_train_done", &temp);*/
2249     if (!AR_SREV_POSEIDON(ah)) {
2250         temp =
2251             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
2252                 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
2253 
2254         if (temp == 0x1) {
2255             agc2_pwr =
2256                 OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
2257                    AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR);
2258 
2259             HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2260                    "%s AGC2_PWR=0x%2x Training done=0x%2x\n",
2261                    __func__, agc2_pwr, temp);
2262 
2263             /* Retrain if agc2_pwr is not in ideal range */
2264             if (agc2_pwr <= AH_PAPRD_IDEAL_AGC2_PWR_RANGE) {
2265                 temp = 0;
2266             }
2267 		}
2268     } else {
2269         temp =
2270             OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
2271                 AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
2272     }
2273     if (!temp) {
2274         /*ath_hal_printf(ah, "%s[%d] PAPRD TEMp Error\n", __func__, __LINE__);*/
2275     }
2276 
2277     return temp;
2278 }
2279 
2280 /*
2281  * ar9300_paprd_dec_tx_pwr
2282  *
2283  * This function do decrease tx power if Paprd is off or train failed.
2284  */
2285 void
2286 ar9300_paprd_dec_tx_pwr(struct ath_hal *ah)
2287 {
2288     u_int32_t   pwr_temp, pwr_reg;
2289     int         i, loop_cnt;
2290     struct ar9300_paprd_pwr_adjust  *p_item;
2291     struct ath_hal_9300 *ahp = AH9300(ah);
2292 
2293     if (AR_SREV_POSEIDON(ah)) {
2294         loop_cnt =
2295         (sizeof(ar9300_paprd_pwr_adj_array) /
2296             sizeof(struct ar9300_paprd_pwr_adjust));
2297         for (i = 0; i < loop_cnt; i++ )
2298         {
2299             p_item = &ar9300_paprd_pwr_adj_array[i];
2300             pwr_reg = OS_REG_READ(ah, p_item->reg_addr);
2301             pwr_temp = ahp->ah_default_tx_power[p_item->target_rate];
2302             pwr_temp -= (p_item->sub_db * 2);
2303             pwr_temp = pwr_temp << p_item->reg_mask_offset;
2304             pwr_temp |= (pwr_reg&~(p_item->reg_mask <<p_item->reg_mask_offset));
2305 
2306             if (pwr_temp != pwr_reg)
2307             {
2308                 OS_REG_WRITE(ah, p_item->reg_addr, pwr_temp);
2309             }
2310         }
2311     }
2312     return;
2313 }
2314 
2315 int ar9300_paprd_thermal_send(struct ath_hal *ah)
2316 {
2317     if (AR_SREV_HORNET(ah)) {
2318         return OS_REG_READ(ah, AR_TFCNT);
2319     } else {
2320         return 1;
2321     }
2322 }
2323 
2324 #if 0
2325 void ar9300_paprd_test_prints(struct ath_hal *ah)
2326 {
2327     u_int32_t i, reg = 0;
2328 
2329     HALDEBUG(NULL, HAL_DEBUG_CALIBRATE, "=====ar9300_paprd_test_prints=======\n");
2330     /*printf("=====ar9300_paprd_test_prints=======\n");*/
2331     HALDEBUG(NULL, HAL_DEBUG_CALIBRATE, "BB_paprd_ctrl0_b0 = 0x%08x\n",
2332         OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B0));
2333     /*
2334      * printf(
2335      *     "BB_paprd_ctrl0_b0 = 0x%08x\n",
2336      *     OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B0));
2337      */
2338     if (!AR_SREV_POSEIDON(ah) && !AR_SREV_HORNET(ah)) {
2339         HALDEBUG(NULL, HAL_DEBUG_CALIBRATE, "BB_paprd_ctrl0_b1 = 0x%08x\n",
2340             OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B1));
2341         /*
2342          * printf(
2343          *     "BB_paprd_ctrl0_b1 = 0x%08x\n",
2344          *     OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B1));
2345          */
2346         HALDEBUG(NULL, HAL_DEBUG_CALIBRATE, "BB_paprd_ctrl0_b2 = 0x%08x\n",
2347             OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B2));
2348         /*
2349          * printf(
2350          *     "BB_paprd_ctrl0_b2 = 0x%08x\n",
2351          *     OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B2));
2352          */
2353     }
2354 
2355     reg = AR_PHY_PAPRD_MEM_TAB_B0;
2356     HALDEBUG(NULL, HAL_DEBUG_CALIBRATE,
2357         "%s[%d] reg %08lx small_signal_gain ch0 0x%08x\n", __func__, __LINE__,
2358         AR_PHY_PA_GAIN123_B0, OS_REG_READ(ah, AR_PHY_PA_GAIN123_B0));
2359     /*
2360      * printf(
2361      *     "%s[%d] reg %08lx small_signal_gain ch0 0x%08x\n",
2362      *     __func__,  __LINE__, AR_PHY_PA_GAIN123_B0,
2363      *     OS_REG_READ(ah, AR_PHY_PA_GAIN123_B0));
2364      */
2365 
2366     for (i = 0; i < 24; i++) {
2367         HALDEBUG(NULL, HAL_DEBUG_CALIBRATE, "%s[%d] reg %08x = 0x%08x\n",
2368             __func__, __LINE__, reg, OS_REG_READ(ah, reg));
2369         /*
2370          * printf(
2371          *     "%s[%d] reg %08x = 0x%08x\n", __func__, __LINE__,
2372          *     reg, OS_REG_READ(ah, reg));
2373          */
2374         reg = reg + 4;
2375     }
2376 
2377     ar9300_paprd_debug_print(ah);
2378     HALDEBUG(NULL, HAL_DEBUG_CALIBRATE,
2379         "=====ar9300_paprd_test_prints end=======\n");
2380     /*printf("=====ar9300_paprd_test_prints end=======\n");*/
2381 
2382     if (!AR_SREV_POSEIDON(ah)) {
2383         reg = AR_PHY_PAPRD_MEM_TAB_B1;
2384         printf("%s[%d] reg %08lx small_signal_gain ch1 0x%08x\n",
2385             __func__, __LINE__,
2386             AR_PHY_PA_GAIN123_B1, OS_REG_READ(ah, AR_PHY_PA_GAIN123_B1));
2387         for (i = 0; i < 24; i++) {
2388             OS_REG_WRITE(ah, reg, paprd_table_val[i]);
2389             HALDEBUG(NULL, HAL_DEBUG_CALIBRATE, "%s[%d] reg %08x = 0x%08x\n",
2390                 __func__, __LINE__, reg, OS_REG_READ(ah, reg));
2391             printf("%s[%d] reg %08x = 0x%08x\n", __func__, __LINE__, reg,
2392                 OS_REG_READ(ah, reg));
2393             reg = reg + 4;
2394         }
2395 
2396         reg = AR_PHY_PAPRD_MEM_TAB_B2;
2397         printf("%s[%d] reg %08lx small_signal_gain ch2 0x%08x\n",
2398             __func__, __LINE__,
2399             AR_PHY_PA_GAIN123_B2, OS_REG_READ(ah, AR_PHY_PA_GAIN123_B2));
2400     }
2401 }
2402 #endif
2403 
2404 #else
2405 int
2406 ar9300_paprd_init_table(struct ath_hal *ah, HAL_CHANNEL * chan)
2407 {
2408     return 0;
2409 }
2410 
2411 HAL_STATUS
2412 ar9300_paprd_setup_gain_table(struct ath_hal * ah, int chain_num)
2413 {
2414     return HAL_OK;
2415 }
2416 
2417 HAL_STATUS
2418 ar9300_paprd_create_curve(struct ath_hal * ah, HAL_CHANNEL * chan,
2419     int chain_num)
2420 {
2421     return HAL_OK;
2422 }
2423 
2424 int
2425 ar9300_paprd_is_done(struct ath_hal *ah)
2426 {
2427     return 0;
2428 }
2429 
2430 void
2431 ar9300_enable_paprd(struct ath_hal *ah, HAL_BOOL enable_flag, HAL_CHANNEL * chan)
2432 {
2433     return;
2434 }
2435 
2436 void
2437 ar9300_populate_paprd_single_table(struct ath_hal *ah, HAL_CHANNEL * chan,
2438     int chain_num)
2439 {
2440     return;
2441 }
2442 
2443 void
2444 ar9300_paprd_dec_tx_pwr(struct ath_hal *ah)
2445 {
2446     return;
2447 }
2448 
2449 int ar9300_paprd_thermal_send(struct ath_hal *ah)
2450 {
2451     return 1;
2452 }
2453 #endif                          /* ATH_SUPPORT_PAPRD */
2454