1250003Sadrian/*
2250003Sadrian * Copyright (c) 2013 Qualcomm Atheros, Inc.
3250003Sadrian *
4250003Sadrian * Permission to use, copy, modify, and/or distribute this software for any
5250003Sadrian * purpose with or without fee is hereby granted, provided that the above
6250003Sadrian * copyright notice and this permission notice appear in all copies.
7250003Sadrian *
8250003Sadrian * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9250003Sadrian * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10250003Sadrian * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11250003Sadrian * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12250003Sadrian * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13250003Sadrian * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14250003Sadrian * PERFORMANCE OF THIS SOFTWARE.
15250003Sadrian */
16250003Sadrian
17250003Sadrian#include "opt_ah.h"
18250003Sadrian#include "ah.h"
19250003Sadrian#include "ar9300.h"
20250003Sadrian#include "ah_internal.h"
21250003Sadrian#include "ar9300paprd.h"
22250003Sadrian#include "ar9300reg.h"
23250003Sadrian
24250003Sadrian
25250003Sadrian#if ATH_SUPPORT_PAPRD
26250003Sadrian
27250003Sadrianstatic struct ar9300_paprd_pwr_adjust ar9300_paprd_pwr_adj_array[] = {
28250003Sadrian/*   rate index     ,   register offset   ,  mask of register               , */
29250003Sadrian  {ALL_TARGET_HT20_5, AR_PHY_POWERTX_RATE5, AR_PHY_POWERTX_RATE5_POWERTXHT20_3,
30250003Sadrian/* mask offset of register             ,  offset  dB*/
31250003Sadrian   AR_PHY_POWERTX_RATE5_POWERTXHT20_3_S,      1},
32250003Sadrian  {ALL_TARGET_HT20_6, AR_PHY_POWERTX_RATE6, AR_PHY_POWERTX_RATE6_POWERTXHT20_4,
33250003Sadrian   AR_PHY_POWERTX_RATE6_POWERTXHT20_4_S,      2},
34250003Sadrian  {ALL_TARGET_HT20_7, AR_PHY_POWERTX_RATE6, AR_PHY_POWERTX_RATE6_POWERTXHT20_5,
35250003Sadrian   AR_PHY_POWERTX_RATE6_POWERTXHT20_5_S,      2},
36250003Sadrian  {ALL_TARGET_HT40_5, AR_PHY_POWERTX_RATE7, AR_PHY_POWERTX_RATE7_POWERTXHT40_3,
37250003Sadrian   AR_PHY_POWERTX_RATE7_POWERTXHT40_3_S,      1},
38250003Sadrian  {ALL_TARGET_HT40_6, AR_PHY_POWERTX_RATE8, AR_PHY_POWERTX_RATE8_POWERTXHT40_4,
39250003Sadrian   AR_PHY_POWERTX_RATE8_POWERTXHT40_4_S,      2},
40250003Sadrian  {ALL_TARGET_HT40_7, AR_PHY_POWERTX_RATE8, AR_PHY_POWERTX_RATE8_POWERTXHT40_5,
41250003Sadrian   AR_PHY_POWERTX_RATE8_POWERTXHT40_5_S,      2},
42250003Sadrian {ALL_TARGET_LEGACY_54, AR_PHY_POWERTX_RATE2, AR_PHY_POWERTX_RATE2_POWERTX54M_7,
43250003Sadrian   AR_PHY_POWERTX_RATE2_POWERTX54M_7_S,       2},
44250003Sadrian};
45250003Sadrian
46250003SadrianHAL_BOOL create_pa_curve(u_int32_t * paprd_train_data_l,
47250003Sadrian    u_int32_t *paprd_train_data_u, u_int32_t *pa_table, u_int32_t *g_fxp_ext,
48250003Sadrian    int * pa_in);
49250003Sadrian
50250003Sadrianstatic int
51250008Sadrianar9300_paprd_setup_single_table(struct ath_hal *ah, struct ieee80211_channel * chan)
52250003Sadrian{
53250008Sadrian    int is_2g = IEEE80211_IS_CHAN_2GHZ(chan);
54250008Sadrian    HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
55250003Sadrian    struct ath_hal_9300 *ahp = AH9300(ah);
56250003Sadrian    int is_ht40 = 0;
57250003Sadrian    u_int32_t am_mask = 0;
58250003Sadrian    u_int32_t val = OS_REG_READ(ah, AR_2040_MODE);
59250003Sadrian    u_int8_t target_power_val_t2[ar9300_rate_size];
60250003Sadrian    int      power_tblindex = 0, power_delta = 0;
61250003Sadrian    int      paprd_scale_factor = 5;
62250003Sadrian
63250003Sadrian    const u_int8_t mask2num[8] = {
64250003Sadrian        0 /* 000 */,
65250003Sadrian        1 /* 001 */,
66250003Sadrian        1 /* 010 */,
67250003Sadrian        2 /* 011 */,
68250003Sadrian        1 /* 100 */,
69250003Sadrian        2 /* 101 */,
70250003Sadrian        2 /* 110 */,
71250003Sadrian        3 /* 111 */
72250003Sadrian    };
73250003Sadrian
74250003Sadrian    ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
75250003Sadrian
76250003Sadrian#define ABS(_x, _y) ((int)_x > (int)_y ? (int)_x - (int)_y : (int)_y - (int)_x)
77250003Sadrian
78250008Sadrian    ar9300_set_target_power_from_eeprom(ah, ichan->channel, target_power_val_t2);
79250003Sadrian    if (val & HAL_HT_MACMODE_2040) {
80250003Sadrian        is_ht40 = 1;
81250003Sadrian    }
82250003Sadrian
83250003Sadrian    /*
84250003Sadrian     * Note on paprd_scale_factor
85250003Sadrian     * This factor is saved in eeprom as 3 bit fields in following fashion.
86250003Sadrian     * In 5G there are 3 scale factors -- upper, mid and lower band.
87250003Sadrian     * Upper band scale factor is coded in bits 25-27 of
88250003Sadrian     * modal_header_5g.paprd_rate_mask_ht20.
89250003Sadrian     * Mid band scale factor is coded in bits 28-30 of
90250003Sadrian     * modal_header_5g.paprd_rate_mask_ht40.
91250003Sadrian     * Lower band scale factor is coded in bits 25-27 of
92250003Sadrian     * modal_header_5g.paprd_rate_mask_ht40.
93250003Sadrian     * For 2G there is only one scale factor. It is saved in bits 25-27 of
94250003Sadrian     * modal_header_2g.paprd_rate_mask_ht20.
95250003Sadrian     */
96250008Sadrian    AH_PAPRD_GET_SCALE_FACTOR(paprd_scale_factor, eep, is_2g, ichan->channel);
97250003Sadrian    if (is_2g) {
98250003Sadrian        if (is_ht40) {
99250003Sadrian            am_mask = ahp->ah_2g_paprd_rate_mask_ht40 & AH_PAPRD_AM_PM_MASK;
100250003Sadrian            power_tblindex = ALL_TARGET_HT40_0_8_16;
101250003Sadrian        } else {
102250003Sadrian            am_mask = ahp->ah_2g_paprd_rate_mask_ht20 & AH_PAPRD_AM_PM_MASK;
103250003Sadrian            power_tblindex = ALL_TARGET_HT20_0_8_16;
104250003Sadrian        }
105250003Sadrian        if (AR_SREV_HORNET(ah) || AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
106250003Sadrian            if (is_ht40) {
107250003Sadrian                ahp->paprd_training_power =
108250003Sadrian                    target_power_val_t2[ALL_TARGET_HT40_7] + 2;
109250003Sadrian            } else {
110250003Sadrian                ahp->paprd_training_power =
111250003Sadrian                    target_power_val_t2[ALL_TARGET_HT20_7] + 2;
112250003Sadrian            }
113250003Sadrian		} else if (AR_SREV_POSEIDON(ah)) {
114250003Sadrian            ahp->paprd_training_power = 25;
115250003Sadrian        } else {
116250003Sadrian            ahp->paprd_training_power =
117250003Sadrian                OS_REG_READ_FIELD_ALT(ah, AR_PHY_POWERTX_RATE5,
118250003Sadrian                AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
119250003Sadrian            if (ABS(target_power_val_t2[power_tblindex],
120250003Sadrian                ahp->paprd_training_power) >  paprd_scale_factor)
121250003Sadrian            {
122250003Sadrian                HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
123250003Sadrian                    "%s[%d]: Chan %d paprd failing EEP PWR 0x%08x"
124250008Sadrian                    "TGT PWR 0x%08x\n", __func__, __LINE__, ichan->channel,
125250003Sadrian                    target_power_val_t2[power_tblindex],
126250003Sadrian                    ahp->paprd_training_power);
127250003Sadrian                goto FAILED;
128250003Sadrian            }
129250003Sadrian
130250003Sadrian            power_delta =
131250003Sadrian                ABS(ahp->paprd_training_power,
132250003Sadrian                    target_power_val_t2[power_tblindex]);
133250003Sadrian
134250003Sadrian            power_delta = power_delta > 4 ? 0 : 4 - power_delta;
135250003Sadrian            ahp->paprd_training_power =
136250003Sadrian                ahp->paprd_training_power - power_delta;
137250003Sadrian        }
138250003Sadrian
139250003Sadrian
140250003Sadrian    } else {
141250003Sadrian        if (is_ht40) {
142250003Sadrian            ahp->paprd_training_power =
143250003Sadrian			    OS_REG_READ_FIELD_ALT(ah, AR_PHY_POWERTX_RATE8,
144250003Sadrian				AR_PHY_POWERTX_RATE8_POWERTXHT40_5);
145250003Sadrian            am_mask = ahp->ah_5g_paprd_rate_mask_ht40 & AH_PAPRD_AM_PM_MASK;
146250003Sadrian            switch (mask2num[ahp->ah_tx_chainmask])
147250003Sadrian            {
148250003Sadrian            case 1:
149250003Sadrian                power_delta = 6;
150250003Sadrian                break;
151250003Sadrian            case 2:
152250003Sadrian                power_delta = 4;
153250003Sadrian                break;
154250003Sadrian            case 3:
155250003Sadrian                power_delta = 2;
156250003Sadrian                break;
157250003Sadrian            default:
158250003Sadrian                goto FAILED;
159250003Sadrian                break;
160250003Sadrian            }
161250003Sadrian            power_tblindex = ALL_TARGET_HT40_7;
162250003Sadrian        } else {
163250003Sadrian            ahp->paprd_training_power =
164250003Sadrian			    OS_REG_READ_FIELD_ALT(ah, AR_PHY_POWERTX_RATE6,
165250003Sadrian				AR_PHY_POWERTX_RATE6_POWERTXHT20_5);
166250003Sadrian            am_mask = ahp->ah_5g_paprd_rate_mask_ht20 & AH_PAPRD_AM_PM_MASK;
167250003Sadrian            switch (mask2num[ahp->ah_tx_chainmask])
168250003Sadrian            {
169250003Sadrian            case 1:
170250003Sadrian                power_delta = 6;
171250003Sadrian                break;
172250003Sadrian            case 2:
173250003Sadrian                power_delta = 4;
174250003Sadrian                break;
175250003Sadrian            case 3:
176250003Sadrian                power_delta = 2;
177250003Sadrian                break;
178250003Sadrian            default:
179250003Sadrian                goto FAILED;
180250003Sadrian                break;
181250003Sadrian            }
182250003Sadrian            power_tblindex = ALL_TARGET_HT20_7;
183250003Sadrian        }
184250003Sadrian        /* Adjust for scale factor */
185250003Sadrian        ahp->paprd_training_power += paprd_scale_factor;
186250003Sadrian        /*
187250003Sadrian        ath_hal_printf(ah, "%s[%d] paprd_scale_factor %d power_delta %d\n",
188250003Sadrian            __func__, __LINE__, paprd_scale_factor, power_delta);
189250003Sadrian         */
190250003Sadrian        if (ABS(target_power_val_t2[power_tblindex], ahp->paprd_training_power)
191250003Sadrian            >  paprd_scale_factor)
192250003Sadrian        {
193250003Sadrian            HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
194250003Sadrian                "%s[%d]: Chan %d paprd failing EEP PWR 0x%08x TGT PWR 0x%08x\n",
195250008Sadrian                __func__, __LINE__, ichan->channel,
196250003Sadrian                target_power_val_t2[power_tblindex], ahp->paprd_training_power);
197250003Sadrian            goto FAILED;
198250003Sadrian        }
199250003Sadrian        ahp->paprd_training_power = ahp->paprd_training_power + power_delta;
200250003Sadrian    }
201250003Sadrian
202250003Sadrian    HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s 2G %d HT40 %d am_mask 0x%08x\n",
203250003Sadrian        __func__, is_2g, is_ht40, am_mask);
204250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK,
205250003Sadrian        am_mask);
206250003Sadrian    if (AR_SREV_HORNET(ah)) {
207250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK,
208250003Sadrian            0);
209250003Sadrian    }
210250003Sadrian    else {
211250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK,
212250003Sadrian            am_mask);
213250003Sadrian    }
214250003Sadrian
215250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK,
216250003Sadrian        AR_PHY_PAPRD_HT40_MASK);
217250003Sadrian    /* chain0 */
218250003Sadrian    if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN0_MASK) {
219250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B0,
220250003Sadrian            AR_PHY_PAPRD_CTRL0_B0_USE_SINGLE_TABLE_MASK, 1);
221250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
222250003Sadrian            AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_AM2PM_ENABLE_0, 1);
223250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
224250003Sadrian            AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_AM2AM_ENABLE_0, 1);
225250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
226250003Sadrian            AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_SCALING_ENA, 0);
227250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
228250003Sadrian            AR_PHY_PAPRD_CTRL1_B0_PA_GAIN_SCALE_FACT_0_MASK, 181);
229250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
230250003Sadrian            AR_PHY_PAPRD_CTRL1_B0_PAPRD_MAG_SCALE_FACT_0, 361);
231250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
232250003Sadrian            AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_SCALING_ENA, 0);
233250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B0,
234250003Sadrian            AR_PHY_PAPRD_CTRL0_B0_PAPRD_MAG_THRSH_0, 3);
235250003Sadrian    }
236250003Sadrian
237250003Sadrian    /* chain1 */
238250003Sadrian    if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN1_MASK) {
239250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B1,
240250003Sadrian            AR_PHY_PAPRD_CTRL0_B1_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_1, 1);
241250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
242250003Sadrian            AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_AM2PM_ENABLE_1, 1);
243250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
244250003Sadrian            AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_AM2AM_ENABLE_1, 1);
245250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
246250003Sadrian            AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_SCALING_ENA, 0);
247250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
248250003Sadrian            AR_PHY_PAPRD_CTRL1_B1_PA_GAIN_SCALE_FACT_1_MASK, 181);
249250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
250250003Sadrian            AR_PHY_PAPRD_CTRL1_B1_PAPRD_MAG_SCALE_FACT_1, 361);
251250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
252250003Sadrian            AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_SCALING_ENA, 0);
253250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B1,
254250003Sadrian            AR_PHY_PAPRD_CTRL0_B1_PAPRD_MAG_THRSH_1, 3);
255250003Sadrian    }
256250003Sadrian
257250003Sadrian    /* chain2 */
258250003Sadrian    if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN2_MASK) {
259250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B2,
260250003Sadrian            AR_PHY_PAPRD_CTRL0_B2_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_2, 1);
261250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
262250003Sadrian            AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_AM2PM_ENABLE_2, 1);
263250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
264250003Sadrian            AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_AM2AM_ENABLE_2, 1);
265250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
266250003Sadrian            AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_SCALING_ENA, 0);
267250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
268250003Sadrian            AR_PHY_PAPRD_CTRL1_B2_PA_GAIN_SCALE_FACT_2_MASK, 181);
269250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
270250003Sadrian            AR_PHY_PAPRD_CTRL1_B2_PAPRD_MAG_SCALE_FACT_2, 361);
271250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
272250003Sadrian            AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_SCALING_ENA, 0);
273250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B2,
274250003Sadrian            AR_PHY_PAPRD_CTRL0_B2_PAPRD_MAG_THRSH_2, 3);
275250003Sadrian    }
276250003Sadrian
277250003Sadrian    ar9300_enable_paprd(ah, AH_FALSE, chan);
278250003Sadrian    if (AR_SREV_POSEIDON(ah)) {
279250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
280250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP, 0x30);
281250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
282250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE, 1);
283250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
284250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE, 1);
285250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
286250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE, 0);
287250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
288250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE, 0);
289250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
290250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING, 28);
291250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
292250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE, 1);
293250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL2_POSEIDON,
294250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, 148);
295250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
296250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN, 4);
297250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
298250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN, 4);
299250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
300250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES, 7);
301250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
302250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL, 1);
303250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
304250003Sadrian	        AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -3);
305250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
306250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE, -15);
307250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
308250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE, 1);
309250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL4_POSEIDON,
310250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA, 0);
311250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL4_POSEIDON,
312250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR, 400);
313250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL4_POSEIDON,
314250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES, 100);
315250003Sadrian    } else {
316250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
317250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP, 0x30);
318250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
319250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE, 1);
320250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
321250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE, 1);
322250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
323250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE, 0);
324250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
325250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE, 0);
326250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
327250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING, 28);
328250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
329250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE, 1);
330250003Sadrian        if (is_2g) {
331250003Sadrian        	 if(AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)){
332250003Sadrian             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL2,
333250003Sadrian                 AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, 0x91);
334250003Sadrian           }else{
335250003Sadrian             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL2,
336250003Sadrian                 AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, 147);
337250003Sadrian           }
338250003Sadrian        }
339250003Sadrian		else if (AR_SREV_WASP(ah) && !is_2g) {
340250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL2,
341250003Sadrian	            AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, 137);
342250003Sadrian		} else {
343250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL2,
344250003Sadrian	            AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, 147);
345250003Sadrian        }
346250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
347250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN, 4);
348250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
349250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN, 4);
350250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
351250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES, 7);
352250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
353250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL, 1);
354250003Sadrian        if (AR_SREV_HORNET(ah) || AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
355250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
356250003Sadrian                AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -3);
357250003Sadrian        } else {
358250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
359250003Sadrian                AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -6);
360250003Sadrian        }
361250003Sadrian        if (is_2g) {
362250003Sadrian            if(AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)){
363250003Sadrian                OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
364250003Sadrian                    AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE, -10);
365250003Sadrian            }else{
366250003Sadrian                OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
367250003Sadrian                    AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE, -15);
368250003Sadrian            }
369250003Sadrian        }
370250003Sadrian        else {
371250003Sadrian             OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
372250003Sadrian                 AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE, -10);
373250003Sadrian        }
374250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
375250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE, 1);
376250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL4,
377250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA, 0);
378250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL4,
379250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR, 400);
380250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL4,
381250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES, 100);
382250003Sadrian    }
383250003Sadrian
384250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_PRE_POST_SCALE_0_B0,
385250003Sadrian        AR_PHY_PAPRD_PRE_POST_SCALE_0_B0_PAPRD_PRE_POST_SCALING_0_0, 261376);
386250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_PRE_POST_SCALE_1_B0,
387250003Sadrian        AR_PHY_PAPRD_PRE_POST_SCALE_1_B0_PAPRD_PRE_POST_SCALING_1_0, 248079);
388250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_PRE_POST_SCALE_2_B0,
389250003Sadrian        AR_PHY_PAPRD_PRE_POST_SCALE_2_B0_PAPRD_PRE_POST_SCALING_2_0, 233759);
390250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_PRE_POST_SCALE_3_B0,
391250003Sadrian        AR_PHY_PAPRD_PRE_POST_SCALE_3_B0_PAPRD_PRE_POST_SCALING_3_0, 220464);
392250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_PRE_POST_SCALE_4_B0,
393250003Sadrian        AR_PHY_PAPRD_PRE_POST_SCALE_4_B0_PAPRD_PRE_POST_SCALING_4_0, 208194);
394250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_PRE_POST_SCALE_5_B0,
395250003Sadrian        AR_PHY_PAPRD_PRE_POST_SCALE_5_B0_PAPRD_PRE_POST_SCALING_5_0, 196949);
396250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_PRE_POST_SCALE_6_B0,
397250003Sadrian        AR_PHY_PAPRD_PRE_POST_SCALE_6_B0_PAPRD_PRE_POST_SCALING_6_0, 185706);
398250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_PRE_POST_SCALE_7_B0,
399250003Sadrian        AR_PHY_PAPRD_PRE_POST_SCALE_7_B0_PAPRD_PRE_POST_SCALING_7_0, 175487);
400250003Sadrian    return 0;
401250003Sadrian
402250003SadrianFAILED:
403250003Sadrian    return -1;
404250003Sadrian#undef ABS
405250003Sadrian}
406250003Sadrian
407250008Sadrian/*
408250008Sadrian * XXX There's another copy of this in ar9300_reset.c, use that!
409250008Sadrian */
410250008Sadrian#if 0
411250003Sadrianstatic inline HAL_CHANNEL_INTERNAL*
412250003Sadrianar9300_check_chan(struct ath_hal *ah, HAL_CHANNEL *chan)
413250003Sadrian{
414250003Sadrian    if ((AR9300_IS_CHAN(chan, CHANNEL_2GHZ) ^
415250003Sadrian         AR9300_IS_CHAN(chan, CHANNEL_5GHZ)) == 0)
416250003Sadrian    {
417250003Sadrian        HALDEBUG(ah, HAL_DEBUG_CHANNEL,
418250003Sadrian            "%s: invalid channel %u/0x%x; not marked as 2GHz or 5GHz\n",
419250003Sadrian            __func__, chan->channel, chan->channel_flags);
420250003Sadrian        return AH_NULL;
421250003Sadrian    }
422250003Sadrian
423250003Sadrian    if ((AR9300_IS_CHAN(chan, CHANNEL_OFDM)     ^
424250003Sadrian         AR9300_IS_CHAN(chan, CHANNEL_CCK)      ^
425250003Sadrian         AR9300_IS_CHAN(chan, CHANNEL_HT20)     ^
426250003Sadrian         AR9300_IS_CHAN(chan, CHANNEL_HT40PLUS) ^
427250003Sadrian         AR9300_IS_CHAN(chan, CHANNEL_HT40MINUS)) == 0)
428250003Sadrian    {
429250003Sadrian        HALDEBUG(ah, HAL_DEBUG_CHANNEL,
430250003Sadrian            "%s: invalid channel %u/0x%x; not marked as "
431250003Sadrian            "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n", __func__,
432250003Sadrian            chan->channel, chan->channel_flags);
433250003Sadrian        return AH_NULL;
434250003Sadrian    }
435250003Sadrian
436250003Sadrian    return (ath_hal_checkchannel(ah, chan));
437250003Sadrian}
438250008Sadrian#endif
439250003Sadrian
440250003Sadrianvoid ar9300_enable_paprd(struct ath_hal *ah, HAL_BOOL enable_flag,
441250008Sadrian    struct ieee80211_channel * chan)
442250003Sadrian{
443250003Sadrian    HAL_BOOL enable = enable_flag;
444250003Sadrian    u_int32_t am_mask = 0;
445250003Sadrian    u_int32_t val = OS_REG_READ(ah, AR_2040_MODE);
446250008Sadrian    int is_2g = IEEE80211_IS_CHAN_2GHZ(chan);
447250008Sadrian    HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
448250003Sadrian    int is_ht40 = 0;
449250003Sadrian    struct ath_hal_9300 *ahp = AH9300(ah);
450250003Sadrian
451250003Sadrian    if (val & HAL_HT_MACMODE_2040) {
452250003Sadrian        is_ht40 = 1;
453250003Sadrian    }
454250003Sadrian    if (enable_flag == AH_TRUE) {
455250003Sadrian        ar9300_eeprom_t *eep = &AH9300(ah)->ah_eeprom;
456250003Sadrian
457250003Sadrian        if (!is_2g) {
458250003Sadrian            /*
459250003Sadrian             * 3 bits for modal_header_5g.paprd_rate_mask_ht20
460250003Sadrian             * is used for sub band disabling of paprd.
461250003Sadrian             * 5G band is divided into 3 sub bands -- upper, mid, lower.
462250003Sadrian             * If bit 30 of modal_header_5g.paprd_rate_mask_ht20 is set
463250003Sadrian             * to one -- disable paprd for upper 5G
464250003Sadrian             * If bit 29 of modal_header_5g.paprd_rate_mask_ht20 is set
465250003Sadrian             * to one -- disable paprd for mid 5G
466250003Sadrian             * If bit 28 of modal_header_5g.paprd_rate_mask_ht20 is set
467250003Sadrian             * to one -- disable paprd for lower 5G
468250003Sadrian             * u_int32_t am_mask = eep->modal_header_5g.paprd_rate_mask_ht20;
469250003Sadrian             */
470250008Sadrian            if (ichan->channel >= UPPER_5G_SUB_BANDSTART) {
471250003Sadrian                if (eep->modal_header_5g.paprd_rate_mask_ht20 & (1 << 30)) {
472250003Sadrian                    enable = AH_FALSE;
473250003Sadrian                }
474250008Sadrian            } else if (ichan->channel >= MID_5G_SUB_BANDSTART) {
475250003Sadrian                if (eep->modal_header_5g.paprd_rate_mask_ht20 & (1 << 29)) {
476250003Sadrian                    enable = AH_FALSE;
477250003Sadrian                }
478250003Sadrian            } else { /* must be in the lower 5G subband */
479250003Sadrian                if (eep->modal_header_5g.paprd_rate_mask_ht20 & (1 << 28)) {
480250003Sadrian                    enable = AH_FALSE;
481250003Sadrian                }
482250003Sadrian            }
483250003Sadrian        }
484250003Sadrian
485250003Sadrian        if (ahp->ah_paprd_broken) {
486250003Sadrian            ahp->ah_paprd_broken = AH_FALSE;
487250003Sadrian            enable = AH_FALSE;
488250003Sadrian
489250003Sadrian            HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
490250003Sadrian                     "%s: PAPRD is in bad state. Don't enable PAPRD\n",
491250003Sadrian                     __func__);
492250003Sadrian        }
493250003Sadrian    }
494250003Sadrian    if (enable) {
495250003Sadrian        HAL_CHANNEL_INTERNAL *ichan;
496250003Sadrian        if (is_2g) {
497250003Sadrian            if (is_ht40) {
498250003Sadrian                am_mask = ahp->ah_2g_paprd_rate_mask_ht40 & AH_PAPRD_AM_PM_MASK;
499250003Sadrian            } else {
500250003Sadrian                am_mask = ahp->ah_2g_paprd_rate_mask_ht20 & AH_PAPRD_AM_PM_MASK;
501250003Sadrian            }
502250003Sadrian        } else {
503250003Sadrian            if (is_ht40) {
504250003Sadrian                am_mask = ahp->ah_5g_paprd_rate_mask_ht40 & AH_PAPRD_AM_PM_MASK;
505250003Sadrian            } else {
506250003Sadrian                am_mask = ahp->ah_5g_paprd_rate_mask_ht20 & AH_PAPRD_AM_PM_MASK;
507250003Sadrian            }
508250003Sadrian        }
509250003Sadrian        /* Earlier we promgrammed TGT Power with Scaled down value, since
510250003Sadrian         * PAPRD CAL was not done.
511250003Sadrian         * Now we finish PAPRD CAL, so bump up the TGT PWR to original
512250003Sadrian         * EEPROM Power. CTLs calc and Maverickd in
513250003Sadrian         * "ar9300_eeprom_set_transmit_power"
514250003Sadrian         */
515250003Sadrian        ichan = ar9300_check_chan(ah, chan);
516250003Sadrian        ichan->paprd_table_write_done = 1;
517250008Sadrian//        chan->paprd_table_write_done = 1;
518250003Sadrian        /*
519250003Sadrian        ath_hal_printf(ah, "%s[%d] eeprom_set_transmit_power PAPRD\n",
520250003Sadrian            __func__, __LINE__);
521250003Sadrian         */
522250008Sadrian        if (ar9300_eeprom_set_transmit_power(ah, &ahp->ah_eeprom, chan,
523250003Sadrian            ath_hal_getctl(ah, chan), ath_hal_getantennaallowed(ah, chan),
524250003Sadrian            ath_hal_get_twice_max_regpower(AH_PRIVATE(ah), ichan, chan),
525250008Sadrian            AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit)) != HAL_OK) {
526250003Sadrian            ichan->paprd_table_write_done = 0;
527250008Sadrian//            chan->paprd_table_write_done = 0;
528250003Sadrian            /* Intentional print */
529250003Sadrian            ath_hal_printf(ah,
530250003Sadrian                "%s[%d] eeprom_set_transmit_power failed ABORT PAPRD\n",
531250003Sadrian                __func__, __LINE__);
532250003Sadrian
533250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B0,
534250003Sadrian                AR_PHY_PAPRD_CTRL0_B0_PAPRD_ENABLE_0, 0);
535250003Sadrian            if (!AR_SREV_POSEIDON(ah) && !AR_SREV_HORNET(ah)) {
536250003Sadrian                OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B1,
537250003Sadrian                    AR_PHY_PAPRD_CTRL0_B1_PAPRD_ENABLE_1, 0);
538250003Sadrian                if (!AR_SREV_JUPITER(ah) || (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN2_MASK)) {
539250003Sadrian                    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B2,
540250003Sadrian                        AR_PHY_PAPRD_CTRL0_B2_PAPRD_ENABLE_2, 0);
541250003Sadrian
542250003Sadrian                }
543250003Sadrian            }
544250003Sadrian            return;
545250003Sadrian        }
546250003Sadrian
547250003Sadrian        HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s 2G %d HT40 %d am_mask 0x%08x\n",
548250003Sadrian            __func__, is_2g, is_ht40, am_mask);
549250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK,
550250003Sadrian            am_mask);
551250003Sadrian        if (AR_SREV_HORNET(ah)) {
552250003Sadrian            OS_REG_RMW_FIELD_ALT(ah,
553250003Sadrian                AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, 0);
554250003Sadrian        } else {
555250003Sadrian            OS_REG_RMW_FIELD_ALT(ah,
556250003Sadrian                AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask);
557250003Sadrian        }
558250003Sadrian
559250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK,
560250003Sadrian            AR_PHY_PAPRD_HT40_MASK);
561250003Sadrian        /* chain0 */
562250003Sadrian        if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN0_MASK) {
563250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B0,
564250003Sadrian                AR_PHY_PAPRD_CTRL0_B0_USE_SINGLE_TABLE_MASK, 1);
565250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
566250003Sadrian                AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_AM2PM_ENABLE_0, 1);
567250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
568250003Sadrian                AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_AM2AM_ENABLE_0, 1);
569250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
570250003Sadrian                AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_SCALING_ENA, 0);
571250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
572250003Sadrian                AR_PHY_PAPRD_CTRL1_B0_PA_GAIN_SCALE_FACT_0_MASK, 181);
573250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
574250003Sadrian                AR_PHY_PAPRD_CTRL1_B0_PAPRD_MAG_SCALE_FACT_0, 361);
575250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
576250003Sadrian                AR_PHY_PAPRD_CTRL1_B0_ADAPTIVE_SCALING_ENA, 0);
577250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B0,
578250003Sadrian                AR_PHY_PAPRD_CTRL0_B0_PAPRD_MAG_THRSH_0, 3);
579250003Sadrian        }
580250003Sadrian        /* chain1 */
581250003Sadrian        if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN1_MASK) {
582250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B1,
583250003Sadrian                AR_PHY_PAPRD_CTRL0_B1_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_1, 1);
584250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
585250003Sadrian                AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_AM2PM_ENABLE_1, 1);
586250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
587250003Sadrian                AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_AM2AM_ENABLE_1, 1);
588250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
589250003Sadrian                AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_SCALING_ENA, 0);
590250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
591250003Sadrian                AR_PHY_PAPRD_CTRL1_B1_PA_GAIN_SCALE_FACT_1_MASK, 181);
592250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
593250003Sadrian                AR_PHY_PAPRD_CTRL1_B1_PAPRD_MAG_SCALE_FACT_1, 361);
594250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
595250003Sadrian                AR_PHY_PAPRD_CTRL1_B1_ADAPTIVE_SCALING_ENA, 0);
596250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B1,
597250003Sadrian                AR_PHY_PAPRD_CTRL0_B1_PAPRD_MAG_THRSH_1, 3);
598250003Sadrian        }
599250003Sadrian        /* chain2 */
600250003Sadrian        if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN2_MASK) {
601250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B2,
602250003Sadrian                AR_PHY_PAPRD_CTRL0_B2_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_2, 1);
603250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
604250003Sadrian                AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_AM2PM_ENABLE_2, 1);
605250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
606250003Sadrian                AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_AM2AM_ENABLE_2, 1);
607250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
608250003Sadrian                AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_SCALING_ENA, 0);
609250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
610250003Sadrian                AR_PHY_PAPRD_CTRL1_B2_PA_GAIN_SCALE_FACT_2_MASK, 181);
611250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
612250003Sadrian                AR_PHY_PAPRD_CTRL1_B2_PAPRD_MAG_SCALE_FACT_2, 361);
613250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
614250003Sadrian                AR_PHY_PAPRD_CTRL1_B2_ADAPTIVE_SCALING_ENA, 0);
615250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B2,
616250003Sadrian                AR_PHY_PAPRD_CTRL0_B2_PAPRD_MAG_THRSH_2, 3);
617250003Sadrian        }
618250003Sadrian
619250003Sadrian        if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN0_MASK) {
620250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B0,
621250003Sadrian                AR_PHY_PAPRD_CTRL0_B0_PAPRD_ENABLE_0, 1);
622250003Sadrian        }
623250003Sadrian
624250003Sadrian        if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN1_MASK) {
625250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B1,
626250003Sadrian                AR_PHY_PAPRD_CTRL0_B1_PAPRD_ENABLE_1, 1);
627250003Sadrian        }
628250003Sadrian
629250003Sadrian        if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN2_MASK) {
630250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B2,
631250003Sadrian                AR_PHY_PAPRD_CTRL0_B2_PAPRD_ENABLE_2, 1);
632250003Sadrian        }
633250003Sadrian
634250003Sadrian    } else {
635250003Sadrian        if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN0_MASK) {
636250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B0,
637250003Sadrian                AR_PHY_PAPRD_CTRL0_B0_PAPRD_ENABLE_0, 0);
638250003Sadrian        }
639250003Sadrian
640250003Sadrian        if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN1_MASK) {
641250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B1,
642250003Sadrian                AR_PHY_PAPRD_CTRL0_B1_PAPRD_ENABLE_1, 0);
643250003Sadrian        }
644250003Sadrian
645250003Sadrian        if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN2_MASK) {
646250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B2,
647250003Sadrian                AR_PHY_PAPRD_CTRL0_B2_PAPRD_ENABLE_2, 0);
648250003Sadrian        }
649250003Sadrian    }
650250003Sadrian}
651250003Sadrian
652250003Sadrianstatic void ar9300_gain_table_entries(struct ath_hal *ah)
653250003Sadrian{
654250003Sadrian    int i;
655250003Sadrian    u_int32_t reg;
656250003Sadrian    u_int32_t *gain_table_entries = AH9300(ah)->paprd_gain_table_entries;
657250003Sadrian    u_int32_t *gain_vs_table_index = AH9300(ah)->paprd_gain_table_index;
658250003Sadrian
659250003Sadrian    reg = AR_PHY_TXGAIN_TAB(1);
660250003Sadrian
661250003Sadrian    for (i = 0; i < 32; i++) {
662250003Sadrian        gain_table_entries[i] = OS_REG_READ(ah, reg);
663250003Sadrian        gain_vs_table_index[i] = (gain_table_entries[i] >> 24) & 0xff;
664250003Sadrian        /*
665250003Sadrian         * ath_hal_printf(
666250003Sadrian         *     ah, "+++reg 0x%08x gain_table_entries[%d] = 0x%08x \n",
667250003Sadrian         *     reg, i, gain_table_entries[i]);
668250003Sadrian         */
669250003Sadrian        reg = reg + 4;
670250003Sadrian    }
671250003Sadrian}
672250003Sadrian
673250003Sadrian/* Get gain index for Target power */
674250003Sadrianstatic unsigned int ar9300_get_desired_gain_for_chain(struct ath_hal *ah,
675250003Sadrian    int chain_num, int target_power)
676250003Sadrian{
677250003Sadrian    int olpc_gain_delta = 0;
678250003Sadrian    int alpha_therm = 0, alpha_volt = 0;
679250003Sadrian    int therm_cal_value = 0, volt_cal_value = 0;
680250003Sadrian    int latest_therm_value = 0, latest_volt_value = 0, olpc_gain_delta_tmp = 0;
681250003Sadrian    int thermal_gain_corr = 0, voltage_gain_corr = 0, desired_scale = 0;
682250003Sadrian    int desired_gain = 0;
683250003Sadrian    int cl_gain_mod = 0;
684250003Sadrian
685250003Sadrian    /* Clear the training done bit */
686250003Sadrian    if (AR_SREV_POSEIDON(ah)) {
687250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
688250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE, 0);
689250003Sadrian    } else {
690250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
691250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE, 0);
692250003Sadrian    }
693250003Sadrian    /*field_read("BB_tpc_12.desired_scale_ht40_5", &desired_scale);*/
694250003Sadrian    desired_scale =
695250003Sadrian        OS_REG_READ_FIELD_ALT(ah, AR_PHY_TPC_12,
696250003Sadrian        AR_PHY_TPC_12_DESIRED_SCALE_HT40_5);
697250003Sadrian    /*field_read("BB_tpc_19.alpha_therm", &alpha_therm);*/
698250003Sadrian    alpha_therm =
699250003Sadrian        OS_REG_READ_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM);
700250003Sadrian    /*field_read("BB_tpc_19.alpha_volt", &alpha_volt);*/
701250003Sadrian    alpha_volt =
702250003Sadrian        OS_REG_READ_FIELD_ALT(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALT_ALPHA_VOLT);
703250003Sadrian
704250003Sadrian    /*field_read("BB_tpc_18.therm_cal_value", &therm_cal_value);*/
705250003Sadrian    therm_cal_value =
706250003Sadrian        OS_REG_READ_FIELD_ALT(ah, AR_PHY_TPC_18,
707250003Sadrian        AR_PHY_TPC_18_ALT_THERM_CAL_VALUE);
708250003Sadrian    /*field_read("BB_tpc_18.volt_cal_value", &volt_cal_value);*/
709250003Sadrian    volt_cal_value =
710250003Sadrian        OS_REG_READ_FIELD_ALT(ah, AR_PHY_TPC_18,
711250003Sadrian        AR_PHY_TPC_18_ALT_VOLT_CAL_VALUE);
712250003Sadrian
713250003Sadrian    /*field_read("BB_therm_adc_4.latest_therm_value", &latest_therm_value);*/
714250003Sadrian    latest_therm_value =
715250003Sadrian        OS_REG_READ_FIELD_ALT(ah, AR_PHY_THERM_ADC_4,
716250003Sadrian        AR_PHY_THERM_ADC_4_LATEST_THERM_VALUE);
717250003Sadrian    /*field_read("BB_therm_adc_4.latest_volt_value", &latest_volt_value);*/
718250003Sadrian    latest_volt_value =
719250003Sadrian        OS_REG_READ_FIELD_ALT(ah, AR_PHY_THERM_ADC_4,
720250003Sadrian        AR_PHY_THERM_ADC_4_LATEST_VOLT_VALUE);
721250003Sadrian
722250003Sadrian    /*
723250003Sadrian     * sprintf(
724250003Sadrian     *     field_name, "%s%d%s%d\0", "BB_tpc_11_b",
725250003Sadrian     *     chain_num, ".olpc_gain_delta_", chain_num);
726250003Sadrian     */
727250003Sadrian    /*field_read(field_name, &olpc_gain_delta_tmp);*/
728250003Sadrian
729250003Sadrian
730250003Sadrian    if (chain_num == 0) {
731250003Sadrian        olpc_gain_delta_tmp =
732250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_TPC_11_B0,
733250003Sadrian            AR_PHY_TPC_11_B0_OLPC_GAIN_DELTA_0);
734250003Sadrian        cl_gain_mod = OS_REG_READ_FIELD_ALT(ah, AR_PHY_CL_TAB_0,
735250003Sadrian            AR_PHY_CL_TAB_0_CL_GAIN_MOD);
736250003Sadrian    } else if (chain_num == 1) {
737250003Sadrian        if (!AR_SREV_POSEIDON(ah)) {
738250003Sadrian            olpc_gain_delta_tmp =
739250003Sadrian                OS_REG_READ_FIELD_ALT(ah, AR_PHY_TPC_11_B1,
740250003Sadrian                AR_PHY_TPC_11_B1_OLPC_GAIN_DELTA_1);
741250003Sadrian            cl_gain_mod = OS_REG_READ_FIELD_ALT(ah, AR_PHY_CL_TAB_1,
742250003Sadrian                AR_PHY_CL_TAB_1_CL_GAIN_MOD);
743250003Sadrian        }
744250003Sadrian    } else if (chain_num == 2) {
745250003Sadrian        if (!AR_SREV_POSEIDON(ah)) {
746250003Sadrian            olpc_gain_delta_tmp =
747250003Sadrian                OS_REG_READ_FIELD_ALT(ah, AR_PHY_TPC_11_B2,
748250003Sadrian                AR_PHY_TPC_11_B2_OLPC_GAIN_DELTA_2);
749250003Sadrian            cl_gain_mod = OS_REG_READ_FIELD_ALT(ah, AR_PHY_CL_TAB_2,
750250003Sadrian                AR_PHY_CL_TAB_2_CL_GAIN_MOD);
751250003Sadrian        }
752250003Sadrian    } else {
753250003Sadrian        /* invalid chain_num */
754250003Sadrian    }
755250003Sadrian
756250003Sadrian    if (olpc_gain_delta_tmp < 128) {
757250003Sadrian        olpc_gain_delta = olpc_gain_delta_tmp;
758250003Sadrian    } else {
759250003Sadrian        olpc_gain_delta = olpc_gain_delta_tmp - 256;
760250003Sadrian    }
761250003Sadrian
762250003Sadrian    thermal_gain_corr =
763250003Sadrian        (int) (alpha_therm * (latest_therm_value - therm_cal_value) +
764250003Sadrian        128) >> 8;
765250003Sadrian    voltage_gain_corr =
766250003Sadrian        (int) (alpha_volt * (latest_volt_value - volt_cal_value) + 64) >> 7;
767250003Sadrian    desired_gain =
768250003Sadrian        target_power - olpc_gain_delta - thermal_gain_corr -
769250003Sadrian        voltage_gain_corr + desired_scale + cl_gain_mod;
770250003Sadrian    /*
771250003Sadrian     * printf(
772250003Sadrian     *     "olpc_gain_delta %d, desired_gain %d\n",
773250003Sadrian     *     olpc_gain_delta, desired_gain);
774250003Sadrian     */
775250003Sadrian#if 0
776250003Sadrian    ath_hal_printf(ah,
777250003Sadrian        "+++ target_power %d olpc_gain_delta %d, cl_gain_mod %d,"
778250003Sadrian        "thermal_gain_corr %d  voltage_gain_corr %d desired_scale %d"
779250003Sadrian        "desired_gain %d\n",
780250003Sadrian        target_power, olpc_gain_delta, cl_gain_mod, thermal_gain_corr,
781250003Sadrian        voltage_gain_corr,
782250003Sadrian        desired_scale, desired_gain);
783250003Sadrian#endif
784250003Sadrian    return (unsigned int) desired_gain;
785250003Sadrian}
786250003Sadrian
787250003Sadrianstatic void ar9300_tx_force_gain(struct ath_hal *ah, unsigned int gain_index)
788250003Sadrian{
789250003Sadrian    int selected_gain_entry, txbb1dbgain, txbb6dbgain, txmxrgain;
790250003Sadrian    int padrvgn_a, padrvgn_b, padrvgn_c, padrvgn_d;
791250003Sadrian    u_int32_t *gain_table_entries = AH9300(ah)->paprd_gain_table_entries;
792250003Sadrian
793250003Sadrian    /*u_int32_t *gain_vs_table_index = ah->paprd_gain_table_index;*/
794250003Sadrian    selected_gain_entry = gain_table_entries[gain_index];
795250003Sadrian    txbb1dbgain = selected_gain_entry & 0x7;
796250003Sadrian    txbb6dbgain = (selected_gain_entry >> 3) & 0x3;
797250003Sadrian    txmxrgain = (selected_gain_entry >> 5) & 0xf;
798250003Sadrian    padrvgn_a = (selected_gain_entry >> 9) & 0xf;
799250003Sadrian    padrvgn_b = (selected_gain_entry >> 13) & 0xf;
800250003Sadrian    padrvgn_c = (selected_gain_entry >> 17) & 0xf;
801250003Sadrian    padrvgn_d = (selected_gain_entry >> 21) & 0x3;
802250003Sadrian
803250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
804250003Sadrian        AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN, txbb1dbgain);
805250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
806250003Sadrian        AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN, txbb6dbgain);
807250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
808250003Sadrian        AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN, txmxrgain);
809250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
810250003Sadrian        AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA, padrvgn_a);
811250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
812250003Sadrian        AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB, padrvgn_b);
813250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
814250003Sadrian        AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC, padrvgn_c);
815250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
816250003Sadrian        AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND, padrvgn_d);
817250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
818250003Sadrian        AR_PHY_TX_FORCED_GAIN_FORCED_ENABLE_PAL, 0);
819250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
820250003Sadrian        AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN, 0);
821250003Sadrian
822250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TPC_1, AR_PHY_TPC_1_FORCED_DAC_GAIN, 0);
823250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_TPC_1, AR_PHY_TPC_1_FORCE_DAC_GAIN, 0);
824250003Sadrian}
825250003Sadrian
826250003Sadrian#define HAL_DEBUG_PAPRD HAL_DEBUG_CALIBRATE  /* driver: conditionally print */
827250003Sadrian
828250003Sadrian#if defined(ART_PAPRD_DEBUG) || defined(AH_DEBUG)
829250003Sadrianstatic void ar9300_paprd_debug_print(struct ath_hal *ah)
830250003Sadrian{
831250003Sadrian    int temp;
832250003Sadrian    int txbb1dbgain, txbb6dbgain, txmxrgain;
833250003Sadrian    int padrvgn_a, padrvgn_b, padrvgn_c, padrvgn_d;
834250003Sadrian
835250003Sadrian    if (AR_SREV_POSEIDON(ah)) {
836250003Sadrian        /*field_read("BB_paprd_trainer_cntl1.cf_paprd_lb_skip", &temp);*/
837250003Sadrian        temp =
838250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
839250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP);
840250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
841250003Sadrian            "BB_paprd_trainer_cntl1.cf_paprd_lb_skip=0x%x\n", temp);
842250003Sadrian        /*field_read("BB_paprd_trainer_cntl1.cf_paprd_lb_enable", &temp);*/
843250003Sadrian        temp =
844250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
845250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE);
846250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
847250003Sadrian            "BB_paprd_trainer_cntl1.cf_paprd_lb_enable=0x%x\n", temp);
848250003Sadrian        /*field_read("BB_paprd_trainer_cntl1.cf_paprd_tx_gain_force", &temp);*/
849250003Sadrian        temp =
850250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
851250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE);
852250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
853250003Sadrian            "BB_paprd_trainer_cntl1.cf_paprd_tx_gain_force=0x%x\n", temp);
854250003Sadrian        /*
855250003Sadrian         * field_read(
856250003Sadrian         *     "BB_paprd_trainer_cntl1.cf_paprd_rx_bb_gain_force", &temp);
857250003Sadrian         */
858250003Sadrian        temp =
859250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
860250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE);
861250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
862250003Sadrian            "BB_paprd_trainer_cntl1.cf_paprd_rx_bb_gain_force=0x%x\n", temp);
863250003Sadrian        /*field_read("BB_paprd_trainer_cntl1.cf_paprd_iqcorr_enable", &temp);*/
864250003Sadrian        temp =
865250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
866250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE);
867250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
868250003Sadrian            "BB_paprd_trainer_cntl1.cf_paprd_iqcorr_enable=0x%x\n", temp);
869250003Sadrian        /*field_read("BB_paprd_trainer_cntl1.cf_paprd_agc2_settling", &temp);*/
870250003Sadrian        temp =
871250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
872250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING);
873250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
874250003Sadrian            "BB_paprd_trainer_cntl1.cf_paprd_agc2_settling=0x%x\n", temp);
875250003Sadrian        /*field_read("BB_paprd_trainer_cntl1.cf_paprd_train_enable", &temp);*/
876250003Sadrian        temp =
877250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1_POSEIDON,
878250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE);
879250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
880250003Sadrian            "BB_paprd_trainer_cntl1.cf_paprd_train_enable=0x%x\n", temp);
881250003Sadrian        /*
882250003Sadrian         * field_read("BB_paprd_trainer_cntl2.cf_paprd_init_rx_bb_gain", &temp);
883250003Sadrian         */
884250003Sadrian        temp =
885250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL2_POSEIDON,
886250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN);
887250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
888250003Sadrian            "BB_paprd_trainer_cntl2.cf_paprd_init_rx_bb_gain=0x%x\n", temp);
889250003Sadrian        /*field_read("BB_paprd_trainer_cntl3.cf_paprd_fine_corr_len", &temp);*/
890250003Sadrian        temp =
891250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
892250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN);
893250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
894250003Sadrian            "BB_paprd_trainer_cntl3.cf_paprd_fine_corr_len=0x%x\n", temp);
895250003Sadrian        /*
896250003Sadrian         * field_read("BB_paprd_trainer_cntl3.cf_paprd_coarse_corr_len", &temp);
897250003Sadrian         */
898250003Sadrian        temp =
899250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
900250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN);
901250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
902250003Sadrian            "BB_paprd_trainer_cntl3.cf_paprd_coarse_corr_len=0x%x\n", temp);
903250003Sadrian        /*
904250003Sadrian         * field_read("BB_paprd_trainer_cntl3.cf_paprd_num_corr_stages", &temp);
905250003Sadrian         */
906250003Sadrian        temp =
907250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
908250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES);
909250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
910250003Sadrian            "BB_paprd_trainer_cntl3.cf_paprd_num_corr_stages=0x%x\n", temp);
911250003Sadrian        /*
912250003Sadrian         * field_read(
913250003Sadrian         *     "BB_paprd_trainer_cntl3.cf_paprd_min_loopback_del", &temp);
914250003Sadrian         */
915250003Sadrian        temp =
916250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
917250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL);
918250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
919250003Sadrian            "BB_paprd_trainer_cntl3.cf_paprd_min_loopback_del=0x%x\n", temp);
920250003Sadrian        /*field_read("BB_paprd_trainer_cntl3.cf_paprd_quick_drop", &temp);*/
921250003Sadrian        temp =
922250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
923250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP);
924250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
925250003Sadrian            "BB_paprd_trainer_cntl3.cf_paprd_quick_drop=0x%x\n", temp);
926250003Sadrian        /*
927250003Sadrian         * field_read(
928250003Sadrian         *     "BB_paprd_trainer_cntl3.cf_paprd_adc_desired_size", &temp);
929250003Sadrian         */
930250003Sadrian        temp =
931250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
932250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE);
933250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
934250003Sadrian            "BB_paprd_trainer_cntl3.cf_paprd_adc_desired_size=0x%x\n", temp);
935250003Sadrian        /*
936250003Sadrian         * field_read("BB_paprd_trainer_cntl3.cf_paprd_bbtxmix_disable", &temp);
937250003Sadrian         */
938250003Sadrian        temp =
939250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
940250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE);
941250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
942250003Sadrian            "BB_paprd_trainer_cntl3.cf_paprd_bbtxmix_disable=0x%x\n", temp);
943250003Sadrian        /*field_read("BB_paprd_trainer_cntl4.cf_paprd_safety_delta", &temp);*/
944250003Sadrian        temp =
945250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL4_POSEIDON,
946250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA);
947250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
948250003Sadrian            "BB_paprd_trainer_cntl4.cf_paprd_safety_delta=0x%x\n", temp);
949250003Sadrian        /*field_read("BB_paprd_trainer_cntl4.cf_paprd_min_corr", &temp);*/
950250003Sadrian        temp =
951250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL4_POSEIDON,
952250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR);
953250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
954250003Sadrian            "BB_paprd_trainer_cntl4.cf_paprd_min_corr=0x%x\n", temp);
955250003Sadrian        /*field_read("BB_paprd_trainer_stat1.paprd_agc2_pwr", &temp);*/
956250003Sadrian        temp =
957250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
958250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR);
959250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
960250003Sadrian            "    paprd_agc2_pwr              = 0x%02x\n", temp);
961250003Sadrian        /*field_read("BB_paprd_trainer_stat1.paprd_rx_gain_idx", &temp);*/
962250003Sadrian        temp =
963250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
964250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX);
965250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
966250003Sadrian            "    paprd_rx_gain_idx           = 0x%02x\n", temp);
967250003Sadrian        /*field_read("BB_paprd_trainer_stat1.paprd_train_active", &temp);*/
968250003Sadrian        temp =
969250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
970250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE);
971250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
972250003Sadrian            "    paprd_train_active          = 0x%08x\n", temp);
973250003Sadrian        /*field_read("BB_paprd_trainer_stat1.paprd_corr_err", &temp);*/
974250003Sadrian        temp =
975250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
976250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR);
977250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
978250003Sadrian            "    paprd_corr_err              = 0x%08x\n", temp);
979250003Sadrian        /*field_read("BB_paprd_trainer_stat1.paprd_train_incomplete", &temp);*/
980250003Sadrian        temp =
981250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
982250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE);
983250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
984250003Sadrian            "    paprd_train_incomplete      = 0x%08x\n", temp);
985250003Sadrian        /*field_read("BB_paprd_trainer_stat1.paprd_train_done", &temp);*/
986250003Sadrian        temp =
987250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
988250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
989250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
990250003Sadrian            "    paprd_train_done            = 0x%08x\n", temp);
991250003Sadrian        /*field_read("BB_paprd_trainer_stat2.paprd_fine_idx", &temp);*/
992250003Sadrian        temp =
993250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT2_POSEIDON,
994250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX);
995250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
996250003Sadrian            "    paprd_fine_idx              = 0x%08x\n", temp);
997250003Sadrian        /*field_read("BB_paprd_trainer_stat2.paprd_coarse_idx", &temp);*/
998250003Sadrian        temp =
999250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT2_POSEIDON,
1000250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX);
1001250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1002250003Sadrian            "    paprd_coarse_idx            = 0x%08x\n", temp);
1003250003Sadrian        /*field_read("BB_paprd_trainer_stat2.paprd_fine_val", &temp);*/
1004250003Sadrian        temp =
1005250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT2_POSEIDON,
1006250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL);
1007250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1008250003Sadrian            "    paprd_fine_val              = 0x%08x\n", temp);
1009250003Sadrian        /*field_read("BB_paprd_trainer_stat3.paprd_train_samples_cnt", &temp);*/
1010250003Sadrian        temp =
1011250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT3_POSEIDON,
1012250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT);
1013250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1014250003Sadrian            "    paprd_train_samples_cnt     = 0x%08x\n", temp);
1015250003Sadrian    } else {
1016250003Sadrian        /*field_read("BB_paprd_trainer_cntl1.cf_paprd_lb_skip", &temp);*/
1017250003Sadrian        temp =
1018250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
1019250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP);
1020250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1021250003Sadrian            "BB_paprd_trainer_cntl1.cf_paprd_lb_skip=0x%x\n", temp);
1022250003Sadrian        /*field_read("BB_paprd_trainer_cntl1.cf_paprd_lb_enable", &temp);*/
1023250003Sadrian        temp =
1024250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
1025250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE);
1026250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1027250003Sadrian            "BB_paprd_trainer_cntl1.cf_paprd_lb_enable=0x%x\n", temp);
1028250003Sadrian        /*field_read("BB_paprd_trainer_cntl1.cf_paprd_tx_gain_force", &temp);*/
1029250003Sadrian        temp =
1030250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
1031250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE);
1032250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1033250003Sadrian            "BB_paprd_trainer_cntl1.cf_paprd_tx_gain_force=0x%x\n", temp);
1034250003Sadrian        /*
1035250003Sadrian         * field_read(
1036250003Sadrian         *     "BB_paprd_trainer_cntl1.cf_paprd_rx_bb_gain_force", &temp);
1037250003Sadrian         */
1038250003Sadrian        temp =
1039250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
1040250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE);
1041250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1042250003Sadrian            "BB_paprd_trainer_cntl1.cf_paprd_rx_bb_gain_force=0x%x\n", temp);
1043250003Sadrian        /*field_read("BB_paprd_trainer_cntl1.cf_paprd_iqcorr_enable", &temp);*/
1044250003Sadrian        temp =
1045250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
1046250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE);
1047250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1048250003Sadrian            "BB_paprd_trainer_cntl1.cf_paprd_iqcorr_enable=0x%x\n", temp);
1049250003Sadrian        /*field_read("BB_paprd_trainer_cntl1.cf_paprd_agc2_settling", &temp);*/
1050250003Sadrian        temp =
1051250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
1052250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING);
1053250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1054250003Sadrian            "BB_paprd_trainer_cntl1.cf_paprd_agc2_settling=0x%x\n", temp);
1055250003Sadrian        /*field_read("BB_paprd_trainer_cntl1.cf_paprd_train_enable", &temp);*/
1056250003Sadrian        temp =
1057250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
1058250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE);
1059250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1060250003Sadrian            "BB_paprd_trainer_cntl1.cf_paprd_train_enable=0x%x\n", temp);
1061250003Sadrian        /*
1062250003Sadrian         * field_read("BB_paprd_trainer_cntl2.cf_paprd_init_rx_bb_gain", &temp);
1063250003Sadrian         */
1064250003Sadrian        temp =
1065250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL2,
1066250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN);
1067250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1068250003Sadrian            "BB_paprd_trainer_cntl2.cf_paprd_init_rx_bb_gain=0x%x\n", temp);
1069250003Sadrian        /*field_read("BB_paprd_trainer_cntl3.cf_paprd_fine_corr_len", &temp);*/
1070250003Sadrian        temp =
1071250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
1072250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN);
1073250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1074250003Sadrian            "BB_paprd_trainer_cntl3.cf_paprd_fine_corr_len=0x%x\n", temp);
1075250003Sadrian        /*
1076250003Sadrian         * field_read("BB_paprd_trainer_cntl3.cf_paprd_coarse_corr_len", &temp);
1077250003Sadrian         */
1078250003Sadrian        temp =
1079250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
1080250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN);
1081250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1082250003Sadrian            "BB_paprd_trainer_cntl3.cf_paprd_coarse_corr_len=0x%x\n", temp);
1083250003Sadrian        /*
1084250003Sadrian         * field_read("BB_paprd_trainer_cntl3.cf_paprd_num_corr_stages", &temp);
1085250003Sadrian         */
1086250003Sadrian        temp =
1087250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
1088250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES);
1089250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1090250003Sadrian            "BB_paprd_trainer_cntl3.cf_paprd_num_corr_stages=0x%x\n", temp);
1091250003Sadrian        /*
1092250003Sadrian         * field_read(
1093250003Sadrian         *     "BB_paprd_trainer_cntl3.cf_paprd_min_loopback_del", &temp);
1094250003Sadrian         */
1095250003Sadrian        temp =
1096250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
1097250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL);
1098250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1099250003Sadrian            "BB_paprd_trainer_cntl3.cf_paprd_min_loopback_del=0x%x\n", temp);
1100250003Sadrian        /*field_read("BB_paprd_trainer_cntl3.cf_paprd_quick_drop", &temp);*/
1101250003Sadrian        temp =
1102250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
1103250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP);
1104250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1105250003Sadrian            "BB_paprd_trainer_cntl3.cf_paprd_quick_drop=0x%x\n", temp);
1106250003Sadrian        /*
1107250003Sadrian         * field_read(
1108250003Sadrian         *     "BB_paprd_trainer_cntl3.cf_paprd_adc_desired_size", &temp);
1109250003Sadrian         */
1110250003Sadrian        temp =
1111250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
1112250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE);
1113250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1114250003Sadrian            "BB_paprd_trainer_cntl3.cf_paprd_adc_desired_size=0x%x\n", temp);
1115250003Sadrian        /*
1116250003Sadrian         * field_read(
1117250003Sadrian         *     "BB_paprd_trainer_cntl3.cf_paprd_bbtxmix_disable", &temp);
1118250003Sadrian         */
1119250003Sadrian        temp =
1120250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
1121250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE);
1122250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1123250003Sadrian            "BB_paprd_trainer_cntl3.cf_paprd_bbtxmix_disable=0x%x\n", temp);
1124250003Sadrian        /*field_read("BB_paprd_trainer_cntl4.cf_paprd_safety_delta", &temp);*/
1125250003Sadrian        temp =
1126250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL4,
1127250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA);
1128250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1129250003Sadrian            "BB_paprd_trainer_cntl4.cf_paprd_safety_delta=0x%x\n", temp);
1130250003Sadrian        /*field_read("BB_paprd_trainer_cntl4.cf_paprd_min_corr", &temp);*/
1131250003Sadrian        temp =
1132250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL4,
1133250003Sadrian            AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR);
1134250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1135250003Sadrian            "BB_paprd_trainer_cntl4.cf_paprd_min_corr=0x%x\n", temp);
1136250003Sadrian        /*field_read("BB_paprd_trainer_stat1.paprd_agc2_pwr", &temp);*/
1137250003Sadrian        temp =
1138250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
1139250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR);
1140250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1141250003Sadrian            "    paprd_agc2_pwr              = 0x%02x\n", temp);
1142250003Sadrian        /*field_read("BB_paprd_trainer_stat1.paprd_rx_gain_idx", &temp);*/
1143250003Sadrian        temp =
1144250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
1145250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX);
1146250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1147250003Sadrian            "    paprd_rx_gain_idx           = 0x%02x\n", temp);
1148250003Sadrian        /*field_read("BB_paprd_trainer_stat1.paprd_train_active", &temp);*/
1149250003Sadrian        temp =
1150250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
1151250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE);
1152250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1153250003Sadrian            "    paprd_train_active          = 0x%08x\n", temp);
1154250003Sadrian        /*field_read("BB_paprd_trainer_stat1.paprd_corr_err", &temp);*/
1155250003Sadrian        temp =
1156250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
1157250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR);
1158250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1159250003Sadrian            "    paprd_corr_err              = 0x%08x\n", temp);
1160250003Sadrian        /*field_read("BB_paprd_trainer_stat1.paprd_train_incomplete", &temp);*/
1161250003Sadrian        temp =
1162250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
1163250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE);
1164250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1165250003Sadrian            "    paprd_train_incomplete      = 0x%08x\n", temp);
1166250003Sadrian        /*field_read("BB_paprd_trainer_stat1.paprd_train_done", &temp);*/
1167250003Sadrian        temp =
1168250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
1169250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
1170250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1171250003Sadrian            "    paprd_train_done            = 0x%08x\n", temp);
1172250003Sadrian        /*field_read("BB_paprd_trainer_stat2.paprd_fine_idx", &temp);*/
1173250003Sadrian        temp =
1174250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT2,
1175250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX);
1176250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1177250003Sadrian            "    paprd_fine_idx              = 0x%08x\n", temp);
1178250003Sadrian        /*field_read("BB_paprd_trainer_stat2.paprd_coarse_idx", &temp);*/
1179250003Sadrian        temp =
1180250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT2,
1181250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX);
1182250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1183250003Sadrian            "    paprd_coarse_idx            = 0x%08x\n", temp);
1184250003Sadrian        /*field_read("BB_paprd_trainer_stat2.paprd_fine_val", &temp);*/
1185250003Sadrian        temp =
1186250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT2,
1187250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL);
1188250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1189250003Sadrian            "    paprd_fine_val              = 0x%08x\n", temp);
1190250003Sadrian        /*field_read("BB_paprd_trainer_stat3.paprd_train_samples_cnt", &temp);*/
1191250003Sadrian        temp =
1192250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT3,
1193250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT);
1194250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1195250003Sadrian            "    paprd_train_samples_cnt     = 0x%08x\n", temp);
1196250003Sadrian    }
1197250003Sadrian
1198250003Sadrian    /*field_read("BB_tpc_1.force_dac_gain", &temp);*/
1199250003Sadrian    temp =
1200250003Sadrian        OS_REG_READ_FIELD_ALT(ah, AR_PHY_TPC_1, AR_PHY_TPC_1_FORCE_DAC_GAIN);
1201250003Sadrian    HALDEBUG(ah, HAL_DEBUG_PAPRD, "    dac_gain_forced     = 0x%08x\n",
1202250003Sadrian        temp);
1203250003Sadrian    /*field_read("BB_tpc_1.forced_dac_gain", &temp);*/
1204250003Sadrian    temp =
1205250003Sadrian        OS_REG_READ_FIELD_ALT(ah, AR_PHY_TPC_1, AR_PHY_TPC_1_FORCED_DAC_GAIN);
1206250003Sadrian    HALDEBUG(ah, HAL_DEBUG_PAPRD, "    forced_dac_gain     = 0x%08x\n",
1207250003Sadrian        temp);
1208250003Sadrian
1209250003Sadrian    /*field_read("BB_paprd_ctrl0_b0.paprd_enable_0", &temp);*/
1210250003Sadrian    temp =
1211250003Sadrian        OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B0,
1212250003Sadrian        AR_PHY_PAPRD_CTRL0_B0_PAPRD_ENABLE_0);
1213250003Sadrian    HALDEBUG(ah, HAL_DEBUG_PAPRD,
1214250003Sadrian        "    BB_paprd_ctrl0_b0.paprd_enable_0     = 0x%08x\n", temp);
1215250003Sadrian    if (!AR_SREV_POSEIDON(ah)) {
1216250003Sadrian        /*field_read("BB_paprd_ctrl0_b1.paprd_enable_1", &temp);*/
1217250003Sadrian        temp =
1218250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B1,
1219250003Sadrian            AR_PHY_PAPRD_CTRL0_B1_PAPRD_ENABLE_1);
1220250003Sadrian        HALDEBUG(ah, HAL_DEBUG_PAPRD,
1221250003Sadrian            "    BB_paprd_ctrl0_b1.paprd_enable_1     = 0x%08x\n", temp);
1222250003Sadrian        if (AH9300(ah)->ah_tx_chainmask & AR9300_CHAIN2_MASK) {
1223250003Sadrian            /*field_read("BB_paprd_ctrl0_b2.paprd_enable_2", &temp);*/
1224250003Sadrian            temp =
1225250003Sadrian                OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL0_B2,
1226250003Sadrian                AR_PHY_PAPRD_CTRL0_B2_PAPRD_ENABLE_2);
1227250003Sadrian            HALDEBUG(ah, HAL_DEBUG_PAPRD,
1228250003Sadrian                "    BB_paprd_ctrl0_b2.paprd_enable_2     = 0x%08x\n", temp);
1229250003Sadrian        }
1230250003Sadrian    }
1231250003Sadrian
1232250003Sadrian    /*field_read("BB_tx_forced_gain.forced_txbb1dbgain", &txbb1dbgain);*/
1233250003Sadrian    txbb1dbgain =
1234250003Sadrian        OS_REG_READ_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
1235250003Sadrian        AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN);
1236250003Sadrian    /*field_read("BB_tx_forced_gain.forced_txbb6dbgain", &txbb6dbgain);*/
1237250003Sadrian    txbb6dbgain =
1238250003Sadrian        OS_REG_READ_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
1239250003Sadrian        AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN);
1240250003Sadrian    /*field_read("BB_tx_forced_gain.forced_txmxrgain", &txmxrgain);*/
1241250003Sadrian    txmxrgain =
1242250003Sadrian        OS_REG_READ_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
1243250003Sadrian        AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN);
1244250003Sadrian    /*field_read("BB_tx_forced_gain.forced_padrvgn_a", &padrvgn_a);*/
1245250003Sadrian    padrvgn_a =
1246250003Sadrian        OS_REG_READ_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
1247250003Sadrian        AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA);
1248250003Sadrian    /*field_read("BB_tx_forced_gain.forced_padrvgn_b", &padrvgn_b);*/
1249250003Sadrian    padrvgn_b =
1250250003Sadrian        OS_REG_READ_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
1251250003Sadrian        AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB);
1252250003Sadrian    /*field_read("BB_tx_forced_gain.forced_padrvgn_c", &padrvgn_c);*/
1253250003Sadrian    padrvgn_c =
1254250003Sadrian        OS_REG_READ_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
1255250003Sadrian        AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC);
1256250003Sadrian    /*field_read("BB_tx_forced_gain.forced_padrvgn_d", &padrvgn_d);*/
1257250003Sadrian    padrvgn_d =
1258250003Sadrian        OS_REG_READ_FIELD_ALT(ah, AR_PHY_TX_FORCED_GAIN,
1259250003Sadrian        AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND);
1260250003Sadrian
1261250003Sadrian    HALDEBUG(ah, HAL_DEBUG_PAPRD,
1262250003Sadrian        "txbb1dbgain=0x%x, txbb6dbgain=0x%x, txmxrgain=0x%x\n",
1263250003Sadrian        txbb1dbgain, txbb6dbgain, txmxrgain);
1264250003Sadrian    HALDEBUG(ah, HAL_DEBUG_PAPRD,
1265250003Sadrian        "padrvgn_a=0x%x, padrvgn_b=0x%x\n", padrvgn_a, padrvgn_b);
1266250003Sadrian    HALDEBUG(ah, HAL_DEBUG_PAPRD,
1267250003Sadrian        "padrvgn_c=0x%x, padrvgn_d=0x%x\n", padrvgn_c, padrvgn_d);
1268250003Sadrian}
1269250003Sadrian#else
1270250003Sadrian#define ar9300_paprd_debug_print(ah) /* dummy macro */
1271250003Sadrian#endif /* defined(ART_PAPRD_DEBUG) || defined(AH_DEBUG) */
1272250003Sadrian
1273250003Sadrianstatic int ar9300_create_pa_curve(struct ath_hal *ah, u_int32_t * pa_table,
1274250003Sadrian    u_int32_t * small_signal_gain, int * pa_in)
1275250003Sadrian{
1276250003Sadrian    int i;
1277250003Sadrian    int status;
1278250003Sadrian    /*char field_name[100];*/
1279250003Sadrian    u_int32_t paprd_train_data_l[48], paprd_train_data_u[48];
1280250003Sadrian    u_int32_t reg;
1281250003Sadrian
1282250003Sadrian    ar9300_paprd_debug_print(ah);
1283250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_CHAN_INFO_MEMORY,
1284250003Sadrian        AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ, 0);
1285250003Sadrian    reg = AR_PHY_CHAN_INFO_TAB_0;
1286250003Sadrian
1287250003Sadrian    for (i = 0; i < 48; i++) {
1288250003Sadrian        /*
1289250003Sadrian         * sprintf(
1290250003Sadrian         *     field_name, "%s%d%s\0", "BB_chan_info_chan_tab_b0[",
1291250003Sadrian         *     i, "].chaninfo_word");
1292250003Sadrian         */
1293250003Sadrian        /*field_read(field_name, &paprd_train_data_l[i]);*/
1294250003Sadrian        paprd_train_data_l[i] = OS_REG_READ(ah, reg);
1295250003Sadrian        reg = reg + 4;
1296250003Sadrian    }
1297250003Sadrian
1298250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_CHAN_INFO_MEMORY,
1299250003Sadrian        AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ, 1);
1300250003Sadrian    reg = AR_PHY_CHAN_INFO_TAB_0;
1301250003Sadrian
1302250003Sadrian    for (i = 0; i < 48; i++) {
1303250003Sadrian        /*
1304250003Sadrian         * sprintf(
1305250003Sadrian         *     field_name, "%s%d%s\0", "BB_chan_info_chan_tab_b0[",
1306250003Sadrian         *     i, "].chaninfo_word");
1307250003Sadrian         */
1308250003Sadrian        /*field_read(field_name, &paprd_train_data_u[i]);*/
1309250003Sadrian        paprd_train_data_u[i] = OS_REG_READ(ah, reg);
1310250003Sadrian        reg = reg + 4;
1311250003Sadrian    }
1312250003Sadrian
1313250003Sadrian    /*
1314250003Sadrian     * for(i=0; i<48; i++)
1315250003Sadrian     *     ath_hal_printf(
1316250003Sadrian     *         ah, "%08x%08x\n", paprd_train_data_u[i], paprd_train_data_l[i]);
1317250003Sadrian     */
1318250003Sadrian    status = 0;
1319250003Sadrian    if (create_pa_curve(
1320250003Sadrian            paprd_train_data_l, paprd_train_data_u,
1321250003Sadrian            pa_table, small_signal_gain, pa_in) ==
1322250003Sadrian            AH_FALSE)
1323250003Sadrian    {
1324250003Sadrian        status = -2;
1325250003Sadrian    }
1326250003Sadrian    /* Clear the training done bit */
1327250003Sadrian    if (AR_SREV_POSEIDON(ah)) {
1328250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
1329250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE, 0);
1330250003Sadrian    } else {
1331250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
1332250003Sadrian            AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE, 0);
1333250003Sadrian    }
1334250003Sadrian    return status;
1335250003Sadrian}
1336250003Sadrian
1337250003Sadrianstatic int find_expn(int num)
1338250003Sadrian{
1339250003Sadrian    int tmp, exp;
1340250003Sadrian
1341250003Sadrian    exp = 0;
1342250003Sadrian    tmp = num >> 1;
1343250003Sadrian
1344250003Sadrian    while (tmp != 0) {
1345250003Sadrian        tmp = tmp >> 1;
1346250003Sadrian        exp++;
1347250003Sadrian    }
1348250003Sadrian
1349250003Sadrian    return exp;
1350250003Sadrian}
1351250003Sadrian
1352250003Sadrianstatic int find_proper_scale(int expn, int n)
1353250003Sadrian{
1354250003Sadrian    int q_pw;
1355250003Sadrian
1356250003Sadrian    q_pw = (expn > n) ? expn - 10 : 0;
1357250003Sadrian    return q_pw;
1358250003Sadrian}
1359250003Sadrian
1360250003Sadrianstatic int find_max(int *array, int length)
1361250003Sadrian{
1362250003Sadrian    int i, loc_max;
1363250003Sadrian
1364250003Sadrian    loc_max = 0;
1365250003Sadrian
1366250003Sadrian    for (i = 0; i < length; i++) {
1367250003Sadrian        if (array[i] > loc_max) {
1368250003Sadrian            loc_max = array[i];
1369250003Sadrian        }
1370250003Sadrian    }
1371250003Sadrian
1372250003Sadrian    return loc_max;
1373250003Sadrian}
1374250003Sadrian
1375250003Sadrianstatic int paprd_abs(int num)
1376250003Sadrian{
1377250003Sadrian    if (num < 0) {
1378250003Sadrian        return -num;
1379250003Sadrian    }
1380250003Sadrian    return num;
1381250003Sadrian}
1382250003Sadrian
1383250003Sadrian#define NUM_BIN 23
1384250003Sadrian
1385250003SadrianHAL_BOOL create_pa_curve(u_int32_t * paprd_train_data_l,
1386250003Sadrian    u_int32_t * paprd_train_data_u, u_int32_t * pa_table,
1387250003Sadrian    u_int32_t * g_fxp_ext, int *pa_in)
1388250003Sadrian{
1389250003Sadrian    unsigned int accum_cnt[NUM_BIN + 1];
1390250003Sadrian    unsigned int accum_tx[NUM_BIN + 1];
1391250003Sadrian    unsigned int accum_rx[NUM_BIN + 1];
1392250003Sadrian    unsigned int accum_ang[NUM_BIN + 1];
1393250003Sadrian    unsigned int thresh_accum_cnt;
1394250003Sadrian
1395250003Sadrian    int max_index;
1396250003Sadrian    int scale_factor;
1397250003Sadrian
1398250003Sadrian    int x_est[NUM_BIN + 1];
1399250003Sadrian    int y[NUM_BIN + 1];
1400250003Sadrian    int theta[NUM_BIN + 1];
1401250003Sadrian    int y_sqr[NUM_BIN + 1];
1402250003Sadrian    int y_quad[NUM_BIN + 1];
1403250003Sadrian    int theta_tilde[NUM_BIN + 1];
1404250003Sadrian    int pa_angle[NUM_BIN + 1];
1405250003Sadrian
1406250003Sadrian    int b1_tmp[NUM_BIN + 1];
1407250003Sadrian    int b2_tmp[NUM_BIN + 1];
1408250003Sadrian    int b1_abs[NUM_BIN + 1];
1409250003Sadrian    int b2_abs[NUM_BIN + 1];
1410250003Sadrian
1411250003Sadrian    int y_lin[NUM_BIN + 1];
1412250003Sadrian    int y_est[NUM_BIN + 1];
1413250003Sadrian    int x_est_fxp1_nonlin[NUM_BIN + 1];
1414250003Sadrian    int x_tilde[NUM_BIN + 1];
1415250003Sadrian    int x_tilde_abs[NUM_BIN + 1];
1416250003Sadrian
1417250003Sadrian    int g_fxp;
1418250003Sadrian    int y_intercept;
1419250003Sadrian    int order_x_by_y;
1420250003Sadrian    int m, half_lo, half_hi;
1421250003Sadrian    int sum_y_sqr;
1422250003Sadrian    int sum_y_quad;
1423250003Sadrian    int q_x, q_b1, q_b2;
1424250003Sadrian    int beta_raw, alpha_raw, scale_b;
1425250003Sadrian    int q_scale_b, q_beta, q_alpha;
1426250003Sadrian    int alpha, beta;
1427250003Sadrian    int order_1, order_2;
1428250003Sadrian    int order1_5x, order2_3x;
1429250003Sadrian    int order1_5x_rem, order2_3x_rem;
1430250003Sadrian    int y5, y3, tmp;
1431250003Sadrian    int bin, idx;
1432250003Sadrian    int theta_low_bin = 0;
1433250003Sadrian
1434250003Sadrian    /*
1435250003Sadrian     * [15:00] u16, accum_cnt[15:00]: number of samples in the bin
1436250003Sadrian     * [42:16] u27, accum_tx[26:00]: sum(tx amplitude) of the bin
1437250003Sadrian     * [63:43] u21, accum_rx[20:00]:
1438250003Sadrian     *     sum(rx amplitude distance to lower bin edge) of the bin
1439250003Sadrian     * [90:64] s27, accum_ang[26:00]: sum(angles) of the bin
1440250003Sadrian     */
1441250003Sadrian    max_index = 0;
1442250003Sadrian    /*
1443250003Sadrian     * Disregard any bin that contains less than
1444250003Sadrian     * or equal to 16 counts of samples
1445250003Sadrian     */
1446250003Sadrian    thresh_accum_cnt = 16;
1447250003Sadrian    scale_factor = 5;
1448250003Sadrian
1449250003Sadrian    for (bin = 0; bin < NUM_BIN; bin++) {
1450250003Sadrian        accum_cnt[bin] = paprd_train_data_l[bin] & 0xffff;
1451250003Sadrian        /* lower 16 bit OR-ed  upper 11 bits */
1452250003Sadrian        accum_tx[bin] =
1453250003Sadrian            ((paprd_train_data_l[bin] >> 16) & 0xffff) |
1454250003Sadrian            ((paprd_train_data_u[bin] & 0x7ff) << 16);
1455250003Sadrian        accum_rx[bin] =
1456250003Sadrian            ((paprd_train_data_u[bin] >> 11) & 0x1f) |
1457250003Sadrian             ((paprd_train_data_l[bin + 23] & 0xffff) << 5);
1458250003Sadrian        accum_ang[bin] =
1459250003Sadrian            ((paprd_train_data_l[bin + 23] >> 16) & 0xffff) |
1460250003Sadrian             ((paprd_train_data_u[bin + 23] & 0x7ff) << 16);
1461250003Sadrian        /*
1462250003Sadrian         * printf(
1463250003Sadrian         *     "%d\t%d\t%d\t%d\n", accum_cnt[bin], accum_tx[bin],
1464250003Sadrian         *     accum_rx[bin], accum_ang[bin]);
1465250003Sadrian         */
1466250003Sadrian        if (accum_cnt[bin] > thresh_accum_cnt) {
1467250003Sadrian            /* accum_cnt[i] will be non-zero at this point */
1468250003Sadrian            x_est[bin + 1] =
1469250003Sadrian                ((((accum_tx[bin] << scale_factor) +
1470250003Sadrian                    accum_cnt[bin]) / accum_cnt[bin]) + 32) >> scale_factor;
1471250003Sadrian            y[bin + 1] =
1472250003Sadrian                (((((accum_rx[bin] << scale_factor) +
1473250003Sadrian                     accum_cnt[bin]) / accum_cnt[bin]) + 32) >> scale_factor) +
1474250003Sadrian                (1 << scale_factor) * max_index + 16;
1475250003Sadrian            if (accum_ang[bin] >= (1 << 26)) {
1476250003Sadrian                theta[bin + 1] =
1477250003Sadrian                    ((accum_ang[bin] - (1 << 27)) * (1 << scale_factor) +
1478250003Sadrian                    accum_cnt[bin]);
1479250003Sadrian                theta[bin + 1] = theta[bin + 1] / (int) accum_cnt[bin];
1480250003Sadrian                /*
1481250003Sadrian                 *  theta[i+1] =
1482250003Sadrian                 *      ((accum_ang[i] - (1 << 27)) *
1483250003Sadrian                 *      (1 << scale_factor) + zz) / zz;
1484250003Sadrian                 */
1485250003Sadrian            } else {
1486250003Sadrian                theta[bin + 1] =
1487250003Sadrian                    ((accum_ang[bin] * (1 << scale_factor)) +
1488250003Sadrian                    accum_cnt[bin]) / accum_cnt[bin];
1489250003Sadrian            }
1490250003Sadrian            max_index++;
1491250003Sadrian        }
1492250003Sadrian        /*
1493250003Sadrian         * printf(
1494250003Sadrian         *     "i=%d, theta[i+1]=%d\t%d\t%d\t%d\t%d\n",
1495250003Sadrian         *     i, theta[i+1], accum_cnt[i],
1496250003Sadrian         *     accum_tx[i], accum_rx[i], accum_ang[i]);
1497250003Sadrian         */
1498250003Sadrian    }
1499250003Sadrian
1500250003Sadrian    /*
1501250003Sadrian     * Find average theta of first 5 bin and all of those to same value.
1502250003Sadrian     * Curve is linear at that range.
1503250003Sadrian     */
1504250003Sadrian    for (bin = 1; bin < 6; bin++) {
1505250003Sadrian        theta_low_bin += theta[bin];
1506250003Sadrian    }
1507250003Sadrian    theta_low_bin = theta_low_bin / 5;
1508250003Sadrian    for (bin = 1; bin < 6; bin++) {
1509250003Sadrian        theta[bin] = theta_low_bin;
1510250003Sadrian    }
1511250003Sadrian
1512250003Sadrian    /* Set values at origin */
1513250003Sadrian    theta[0] = theta_low_bin;
1514250003Sadrian
1515250003Sadrian    for (bin = 0; bin <= max_index; bin++) {
1516250003Sadrian        theta[bin] = theta[bin] - theta_low_bin;
1517250003Sadrian        /*printf("bin=%d, theta[bin] = %d\n", bin, theta[bin]);*/
1518250003Sadrian    }
1519250003Sadrian
1520250003Sadrian    x_est[0] = 0;
1521250003Sadrian    y[0] = 0;
1522250003Sadrian    scale_factor = 8;
1523250003Sadrian    /* low signal gain */
1524250003Sadrian    if (x_est[6] == x_est[3]) {
1525250003Sadrian        return AH_FALSE;
1526250003Sadrian    }
1527250003Sadrian    g_fxp =
1528250003Sadrian        (((y[6] - y[3]) * 1 << scale_factor) + (x_est[6] - x_est[3])) /
1529250003Sadrian        (x_est[6] - x_est[3]);
1530250003Sadrian    if (g_fxp == 0) {
1531250003Sadrian        /*
1532250003Sadrian         * ath_hal_printf(
1533250003Sadrian         *     NULL, "%s[%d] Potential divide by zero error\n",
1534250003Sadrian         *     __func__, __LINE__);
1535250003Sadrian         */
1536250003Sadrian        return AH_FALSE;
1537250003Sadrian    }
1538250003Sadrian
1539250003Sadrian    for (bin = 0; bin <= max_index; bin++) {
1540250003Sadrian        y_lin[bin] =
1541250003Sadrian            (g_fxp * (x_est[bin] - x_est[3]) + (1 << scale_factor)) /
1542250003Sadrian            (1 << scale_factor) + y[3];
1543250003Sadrian    }
1544250003Sadrian    y_intercept = y_lin[0];
1545250003Sadrian
1546250003Sadrian    for (bin = 0; bin <= max_index; bin++) {
1547250003Sadrian        y_est[bin] = y[bin] - y_intercept;
1548250003Sadrian        y_lin[bin] = y_lin[bin] - y_intercept;
1549250003Sadrian    }
1550250003Sadrian
1551250003Sadrian    for (bin = 0; bin <= 3; bin++) {
1552250003Sadrian        y_est[bin] = bin * 32;
1553250003Sadrian        /* g_fxp was checked for zero already */
1554250003Sadrian        x_est[bin] = ((y_est[bin] * 1 << scale_factor) + g_fxp) / g_fxp;
1555250003Sadrian    }
1556250003Sadrian
1557250003Sadrian    /*
1558250003Sadrian     *  for (bin = 0; bin <= max_index; bin++) {
1559250003Sadrian     *      printf("y_est[%d] = %d, x_est[%d]=%d\n",
1560250003Sadrian     *          bin, y_est[bin], bin, x_est[bin]);
1561250003Sadrian     *  }
1562250003Sadrian     */
1563250003Sadrian    for (bin = 0; bin <= max_index; bin++) {
1564250003Sadrian        x_est_fxp1_nonlin[bin] =
1565250003Sadrian            x_est[bin] - ((1 << scale_factor) * y_est[bin] + g_fxp) / g_fxp;
1566250003Sadrian        /*printf("x_est_fxp1_nonlin[%d] = %d\n", bin, x_est_fxp1_nonlin[bin]);*/
1567250003Sadrian    }
1568250003Sadrian
1569250003Sadrian    /* Check for divide by 0 */
1570250003Sadrian    if (y_est[max_index] == 0) {
1571250003Sadrian        return AH_FALSE;
1572250003Sadrian    }
1573250003Sadrian    order_x_by_y =
1574250003Sadrian        (x_est_fxp1_nonlin[max_index] + y_est[max_index]) / y_est[max_index];
1575250003Sadrian    if (order_x_by_y == 0) {
1576250003Sadrian        m = 10;
1577250003Sadrian    } else if (order_x_by_y == 1) {
1578250003Sadrian        m = 9;
1579250003Sadrian    } else {
1580250003Sadrian        m = 8;
1581250003Sadrian    }
1582250003Sadrian
1583250003Sadrian    half_lo = (max_index > 15) ? 7 : max_index >> 1;
1584250003Sadrian    half_hi = max_index - half_lo;
1585250003Sadrian    scale_factor = 8;
1586250003Sadrian    sum_y_sqr = 0;
1587250003Sadrian    sum_y_quad = 0;
1588250003Sadrian
1589250003Sadrian    for (bin = 0; bin <= half_hi; bin++) {
1590250003Sadrian        if (y_est[bin + half_lo] == 0) {
1591250003Sadrian            /*
1592250003Sadrian             * ath_hal_printf(
1593250003Sadrian             *     NULL, "%s Potential divide by zero error\n", __func__);
1594250003Sadrian             */
1595250003Sadrian            return AH_FALSE;
1596250003Sadrian        }
1597250003Sadrian
1598250003Sadrian        x_tilde[bin] =
1599250003Sadrian            (x_est_fxp1_nonlin[bin + half_lo] * (1 << m) +
1600250003Sadrian             y_est[bin + half_lo]) / y_est[bin + half_lo];
1601250003Sadrian        x_tilde[bin] = (x_tilde[bin] * (1 << m) + y_est[bin + half_lo]) /
1602250003Sadrian            y_est[bin + half_lo];
1603250003Sadrian        x_tilde[bin] = (x_tilde[bin] * (1 << m) + y_est[bin + half_lo]) /
1604250003Sadrian            y_est[bin + half_lo];
1605250003Sadrian
1606250003Sadrian        y_sqr[bin] =
1607250003Sadrian            (y_est[bin + half_lo] * y_est[bin + half_lo] +
1608250003Sadrian             (scale_factor * scale_factor)) / (scale_factor * scale_factor);
1609250003Sadrian        x_tilde_abs[bin] = paprd_abs(x_tilde[bin]);
1610250003Sadrian        y_quad[bin] = y_sqr[bin] * y_sqr[bin];
1611250003Sadrian        sum_y_sqr = sum_y_sqr + y_sqr[bin];
1612250003Sadrian        sum_y_quad = sum_y_quad + y_quad[bin];
1613250003Sadrian    }
1614250003Sadrian
1615250003Sadrian    /*printf("sum_y_sqr = %d, sum_y_quad=%d\n", sum_y_sqr, sum_y_quad);*/
1616250003Sadrian
1617250003Sadrian    for (bin = 0; bin <= half_hi; bin++) {
1618250003Sadrian        b1_tmp[bin] = y_sqr[bin] * (half_hi + 1) - sum_y_sqr;
1619250003Sadrian        b2_tmp[bin] = sum_y_quad - sum_y_sqr * y_sqr[bin];
1620250003Sadrian        b1_abs[bin] = paprd_abs(b1_tmp[bin]);
1621250003Sadrian        b2_abs[bin] = paprd_abs(b2_tmp[bin]);
1622250003Sadrian
1623250003Sadrian        /*
1624250003Sadrian         * printf(
1625250003Sadrian         *     "bin=%d, b1_tmp[bin] = %d, b2_tmp[bin] = %d\n",
1626250003Sadrian         *     bin, b1_tmp[bin], b2_tmp[bin]);
1627250003Sadrian         */
1628250003Sadrian    }
1629250003Sadrian
1630250003Sadrian    q_x = find_proper_scale(find_expn(find_max(x_tilde_abs, half_hi + 1)), 10);
1631250003Sadrian    q_b1 = find_proper_scale(find_expn(find_max(b1_abs, half_hi + 1)), 10);
1632250003Sadrian    q_b2 = find_proper_scale(find_expn(find_max(b2_abs, half_hi + 1)), 10);
1633250003Sadrian
1634250003Sadrian    beta_raw = 0;
1635250003Sadrian    alpha_raw = 0;
1636250003Sadrian
1637250003Sadrian    for (bin = 0; bin <= half_hi; bin++) {
1638250003Sadrian        x_tilde[bin] = x_tilde[bin] / (1 << q_x);
1639250003Sadrian        b1_tmp[bin] = b1_tmp[bin] / (1 << q_b1);
1640250003Sadrian        b2_tmp[bin] = b2_tmp[bin] / (1 << q_b2);
1641250003Sadrian
1642250003Sadrian        /*
1643250003Sadrian         * printf(
1644250003Sadrian         *     "bin=%d, b1_tmp[bin]=%d b2_tmp[bin]=%d x_tilde[bin] = %d\n",
1645250003Sadrian         *     bin, b1_tmp[bin], b2_tmp[bin], x_tilde[bin]);
1646250003Sadrian         */
1647250003Sadrian        beta_raw = beta_raw + b1_tmp[bin] * x_tilde[bin];
1648250003Sadrian        alpha_raw = alpha_raw + b2_tmp[bin] * x_tilde[bin];
1649250003Sadrian    }
1650250003Sadrian
1651250003Sadrian    scale_b =
1652250003Sadrian        ((sum_y_quad / scale_factor) * (half_hi + 1) -
1653250003Sadrian        (sum_y_sqr / scale_factor) * sum_y_sqr) * scale_factor;
1654250003Sadrian    q_scale_b = find_proper_scale(find_expn(paprd_abs(scale_b)), 10);
1655250003Sadrian    scale_b = scale_b / (1 << q_scale_b);
1656250003Sadrian    /* Check for divide by 0 */
1657250003Sadrian    if (scale_b == 0) {
1658250003Sadrian        return AH_FALSE;
1659250003Sadrian    }
1660250003Sadrian    q_beta = find_proper_scale(find_expn(paprd_abs(beta_raw)), 10);
1661250003Sadrian    q_alpha = find_proper_scale(find_expn(paprd_abs(alpha_raw)), 10);
1662250003Sadrian
1663250003Sadrian    beta_raw = beta_raw / (1 << q_beta);
1664250003Sadrian    alpha_raw = alpha_raw / (1 << q_alpha);
1665250003Sadrian    alpha = (alpha_raw << 10) / scale_b;
1666250003Sadrian    beta = (beta_raw << 10) / scale_b;
1667250003Sadrian    order_1 = 3 * m - q_x - q_b1 - q_beta + 10 + q_scale_b;
1668250003Sadrian    order_2 = 3 * m - q_x - q_b2 - q_alpha + 10 + q_scale_b;
1669250003Sadrian
1670250003Sadrian    order1_5x = order_1 / 5;
1671250003Sadrian    order2_3x = order_2 / 3;
1672250003Sadrian
1673250003Sadrian    order1_5x_rem = order_1 - 5 * order1_5x;
1674250003Sadrian    order2_3x_rem = order_2 - 3 * order2_3x;
1675250003Sadrian
1676250003Sadrian    for (idx = 0; idx < AR9300_PAPRD_TABLE_SZ; idx++) {
1677250003Sadrian        tmp = idx * 32;
1678250003Sadrian        y5 = ((beta * tmp) >> 6) >> order1_5x;
1679250003Sadrian        y5 = (y5 * tmp) >> order1_5x;
1680250003Sadrian        y5 = (y5 * tmp) >> order1_5x;
1681250003Sadrian        y5 = (y5 * tmp) >> order1_5x;
1682250003Sadrian        y5 = (y5 * tmp) >> order1_5x;
1683250003Sadrian
1684250003Sadrian        y5 = y5 >> order1_5x_rem;
1685250003Sadrian        y3 = (alpha * tmp) >> order2_3x;
1686250003Sadrian        y3 = (y3 * tmp) >> order2_3x;
1687250003Sadrian        y3 = (y3 * tmp) >> order2_3x;
1688250003Sadrian
1689250003Sadrian        y3 = y3 >> order2_3x_rem;
1690250003Sadrian        /* g_fxp was checked for zero already */
1691250003Sadrian        pa_in[idx] = y5 + y3 + (256 * tmp) / g_fxp;
1692250003Sadrian    }
1693250003Sadrian
1694250003Sadrian    for (idx = 1; idx < 23; idx++) {
1695250003Sadrian        tmp = pa_in[idx + 1] - pa_in[idx];
1696250003Sadrian        if (tmp < 0) {
1697250003Sadrian            pa_in[idx + 1] = pa_in[idx] + (pa_in[idx] - pa_in[idx - 1]);
1698250003Sadrian        }
1699250003Sadrian    }
1700250003Sadrian
1701250003Sadrian    for (idx = 0; idx < AR9300_PAPRD_TABLE_SZ; idx++) {
1702250003Sadrian        pa_in[idx] = (pa_in[idx] < 1400) ? pa_in[idx] : 1400;
1703250003Sadrian        /*printf("idx=%d, pa_in[idx]=%d\n", i, pa_in[idx]);*/
1704250003Sadrian    }
1705250003Sadrian
1706250003Sadrian    beta_raw = 0;
1707250003Sadrian    alpha_raw = 0;
1708250003Sadrian
1709250003Sadrian    for (bin = 0; bin <= half_hi; bin++) {
1710250003Sadrian        /*
1711250003Sadrian         *  printf(
1712250003Sadrian         *      "bin=%d half_lo=%d m=%d theta[bin+half_lo]=%d "
1713250003Sadrian         *      "y_est[bin+half_lo]=%d\n",
1714250003Sadrian         *      bin, half_lo, m, theta[bin+half_lo], y_est[bin+half_lo]);
1715250003Sadrian         */
1716250003Sadrian        /* y_est[] was already checked for zero */
1717250003Sadrian        theta_tilde[bin] =
1718250003Sadrian            ((theta[bin + half_lo] << m) + y_est[bin + half_lo]) /
1719250003Sadrian            y_est[bin + half_lo];
1720250003Sadrian        theta_tilde[bin] = ((theta_tilde[bin] << m) + y_est[bin + half_lo]) /
1721250003Sadrian            y_est[bin + half_lo];
1722250003Sadrian        theta_tilde[bin] = ((theta_tilde[bin] << m) + y_est[bin + half_lo]) /
1723250003Sadrian            y_est[bin + half_lo];
1724250003Sadrian
1725250003Sadrian        /*printf("bin=%d theta_tilde[bin]=%d\n", bin, theta_tilde[bin]);*/
1726250003Sadrian        beta_raw = beta_raw + b1_tmp[bin] * theta_tilde[bin];
1727250003Sadrian        alpha_raw = alpha_raw + b2_tmp[bin] * theta_tilde[bin];
1728250003Sadrian
1729250003Sadrian        /*
1730250003Sadrian        printf("bin=%d, alpha_raw=%d, beta_raw=%d\n", bin, alpha_raw, beta_raw);
1731250003Sadrian         */
1732250003Sadrian    }
1733250003Sadrian
1734250003Sadrian    q_beta = find_proper_scale(find_expn(paprd_abs(beta_raw)), 10);
1735250003Sadrian    q_alpha = find_proper_scale(find_expn(paprd_abs(alpha_raw)), 10);
1736250003Sadrian
1737250003Sadrian    beta_raw = beta_raw / (1 << q_beta);
1738250003Sadrian    alpha_raw = alpha_raw / (1 << q_alpha);
1739250003Sadrian    /* scale_b checked for zero previously */
1740250003Sadrian    alpha = (alpha_raw << 10) / scale_b;
1741250003Sadrian    beta = (beta_raw << 10) / scale_b;
1742250003Sadrian    order_1 = 3 * m - q_x - q_b1 - q_beta + 10 + q_scale_b + 5;
1743250003Sadrian    order_2 = 3 * m - q_x - q_b2 - q_alpha + 10 + q_scale_b + 5;
1744250003Sadrian
1745250003Sadrian    order1_5x = order_1 / 5;
1746250003Sadrian    order2_3x = order_2 / 3;
1747250003Sadrian
1748250003Sadrian    order1_5x_rem = order_1 - 5 * order1_5x;
1749250003Sadrian    order2_3x_rem = order_2 - 3 * order2_3x;
1750250003Sadrian
1751250003Sadrian    for (idx = 0; idx < AR9300_PAPRD_TABLE_SZ; idx++) {
1752250003Sadrian        tmp = idx * 32;
1753250003Sadrian
1754250003Sadrian        if (beta > 0) {
1755250003Sadrian            y5 = (((beta * tmp - 64) >> 6) -
1756250003Sadrian                (1 << order1_5x)) / (1 << order1_5x);
1757250003Sadrian        } else {
1758250003Sadrian            y5 = ((((beta * tmp - 64) >> 6) +
1759250003Sadrian                    (1 << order1_5x)) / (1 << order1_5x));
1760250003Sadrian        }
1761250003Sadrian
1762250003Sadrian        y5 = (y5 * tmp) / (1 << order1_5x);
1763250003Sadrian        y5 = (y5 * tmp) / (1 << order1_5x);
1764250003Sadrian        y5 = (y5 * tmp) / (1 << order1_5x);
1765250003Sadrian        y5 = (y5 * tmp) / (1 << order1_5x);
1766250003Sadrian
1767250003Sadrian        y5 = y5 / (1 << order1_5x_rem);
1768250003Sadrian
1769250003Sadrian        if (beta > 0) {
1770250003Sadrian            y3 = (alpha * tmp - (1 << order2_3x)) / (1 << order2_3x);
1771250003Sadrian        } else {
1772250003Sadrian            y3 = (alpha * tmp + (1 << order2_3x)) / (1 << order2_3x);
1773250003Sadrian        }
1774250003Sadrian
1775250003Sadrian        y3 = (y3 * tmp) / (1 << order2_3x);
1776250003Sadrian        y3 = (y3 * tmp) / (1 << order2_3x);
1777250003Sadrian
1778250003Sadrian        y3 = y3 / (1 << order2_3x_rem);
1779250003Sadrian        pa_angle[idx] = y5 + y3;
1780250003Sadrian        /*printf("idx=%d, y5 = %d, y3=%d\n", idx, y5, y3);*/
1781250003Sadrian        pa_angle[idx] =
1782250003Sadrian            (pa_angle[idx] < -150) ? -150 : ((pa_angle[idx] >
1783250003Sadrian                150) ? 150 : pa_angle[idx]);
1784250003Sadrian    }
1785250003Sadrian
1786250003Sadrian    pa_angle[0] = 0;
1787250003Sadrian    pa_angle[1] = 0;
1788250003Sadrian    pa_angle[2] = 0;
1789250003Sadrian    pa_angle[3] = 0;
1790250003Sadrian
1791250003Sadrian    pa_angle[4] = (pa_angle[5] + 2) >> 1;
1792250003Sadrian
1793250003Sadrian    for (idx = 0; idx < AR9300_PAPRD_TABLE_SZ; idx++) {
1794250003Sadrian        pa_table[idx] = ((pa_in[idx] & 0x7ff) << 11) + (pa_angle[idx] & 0x7ff);
1795250003Sadrian        /*
1796250003Sadrian         * HALDEBUG(
1797250003Sadrian         *     NULL, HAL_DEBUG_UNMASKABLE,"%d\t%d\t0x%x\n",
1798250003Sadrian         *     pa_in[idx], pa_angle[idx], pa_table[idx]);
1799250003Sadrian         */
1800250003Sadrian    }
1801250003Sadrian
1802250003Sadrian    /*HALDEBUG(NULL, HAL_DEBUG_UNMASKABLE, "g_fxp = %d\n", g_fxp);*/
1803250003Sadrian    *g_fxp_ext = g_fxp;
1804250003Sadrian    return AH_TRUE;
1805250003Sadrian}
1806250003Sadrian
1807250003Sadrian// Due to a hardware bug, when transmitting with just one chain the papd
1808250003Sadrian// data for chain 0 is always used. So when using chain 2 or 4, the
1809250003Sadrian// corresponding data must be copied into the chain 0 area.
1810250003Sadrianvoid ar9300_swizzle_paprd_entries(struct ath_hal *ah, unsigned int txchain)
1811250003Sadrian{
1812250003Sadrian    int i;
1813250003Sadrian    u_int32_t *paprd_table_val = NULL;
1814250003Sadrian    u_int32_t small_signal_gain = 0;
1815250003Sadrian    u_int32_t reg = 0;
1816250003Sadrian
1817250003Sadrian    reg = AR_PHY_PAPRD_MEM_TAB_B0;
1818250003Sadrian    switch (txchain) {
1819250003Sadrian    case 0x1:
1820250003Sadrian    case 0x3:
1821250003Sadrian    case 0x7:
1822250003Sadrian	paprd_table_val = &AH9300(ah)->pa_table[0][0];
1823250003Sadrian	small_signal_gain = AH9300(ah)->small_signal_gain[0];
1824250003Sadrian	break;
1825250003Sadrian    case 0x2:
1826250003Sadrian	paprd_table_val = &AH9300(ah)->pa_table[1][0];
1827250003Sadrian	small_signal_gain = AH9300(ah)->small_signal_gain[1];
1828250003Sadrian	break;
1829250003Sadrian    case 0x4:
1830250003Sadrian	paprd_table_val = &AH9300(ah)->pa_table[2][0];
1831250003Sadrian	small_signal_gain = AH9300(ah)->small_signal_gain[2];
1832250003Sadrian	break;
1833250003Sadrian    default:
1834250003Sadrian	// Error out.
1835250003Sadrian	ath_hal_printf(ah, "YAK! Bad chain mask %x\n", txchain);
1836250003Sadrian	return;
1837250003Sadrian    }
1838250003Sadrian    for (i = 0; i < AR9300_PAPRD_TABLE_SZ; i++) {
1839250003Sadrian        OS_REG_WRITE(ah, reg, paprd_table_val[i]);
1840250003Sadrian        HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s[%d] reg %08x = 0x%08x\n", __func__,
1841250003Sadrian		 __LINE__, reg, paprd_table_val[i]);
1842250003Sadrian
1843250003Sadrian        reg = reg + 4;
1844250003Sadrian    }
1845250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PA_GAIN123_B0,AR_PHY_PA_GAIN123_B0_PA_GAIN1_0, small_signal_gain);
1846250003Sadrian    HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s[%d] reg %08x small_signal_gain 0x%08x\n", __func__, __LINE__,
1847250003Sadrian	     (unsigned) AR_PHY_PA_GAIN123_B0, OS_REG_READ(ah, AR_PHY_PA_GAIN123_B0));
1848250003Sadrian
1849250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0, AR_PHY_PAPRD_CTRL1_B0_PAPRD_POWER_AT_AM2AM_CAL_0,
1850250003Sadrian			 AH9300(ah)->paprd_training_power);
1851250003Sadrian    HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s[%d] reg %08x = 0x%08x\n", __func__, __LINE__,
1852250003Sadrian	     (unsigned) AR_PHY_PAPRD_CTRL1_B0, OS_REG_READ(ah, AR_PHY_PAPRD_CTRL1_B0));
1853250003Sadrian
1854250003Sadrian}
1855250003Sadrian
1856250008Sadrianvoid ar9300_populate_paprd_single_table(struct ath_hal *ah,
1857250008Sadrian    struct ieee80211_channel *chan, int chain_num)
1858250003Sadrian{
1859250003Sadrian    int i, j, bad_read = 0;
1860250008Sadrian#ifdef	AH_DEBUG
1861250008Sadrian    HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
1862250008Sadrian#endif
1863250003Sadrian    u_int32_t *paprd_table_val = &AH9300(ah)->pa_table[chain_num][0];
1864250003Sadrian    u_int32_t small_signal_gain = AH9300(ah)->small_signal_gain[chain_num];
1865250003Sadrian    u_int32_t reg = 0;
1866250003Sadrian
1867250003Sadrian    HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
1868250003Sadrian        "%s[%d]: channel %d paprd_done %d write %d\n", __func__, __LINE__,
1869250008Sadrian        ichan->channel, ichan->paprd_done, ichan->paprd_table_write_done);
1870250003Sadrian
1871250003Sadrian    if (chain_num == 0) {
1872250003Sadrian        reg = AR_PHY_PAPRD_MEM_TAB_B0;
1873250003Sadrian    } else if (chain_num == 1) {
1874250003Sadrian        reg = AR_PHY_PAPRD_MEM_TAB_B1;
1875250003Sadrian    } else if (chain_num == 2) {
1876250003Sadrian        reg = AR_PHY_PAPRD_MEM_TAB_B2;
1877250003Sadrian    }
1878250003Sadrian
1879250003Sadrian    for (i = 0; i < AR9300_PAPRD_TABLE_SZ; i++) {
1880250003Sadrian        if (AR_SREV_POSEIDON(ah)) {
1881250003Sadrian            HALASSERT(chain_num == 0x1);
1882250003Sadrian            if ((reg == AR_PHY_PAPRD_MEM_TAB_B1) ||
1883250003Sadrian                (reg == AR_PHY_PAPRD_MEM_TAB_B2)) {
1884250003Sadrian                continue;
1885250003Sadrian            }
1886250003Sadrian        }
1887250003Sadrian        /*
1888250003Sadrian         * sprintf(
1889250003Sadrian         *     field_name, "%s%d[%d]%s\0", "BB_paprd_mem_tab_b",
1890250003Sadrian         *     chain_num, i, ".paprd_mem");
1891250003Sadrian         */
1892250003Sadrian        OS_REG_WRITE(ah, reg, paprd_table_val[i]);
1893250003Sadrian        HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s[%d] reg %08x = 0x%08x\n", __func__,
1894250003Sadrian            __LINE__, reg, paprd_table_val[i]);
1895250003Sadrian        /*
1896250003Sadrian         * printf(
1897250003Sadrian         *     "%s[%d] reg %08x = 0x%08x\n",
1898250003Sadrian         *     __func__, __LINE__, reg, paprd_table_val[i]);
1899250003Sadrian         */
1900250003Sadrian         if (OS_REG_READ(ah, reg) == 0xdeadbeef) {
1901250003Sadrian            HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
1902250003Sadrian                     "%s: Reg0x%x = 0xdeadbeef\n", __func__, reg);
1903250003Sadrian            bad_read++;
1904250003Sadrian            for (j = AR_PHY_PAPRD_MEM_TAB_B0; j < (AR_PHY_PAPRD_MEM_TAB_B0 + 0x10); j+=4)
1905250003Sadrian            {
1906250003Sadrian                if (OS_REG_READ(ah, j) == 0xdeadbeef) {
1907250003Sadrian                    HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
1908250003Sadrian                             "%s: Reg0x%x = 0xdeadbeef\n", __func__, j);
1909250003Sadrian                    bad_read++;
1910250003Sadrian                }
1911250003Sadrian            }
1912250003Sadrian            for (j = AR_PHY_PAPRD_MEM_TAB_B1; j < (AR_PHY_PAPRD_MEM_TAB_B1 + 0x10); j+=4)
1913250003Sadrian            {
1914250003Sadrian                if (OS_REG_READ(ah, j) == 0xdeadbeef) {
1915250003Sadrian                    HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
1916250003Sadrian                             "%s: Reg0x%x = 0xdeadbeef\n", __func__, j);
1917250003Sadrian                    bad_read++;
1918250003Sadrian                }
1919250003Sadrian            }
1920250003Sadrian         }
1921250003Sadrian
1922250003Sadrian        reg = reg + 4;
1923250003Sadrian    }
1924250003Sadrian
1925250003Sadrian    if (bad_read > 4) {
1926250003Sadrian        HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
1927250003Sadrian                 "%s: Get %d 0xdeadbeef. Mark PAPRD as broken.\n",
1928250003Sadrian                 __func__, bad_read);
1929250003Sadrian        AH9300(ah)->ah_paprd_broken = AH_TRUE;
1930250003Sadrian    }
1931250003Sadrian
1932250003Sadrian    if (chain_num == 0) {
1933250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PA_GAIN123_B0,
1934250003Sadrian            AR_PHY_PA_GAIN123_B0_PA_GAIN1_0, small_signal_gain);
1935250003Sadrian        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
1936250003Sadrian            "%s[%d] reg %08x small_signal_gain 0x%08x\n", __func__, __LINE__,
1937250003Sadrian            (unsigned) AR_PHY_PA_GAIN123_B0,
1938250003Sadrian            OS_REG_READ(ah, AR_PHY_PA_GAIN123_B0));
1939250003Sadrian    } else if (chain_num == 1) {
1940250003Sadrian        if (!AR_SREV_POSEIDON(ah) && !AR_SREV_HORNET(ah) && !AR_SREV_APHRODITE(ah)) {
1941250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PA_GAIN123_B1,
1942250003Sadrian                AR_PHY_PA_GAIN123_B1_PA_GAIN1_1, small_signal_gain);
1943250003Sadrian            HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
1944250003Sadrian                "%s[%d] reg %08x small_signal_gain 0x%08x\n",
1945250003Sadrian                __func__, __LINE__,
1946250003Sadrian                (unsigned) AR_PHY_PA_GAIN123_B1,
1947250003Sadrian                OS_REG_READ(ah, AR_PHY_PA_GAIN123_B1));
1948250003Sadrian        }
1949250003Sadrian    } else if (chain_num == 2) {
1950250003Sadrian        if (!AR_SREV_POSEIDON(ah) && !AR_SREV_HORNET(ah) && !AR_SREV_APHRODITE(ah)) {
1951250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PA_GAIN123_B2,
1952250003Sadrian                AR_PHY_PA_GAIN123_B2_PA_GAIN1_2, small_signal_gain);
1953250003Sadrian            HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
1954250003Sadrian                "%s[%d] reg %08x small_signal_gain 0x%08x\n",
1955250003Sadrian                __func__, __LINE__,
1956250003Sadrian                (unsigned) AR_PHY_PA_GAIN123_B2,
1957250003Sadrian                OS_REG_READ(ah, AR_PHY_PA_GAIN123_B2));
1958250003Sadrian        }
1959250003Sadrian    } else {
1960250003Sadrian        /* invalid channel number */
1961250003Sadrian    }
1962250003Sadrian
1963250003Sadrian    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B0,
1964250003Sadrian        AR_PHY_PAPRD_CTRL1_B0_PAPRD_POWER_AT_AM2AM_CAL_0,
1965250003Sadrian        AH9300(ah)->paprd_training_power);
1966250003Sadrian    HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s[%d] reg %08x = 0x%08x\n", __func__,
1967250003Sadrian        __LINE__, (unsigned) AR_PHY_PAPRD_CTRL1_B0,
1968250003Sadrian        OS_REG_READ(ah, AR_PHY_PAPRD_CTRL1_B0));
1969250003Sadrian    if (!AR_SREV_POSEIDON(ah) && !AR_SREV_HORNET(ah) && !AR_SREV_APHRODITE(ah)) {
1970250003Sadrian        OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B1,
1971250003Sadrian            AR_PHY_PAPRD_CTRL1_B1_PAPRD_POWER_AT_AM2AM_CAL_1,
1972250003Sadrian            AH9300(ah)->paprd_training_power);
1973250003Sadrian        HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s[%d] reg %08x = 0x%08x\n", __func__,
1974250003Sadrian            __LINE__, (unsigned) AR_PHY_PAPRD_CTRL1_B1,
1975250003Sadrian            OS_REG_READ(ah, AR_PHY_PAPRD_CTRL1_B1));
1976250003Sadrian        if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
1977250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_CTRL1_B2,
1978250003Sadrian                AR_PHY_PAPRD_CTRL1_B2_PAPRD_POWER_AT_AM2AM_CAL_2,
1979250003Sadrian                AH9300(ah)->paprd_training_power);
1980250003Sadrian            HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
1981250003Sadrian                "%s[%d] reg %08x = 0x%08x\n", __func__,
1982250003Sadrian                __LINE__, (unsigned) AR_PHY_PAPRD_CTRL1_B2,
1983250003Sadrian                OS_REG_READ(ah, AR_PHY_PAPRD_CTRL1_B2));
1984250003Sadrian        }
1985250003Sadrian    }
1986250003Sadrian    /*ar9300_enable_paprd(ah, AH_TRUE);*/
1987250003Sadrian}
1988250003Sadrian
1989250003SadrianHAL_STATUS ar9300_paprd_setup_gain_table(struct ath_hal *ah, int chain_num)
1990250003Sadrian{
1991250003Sadrian    unsigned int i, desired_gain, gain_index;
1992250003Sadrian    HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
1993250003Sadrian        "Run papredistortion single table algorithm:: Training power = %d\n",
1994250003Sadrian        AH9300(ah)->paprd_training_power / 2);
1995250003Sadrian
1996250003Sadrian    if (AH9300(ah)->ah_tx_chainmask & (1 << chain_num)) {
1997250003Sadrian        /* this is an active chain */
1998250003Sadrian        desired_gain = ar9300_get_desired_gain_for_chain(
1999250003Sadrian            ah, chain_num, AH9300(ah)->paprd_training_power);
2000250003Sadrian        /* find out gain index */
2001250003Sadrian        gain_index = 0;
2002250003Sadrian
2003250003Sadrian        for (i = 0; i < 32; i++) {
2004250003Sadrian            if (AH9300(ah)->paprd_gain_table_index[i] < desired_gain) {
2005250003Sadrian                gain_index = gain_index + 1;
2006250003Sadrian            } else {
2007250003Sadrian                break;
2008250003Sadrian            }
2009250003Sadrian        }
2010250003Sadrian
2011250003Sadrian        /*printf("gain_index = %d\n", gain_index);*/
2012250003Sadrian        /*ath_hal_printf(ah, "++++ gain_index = %d\n", gain_index);*/
2013250003Sadrian        ar9300_tx_force_gain(ah, gain_index);
2014250003Sadrian        if (AR_SREV_POSEIDON(ah)) {
2015250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
2016250003Sadrian                AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE, 0);
2017250003Sadrian        } else {
2018250003Sadrian            OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
2019250003Sadrian                AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE, 0);
2020250003Sadrian        }
2021250003Sadrian    }
2022250003Sadrian
2023250003Sadrian    return HAL_OK;
2024250003Sadrian}
2025250003Sadrian
2026250003Sadrianstatic HAL_BOOL ar9300_paprd_retrain_pain(struct ath_hal * ah, int * pa_in)
2027250003Sadrian{
2028250003Sadrian    int count = 0, i;
2029250003Sadrian    int capdiv_offset = 0, quick_drop_offset;
2030250003Sadrian    int capdiv2g, quick_drop;
2031250003Sadrian
2032250003Sadrian    capdiv2g = (OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF3) >> 1) & 0xF;
2033250003Sadrian    if (!AR_SREV_POSEIDON(ah)) {
2034250003Sadrian        quick_drop =
2035250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
2036250003Sadrian                AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP);
2037250003Sadrian    } else {
2038250003Sadrian        quick_drop =
2039250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
2040250003Sadrian                AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP);
2041250003Sadrian    }
2042250003Sadrian
2043250003Sadrian    if ( quick_drop != 0 ) {
2044250003Sadrian        quick_drop -= 0x40;
2045250003Sadrian    }
2046250003Sadrian    for (i = 0; i < (NUM_BIN + 1); i++) {
2047250003Sadrian        if (pa_in[i] == 1400) {
2048250003Sadrian            count++;
2049250003Sadrian        }
2050250003Sadrian    }
2051250003Sadrian
2052250003Sadrian    if (AR_SREV_POSEIDON(ah)) {
2053250003Sadrian        if ((pa_in[23] < 800) || (pa_in[23] == 1400)) {
2054250003Sadrian            if (pa_in[23] < 800) {
2055250003Sadrian                capdiv_offset = (int)((1000 - pa_in[23] + 75) / 150);
2056250003Sadrian                capdiv2g = capdiv2g + capdiv_offset;
2057250003Sadrian                if (capdiv2g > 7) {
2058250003Sadrian                    capdiv2g = 7;
2059250003Sadrian                    if (pa_in[23] < 600) {
2060250003Sadrian                        quick_drop = quick_drop + 1;
2061250003Sadrian                        if (quick_drop > 0) {
2062250003Sadrian                            quick_drop = 0;
2063250003Sadrian                        }
2064250003Sadrian                    }
2065250003Sadrian                }
2066250003Sadrian
2067250003Sadrian                OS_REG_RMW_FIELD(ah,
2068250003Sadrian                    AR_PHY_65NM_CH0_TXRF3,
2069250003Sadrian    			    AR_PHY_65NM_CH0_TXRF3_CAPDIV2G,
2070250003Sadrian    			    capdiv2g);
2071250003Sadrian
2072250003Sadrian                OS_REG_RMW_FIELD_ALT(ah,
2073250003Sadrian                    AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
2074250003Sadrian                    AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
2075250003Sadrian                    quick_drop);
2076250003Sadrian
2077250003Sadrian                return AH_TRUE;
2078250003Sadrian            } /* end of if (pa_in[23] < 800) */
2079250003Sadrian            else if (pa_in[23] == 1400) {
2080250003Sadrian                quick_drop_offset = (int)(count / 3);
2081250003Sadrian                if (quick_drop_offset > 2) {
2082250003Sadrian                    quick_drop_offset = 2;
2083250003Sadrian                }
2084250003Sadrian                quick_drop = quick_drop + quick_drop_offset;
2085250003Sadrian                capdiv2g = capdiv2g + (int)(quick_drop_offset / 2);
2086250003Sadrian                if (capdiv2g > 7) {
2087250003Sadrian                    capdiv2g = 7;
2088250003Sadrian                }
2089250003Sadrian                if (quick_drop > 0) {
2090250003Sadrian                    quick_drop = 0;
2091250003Sadrian                    capdiv2g = capdiv2g - (int)(quick_drop_offset / 1);
2092250003Sadrian    				if (capdiv2g < 0) {
2093250003Sadrian                        capdiv2g = 0;
2094250003Sadrian    				}
2095250003Sadrian                }
2096250003Sadrian                OS_REG_RMW_FIELD(ah,
2097250003Sadrian                        AR_PHY_65NM_CH0_TXRF3,
2098250003Sadrian    			        AR_PHY_65NM_CH0_TXRF3_CAPDIV2G,
2099250003Sadrian    			        capdiv2g);
2100250003Sadrian
2101250003Sadrian                OS_REG_RMW_FIELD_ALT(ah,
2102250003Sadrian                        AR_PHY_PAPRD_TRAINER_CNTL3_POSEIDON,
2103250003Sadrian        			    AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
2104250003Sadrian                        quick_drop);
2105250003Sadrian
2106250003Sadrian                return AH_TRUE;
2107250003Sadrian                /* sleep(1); */
2108250003Sadrian            } /* end of if (pa_in[23] == 1400)*/
2109250003Sadrian        } /* end of if ((pa_in[23] < 800) || (pa_in[23] == 1400)) */
2110250003Sadrian    }else if (AR_SREV_HORNET(ah)) {
2111250003Sadrian        if ((pa_in[23] < 1000) || (pa_in[23] == 1400)) {
2112250003Sadrian            if (pa_in[23] < 1000) {
2113250003Sadrian                capdiv_offset = ((1000 - pa_in[23]) / 100);
2114250003Sadrian                capdiv2g = capdiv2g + capdiv_offset;
2115250003Sadrian                if (capdiv_offset > 3) {
2116250003Sadrian                    quick_drop_offset = 1;
2117250003Sadrian                    quick_drop = quick_drop - quick_drop_offset;
2118250003Sadrian                    capdiv2g = capdiv2g + 1;
2119250003Sadrian                    if (capdiv2g > 6) {
2120250003Sadrian                        capdiv2g = 6;
2121250003Sadrian                    }
2122250003Sadrian                    if (quick_drop < -4) {
2123250003Sadrian                        quick_drop = -4;
2124250003Sadrian                    }
2125250003Sadrian                    OS_REG_RMW_FIELD(ah,
2126250003Sadrian                        AR_PHY_65NM_CH0_TXRF3,
2127250003Sadrian                        AR_PHY_65NM_CH0_TXRF3_CAPDIV2G,
2128250003Sadrian                        capdiv2g);
2129250003Sadrian                    OS_REG_RMW_FIELD_ALT(ah,
2130250003Sadrian                        AR_PHY_PAPRD_TRAINER_CNTL3,
2131250003Sadrian                        AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
2132250003Sadrian                        quick_drop);
2133250003Sadrian                    return AH_TRUE;
2134250003Sadrian                } else {
2135250003Sadrian                    capdiv2g = capdiv2g + capdiv_offset;
2136250003Sadrian                    if (capdiv2g > 6) {
2137250003Sadrian                        capdiv2g = 6;
2138250003Sadrian                    }
2139250003Sadrian                    if (quick_drop < -4) {
2140250003Sadrian                        quick_drop = -4;
2141250003Sadrian                    }
2142250003Sadrian                    OS_REG_RMW_FIELD(ah,
2143250003Sadrian                        AR_PHY_65NM_CH0_TXRF3,
2144250003Sadrian                        AR_PHY_65NM_CH0_TXRF3_CAPDIV2G,
2145250003Sadrian                        capdiv2g);
2146250003Sadrian                    OS_REG_RMW_FIELD_ALT(ah,
2147250003Sadrian                        AR_PHY_PAPRD_TRAINER_CNTL3,
2148250003Sadrian                        AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
2149250003Sadrian                        quick_drop);
2150250003Sadrian                    return AH_TRUE;
2151250003Sadrian                }
2152250003Sadrian            } /* end of if (PA_in[23] < 1000) */
2153250003Sadrian            else if (pa_in[23] == 1400) {
2154250003Sadrian                if (count > 3) {
2155250003Sadrian                    quick_drop_offset = 1;
2156250003Sadrian                    quick_drop = quick_drop + quick_drop_offset;
2157250003Sadrian                    capdiv2g = capdiv2g - (count / 4);
2158250003Sadrian                    if (capdiv2g < 0) {
2159250003Sadrian                        capdiv2g = 0;
2160250003Sadrian                    }
2161250003Sadrian                    if (quick_drop > -2) {
2162250003Sadrian                        quick_drop = -2;
2163250003Sadrian                    }
2164250003Sadrian                    OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_TXRF3,
2165250003Sadrian                        AR_PHY_65NM_CH0_TXRF3_CAPDIV2G,
2166250003Sadrian                        capdiv2g);
2167250003Sadrian                    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
2168250003Sadrian                        AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
2169250003Sadrian                        quick_drop);
2170250003Sadrian                    return AH_TRUE;
2171250003Sadrian                } else {
2172250003Sadrian                    capdiv2g = capdiv2g - 1;
2173250003Sadrian                    if (capdiv2g < 0) {
2174250003Sadrian                        capdiv2g = 0;
2175250003Sadrian                    }
2176250003Sadrian                    OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_TXRF3,
2177250003Sadrian                        AR_PHY_65NM_CH0_TXRF3_CAPDIV2G,
2178250003Sadrian                        capdiv2g);
2179250003Sadrian                    OS_REG_RMW_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
2180250003Sadrian                        AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
2181250003Sadrian                        quick_drop);
2182250003Sadrian                    return AH_TRUE;
2183250003Sadrian                }
2184250003Sadrian            } /* end of if (PA_in[23] == 1400)*/
2185250003Sadrian        } /* end of if ((PA_in[23] < 1000) || (PA_in[23] == 1400)) */
2186250003Sadrian    }
2187250003Sadrian
2188250003Sadrian    return AH_FALSE;
2189250003Sadrian}
2190250003Sadrian
2191250008SadrianHAL_STATUS ar9300_paprd_create_curve(struct ath_hal * ah,
2192250008Sadrian  struct ieee80211_channel * chan, int chain_num)
2193250003Sadrian{
2194250003Sadrian    int status = 0;
2195250003Sadrian    u_int32_t *pa_table, small_signal_gain;
2196250003Sadrian    int pa_in[NUM_BIN + 1];
2197250003Sadrian
2198250003Sadrian    if (AH9300(ah)->ah_tx_chainmask & (1 << chain_num)) {
2199250003Sadrian        pa_table = &AH9300(ah)->pa_table[chain_num][0];
2200250003Sadrian        /* Compute PA table and gain index */
2201250003Sadrian        status = ar9300_create_pa_curve(ah, &pa_table[0], &small_signal_gain,
2202250003Sadrian                    &pa_in[0]);
2203250003Sadrian
2204250003Sadrian		if (AR_SREV_WASP(ah)) {
2205250003Sadrian			OS_DELAY(1000);
2206250003Sadrian		}
2207250003Sadrian
2208250003Sadrian        if (status != 0) {
2209250003Sadrian            ath_hal_printf(ah, "ERROR:: paprd failed with error code = %d\n",
2210250003Sadrian                status);
2211250003Sadrian            return -1;
2212250003Sadrian        }
2213250003Sadrian        AH9300(ah)->small_signal_gain[chain_num] = small_signal_gain;
2214250003Sadrian
2215250003Sadrian        if (AR_SREV_POSEIDON(ah) || AR_SREV_HORNET(ah)) {
2216250003Sadrian            if (ar9300_paprd_retrain_pain(ah, pa_in)) {
2217250003Sadrian                /* need re-train PAPRD */
2218250003Sadrian                return HAL_EINPROGRESS;
2219250003Sadrian		    }
2220250003Sadrian        }
2221250003Sadrian    }
2222250003Sadrian    return HAL_OK;
2223250003Sadrian}
2224250003Sadrian
2225250008Sadrianint ar9300_paprd_init_table(struct ath_hal *ah, struct ieee80211_channel * chan)
2226250003Sadrian{
2227250008Sadrian    HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
2228250008Sadrian
2229250008Sadrian    if ((AR_SREV_WASP(ah) && IS_CHAN_5GHZ(ichan)) ||
2230250003Sadrian         ar9300_paprd_setup_single_table(ah, chan)) {
2231250003Sadrian        goto FAIL;
2232250003Sadrian    }
2233250003Sadrian    OS_MEMZERO(AH9300(ah)->paprd_gain_table_entries,
2234250003Sadrian        sizeof(AH9300(ah)->paprd_gain_table_entries));
2235250003Sadrian    OS_MEMZERO(AH9300(ah)->paprd_gain_table_index,
2236250003Sadrian        sizeof(AH9300(ah)->paprd_gain_table_index));
2237250003Sadrian
2238250003Sadrian    ar9300_gain_table_entries(ah);
2239250003Sadrian    return 0;
2240250003SadrianFAIL:
2241250003Sadrian    return -1;
2242250003Sadrian}
2243250003Sadrian
2244250003Sadrianint ar9300_paprd_is_done(struct ath_hal *ah)
2245250003Sadrian{
2246250003Sadrian    int temp, agc2_pwr;
2247250003Sadrian
2248250003Sadrian    /*field_read("BB_paprd_trainer_stat1.paprd_train_done", &temp);*/
2249250003Sadrian    if (!AR_SREV_POSEIDON(ah)) {
2250250003Sadrian        temp =
2251250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
2252250003Sadrian                AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
2253250003Sadrian
2254250003Sadrian        if (temp == 0x1) {
2255250003Sadrian            agc2_pwr =
2256250003Sadrian                OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
2257250003Sadrian                   AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR);
2258250003Sadrian
2259250003Sadrian            HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2260250003Sadrian                   "%s AGC2_PWR=0x%2x Training done=0x%2x\n",
2261250003Sadrian                   __func__, agc2_pwr, temp);
2262250003Sadrian
2263250003Sadrian            /* Retrain if agc2_pwr is not in ideal range */
2264250003Sadrian            if (agc2_pwr <= AH_PAPRD_IDEAL_AGC2_PWR_RANGE) {
2265250003Sadrian                temp = 0;
2266250003Sadrian            }
2267250003Sadrian		}
2268250003Sadrian    } else {
2269250003Sadrian        temp =
2270250003Sadrian            OS_REG_READ_FIELD_ALT(ah, AR_PHY_PAPRD_TRAINER_STAT1_POSEIDON,
2271250003Sadrian                AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
2272250003Sadrian    }
2273250003Sadrian    if (!temp) {
2274250003Sadrian        /*ath_hal_printf(ah, "%s[%d] PAPRD TEMp Error\n", __func__, __LINE__);*/
2275250003Sadrian    }
2276250003Sadrian
2277250003Sadrian    return temp;
2278250003Sadrian}
2279250003Sadrian
2280250003Sadrian/*
2281250003Sadrian * ar9300_paprd_dec_tx_pwr
2282250003Sadrian *
2283250003Sadrian * This function do decrease tx power if Paprd is off or train failed.
2284250003Sadrian */
2285250003Sadrianvoid
2286250003Sadrianar9300_paprd_dec_tx_pwr(struct ath_hal *ah)
2287250003Sadrian{
2288250003Sadrian    u_int32_t   pwr_temp, pwr_reg;
2289250003Sadrian    int         i, loop_cnt;
2290250003Sadrian    struct ar9300_paprd_pwr_adjust  *p_item;
2291250003Sadrian    struct ath_hal_9300 *ahp = AH9300(ah);
2292250003Sadrian
2293250003Sadrian    if (AR_SREV_POSEIDON(ah)) {
2294250003Sadrian        loop_cnt =
2295250003Sadrian        (sizeof(ar9300_paprd_pwr_adj_array) /
2296250003Sadrian            sizeof(struct ar9300_paprd_pwr_adjust));
2297250003Sadrian        for (i = 0; i < loop_cnt; i++ )
2298250003Sadrian        {
2299250003Sadrian            p_item = &ar9300_paprd_pwr_adj_array[i];
2300250003Sadrian            pwr_reg = OS_REG_READ(ah, p_item->reg_addr);
2301250003Sadrian            pwr_temp = ahp->ah_default_tx_power[p_item->target_rate];
2302250003Sadrian            pwr_temp -= (p_item->sub_db * 2);
2303250003Sadrian            pwr_temp = pwr_temp << p_item->reg_mask_offset;
2304250003Sadrian            pwr_temp |= (pwr_reg&~(p_item->reg_mask <<p_item->reg_mask_offset));
2305250003Sadrian
2306250003Sadrian            if (pwr_temp != pwr_reg)
2307250003Sadrian            {
2308250003Sadrian                OS_REG_WRITE(ah, p_item->reg_addr, pwr_temp);
2309250003Sadrian            }
2310250003Sadrian        }
2311250003Sadrian    }
2312250003Sadrian    return;
2313250003Sadrian}
2314250003Sadrian
2315250003Sadrianint ar9300_paprd_thermal_send(struct ath_hal *ah)
2316250003Sadrian{
2317250003Sadrian    if (AR_SREV_HORNET(ah)) {
2318250003Sadrian        return OS_REG_READ(ah, AR_TFCNT);
2319250003Sadrian    } else {
2320250003Sadrian        return 1;
2321250003Sadrian    }
2322250003Sadrian}
2323250003Sadrian
2324250003Sadrian#if 0
2325250003Sadrianvoid ar9300_paprd_test_prints(struct ath_hal *ah)
2326250003Sadrian{
2327250003Sadrian    u_int32_t i, reg = 0;
2328250003Sadrian
2329250003Sadrian    HALDEBUG(NULL, HAL_DEBUG_CALIBRATE, "=====ar9300_paprd_test_prints=======\n");
2330250003Sadrian    /*printf("=====ar9300_paprd_test_prints=======\n");*/
2331250003Sadrian    HALDEBUG(NULL, HAL_DEBUG_CALIBRATE, "BB_paprd_ctrl0_b0 = 0x%08x\n",
2332250003Sadrian        OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B0));
2333250003Sadrian    /*
2334250003Sadrian     * printf(
2335250003Sadrian     *     "BB_paprd_ctrl0_b0 = 0x%08x\n",
2336250003Sadrian     *     OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B0));
2337250003Sadrian     */
2338250003Sadrian    if (!AR_SREV_POSEIDON(ah) && !AR_SREV_HORNET(ah)) {
2339250003Sadrian        HALDEBUG(NULL, HAL_DEBUG_CALIBRATE, "BB_paprd_ctrl0_b1 = 0x%08x\n",
2340250003Sadrian            OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B1));
2341250003Sadrian        /*
2342250003Sadrian         * printf(
2343250003Sadrian         *     "BB_paprd_ctrl0_b1 = 0x%08x\n",
2344250003Sadrian         *     OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B1));
2345250003Sadrian         */
2346250003Sadrian        HALDEBUG(NULL, HAL_DEBUG_CALIBRATE, "BB_paprd_ctrl0_b2 = 0x%08x\n",
2347250003Sadrian            OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B2));
2348250003Sadrian        /*
2349250003Sadrian         * printf(
2350250003Sadrian         *     "BB_paprd_ctrl0_b2 = 0x%08x\n",
2351250003Sadrian         *     OS_REG_READ(ah, AR_PHY_PAPRD_CTRL0_B2));
2352250003Sadrian         */
2353250003Sadrian    }
2354250003Sadrian
2355250003Sadrian    reg = AR_PHY_PAPRD_MEM_TAB_B0;
2356250003Sadrian    HALDEBUG(NULL, HAL_DEBUG_CALIBRATE,
2357250003Sadrian        "%s[%d] reg %08lx small_signal_gain ch0 0x%08x\n", __func__, __LINE__,
2358250003Sadrian        AR_PHY_PA_GAIN123_B0, OS_REG_READ(ah, AR_PHY_PA_GAIN123_B0));
2359250003Sadrian    /*
2360250003Sadrian     * printf(
2361250003Sadrian     *     "%s[%d] reg %08lx small_signal_gain ch0 0x%08x\n",
2362250003Sadrian     *     __func__,  __LINE__, AR_PHY_PA_GAIN123_B0,
2363250003Sadrian     *     OS_REG_READ(ah, AR_PHY_PA_GAIN123_B0));
2364250003Sadrian     */
2365250003Sadrian
2366250003Sadrian    for (i = 0; i < 24; i++) {
2367250003Sadrian        HALDEBUG(NULL, HAL_DEBUG_CALIBRATE, "%s[%d] reg %08x = 0x%08x\n",
2368250003Sadrian            __func__, __LINE__, reg, OS_REG_READ(ah, reg));
2369250003Sadrian        /*
2370250003Sadrian         * printf(
2371250003Sadrian         *     "%s[%d] reg %08x = 0x%08x\n", __func__, __LINE__,
2372250003Sadrian         *     reg, OS_REG_READ(ah, reg));
2373250003Sadrian         */
2374250003Sadrian        reg = reg + 4;
2375250003Sadrian    }
2376250003Sadrian
2377250003Sadrian    ar9300_paprd_debug_print(ah);
2378250003Sadrian    HALDEBUG(NULL, HAL_DEBUG_CALIBRATE,
2379250003Sadrian        "=====ar9300_paprd_test_prints end=======\n");
2380250003Sadrian    /*printf("=====ar9300_paprd_test_prints end=======\n");*/
2381250003Sadrian
2382250003Sadrian    if (!AR_SREV_POSEIDON(ah)) {
2383250003Sadrian        reg = AR_PHY_PAPRD_MEM_TAB_B1;
2384250003Sadrian        printf("%s[%d] reg %08lx small_signal_gain ch1 0x%08x\n",
2385250003Sadrian            __func__, __LINE__,
2386250003Sadrian            AR_PHY_PA_GAIN123_B1, OS_REG_READ(ah, AR_PHY_PA_GAIN123_B1));
2387250003Sadrian        for (i = 0; i < 24; i++) {
2388250003Sadrian            OS_REG_WRITE(ah, reg, paprd_table_val[i]);
2389250003Sadrian            HALDEBUG(NULL, HAL_DEBUG_CALIBRATE, "%s[%d] reg %08x = 0x%08x\n",
2390250003Sadrian                __func__, __LINE__, reg, OS_REG_READ(ah, reg));
2391250003Sadrian            printf("%s[%d] reg %08x = 0x%08x\n", __func__, __LINE__, reg,
2392250003Sadrian                OS_REG_READ(ah, reg));
2393250003Sadrian            reg = reg + 4;
2394250003Sadrian        }
2395250003Sadrian
2396250003Sadrian        reg = AR_PHY_PAPRD_MEM_TAB_B2;
2397250003Sadrian        printf("%s[%d] reg %08lx small_signal_gain ch2 0x%08x\n",
2398250003Sadrian            __func__, __LINE__,
2399250003Sadrian            AR_PHY_PA_GAIN123_B2, OS_REG_READ(ah, AR_PHY_PA_GAIN123_B2));
2400250003Sadrian    }
2401250003Sadrian}
2402250003Sadrian#endif
2403250003Sadrian
2404250003Sadrian#else
2405250003Sadrianint
2406250003Sadrianar9300_paprd_init_table(struct ath_hal *ah, HAL_CHANNEL * chan)
2407250003Sadrian{
2408250003Sadrian    return 0;
2409250003Sadrian}
2410250003Sadrian
2411250003SadrianHAL_STATUS
2412250003Sadrianar9300_paprd_setup_gain_table(struct ath_hal * ah, int chain_num)
2413250003Sadrian{
2414250003Sadrian    return HAL_OK;
2415250003Sadrian}
2416250003Sadrian
2417250003SadrianHAL_STATUS
2418250003Sadrianar9300_paprd_create_curve(struct ath_hal * ah, HAL_CHANNEL * chan,
2419250003Sadrian    int chain_num)
2420250003Sadrian{
2421250003Sadrian    return HAL_OK;
2422250003Sadrian}
2423250003Sadrian
2424250003Sadrianint
2425250003Sadrianar9300_paprd_is_done(struct ath_hal *ah)
2426250003Sadrian{
2427250003Sadrian    return 0;
2428250003Sadrian}
2429250003Sadrian
2430250003Sadrianvoid
2431250003Sadrianar9300_enable_paprd(struct ath_hal *ah, HAL_BOOL enable_flag, HAL_CHANNEL * chan)
2432250003Sadrian{
2433250003Sadrian    return;
2434250003Sadrian}
2435250003Sadrian
2436250003Sadrianvoid
2437250003Sadrianar9300_populate_paprd_single_table(struct ath_hal *ah, HAL_CHANNEL * chan,
2438250003Sadrian    int chain_num)
2439250003Sadrian{
2440250003Sadrian    return;
2441250003Sadrian}
2442250003Sadrian
2443250003Sadrianvoid
2444250003Sadrianar9300_paprd_dec_tx_pwr(struct ath_hal *ah)
2445250003Sadrian{
2446250003Sadrian    return;
2447250003Sadrian}
2448250003Sadrian
2449250003Sadrianint ar9300_paprd_thermal_send(struct ath_hal *ah)
2450250003Sadrian{
2451250003Sadrian    return 1;
2452250003Sadrian}
2453250003Sadrian#endif                          /* ATH_SUPPORT_PAPRD */
2454