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
27static 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
46HAL_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
50static int
51ar9300_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
402FAILED:
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
411static inline HAL_CHANNEL_INTERNAL*
412ar9300_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
440void 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
652static 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 */
674static 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
787static 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)
829static 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
1273static 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
1337static 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
1352static 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
1360static 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
1375static 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
1385HAL_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.
1810void 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
1856void 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
1989HAL_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
2026static 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
2191HAL_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
2225int 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;
2240FAIL:
2241    return -1;
2242}
2243
2244int 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 */
2285void
2286ar9300_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
2315int 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
2325void 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
2405int
2406ar9300_paprd_init_table(struct ath_hal *ah, HAL_CHANNEL * chan)
2407{
2408    return 0;
2409}
2410
2411HAL_STATUS
2412ar9300_paprd_setup_gain_table(struct ath_hal * ah, int chain_num)
2413{
2414    return HAL_OK;
2415}
2416
2417HAL_STATUS
2418ar9300_paprd_create_curve(struct ath_hal * ah, HAL_CHANNEL * chan,
2419    int chain_num)
2420{
2421    return HAL_OK;
2422}
2423
2424int
2425ar9300_paprd_is_done(struct ath_hal *ah)
2426{
2427    return 0;
2428}
2429
2430void
2431ar9300_enable_paprd(struct ath_hal *ah, HAL_BOOL enable_flag, HAL_CHANNEL * chan)
2432{
2433    return;
2434}
2435
2436void
2437ar9300_populate_paprd_single_table(struct ath_hal *ah, HAL_CHANNEL * chan,
2438    int chain_num)
2439{
2440    return;
2441}
2442
2443void
2444ar9300_paprd_dec_tx_pwr(struct ath_hal *ah)
2445{
2446    return;
2447}
2448
2449int ar9300_paprd_thermal_send(struct ath_hal *ah)
2450{
2451    return 1;
2452}
2453#endif                          /* ATH_SUPPORT_PAPRD */
2454