ar9300_reset.c revision 250007
1/*
2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
15 */
16
17
18
19#include "opt_ah.h"
20
21#ifdef AH_SUPPORT_AR9300
22
23#include "ah.h"
24#include "ah_internal.h"
25#include "ah_devid.h"
26#include "ah_desc.h"
27
28#include "ar9300.h"
29#include "ar9300reg.h"
30#include "ar9300phy.h"
31#include "ar9300desc.h"
32
33#define FIX_NOISE_FLOOR     1
34
35
36
37/* Additional Time delay to wait after activiting the Base band */
38#define BASE_ACTIVATE_DELAY         100     /* usec */
39#define RTC_PLL_SETTLE_DELAY        100     /* usec */
40#define COEF_SCALE_S                24
41#define HT40_CHANNEL_CENTER_SHIFT   10      /* MHz      */
42
43#define DELPT 32
44
45extern  HAL_BOOL ar9300_reset_tx_queue(struct ath_hal *ah, u_int q);
46extern  u_int32_t ar9300_num_tx_pending(struct ath_hal *ah, u_int q);
47
48
49#define MAX_MEASUREMENT 8
50#define MAXIQCAL 3
51struct coeff_t {
52    int32_t mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL];
53    int32_t phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL];
54    int32_t iqc_coeff[2];
55    int last_nmeasurement;
56    HAL_BOOL last_cal;
57};
58
59static HAL_BOOL ar9300_tx_iq_cal_hw_run(struct ath_hal *ah);
60static void ar9300_tx_iq_cal_post_proc(struct ath_hal *ah,HAL_CHANNEL_INTERNAL *ichan,
61       int iqcal_idx, int max_iqcal, HAL_BOOL is_cal_reusable, HAL_BOOL apply_last_corr);
62static void ar9300_tx_iq_cal_outlier_detection(struct ath_hal *ah,HAL_CHANNEL_INTERNAL *ichan,
63       u_int32_t num_chains, struct coeff_t *coeff, HAL_BOOL is_cal_reusable);
64#if ATH_SUPPORT_CAL_REUSE
65static void ar9300_tx_iq_cal_apply(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan);
66#endif
67
68
69static inline void ar9300_prog_ini(struct ath_hal *ah, struct ar9300_ini_array *ini_arr, int column);
70static inline void ar9300_set_rf_mode(struct ath_hal *ah, HAL_CHANNEL *chan);
71static inline HAL_BOOL ar9300_init_cal(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL skip_if_none, HAL_BOOL apply_last_corr);
72static inline void ar9300_init_user_settings(struct ath_hal *ah);
73
74#ifdef HOST_OFFLOAD
75/*
76 * For usb offload solution, some USB registers must be tuned
77 * to gain better stability/performance but these registers
78 * might be changed while doing wlan reset so do this here
79 */
80#define WAR_USB_DISABLE_PLL_LOCK_DETECT(__ah) \
81do { \
82    if (AR_SREV_HORNET(__ah) || AR_SREV_WASP(__ah)) { \
83        volatile u_int32_t *usb_ctrl_r1 = (u_int32_t *) 0xb8116c84; \
84        volatile u_int32_t *usb_ctrl_r2 = (u_int32_t *) 0xb8116c88; \
85        *usb_ctrl_r1 = (*usb_ctrl_r1 & 0xffefffff); \
86        *usb_ctrl_r2 = (*usb_ctrl_r2 & 0xfc1fffff) | (1 << 21) | (3 << 22); \
87    } \
88} while (0)
89#else
90#define WAR_USB_DISABLE_PLL_LOCK_DETECT(__ah)
91#endif
92
93static inline void
94ar9300_attach_hw_platform(struct ath_hal *ah)
95{
96    struct ath_hal_9300 *ahp = AH9300(ah);
97
98    ahp->ah_hwp = HAL_TRUE_CHIP;
99    return;
100}
101
102/* Adjust various register settings based on half/quarter rate clock setting.
103 * This includes: +USEC, TX/RX latency,
104 *                + IFS params: slot, eifs, misc etc.
105 * SIFS stays the same.
106 */
107static void
108ar9300_set_ifs_timing(struct ath_hal *ah, HAL_CHANNEL *chan)
109{
110    u_int32_t tx_lat, rx_lat, usec, slot, regval, eifs;
111
112    regval = OS_REG_READ(ah, AR_USEC);
113    regval &= ~(AR_USEC_RX_LATENCY | AR_USEC_TX_LATENCY | AR_USEC_USEC);
114    if (IS_CHAN_HALF_RATE(chan)) { /* half rates */
115        slot = ar9300_mac_to_clks(ah, AR_SLOT_HALF);
116        eifs = ar9300_mac_to_clks(ah, AR_EIFS_HALF);
117        if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { /* fast clock */
118            rx_lat = SM(AR_RX_LATENCY_HALF_FAST_CLOCK, AR_USEC_RX_LATENCY);
119            tx_lat = SM(AR_TX_LATENCY_HALF_FAST_CLOCK, AR_USEC_TX_LATENCY);
120            usec = SM(AR_USEC_HALF_FAST_CLOCK, AR_USEC_USEC);
121        } else {
122            rx_lat = SM(AR_RX_LATENCY_HALF, AR_USEC_RX_LATENCY);
123            tx_lat = SM(AR_TX_LATENCY_HALF, AR_USEC_TX_LATENCY);
124            usec = SM(AR_USEC_HALF, AR_USEC_USEC);
125        }
126    } else { /* quarter rate */
127        slot = ar9300_mac_to_clks(ah, AR_SLOT_QUARTER);
128        eifs = ar9300_mac_to_clks(ah, AR_EIFS_QUARTER);
129        if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { /* fast clock */
130            rx_lat = SM(AR_RX_LATENCY_QUARTER_FAST_CLOCK, AR_USEC_RX_LATENCY);
131            tx_lat = SM(AR_TX_LATENCY_QUARTER_FAST_CLOCK, AR_USEC_TX_LATENCY);
132            usec = SM(AR_USEC_QUARTER_FAST_CLOCK, AR_USEC_USEC);
133        } else {
134            rx_lat = SM(AR_RX_LATENCY_QUARTER, AR_USEC_RX_LATENCY);
135            tx_lat = SM(AR_TX_LATENCY_QUARTER, AR_USEC_TX_LATENCY);
136            usec = SM(AR_USEC_QUARTER, AR_USEC_USEC);
137        }
138    }
139
140    OS_REG_WRITE(ah, AR_USEC, (usec | regval | tx_lat | rx_lat));
141    OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, slot);
142    OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS, eifs);
143}
144
145
146/*
147 * This inline function configures the chip either
148 * to encrypt/decrypt management frames or pass thru
149 */
150static inline void
151ar9300_init_mfp(struct ath_hal * ah)
152{
153    u_int32_t   mfpcap, mfp_qos;
154
155    ath_hal_getcapability(ah, HAL_CAP_MFP, 0, &mfpcap);
156
157    if (mfpcap == HAL_MFP_QOSDATA) {
158        /* Treat like legacy hardware. Do not touch the MFP registers. */
159        HALDEBUG(ah, HAL_DEBUG_RESET, "%s forced to use QOSDATA\n", __func__);
160        return;
161    }
162
163    /* MFP support (Sowl 1.0 or greater) */
164    if (mfpcap == HAL_MFP_HW_CRYPTO) {
165        /* configure hardware MFP support */
166        HALDEBUG(ah, HAL_DEBUG_RESET, "%s using HW crypto\n", __func__);
167        OS_REG_RMW_FIELD(ah,
168            AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT, AR_AES_MUTE_MASK1_FC_MGMT_MFP);
169        OS_REG_RMW(ah,
170            AR_PCU_MISC_MODE2, AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE,
171            AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
172        /*
173        * Mask used to construct AAD for CCMP-AES
174        * Cisco spec defined bits 0-3 as mask
175        * IEEE802.11w defined as bit 4.
176        */
177        if (ath_hal_get_mfp_qos(ah)) {
178            mfp_qos = AR_MFP_QOS_MASK_IEEE;
179        } else {
180            mfp_qos = AR_MFP_QOS_MASK_CISCO;
181        }
182        OS_REG_RMW_FIELD(ah,
183            AR_PCU_MISC_MODE2, AR_PCU_MISC_MODE2_MGMT_QOS, mfp_qos);
184    } else if (mfpcap == HAL_MFP_PASSTHRU) {
185        /* Disable en/decrypt by hardware */
186        HALDEBUG(ah, HAL_DEBUG_RESET, "%s using passthru\n", __func__);
187        OS_REG_RMW(ah,
188            AR_PCU_MISC_MODE2,
189            AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT,
190            AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
191    }
192}
193
194void
195ar9300_get_channel_centers(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
196    CHAN_CENTERS *centers)
197{
198    int8_t      extoff;
199    struct ath_hal_9300 *ahp = AH9300(ah);
200
201    if (!IS_CHAN_HT40(chan)) {
202        centers->ctl_center = centers->ext_center =
203        centers->synth_center = chan->channel;
204        return;
205    }
206
207    HALASSERT(IS_CHAN_HT40(chan));
208
209    /*
210     * In 20/40 phy mode, the center frequency is
211     * "between" the primary and extension channels.
212     */
213    if (chan->channel_flags & CHANNEL_HT40PLUS) {
214        centers->synth_center = chan->channel + HT40_CHANNEL_CENTER_SHIFT;
215        extoff = 1;
216    } else {
217        centers->synth_center = chan->channel - HT40_CHANNEL_CENTER_SHIFT;
218        extoff = -1;
219    }
220
221    centers->ctl_center =
222        centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT);
223    centers->ext_center =
224        centers->synth_center +
225        (extoff * ((ahp->ah_ext_prot_spacing == HAL_HT_EXTPROTSPACING_20) ?
226            HT40_CHANNEL_CENTER_SHIFT : 15));
227}
228
229/*
230 * Read the noise-floor values from the HW.
231 * Specifically, read the minimum clear-channel assessment value for
232 * each chain, for both the control and extension channels.
233 * (The received power level during clear-channel periods is the
234 * noise floor.)
235 * These noise floor values computed by the HW will be stored in the
236 * NF history buffer.
237 * The HW sometimes produces bogus NF values.  To avoid using these
238 * bogus values, the NF data is (a) range-limited, and (b) filtered.
239 * However, this data-processing is done when reading the NF values
240 * out of the history buffer.  The history buffer stores the raw values.
241 * This allows the NF history buffer to be used to check for interference.
242 * A single high NF reading might be a bogus HW value, but if the NF
243 * readings are consistently high, it must be due to interference.
244 * This is the purpose of storing raw NF values in the history buffer,
245 * rather than processed values.  By looking at a history of NF values
246 * that have not been range-limited, we can check if they are consistently
247 * high (due to interference).
248 */
249#define AH_NF_SIGN_EXTEND(nf)      \
250    ((nf) & 0x100) ?               \
251        0 - (((nf) ^ 0x1ff) + 1) : \
252        (nf)
253void
254ar9300_upload_noise_floor(struct ath_hal *ah, int is_2g,
255    int16_t nfarray[NUM_NF_READINGS])
256{
257    int16_t nf;
258    int chan, chain;
259    u_int32_t regs[NUM_NF_READINGS] = {
260        /* control channel */
261        AR_PHY_CCA_0,     /* chain 0 */
262        AR_PHY_CCA_1,     /* chain 1 */
263        AR_PHY_CCA_2,     /* chain 2 */
264        /* extension channel */
265        AR_PHY_EXT_CCA,   /* chain 0 */
266        AR_PHY_EXT_CCA_1, /* chain 1 */
267        AR_PHY_EXT_CCA_2, /* chain 2 */
268    };
269    u_int8_t chainmask;
270
271    /*
272     * Within a given channel (ctl vs. ext), the CH0, CH1, and CH2
273     * masks and shifts are the same, though they differ for the
274     * control vs. extension channels.
275     */
276    u_int32_t masks[2] = {
277        AR_PHY_MINCCA_PWR,     /* control channel */
278        AR_PHY_EXT_MINCCA_PWR, /* extention channel */
279    };
280    u_int8_t shifts[2] = {
281        AR_PHY_MINCCA_PWR_S,     /* control channel */
282        AR_PHY_EXT_MINCCA_PWR_S, /* extention channel */
283    };
284
285    /*
286     * Force NF calibration for all chains.
287     */
288    if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) {
289        chainmask = 0x01;
290    } else if (AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah)) {
291        chainmask = 0x03;
292    } else {
293        chainmask = 0x07;
294    }
295
296    for (chan = 0; chan < 2 /*ctl,ext*/; chan++) {
297        for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
298            int i;
299
300            if (!((chainmask >> chain) & 0x1)) {
301                continue;
302            }
303            i = chan * AR9300_MAX_CHAINS + chain;
304            nf = (OS_REG_READ(ah, regs[i]) & masks[chan]) >> shifts[chan];
305            nfarray[i] = AH_NF_SIGN_EXTEND(nf);
306        }
307    }
308}
309
310/* ar9300_get_min_cca_pwr -
311 * Used by the scan function for a quick read of the noise floor.
312 * This is used to detect presence of CW interference such as video bridge.
313 * The noise floor is assumed to have been already started during reset
314 * called during channel change. The function checks if the noise floor
315 * reading is done. In case it has been done, it reads the noise floor value.
316 * If the noise floor calibration has not been finished, it assumes this is
317 * due to presence of CW interference an returns a high value for noise floor,
318 * derived from the CW interference threshold + margin fudge factor.
319 */
320#define BAD_SCAN_NF_MARGIN (30)
321int16_t ar9300_get_min_cca_pwr(struct ath_hal *ah)
322{
323    int16_t nf;
324    struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
325
326    if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0) {
327        nf = MS(OS_REG_READ(ah, AR_PHY_CCA_0), AR9280_PHY_MINCCA_PWR);
328        if (nf & 0x100) {
329            nf = 0 - ((nf ^ 0x1ff) + 1);
330        }
331    } else {
332        /* NF calibration is not done, assume CW interference */
333        nf = ahpriv->nfp->nominal + ahpriv->nf_cw_int_delta +
334            BAD_SCAN_NF_MARGIN;
335    }
336    return nf;
337}
338
339
340/*
341 * Noise Floor values for all chains.
342 * Most recently updated values from the NF history buffer are used.
343 */
344void ar9300_chain_noise_floor(struct ath_hal *ah, int16_t *nf_buf,
345    HAL_CHANNEL *chan, int is_scan)
346{
347    struct ath_hal_9300 *ahp = AH9300(ah);
348    int i, nf_hist_len, recent_nf_index = 0;
349    HAL_NFCAL_HIST_FULL *h;
350    u_int8_t rx_chainmask = ahp->ah_rx_chainmask | (ahp->ah_rx_chainmask << 3);
351    HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
352    HALASSERT(ichan);
353
354#ifdef ATH_NF_PER_CHAN
355    /* Fill 0 if valid internal channel is not found */
356    if (ichan == AH_NULL) {
357        OS_MEMZERO(nf_buf, sizeof(nf_buf[0])*NUM_NF_READINGS);
358        return;
359    }
360    h = &ichan->nf_cal_hist;
361    nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
362#else
363    /*
364     * If a scan is not in progress, then the most recent value goes
365     * into ahpriv->nf_cal_hist.  If a scan is in progress, then
366     * the most recent value goes into ichan->nf_cal_hist.
367     * Thus, return the value from ahpriv->nf_cal_hist if there's
368     * no scan, and if the specified channel is the current channel.
369     * Otherwise, return the noise floor from ichan->nf_cal_hist.
370     */
371    if ((!is_scan) && chan->channel == AH_PRIVATE(ah)->ah_curchan->channel) {
372        h = &AH_PRIVATE(ah)->nf_cal_hist;
373        nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
374    } else {
375        /* Fill 0 if valid internal channel is not found */
376        if (ichan == AH_NULL) {
377            OS_MEMZERO(nf_buf, sizeof(nf_buf[0])*NUM_NF_READINGS);
378            return;
379        }
380       /*
381        * It is okay to treat a HAL_NFCAL_HIST_SMALL struct as if it were a
382        * HAL_NFCAL_HIST_FULL struct, as long as only the index 0 of the
383        * nf_cal_buffer is used (nf_cal_buffer[0][0:NUM_NF_READINGS-1])
384        */
385        h = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist;
386        nf_hist_len = HAL_NF_CAL_HIST_LEN_SMALL;
387    }
388#endif
389    /* Get most recently updated values from nf cal history buffer */
390    recent_nf_index =
391        (h->base.curr_index) ? h->base.curr_index - 1 : nf_hist_len - 1;
392
393    for (i = 0; i < NUM_NF_READINGS; i++) {
394        /* Fill 0 for unsupported chains */
395        if (!(rx_chainmask & (1 << i))) {
396            nf_buf[i] = 0;
397            continue;
398        }
399        nf_buf[i] = h->nf_cal_buffer[recent_nf_index][i];
400    }
401}
402
403
404/*
405 * Pick up the medium one in the noise floor buffer and update the
406 * corresponding range for valid noise floor values
407 */
408static int16_t
409ar9300_get_nf_hist_mid(struct ath_hal *ah, HAL_NFCAL_HIST_FULL *h, int reading,
410    int hist_len)
411{
412    int16_t nfval;
413    int16_t sort[HAL_NF_CAL_HIST_LEN_FULL]; /* upper bound for hist_len */
414    int i, j;
415
416    for (i = 0; i < hist_len; i++) {
417        sort[i] = h->nf_cal_buffer[i][reading];
418        HALDEBUG(ah, HAL_DEBUG_NF_CAL,
419            "nf_cal_buffer[%d][%d] = %d\n", i, reading, (int)sort[i]);
420    }
421    for (i = 0; i < hist_len - 1; i++) {
422        for (j = 1; j < hist_len - i; j++) {
423            if (sort[j] > sort[j - 1]) {
424                nfval = sort[j];
425                sort[j] = sort[j - 1];
426                sort[j - 1] = nfval;
427            }
428        }
429    }
430    nfval = sort[(hist_len - 1) >> 1];
431
432    return nfval;
433}
434
435static int16_t ar9300_limit_nf_range(struct ath_hal *ah, int16_t nf)
436{
437    if (nf < AH_PRIVATE(ah)->nfp->min) {
438        return AH_PRIVATE(ah)->nfp->nominal;
439    } else if (nf > AH_PRIVATE(ah)->nfp->max) {
440        return AH_PRIVATE(ah)->nfp->max;
441    }
442    return nf;
443}
444
445#ifndef ATH_NF_PER_CHAN
446inline static void
447ar9300_reset_nf_hist_buff(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
448{
449    HAL_CHAN_NFCAL_HIST *h = &ichan->nf_cal_hist;
450    HAL_NFCAL_HIST_FULL *home = &AH_PRIVATE(ah)->nf_cal_hist;
451    int i;
452
453    /*
454     * Copy the value for the channel in question into the home-channel
455     * NF history buffer.  The channel NF is probably a value filled in by
456     * a prior background channel scan, but if no scan has been done then
457     * it is the nominal noise floor filled in by ath_hal_init_NF_buffer
458     * for this chip and the channel's band.
459     * Replicate this channel NF into all entries of the home-channel NF
460     * history buffer.
461     * If the channel NF was filled in by a channel scan, it has not had
462     * bounds limits applied to it yet - do so now.  It is important to
463     * apply bounds limits to the priv_nf value that gets loaded into the
464     * WLAN chip's min_cca_pwr register field.  It is also necessary to
465     * apply bounds limits to the nf_cal_buffer[] elements.  Since we are
466     * replicating a single NF reading into all nf_cal_buffer elements,
467     * if the single reading were above the CW_INT threshold, the CW_INT
468     * check in ar9300_get_nf would immediately conclude that CW interference
469     * is present, even though we're not supposed to set CW_INT unless
470     * NF values are _consistently_ above the CW_INT threshold.
471     * Applying the bounds limits to the nf_cal_buffer contents fixes this
472     * problem.
473     */
474    for (i = 0; i < NUM_NF_READINGS; i ++) {
475        int j;
476        int16_t nf;
477        /*
478         * No need to set curr_index, since it already has a value in
479         * the range [0..HAL_NF_CAL_HIST_LEN_FULL), and all nf_cal_buffer
480         * values will be the same.
481         */
482        nf = ar9300_limit_nf_range(ah, h->nf_cal_buffer[0][i]);
483        for (j = 0; j < HAL_NF_CAL_HIST_LEN_FULL; j++) {
484            home->nf_cal_buffer[j][i] = nf;
485        }
486        AH_PRIVATE(ah)->nf_cal_hist.base.priv_nf[i] = nf;
487    }
488}
489#endif
490
491/*
492 *  Update the noise floor buffer as a ring buffer
493 */
494static int16_t
495ar9300_update_nf_hist_buff(struct ath_hal *ah, HAL_NFCAL_HIST_FULL *h,
496   int16_t *nfarray, int hist_len)
497{
498    int i, nr;
499    int16_t nf_no_lim_chain0;
500
501    nf_no_lim_chain0 = ar9300_get_nf_hist_mid(ah, h, 0, hist_len);
502
503    HALDEBUG(ah, HAL_DEBUG_NF_CAL, "%s[%d] BEFORE\n", __func__, __LINE__);
504    for (nr = 0; nr < HAL_NF_CAL_HIST_LEN_FULL; nr++) {
505        for (i = 0; i < NUM_NF_READINGS; i++) {
506            HALDEBUG(ah, HAL_DEBUG_NF_CAL,
507                "nf_cal_buffer[%d][%d] = %d\n",
508                nr, i, (int)h->nf_cal_buffer[nr][i]);
509        }
510    }
511    for (i = 0; i < NUM_NF_READINGS; i++) {
512        h->nf_cal_buffer[h->base.curr_index][i] = nfarray[i];
513        h->base.priv_nf[i] = ar9300_limit_nf_range(
514            ah, ar9300_get_nf_hist_mid(ah, h, i, hist_len));
515    }
516    HALDEBUG(ah, HAL_DEBUG_NF_CAL, "%s[%d] AFTER\n", __func__, __LINE__);
517    for (nr = 0; nr < HAL_NF_CAL_HIST_LEN_FULL; nr++) {
518        for (i = 0; i < NUM_NF_READINGS; i++) {
519            HALDEBUG(ah, HAL_DEBUG_NF_CAL,
520                "nf_cal_buffer[%d][%d] = %d\n",
521                nr, i, (int)h->nf_cal_buffer[nr][i]);
522        }
523    }
524
525    if (++h->base.curr_index >= hist_len) {
526        h->base.curr_index = 0;
527    }
528
529    return nf_no_lim_chain0;
530}
531
532#if UNUSED
533static HAL_BOOL
534get_noise_floor_thresh(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *chan,
535    int16_t *nft)
536{
537    struct ath_hal_9300 *ahp = AH9300(ah);
538
539    switch (chan->channel_flags & CHANNEL_ALL_NOTURBO) {
540    case CHANNEL_A:
541    case CHANNEL_A_HT20:
542    case CHANNEL_A_HT40PLUS:
543    case CHANNEL_A_HT40MINUS:
544        *nft = (int8_t)ar9300_eeprom_get(ahp, EEP_NFTHRESH_5);
545        break;
546    case CHANNEL_B:
547    case CHANNEL_G:
548    case CHANNEL_G_HT20:
549    case CHANNEL_G_HT40PLUS:
550    case CHANNEL_G_HT40MINUS:
551        *nft = (int8_t)ar9300_eeprom_get(ahp, EEP_NFTHRESH_2);
552        break;
553    default:
554        HALDEBUG(ah, HAL_DEBUG_CHANNEL, "%s: invalid channel flags 0x%x\n",
555                __func__, chan->channel_flags);
556        return AH_FALSE;
557    }
558    return AH_TRUE;
559}
560#endif
561
562/*
563 * Read the NF and check it against the noise floor threshhold
564 */
565#define IS(_c, _f)       (((_c)->channel_flags & _f) || 0)
566static int
567ar9300_store_new_nf(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, int is_scan)
568{
569    struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
570    int nf_hist_len;
571    int16_t nf_no_lim;
572    int16_t nfarray[NUM_NF_READINGS] = {0};
573    HAL_NFCAL_HIST_FULL *h;
574    int is_2g = 0;
575
576    if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
577        u_int32_t tsf32, nf_cal_dur_tsf;
578        /*
579         * The reason the NF calibration did not complete may just be that
580         * not enough time has passed since the NF calibration was started,
581         * because under certain conditions (when first moving to a new
582         * channel) the NF calibration may be checked very repeatedly.
583         * Or, there may be CW interference keeping the NF calibration
584         * from completing.  Check the delta time between when the NF
585         * calibration was started and now to see whether the NF calibration
586         * should have already completed (but hasn't, probably due to CW
587         * interference), or hasn't had enough time to finish yet.
588         */
589        /*
590         * AH_NF_CAL_DUR_MAX_TSF - A conservative maximum time that the
591         *     HW should need to finish a NF calibration.  If the HW
592         *     does not complete a NF calibration within this time period,
593         *     there must be a problem - probably CW interference.
594         * AH_NF_CAL_PERIOD_MAX_TSF - A conservative maximum time between
595         *     check of the HW's NF calibration being finished.
596         *     If the difference between the current TSF and the TSF
597         *     recorded when the NF calibration started is larger than this
598         *     value, the TSF must have been reset.
599         *     In general, we expect the TSF to only be reset during
600         *     regular operation for STAs, not for APs.  However, an
601         *     AP's TSF could be reset when joining an IBSS.
602         *     There's an outside chance that this could result in the
603         *     CW_INT flag being erroneously set, if the TSF adjustment
604         *     is smaller than AH_NF_CAL_PERIOD_MAX_TSF but larger than
605         *     AH_NF_CAL_DUR_TSF.  However, even if this does happen,
606         *     it shouldn't matter, as the IBSS case shouldn't be
607         *     concerned about CW_INT.
608         */
609        /* AH_NF_CAL_DUR_TSF - 90 sec in usec units */
610        #define AH_NF_CAL_DUR_TSF (90 * 1000 * 1000)
611        /* AH_NF_CAL_PERIOD_MAX_TSF - 180 sec in usec units */
612        #define AH_NF_CAL_PERIOD_MAX_TSF (180 * 1000 * 1000)
613        /* wraparound handled by using unsigned values */
614        tsf32 = ar9300_get_tsf32(ah);
615        nf_cal_dur_tsf = tsf32 - AH9300(ah)->nf_tsf32;
616        if (nf_cal_dur_tsf > AH_NF_CAL_PERIOD_MAX_TSF) {
617            /*
618             * The TSF must have gotten reset during the NF cal -
619             * just reset the NF TSF timestamp, so the next time
620             * this function is called, the timestamp comparison
621             * will be valid.
622             */
623            AH9300(ah)->nf_tsf32 = tsf32;
624        } else if (nf_cal_dur_tsf > AH_NF_CAL_DUR_TSF) {
625            HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
626                "%s: NF did not complete in calibration window\n", __func__);
627            /* the NF incompletion is probably due to CW interference */
628            chan->channel_flags |= CHANNEL_CW_INT;
629        }
630        return 0; /* HW's NF measurement not finished */
631    }
632    HALDEBUG(ah, HAL_DEBUG_NF_CAL,
633        "%s[%d] chan %d\n", __func__, __LINE__, chan->channel);
634    is_2g = IS(chan, CHANNEL_2GHZ);
635    ar9300_upload_noise_floor(ah, is_2g, nfarray);
636
637    /* Update the NF buffer for each chain masked by chainmask */
638#ifdef ATH_NF_PER_CHAN
639    h = &chan->nf_cal_hist;
640    nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
641#else
642    if (is_scan) {
643        /*
644         * This channel's NF cal info is just a HAL_NFCAL_HIST_SMALL struct
645         * rather than a HAL_NFCAL_HIST_FULL struct.
646         * As long as we only use the first history element of nf_cal_buffer
647         * (nf_cal_buffer[0][0:NUM_NF_READINGS-1]), we can use
648         * HAL_NFCAL_HIST_SMALL and HAL_NFCAL_HIST_FULL interchangeably.
649         */
650        h = (HAL_NFCAL_HIST_FULL *) &chan->nf_cal_hist;
651        nf_hist_len = HAL_NF_CAL_HIST_LEN_SMALL;
652    } else {
653        h = &AH_PRIVATE(ah)->nf_cal_hist;
654        nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
655    }
656#endif
657
658    /*
659     * nf_no_lim = median value from NF history buffer without bounds limits,
660     * priv_nf = median value from NF history buffer with bounds limits.
661     */
662    nf_no_lim = ar9300_update_nf_hist_buff(ah, h, nfarray, nf_hist_len);
663    chan->raw_noise_floor = h->base.priv_nf[0];
664
665    /* check if there is interference */
666    chan->channel_flags &= (~CHANNEL_CW_INT);
667    /*
668     * Use AR9300_EMULATION to check for emulation purpose as PCIE Device ID
669     * 0xABCD is recognized as valid Osprey as WAR in some EVs.
670     */
671    if (nf_no_lim > ahpriv->nfp->nominal + ahpriv->nf_cw_int_delta) {
672        /*
673         * Since this CW interference check is being applied to the
674         * median element of the NF history buffer, this indicates that
675         * the CW interference is persistent.  A single high NF reading
676         * will not show up in the median, and thus will not cause the
677         * CW_INT flag to be set.
678         */
679        HALDEBUG(ah, HAL_DEBUG_NF_CAL,
680            "%s: NF Cal: CW interferer detected through NF: %d\n",
681            __func__, nf_no_lim);
682        chan->channel_flags |= CHANNEL_CW_INT;
683    }
684    return 1; /* HW's NF measurement finished */
685}
686#undef IS
687
688static inline void
689ar9300_get_delta_slope_values(struct ath_hal *ah, u_int32_t coef_scaled,
690    u_int32_t *coef_mantissa, u_int32_t *coef_exponent)
691{
692    u_int32_t coef_exp, coef_man;
693
694    /*
695     * ALGO -> coef_exp = 14-floor(log2(coef));
696     * floor(log2(x)) is the highest set bit position
697     */
698    for (coef_exp = 31; coef_exp > 0; coef_exp--) {
699        if ((coef_scaled >> coef_exp) & 0x1) {
700            break;
701        }
702    }
703    /* A coef_exp of 0 is a legal bit position but an unexpected coef_exp */
704    HALASSERT(coef_exp);
705    coef_exp = 14 - (coef_exp - COEF_SCALE_S);
706
707
708    /*
709     * ALGO -> coef_man = floor(coef* 2^coef_exp+0.5);
710     * The coefficient is already shifted up for scaling
711     */
712    coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
713
714    *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
715    *coef_exponent = coef_exp - 16;
716}
717
718#define MAX_ANALOG_START        319             /* XXX */
719
720/*
721 * Delta slope coefficient computation.
722 * Required for OFDM operation.
723 */
724static void
725ar9300_set_delta_slope(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
726{
727    u_int32_t coef_scaled, ds_coef_exp, ds_coef_man;
728    u_int32_t fclk = COEFF; /* clock * 2.5 */
729
730    u_int32_t clock_mhz_scaled = 0x1000000 * fclk;
731    CHAN_CENTERS centers;
732
733    /*
734     * half and quarter rate can divide the scaled clock by 2 or 4
735     * scale for selected channel bandwidth
736     */
737    if (IS_CHAN_HALF_RATE(chan)) {
738        clock_mhz_scaled = clock_mhz_scaled >> 1;
739    } else if (IS_CHAN_QUARTER_RATE(chan)) {
740        clock_mhz_scaled = clock_mhz_scaled >> 2;
741    }
742
743    /*
744     * ALGO -> coef = 1e8/fcarrier*fclock/40;
745     * scaled coef to provide precision for this floating calculation
746     */
747    ar9300_get_channel_centers(ah, chan, &centers);
748    coef_scaled = clock_mhz_scaled / centers.synth_center;
749
750    ar9300_get_delta_slope_values(ah, coef_scaled, &ds_coef_man, &ds_coef_exp);
751
752    OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
753    OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
754
755    /*
756     * For Short GI,
757     * scaled coeff is 9/10 that of normal coeff
758     */
759    coef_scaled = (9 * coef_scaled) / 10;
760
761    ar9300_get_delta_slope_values(ah, coef_scaled, &ds_coef_man, &ds_coef_exp);
762
763    /* for short gi */
764    OS_REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA, AR_PHY_SGI_DSC_MAN, ds_coef_man);
765    OS_REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA, AR_PHY_SGI_DSC_EXP, ds_coef_exp);
766}
767
768#define IS(_c, _f)       (((_c)->channel_flags & _f) || 0)
769
770static inline HAL_CHANNEL_INTERNAL*
771ar9300_check_chan(struct ath_hal *ah, HAL_CHANNEL *chan)
772{
773    if ((IS(chan, CHANNEL_2GHZ) ^ IS(chan, CHANNEL_5GHZ)) == 0) {
774        HALDEBUG(ah, HAL_DEBUG_CHANNEL,
775            "%s: invalid channel %u/0x%x; not marked as 2GHz or 5GHz\n",
776            __func__, chan->channel, chan->channel_flags);
777        return AH_NULL;
778    }
779
780    if ((IS(chan, CHANNEL_OFDM) ^ IS(chan, CHANNEL_CCK) ^
781         IS(chan, CHANNEL_HT20) ^ IS(chan, CHANNEL_HT40PLUS) ^
782         IS(chan, CHANNEL_HT40MINUS)) == 0)
783    {
784        HALDEBUG(ah, HAL_DEBUG_CHANNEL,
785            "%s: invalid channel %u/0x%x; not marked as "
786            "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n",
787            __func__, chan->channel, chan->channel_flags);
788        return AH_NULL;
789    }
790
791    return (ath_hal_checkchannel(ah, chan));
792}
793#undef IS
794
795static void
796ar9300_set_11n_regs(struct ath_hal *ah, HAL_CHANNEL *chan,
797    HAL_HT_MACMODE macmode)
798{
799    u_int32_t phymode;
800    struct ath_hal_9300 *ahp = AH9300(ah);
801    u_int32_t enable_dac_fifo;
802
803    /* XXX */
804    enable_dac_fifo =
805        OS_REG_READ(ah, AR_PHY_GEN_CTRL) & AR_PHY_GC_ENABLE_DAC_FIFO;
806
807    /* Enable 11n HT, 20 MHz */
808    phymode =
809        AR_PHY_GC_HT_EN | AR_PHY_GC_SINGLE_HT_LTF1 | AR_PHY_GC_SHORT_GI_40
810        | enable_dac_fifo;
811    /* Configure baseband for dynamic 20/40 operation */
812    if (IS_CHAN_HT40(chan)) {
813        phymode |= AR_PHY_GC_DYN2040_EN;
814        /* Configure control (primary) channel at +-10MHz */
815        if (chan->channel_flags & CHANNEL_HT40PLUS) {
816            phymode |= AR_PHY_GC_DYN2040_PRI_CH;
817        }
818
819        /* Configure 20/25 spacing */
820        if (ahp->ah_ext_prot_spacing == HAL_HT_EXTPROTSPACING_25) {
821            phymode |= AR_PHY_GC_DYN2040_EXT_CH;
822        }
823    }
824
825    /* make sure we preserve INI settings */
826    phymode |= OS_REG_READ(ah, AR_PHY_GEN_CTRL);
827
828    /* EV 62881/64991 - turn off Green Field detection for Maverick STA beta */
829    phymode &= ~AR_PHY_GC_GF_DETECT_EN;
830
831    OS_REG_WRITE(ah, AR_PHY_GEN_CTRL, phymode);
832
833    /* Set IFS timing for half/quarter rates */
834    if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) {
835        u_int32_t modeselect = OS_REG_READ(ah, AR_PHY_MODE);
836
837        if (IS_CHAN_HALF_RATE(chan)) {
838            modeselect |= AR_PHY_MS_HALF_RATE;
839        } else if (IS_CHAN_QUARTER_RATE(chan)) {
840            modeselect |= AR_PHY_MS_QUARTER_RATE;
841        }
842        OS_REG_WRITE(ah, AR_PHY_MODE, modeselect);
843
844        ar9300_set_ifs_timing(ah, chan);
845        OS_REG_RMW_FIELD(
846            ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_CF_OVERLAP_WINDOW, 0x3);
847    }
848
849    /* Configure MAC for 20/40 operation */
850    ar9300_set_11n_mac2040(ah, macmode);
851
852    /* global transmit timeout (25 TUs default)*/
853    /* XXX - put this elsewhere??? */
854    OS_REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
855
856    /* carrier sense timeout */
857    OS_REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
858}
859
860/*
861 * Spur mitigation for MRC CCK
862 */
863static void
864ar9300_spur_mitigate_mrc_cck(struct ath_hal *ah, HAL_CHANNEL *chan)
865{
866    int i;
867    /* spur_freq_for_osprey - hardcoded by Systems team for now. */
868    u_int32_t spur_freq_for_osprey[4] = { 2420, 2440, 2464, 2480 };
869    u_int32_t spur_freq_for_jupiter[2] = { 2440, 2464};
870    int cur_bb_spur, negative = 0, cck_spur_freq;
871    u_int8_t* spur_fbin_ptr = NULL;
872    int synth_freq;
873    int range = 10;
874    int max_spurcounts = OSPREY_EEPROM_MODAL_SPURS;
875
876    /*
877     * Need to verify range +/- 10 MHz in control channel, otherwise spur
878     * is out-of-band and can be ignored.
879     */
880    if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) ||
881        AR_SREV_WASP(ah)  || AR_SREV_SCORPION(ah)) {
882        spur_fbin_ptr = ar9300_eeprom_get_spur_chans_ptr(ah, 1);
883        if (spur_fbin_ptr[0] == 0) {
884            return;      /* No spur in the mode */
885        }
886        if (IS_CHAN_HT40(chan)) {
887            range = 19;
888            if (OS_REG_READ_FIELD(ah, AR_PHY_GEN_CTRL, AR_PHY_GC_DYN2040_PRI_CH)
889                == 0x0)
890            {
891                synth_freq = chan->channel + 10;
892            } else {
893                synth_freq = chan->channel - 10;
894            }
895        } else {
896            range = 10;
897            synth_freq = chan->channel;
898        }
899    } else if(AR_SREV_JUPITER(ah)) {
900        range = 5;
901        max_spurcounts = 2; /* Hardcoded by Jupiter Systems team for now. */
902        synth_freq = chan->channel;
903    } else {
904        range = 10;
905        max_spurcounts = 4; /* Hardcoded by Osprey Systems team for now. */
906        synth_freq = chan->channel;
907    }
908
909    for (i = 0; i < max_spurcounts; i++) {
910        negative = 0;
911
912        if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) ||
913            AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
914            cur_bb_spur =
915                FBIN2FREQ(spur_fbin_ptr[i], HAL_FREQ_BAND_2GHZ) - synth_freq;
916        } else if(AR_SREV_JUPITER(ah)) {
917            cur_bb_spur = spur_freq_for_jupiter[i] - synth_freq;
918        } else {
919            cur_bb_spur = spur_freq_for_osprey[i] - synth_freq;
920        }
921
922        if (cur_bb_spur < 0) {
923            negative = 1;
924            cur_bb_spur = -cur_bb_spur;
925        }
926        if (cur_bb_spur < range) {
927            cck_spur_freq = (int)((cur_bb_spur << 19) / 11);
928            if (negative == 1) {
929                cck_spur_freq = -cck_spur_freq;
930            }
931            cck_spur_freq = cck_spur_freq & 0xfffff;
932            /*OS_REG_WRITE_field(ah, BB_agc_control.ycok_max, 0x7);*/
933            OS_REG_RMW_FIELD(ah,
934                AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_YCOK_MAX, 0x7);
935            /*OS_REG_WRITE_field(ah, BB_cck_spur_mit.spur_rssi_thr, 0x7f);*/
936            OS_REG_RMW_FIELD(ah,
937                AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR, 0x7f);
938            /*OS_REG_WRITE(ah, BB_cck_spur_mit.spur_filter_type, 0x2);*/
939            OS_REG_RMW_FIELD(ah,
940                AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE, 0x2);
941            /*OS_REG_WRITE(ah, BB_cck_spur_mit.use_cck_spur_mit, 0x1);*/
942            OS_REG_RMW_FIELD(ah,
943                AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT, 0x1);
944            /*OS_REG_WRITE(ah, BB_cck_spur_mit.cck_spur_freq, cck_spur_freq);*/
945            OS_REG_RMW_FIELD(ah,
946                AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ,
947                cck_spur_freq);
948            return;
949        }
950    }
951
952    /*OS_REG_WRITE(ah, BB_agc_control.ycok_max, 0x5);*/
953    OS_REG_RMW_FIELD(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_YCOK_MAX, 0x5);
954    /*OS_REG_WRITE(ah, BB_cck_spur_mit.use_cck_spur_mit, 0x0);*/
955    OS_REG_RMW_FIELD(ah,
956        AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT, 0x0);
957    /*OS_REG_WRITE(ah, BB_cck_spur_mit.cck_spur_freq, 0x0);*/
958    OS_REG_RMW_FIELD(ah,
959        AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ, 0x0);
960}
961
962/* Spur mitigation for OFDM */
963static void
964ar9300_spur_mitigate_ofdm(struct ath_hal *ah, HAL_CHANNEL *chan)
965{
966    int synth_freq;
967    int range = 10;
968    int freq_offset = 0;
969    int spur_freq_sd = 0;
970    int spur_subchannel_sd = 0;
971    int spur_delta_phase = 0;
972    int mask_index = 0;
973    int i;
974    int mode;
975    u_int8_t* spur_chans_ptr;
976
977    if (IS_CHAN_5GHZ(chan)) {
978        spur_chans_ptr = ar9300_eeprom_get_spur_chans_ptr(ah, 0);
979        mode = 0;
980    } else {
981        spur_chans_ptr = ar9300_eeprom_get_spur_chans_ptr(ah, 1);
982        mode = 1;
983    }
984
985    if (IS_CHAN_HT40(chan)) {
986        range = 19;
987        if (OS_REG_READ_FIELD(ah, AR_PHY_GEN_CTRL, AR_PHY_GC_DYN2040_PRI_CH)
988            == 0x0)
989        {
990            synth_freq = chan->channel - 10;
991        } else {
992            synth_freq = chan->channel + 10;
993        }
994    } else {
995        range = 10;
996        synth_freq = chan->channel;
997    }
998
999    /* Clean all spur register fields */
1000    OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0);
1001    OS_REG_RMW_FIELD(ah, AR_PHY_TIMING11, AR_PHY_TIMING11_SPUR_FREQ_SD, 0);
1002    OS_REG_RMW_FIELD(ah, AR_PHY_TIMING11, AR_PHY_TIMING11_SPUR_DELTA_PHASE, 0);
1003    OS_REG_RMW_FIELD(ah,
1004        AR_PHY_SFCORR_EXT, AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, 0);
1005    OS_REG_RMW_FIELD(ah,
1006        AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0);
1007    OS_REG_RMW_FIELD(ah,
1008        AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0);
1009    OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0);
1010    OS_REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 0);
1011    OS_REG_RMW_FIELD(ah,
1012        AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 0);
1013    OS_REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0);
1014    OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0);
1015    OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0);
1016    OS_REG_RMW_FIELD(ah,
1017        AR_PHY_PILOT_SPUR_MASK, AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, 0);
1018    OS_REG_RMW_FIELD(ah,
1019        AR_PHY_SPUR_MASK_A, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, 0);
1020    OS_REG_RMW_FIELD(ah,
1021        AR_PHY_CHAN_SPUR_MASK, AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, 0);
1022    OS_REG_RMW_FIELD(ah,
1023        AR_PHY_PILOT_SPUR_MASK, AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0);
1024    OS_REG_RMW_FIELD(ah,
1025        AR_PHY_CHAN_SPUR_MASK, AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0);
1026    OS_REG_RMW_FIELD(ah,
1027        AR_PHY_SPUR_MASK_A, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0);
1028    OS_REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0);
1029
1030    i = 0;
1031    while (spur_chans_ptr[i] && i < 5) {
1032        freq_offset = FBIN2FREQ(spur_chans_ptr[i], mode) - synth_freq;
1033        if (abs(freq_offset) < range) {
1034            /*
1035            printf(
1036                "Spur Mitigation for OFDM: Synth Frequency = %d, "
1037                "Spur Frequency = %d\n",
1038                synth_freq, FBIN2FREQ(spur_chans_ptr[i], mode));
1039             */
1040            if (IS_CHAN_HT40(chan)) {
1041                if (freq_offset < 0) {
1042                    if (OS_REG_READ_FIELD(
1043                        ah, AR_PHY_GEN_CTRL, AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
1044                    {
1045                        spur_subchannel_sd = 1;
1046                    } else {
1047                        spur_subchannel_sd = 0;
1048                    }
1049                    spur_freq_sd = ((freq_offset + 10) << 9) / 11;
1050                } else {
1051                    if (OS_REG_READ_FIELD(ah,
1052                        AR_PHY_GEN_CTRL, AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
1053                    {
1054                        spur_subchannel_sd = 0;
1055                    } else {
1056                        spur_subchannel_sd = 1;
1057                    }
1058                    spur_freq_sd = ((freq_offset - 10) << 9) / 11;
1059                }
1060                spur_delta_phase = (freq_offset << 17) / 5;
1061            } else {
1062                spur_subchannel_sd = 0;
1063                spur_freq_sd = (freq_offset << 9) / 11;
1064                spur_delta_phase = (freq_offset << 18) / 5;
1065            }
1066            spur_freq_sd = spur_freq_sd & 0x3ff;
1067            spur_delta_phase = spur_delta_phase & 0xfffff;
1068            /*
1069            printf(
1070                "spur_subchannel_sd = %d, spur_freq_sd = 0x%x, "
1071                "spur_delta_phase = 0x%x\n", spur_subchannel_sd,
1072                spur_freq_sd, spur_delta_phase);
1073             */
1074
1075            /* OFDM Spur mitigation */
1076            OS_REG_RMW_FIELD(ah,
1077                AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0x1);
1078            OS_REG_RMW_FIELD(ah,
1079                AR_PHY_TIMING11, AR_PHY_TIMING11_SPUR_FREQ_SD, spur_freq_sd);
1080            OS_REG_RMW_FIELD(ah,
1081                AR_PHY_TIMING11, AR_PHY_TIMING11_SPUR_DELTA_PHASE,
1082                spur_delta_phase);
1083            OS_REG_RMW_FIELD(ah,
1084                AR_PHY_SFCORR_EXT, AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD,
1085                spur_subchannel_sd);
1086            OS_REG_RMW_FIELD(ah,
1087                AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0x1);
1088            OS_REG_RMW_FIELD(ah,
1089                AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR,
1090                0x1);
1091            OS_REG_RMW_FIELD(ah,
1092                AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0x1);
1093            OS_REG_RMW_FIELD(ah,
1094                AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH, 34);
1095            OS_REG_RMW_FIELD(ah,
1096                AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 1);
1097
1098            /*
1099             * Do not subtract spur power from noise floor for wasp.
1100             * This causes the maximum client test (on Veriwave) to fail
1101             * when run on spur channel (2464 MHz).
1102             * Refer to ev#82746 and ev#82744.
1103             */
1104            if (!AR_SREV_WASP(ah) && (OS_REG_READ_FIELD(ah, AR_PHY_MODE,
1105                                           AR_PHY_MODE_DYNAMIC) == 0x1)) {
1106                OS_REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
1107                    AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 1);
1108            }
1109
1110            mask_index = (freq_offset << 4) / 5;
1111            if (mask_index < 0) {
1112                mask_index = mask_index - 1;
1113            }
1114            mask_index = mask_index & 0x7f;
1115            /*printf("Bin 0x%x\n", mask_index);*/
1116
1117            OS_REG_RMW_FIELD(ah,
1118                AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0x1);
1119            OS_REG_RMW_FIELD(ah,
1120                AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0x1);
1121            OS_REG_RMW_FIELD(ah,
1122                AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0x1);
1123            OS_REG_RMW_FIELD(ah,
1124                AR_PHY_PILOT_SPUR_MASK,
1125                AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, mask_index);
1126            OS_REG_RMW_FIELD(ah,
1127                AR_PHY_SPUR_MASK_A, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A,
1128                mask_index);
1129            OS_REG_RMW_FIELD(ah,
1130                AR_PHY_CHAN_SPUR_MASK,
1131                AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, mask_index);
1132            OS_REG_RMW_FIELD(ah,
1133                AR_PHY_PILOT_SPUR_MASK, AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A,
1134                0xc);
1135            OS_REG_RMW_FIELD(ah,
1136                AR_PHY_CHAN_SPUR_MASK, AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A,
1137                0xc);
1138            OS_REG_RMW_FIELD(ah,
1139                AR_PHY_SPUR_MASK_A, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0xa0);
1140            OS_REG_RMW_FIELD(ah,
1141                AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0xff);
1142            /*
1143            printf("BB_timing_control_4 = 0x%x\n",
1144                OS_REG_READ(ah, AR_PHY_TIMING4));
1145            printf("BB_timing_control_11 = 0x%x\n",
1146                OS_REG_READ(ah, AR_PHY_TIMING11));
1147            printf("BB_ext_chan_scorr_thr = 0x%x\n",
1148                OS_REG_READ(ah, AR_PHY_SFCORR_EXT));
1149            printf("BB_spur_mask_controls = 0x%x\n",
1150                OS_REG_READ(ah, AR_PHY_SPUR_REG));
1151            printf("BB_pilot_spur_mask = 0x%x\n",
1152                OS_REG_READ(ah, AR_PHY_PILOT_SPUR_MASK));
1153            printf("BB_chan_spur_mask = 0x%x\n",
1154                OS_REG_READ(ah, AR_PHY_CHAN_SPUR_MASK));
1155            printf("BB_vit_spur_mask_A = 0x%x\n",
1156                OS_REG_READ(ah, AR_PHY_SPUR_MASK_A));
1157             */
1158            break;
1159        }
1160        i++;
1161    }
1162}
1163
1164
1165/*
1166 * Convert to baseband spur frequency given input channel frequency
1167 * and compute register settings below.
1168 */
1169static void
1170ar9300_spur_mitigate(struct ath_hal *ah, HAL_CHANNEL *chan)
1171{
1172    ar9300_spur_mitigate_ofdm(ah, chan);
1173    ar9300_spur_mitigate_mrc_cck(ah, chan);
1174}
1175
1176
1177/**************************************************************
1178 * ar9300_channel_change
1179 * Assumes caller wants to change channel, and not reset.
1180 */
1181static inline HAL_BOOL
1182ar9300_channel_change(struct ath_hal *ah, HAL_CHANNEL *chan,
1183    HAL_CHANNEL_INTERNAL *ichan, HAL_HT_MACMODE macmode)
1184{
1185
1186    u_int32_t synth_delay, qnum;
1187    struct ath_hal_9300 *ahp = AH9300(ah);
1188
1189    /* TX must be stopped by now */
1190    for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
1191        if (ar9300_num_tx_pending(ah, qnum)) {
1192            HALDEBUG(ah, HAL_DEBUG_QUEUE,
1193                "%s: Transmit frames pending on queue %d\n", __func__, qnum);
1194            HALASSERT(0);
1195            return AH_FALSE;
1196        }
1197    }
1198
1199
1200    /*
1201     * Kill last Baseband Rx Frame - Request analog bus grant
1202     */
1203    OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
1204    if (!ath_hal_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
1205            AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT))
1206    {
1207        HALDEBUG(ah, HAL_DEBUG_PHY_IO,
1208            "%s: Could not kill baseband RX\n", __func__);
1209        return AH_FALSE;
1210    }
1211
1212
1213    /* Setup 11n MAC/Phy mode registers */
1214    ar9300_set_11n_regs(ah, chan, macmode);
1215
1216    /*
1217     * Change the synth
1218     */
1219    if (!ahp->ah_rf_hal.set_channel(ah, ichan)) {
1220        HALDEBUG(ah, HAL_DEBUG_CHANNEL, "%s: failed to set channel\n", __func__);
1221        return AH_FALSE;
1222    }
1223
1224    /*
1225     * Some registers get reinitialized during ATH_INI_POST INI programming.
1226     */
1227    ar9300_init_user_settings(ah);
1228
1229    /*
1230     * Setup the transmit power values.
1231     *
1232     * After the public to private hal channel mapping, ichan contains the
1233     * valid regulatory power value.
1234     * ath_hal_getctl and ath_hal_getantennaallowed look up ichan from chan.
1235     */
1236    if (ar9300_eeprom_set_transmit_power(
1237         ah, &ahp->ah_eeprom, ichan, ath_hal_getctl(ah, chan),
1238         ath_hal_getantennaallowed(ah, chan),
1239         ath_hal_get_twice_max_regpower(AH_PRIVATE(ah), ichan, chan),
1240         AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_power_limit)) != HAL_OK)
1241    {
1242        HALDEBUG(ah, HAL_DEBUG_EEPROM,
1243            "%s: error init'ing transmit power\n", __func__);
1244        return AH_FALSE;
1245    }
1246
1247    /*
1248     * Release the RFBus Grant.
1249     */
1250    OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
1251
1252    /*
1253     * Write spur immunity and delta slope for OFDM enabled modes (A, G, Turbo)
1254     */
1255    if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) {
1256        ar9300_set_delta_slope(ah, ichan);
1257    } else {
1258        /* Set to Ini default */
1259        OS_REG_WRITE(ah, AR_PHY_TIMING3, 0x9c0a9f6b);
1260        OS_REG_WRITE(ah, AR_PHY_SGI_DELTA, 0x00046384);
1261    }
1262
1263    ar9300_spur_mitigate(ah, chan);
1264
1265
1266    /*
1267     * Wait for the frequency synth to settle (synth goes on via PHY_ACTIVE_EN).
1268     * Read the phy active delay register. Value is in 100ns increments.
1269     */
1270    synth_delay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
1271    if (IS_CHAN_CCK(chan)) {
1272        synth_delay = (4 * synth_delay) / 22;
1273    } else {
1274        synth_delay /= 10;
1275    }
1276
1277    OS_DELAY(synth_delay + BASE_ACTIVATE_DELAY);
1278
1279    /*
1280     * Do calibration.
1281     */
1282
1283    return AH_TRUE;
1284}
1285
1286void
1287ar9300_set_operating_mode(struct ath_hal *ah, int opmode)
1288{
1289    u_int32_t val;
1290
1291    val = OS_REG_READ(ah, AR_STA_ID1);
1292    val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
1293    switch (opmode) {
1294    case HAL_M_HOSTAP:
1295        OS_REG_WRITE(ah, AR_STA_ID1,
1296            val | AR_STA_ID1_STA_AP | AR_STA_ID1_KSRCH_MODE);
1297        OS_REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1298        break;
1299    case HAL_M_IBSS:
1300        OS_REG_WRITE(ah, AR_STA_ID1,
1301            val | AR_STA_ID1_ADHOC | AR_STA_ID1_KSRCH_MODE);
1302        OS_REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1303        break;
1304    case HAL_M_STA:
1305    case HAL_M_MONITOR:
1306        OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
1307        break;
1308    }
1309}
1310
1311/* XXX need the logic for Osprey */
1312inline void
1313ar9300_init_pll(struct ath_hal *ah, HAL_CHANNEL *chan)
1314{
1315    u_int32_t pll;
1316    u_int8_t clk_25mhz = AH9300(ah)->clk_25mhz;
1317
1318    if (AR_SREV_HORNET(ah)) {
1319        if (clk_25mhz) {
1320            /* Hornet uses PLL_CONTROL_2. Xtal is 25MHz for Hornet.
1321             * REFDIV set to 0x1.
1322             * $xtal_freq = 25;
1323             * $PLL2_div = (704/$xtal_freq); # 176 * 4 = 704.
1324             * MAC and BB run at 176 MHz.
1325             * $PLL2_divint = int($PLL2_div);
1326             * $PLL2_divfrac = $PLL2_div - $PLL2_divint;
1327             * $PLL2_divfrac = int($PLL2_divfrac * 0x4000); # 2^14
1328             * $PLL2_Val = ($PLL2_divint & 0x3f) << 19 | (0x1) << 14 |
1329             *     $PLL2_divfrac & 0x3fff;
1330             * Therefore, $PLL2_Val = 0xe04a3d
1331             */
1332#define DPLL2_KD_VAL            0x1D
1333#define DPLL2_KI_VAL            0x06
1334#define DPLL3_PHASE_SHIFT_VAL   0x1
1335
1336            /* Rewrite DDR PLL2 and PLL3 */
1337            /* program DDR PLL ki and kd value, ki=0x6, kd=0x1d */
1338            OS_REG_WRITE(ah, AR_HORNET_CH0_DDR_DPLL2, 0x18e82f01);
1339
1340            /* program DDR PLL phase_shift to 0x1 */
1341            OS_REG_RMW_FIELD(ah, AR_HORNET_CH0_DDR_DPLL3,
1342                AR_PHY_BB_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
1343
1344            OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
1345            OS_DELAY(1000);
1346
1347            /* program refdiv, nint, frac to RTC register */
1348            OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0xe04a3d);
1349
1350            /* program BB PLL ki and kd value, ki=0x6, kd=0x1d */
1351            OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1352                AR_PHY_BB_DPLL2_KD, DPLL2_KD_VAL);
1353            OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1354                AR_PHY_BB_DPLL2_KI, DPLL2_KI_VAL);
1355
1356            /* program BB PLL phase_shift to 0x1 */
1357            OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL3,
1358                AR_PHY_BB_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
1359        } else { /* 40MHz */
1360#undef  DPLL2_KD_VAL
1361#undef  DPLL2_KI_VAL
1362#define DPLL2_KD_VAL            0x3D
1363#define DPLL2_KI_VAL            0x06
1364            /* Rewrite DDR PLL2 and PLL3 */
1365            /* program DDR PLL ki and kd value, ki=0x6, kd=0x3d */
1366            OS_REG_WRITE(ah, AR_HORNET_CH0_DDR_DPLL2, 0x19e82f01);
1367
1368            /* program DDR PLL phase_shift to 0x1 */
1369            OS_REG_RMW_FIELD(ah, AR_HORNET_CH0_DDR_DPLL3,
1370                AR_PHY_BB_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
1371
1372            OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
1373            OS_DELAY(1000);
1374
1375            /* program refdiv, nint, frac to RTC register */
1376            OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666);
1377
1378            /* program BB PLL ki and kd value, ki=0x6, kd=0x3d */
1379            OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1380                AR_PHY_BB_DPLL2_KD, DPLL2_KD_VAL);
1381            OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1382                AR_PHY_BB_DPLL2_KI, DPLL2_KI_VAL);
1383
1384            /* program BB PLL phase_shift to 0x1 */
1385            OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL3,
1386                AR_PHY_BB_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
1387        }
1388        OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c);
1389        OS_DELAY(1000);
1390    } else if (AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) {
1391        OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2, AR_PHY_BB_DPLL2_PLL_PWD, 0x1);
1392
1393        /* program BB PLL ki and kd value, ki=0x4, kd=0x40 */
1394        OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1395            AR_PHY_BB_DPLL2_KD, 0x40);
1396        OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1397            AR_PHY_BB_DPLL2_KI, 0x4);
1398
1399        OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL1,
1400            AR_PHY_BB_DPLL1_REFDIV, 0x5);
1401        OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL1,
1402            AR_PHY_BB_DPLL1_NINI, 0x58);
1403        OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL1,
1404            AR_PHY_BB_DPLL1_NFRAC, 0x0);
1405
1406        OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1407            AR_PHY_BB_DPLL2_OUTDIV, 0x1);
1408        OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1409            AR_PHY_BB_DPLL2_LOCAL_PLL, 0x1);
1410        OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1411            AR_PHY_BB_DPLL2_EN_NEGTRIG, 0x1);
1412
1413        /* program BB PLL phase_shift to 0x6 */
1414        OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL3,
1415            AR_PHY_BB_DPLL3_PHASE_SHIFT, 0x6);
1416
1417        OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1418            AR_PHY_BB_DPLL2_PLL_PWD, 0x0);
1419        OS_DELAY(1000);
1420
1421        OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c);
1422        OS_DELAY(1000);
1423    } else if (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
1424#define SRIF_PLL 1
1425        u_int32_t regdata, pll2_divint, pll2_divfrac;
1426
1427#ifndef SRIF_PLL
1428	u_int32_t pll2_clkmode;
1429#endif
1430
1431#ifdef SRIF_PLL
1432        u_int32_t refdiv;
1433#endif
1434        if (clk_25mhz) {
1435#ifndef SRIF_PLL
1436            pll2_divint = 0x1c;
1437            pll2_divfrac = 0xa3d7;
1438#else
1439            pll2_divint = 0x54;
1440            pll2_divfrac = 0x1eb85;
1441            refdiv = 3;
1442#endif
1443        } else {
1444#ifndef SRIF_PLL
1445            pll2_divint = 0x11;
1446            pll2_divfrac = 0x26666;
1447#else
1448            if (AR_SREV_WASP(ah)) {
1449                pll2_divint = 88;
1450                pll2_divfrac = 0;
1451                refdiv = 5;
1452            } else {
1453                pll2_divint = 0x11;
1454                pll2_divfrac = 0x26666;
1455                refdiv = 1;
1456            }
1457#endif
1458        }
1459#ifndef SRIF_PLL
1460        pll2_clkmode = 0x3d;
1461#endif
1462        /* PLL programming through SRIF Local Mode */
1463        OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); /* Bypass mode */
1464        OS_DELAY(1000);
1465        do {
1466            regdata = OS_REG_READ(ah, AR_PHY_PLL_MODE);
1467            regdata = regdata | (0x1 << 16);
1468            OS_REG_WRITE(ah, AR_PHY_PLL_MODE, regdata); /* PWD_PLL set to 1 */
1469            OS_DELAY(100);
1470            /* override int, frac, refdiv */
1471#ifndef SRIF_PLL
1472            OS_REG_WRITE(ah, AR_PHY_PLL_CONTROL,
1473                ((1 << 27) | (pll2_divint << 18) | pll2_divfrac));
1474#else
1475            OS_REG_WRITE(ah, AR_PHY_PLL_CONTROL,
1476                ((refdiv << 27) | (pll2_divint << 18) | pll2_divfrac));
1477#endif
1478            OS_DELAY(100);
1479            regdata = OS_REG_READ(ah, AR_PHY_PLL_MODE);
1480#ifndef SRIF_PLL
1481            regdata = (regdata & 0x80071fff) |
1482                (0x1 << 30) | (0x1 << 13) | (0x6 << 26) | (pll2_clkmode << 19);
1483#else
1484            if (AR_SREV_WASP(ah)) {
1485                regdata = (regdata & 0x80071fff) |
1486                    (0x1 << 30) | (0x1 << 13) | (0x4 << 26) | (0x18 << 19);
1487            } else {
1488                regdata = (regdata & 0x80071fff) |
1489                    (0x3 << 30) | (0x1 << 13) | (0x4 << 26) | (0x60 << 19);
1490            }
1491#endif
1492            /* Ki, Kd, Local PLL, Outdiv */
1493            OS_REG_WRITE(ah, AR_PHY_PLL_MODE, regdata);
1494            regdata = OS_REG_READ(ah, AR_PHY_PLL_MODE);
1495            regdata = (regdata & 0xfffeffff);
1496            OS_REG_WRITE(ah, AR_PHY_PLL_MODE, regdata); /* PWD_PLL set to 0 */
1497            OS_DELAY(1000);
1498            if (AR_SREV_WASP(ah)) {
1499                /* clear do measure */
1500                regdata = OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL3);
1501                regdata &= ~(1 << 30);
1502                OS_REG_WRITE(ah, AR_PHY_PLL_BB_DPLL3, regdata);
1503                OS_DELAY(100);
1504
1505                /* set do measure */
1506                regdata = OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL3);
1507                regdata |= (1 << 30);
1508                OS_REG_WRITE(ah, AR_PHY_PLL_BB_DPLL3, regdata);
1509
1510                /* wait for measure done */
1511                do {
1512                    regdata = OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL4);
1513                } while ((regdata & (1 << 3)) == 0);
1514
1515                /* clear do measure */
1516                regdata = OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL3);
1517                regdata &= ~(1 << 30);
1518                OS_REG_WRITE(ah, AR_PHY_PLL_BB_DPLL3, regdata);
1519
1520                /* get measure sqsum dvc */
1521                regdata = (OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL3) & 0x007FFFF8) >> 3;
1522            } else {
1523                break;
1524            }
1525        } while (regdata >= 0x40000);
1526
1527        /* Remove from Bypass mode */
1528        OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c);
1529        OS_DELAY(1000);
1530    } else {
1531        pll = SM(0x5, AR_RTC_PLL_REFDIV);
1532
1533        /* Supposedly not needed on Osprey */
1534#if 0
1535        if (chan && IS_CHAN_HALF_RATE(chan)) {
1536            pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
1537        } else if (chan && IS_CHAN_QUARTER_RATE(chan)) {
1538            pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
1539        }
1540#endif
1541        if (chan && IS_CHAN_5GHZ(chan)) {
1542            pll |= SM(0x28, AR_RTC_PLL_DIV);
1543            /*
1544             * When doing fast clock, set PLL to 0x142c
1545             */
1546            if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
1547                pll = 0x142c;
1548            }
1549        } else {
1550            pll |= SM(0x2c, AR_RTC_PLL_DIV);
1551        }
1552
1553        OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
1554    }
1555
1556    /* TODO:
1557     * For multi-band owl, switch between bands by reiniting the PLL.
1558     */
1559    OS_DELAY(RTC_PLL_SETTLE_DELAY);
1560
1561    OS_REG_WRITE(ah, AR_RTC_SLEEP_CLK,
1562        AR_RTC_FORCE_DERIVED_CLK | AR_RTC_PCIE_RST_PWDN_EN);
1563
1564    if (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
1565        if (clk_25mhz) {
1566            OS_REG_WRITE(ah,
1567                AR_RTC_DERIVED_RTC_CLK, (0x17c << 1)); /* 32KHz sleep clk */
1568            OS_REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
1569            OS_REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae);
1570        } else {
1571            OS_REG_WRITE(ah,
1572                AR_RTC_DERIVED_RTC_CLK, (0x261 << 1)); /* 32KHz sleep clk */
1573            OS_REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
1574            OS_REG_WRITE(ah, AR_SLP32_INC, 0x0001e800);
1575        }
1576        OS_DELAY(100);
1577    }
1578}
1579
1580static inline HAL_BOOL
1581ar9300_set_reset(struct ath_hal *ah, int type)
1582{
1583    u_int32_t rst_flags;
1584    u_int32_t tmp_reg;
1585
1586    HALASSERT(type == HAL_RESET_WARM || type == HAL_RESET_COLD);
1587
1588    /*
1589     * RTC Force wake should be done before resetting the MAC.
1590     * MDK/ART does it that way.
1591     */
1592    OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_WA), AH9300(ah)->ah_wa_reg_val);
1593    OS_DELAY(10); /* delay to allow AR_WA reg write to kick in */
1594    OS_REG_WRITE(ah,
1595        AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1596
1597    /* Reset AHB */
1598    /* Bug26871 */
1599    tmp_reg = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE));
1600    if (AR_SREV_WASP(ah)) {
1601        if (tmp_reg & (AR9340_INTR_SYNC_LOCAL_TIMEOUT)) {
1602            OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), 0);
1603            OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), AR_RC_HOSTIF);
1604        }
1605    } else {
1606        if (tmp_reg & (AR9300_INTR_SYNC_LOCAL_TIMEOUT | AR9300_INTR_SYNC_RADM_CPL_TIMEOUT)) {
1607            OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), 0);
1608            OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), AR_RC_HOSTIF);
1609        }
1610        else {
1611            /* NO AR_RC_AHB in Osprey */
1612            /*OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), AR_RC_AHB);*/
1613        }
1614    }
1615
1616    rst_flags = AR_RTC_RC_MAC_WARM;
1617    if (type == HAL_RESET_COLD) {
1618        rst_flags |= AR_RTC_RC_MAC_COLD;
1619    }
1620
1621#ifdef AH_SUPPORT_HORNET
1622    /* Hornet WAR: trigger SoC to reset WMAC if ...
1623     * (1) doing cold reset. Ref: EV 69254
1624     * (2) beacon pending. Ref: EV 70983
1625     */
1626    if (AR_SREV_HORNET(ah) &&
1627        (ar9300_num_tx_pending(
1628            ah, AH_PRIVATE(ah)->ah_caps.hal_total_queues - 1) != 0 ||
1629         type == HAL_RESET_COLD))
1630    {
1631        u_int32_t time_out;
1632#define AR_SOC_RST_RESET         0xB806001C
1633#define AR_SOC_BOOT_STRAP        0xB80600AC
1634#define AR_SOC_WLAN_RST          0x00000800 /* WLAN reset */
1635#define REG_WRITE(_reg, _val)    *((volatile u_int32_t *)(_reg)) = (_val);
1636#define REG_READ(_reg)           *((volatile u_int32_t *)(_reg))
1637        HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Hornet SoC reset WMAC.\n", __func__);
1638
1639        REG_WRITE(AR_SOC_RST_RESET,
1640            REG_READ(AR_SOC_RST_RESET) | AR_SOC_WLAN_RST);
1641        REG_WRITE(AR_SOC_RST_RESET,
1642            REG_READ(AR_SOC_RST_RESET) & (~AR_SOC_WLAN_RST));
1643
1644        time_out = 0;
1645
1646        while (1) {
1647            tmp_reg = REG_READ(AR_SOC_BOOT_STRAP);
1648            if ((tmp_reg & 0x10) == 0) {
1649                break;
1650            }
1651            if (time_out > 20) {
1652                break;
1653            }
1654            OS_DELAY(10000);
1655            time_out++;
1656        }
1657
1658        OS_REG_WRITE(ah, AR_RTC_RESET, 1);
1659#undef REG_READ
1660#undef REG_WRITE
1661#undef AR_SOC_WLAN_RST
1662#undef AR_SOC_RST_RESET
1663#undef AR_SOC_BOOT_STRAP
1664    }
1665#endif /* AH_SUPPORT_HORNET */
1666
1667#ifdef AH_SUPPORT_SCORPION
1668    if (AR_SREV_SCORPION(ah)) {
1669#define DDR_CTL_CONFIG_ADDRESS                                       0xb8000000
1670#define DDR_CTL_CONFIG_OFFSET                                        0x0108
1671#define DDR_CTL_CONFIG_CLIENT_ACTIVITY_MSB                           29
1672#define DDR_CTL_CONFIG_CLIENT_ACTIVITY_LSB                           21
1673#define DDR_CTL_CONFIG_CLIENT_ACTIVITY_MASK                          0x3fe00000
1674#define DDR_CTL_CONFIG_CLIENT_ACTIVITY_GET(x)                        (((x) & DDR_CTL_CONFIG_CLIENT_ACTIVITY_MASK) >> DDR_CTL_CONFIG_CLIENT_ACTIVITY_LSB)
1675#define DDR_CTL_CONFIG_CLIENT_ACTIVITY_SET(x)                        (((x) << DDR_CTL_CONFIG_CLIENT_ACTIVITY_LSB) & DDR_CTL_CONFIG_CLIENT_ACTIVITY_MASK)
1676#define MAC_DMA_CFG_ADDRESS                                          0xb8100000
1677#define MAC_DMA_CFG_OFFSET                                           0x0014
1678
1679#define MAC_DMA_CFG_HALT_REQ_MSB                                     11
1680#define MAC_DMA_CFG_HALT_REQ_LSB                                     11
1681#define MAC_DMA_CFG_HALT_REQ_MASK                                    0x00000800
1682#define MAC_DMA_CFG_HALT_REQ_GET(x)                                  (((x) & MAC_DMA_CFG_HALT_REQ_MASK) >> MAC_DMA_CFG_HALT_REQ_LSB)
1683#define MAC_DMA_CFG_HALT_REQ_SET(x)                                  (((x) << MAC_DMA_CFG_HALT_REQ_LSB) & MAC_DMA_CFG_HALT_REQ_MASK)
1684#define MAC_DMA_CFG_HALT_ACK_MSB                                     12
1685#define MAC_DMA_CFG_HALT_ACK_LSB                                     12
1686#define MAC_DMA_CFG_HALT_ACK_MASK                                    0x00001000
1687#define MAC_DMA_CFG_HALT_ACK_GET(x)                                  (((x) & MAC_DMA_CFG_HALT_ACK_MASK) >> MAC_DMA_CFG_HALT_ACK_LSB)
1688#define MAC_DMA_CFG_HALT_ACK_SET(x)                                  (((x) << MAC_DMA_CFG_HALT_ACK_LSB) & MAC_DMA_CFG_HALT_ACK_MASK)
1689
1690#define RST_RESET                                                    0xB806001c
1691#define RTC_RESET                                                    (1<<27)
1692
1693#define REG_READ(_reg)          *((volatile u_int32_t *)(_reg))
1694#define REG_WRITE(_reg, _val)   *((volatile u_int32_t *)(_reg)) = (_val);
1695
1696#define DDR_REG_READ(_ah, _reg) \
1697	    *((volatile u_int32_t *)( DDR_CTL_CONFIG_ADDRESS + (_reg)))
1698#define DDR_REG_WRITE(_ah, _reg, _val) \
1699	    *((volatile u_int32_t *)(DDR_CTL_CONFIG_ADDRESS + (_reg))) = (_val)
1700
1701	    OS_REG_WRITE(ah,MAC_DMA_CFG_OFFSET, (OS_REG_READ(ah,MAC_DMA_CFG_OFFSET) & ~MAC_DMA_CFG_HALT_REQ_MASK) |
1702			    MAC_DMA_CFG_HALT_REQ_SET(1));
1703
1704	    {
1705		    int count;
1706            u_int32_t data;
1707
1708		    count = 0;
1709		    while (!MAC_DMA_CFG_HALT_ACK_GET(OS_REG_READ(ah, MAC_DMA_CFG_OFFSET) ))
1710		    {
1711			    count++;
1712			    if (count > 10) {
1713				    ath_hal_printf(ah, "Halt ACK timeout\n");
1714				    break;
1715			    }
1716			    OS_DELAY(10);
1717		    }
1718
1719		    data = DDR_REG_READ(ah,DDR_CTL_CONFIG_OFFSET);
1720		    ath_hal_printf(ah, "check DDR Activity - HIGH\n");
1721
1722		    count = 0;
1723		    while (DDR_CTL_CONFIG_CLIENT_ACTIVITY_GET(data)) {
1724			    //      AVE_DEBUG(0,"DDR Activity - HIGH\n");
1725			    ath_hal_printf(ah, "DDR Activity - HIGH\n");
1726			    count++;
1727			    OS_DELAY(10);
1728			    data = DDR_REG_READ(ah,DDR_CTL_CONFIG_OFFSET);
1729			    if (count > 10) {
1730				    ath_hal_printf(ah, "DDR Activity timeout\n");
1731				    break;
1732			    }
1733		    }
1734	    }
1735
1736
1737	    {
1738		    //Force RTC reset
1739		    REG_WRITE(RST_RESET, (REG_READ(RST_RESET) | RTC_RESET));
1740		    OS_DELAY(10);
1741		    REG_WRITE(RST_RESET, (REG_READ(RST_RESET) & ~RTC_RESET));
1742		    OS_DELAY(10);
1743		    OS_REG_WRITE(ah, AR_RTC_RESET, 0);
1744		    OS_DELAY(10);
1745		    OS_REG_WRITE(ah, AR_RTC_RESET, 1);
1746		    OS_DELAY(10);
1747		    ath_hal_printf(ah,"%s: Scorpion SoC RTC reset done.\n", __func__);
1748	    }
1749#undef REG_READ
1750#undef REG_WRITE
1751    }
1752#endif  /* AH_SUPPORT_SCORPION */
1753
1754    /*
1755     * Set Mac(BB,Phy) Warm Reset
1756     */
1757    OS_REG_WRITE(ah, AR_RTC_RC, rst_flags);
1758
1759    OS_DELAY(50); /* XXX 50 usec */
1760
1761    /*
1762     * Clear resets and force wakeup
1763     */
1764    OS_REG_WRITE(ah, AR_RTC_RC, 0);
1765    if (!ath_hal_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) {
1766        HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
1767            "%s: RTC stuck in MAC reset\n", __FUNCTION__);
1768        HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
1769            "%s: AR_RTC_RC = 0x%x\n", __func__, OS_REG_READ(ah, AR_RTC_RC));
1770        return AH_FALSE;
1771    }
1772
1773    /* Clear AHB reset */
1774    OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), 0);
1775
1776    ar9300_attach_hw_platform(ah);
1777
1778    return AH_TRUE;
1779}
1780
1781static inline HAL_BOOL
1782ar9300_set_reset_power_on(struct ath_hal *ah)
1783{
1784    /* Force wake */
1785    OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_WA), AH9300(ah)->ah_wa_reg_val);
1786    OS_DELAY(10); /* delay to allow AR_WA reg write to kick in */
1787    OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1788        AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1789    /*
1790     * RTC reset and clear. Some delay in between is needed
1791     * to give the chip time to settle.
1792     */
1793    OS_REG_WRITE(ah, AR_RTC_RESET, 0);
1794    OS_DELAY(2);
1795    OS_REG_WRITE(ah, AR_RTC_RESET, 1);
1796
1797    /*
1798     * Poll till RTC is ON
1799     */
1800#define AH_RTC_POLL_TIMEOUT AH_WAIT_TIMEOUT
1801    if (!ath_hal_wait(ah,
1802             AR_RTC_STATUS, AR_RTC_STATUS_M,
1803             AR_RTC_STATUS_ON, AH_RTC_POLL_TIMEOUT))
1804    {
1805        HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
1806            "%s: RTC not waking up for %d\n", __FUNCTION__, AH_WAIT_TIMEOUT);
1807        return AH_FALSE;
1808    }
1809
1810    /*
1811     * Read Revisions from Chip right after RTC is on for the first time.
1812     * This helps us detect the chip type early and initialize it accordingly.
1813     */
1814    ar9300_read_revisions(ah);
1815
1816    /*
1817     * Warm reset if we aren't really powering on,
1818     * just restarting the driver.
1819     */
1820    return ar9300_set_reset(ah, HAL_RESET_WARM);
1821}
1822
1823/*
1824 * Write the given reset bit mask into the reset register
1825 */
1826HAL_BOOL
1827ar9300_set_reset_reg(struct ath_hal *ah, u_int32_t type)
1828{
1829    HAL_BOOL ret = AH_FALSE;
1830
1831    /*
1832     * Set force wake
1833     */
1834    OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_WA), AH9300(ah)->ah_wa_reg_val);
1835    OS_DELAY(10); /* delay to allow AR_WA reg write to kick in */
1836    OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1837        AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1838
1839    switch (type) {
1840    case HAL_RESET_POWER_ON:
1841        ret = ar9300_set_reset_power_on(ah);
1842        break;
1843    case HAL_RESET_WARM:
1844    case HAL_RESET_COLD:
1845        ret = ar9300_set_reset(ah, type);
1846        break;
1847    default:
1848        break;
1849    }
1850
1851#if ATH_SUPPORT_MCI
1852    if (AH_PRIVATE(ah)->ah_caps.hal_mci_support) {
1853        OS_REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2);
1854    }
1855#endif
1856
1857    return ret;
1858}
1859
1860/*
1861 * Places the PHY and Radio chips into reset.  A full reset
1862 * must be called to leave this state.  The PCI/MAC/PCU are
1863 * not placed into reset as we must receive interrupt to
1864 * re-enable the hardware.
1865 */
1866HAL_BOOL
1867ar9300_phy_disable(struct ath_hal *ah)
1868{
1869    if (!ar9300_set_reset_reg(ah, HAL_RESET_WARM)) {
1870        return AH_FALSE;
1871    }
1872
1873#ifdef ATH_SUPPORT_LED
1874#define REG_READ(_reg)          *((volatile u_int32_t *)(_reg))
1875#define REG_WRITE(_reg, _val)   *((volatile u_int32_t *)(_reg)) = (_val);
1876#define ATH_GPIO_OE             0xB8040000
1877#define ATH_GPIO_OUT            0xB8040008 /* GPIO Ouput Value reg.*/
1878    if (AR_SREV_WASP(ah)) {
1879        if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) {
1880            REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 13)));
1881        }
1882        else {
1883            REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 12)));
1884        }
1885    }
1886    else if (AR_SREV_SCORPION(ah)) {
1887        if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) {
1888            REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 13)));
1889        }
1890        else {
1891            REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 12)));
1892        }
1893        /* Turn off JMPST led */
1894        REG_WRITE(ATH_GPIO_OUT, (REG_READ(ATH_GPIO_OUT) | (0x1 << 15)));
1895    }
1896#undef REG_READ
1897#undef REG_WRITE
1898#endif
1899
1900    if ( AR_SREV_OSPREY(ah) ) {
1901        OS_REG_RMW(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX1), 0x0, 0x1f);
1902    }
1903
1904
1905    ar9300_init_pll(ah, AH_NULL);
1906
1907    return AH_TRUE;
1908}
1909
1910/*
1911 * Places all of hardware into reset
1912 */
1913HAL_BOOL
1914ar9300_disable(struct ath_hal *ah)
1915{
1916    if (!ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE)) {
1917        return AH_FALSE;
1918    }
1919    if (!ar9300_set_reset_reg(ah, HAL_RESET_COLD)) {
1920        return AH_FALSE;
1921    }
1922
1923    ar9300_init_pll(ah, AH_NULL);
1924
1925    return AH_TRUE;
1926}
1927
1928/*
1929 * TODO: Only write the PLL if we're changing to or from CCK mode
1930 *
1931 * WARNING: The order of the PLL and mode registers must be correct.
1932 */
1933static inline void
1934ar9300_set_rf_mode(struct ath_hal *ah, HAL_CHANNEL *chan)
1935{
1936    u_int32_t rf_mode = 0;
1937
1938    if (chan == AH_NULL) {
1939        return;
1940    }
1941    switch (AH9300(ah)->ah_hwp) {
1942    case HAL_TRUE_CHIP:
1943        rf_mode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan)) ?
1944            AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
1945        break;
1946    default:
1947        HALASSERT(0);
1948        break;
1949    }
1950    /*  Phy mode bits for 5GHz channels requiring Fast Clock */
1951    if ( IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
1952        rf_mode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
1953    }
1954    OS_REG_WRITE(ah, AR_PHY_MODE, rf_mode);
1955}
1956
1957/*
1958 * Places the hardware into reset and then pulls it out of reset
1959 */
1960HAL_BOOL
1961ar9300_chip_reset(struct ath_hal *ah, HAL_CHANNEL *chan)
1962{
1963    struct ath_hal_9300     *ahp = AH9300(ah);
1964    OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->channel : 0);
1965
1966    /*
1967     * Warm reset is optimistic.
1968     */
1969    if (!ar9300_set_reset_reg(ah, HAL_RESET_WARM)) {
1970        return AH_FALSE;
1971    }
1972
1973    /* Bring out of sleep mode (AGAIN) */
1974    if (!ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE)) {
1975        return AH_FALSE;
1976    }
1977
1978    ahp->ah_chip_full_sleep = AH_FALSE;
1979
1980    if (AR_SREV_HORNET(ah)) {
1981        ar9300_internal_regulator_apply(ah);
1982    }
1983
1984    ar9300_init_pll(ah, chan);
1985
1986    /*
1987     * Perform warm reset before the mode/PLL/turbo registers
1988     * are changed in order to deactivate the radio.  Mode changes
1989     * with an active radio can result in corrupted shifts to the
1990     * radio device.
1991     */
1992    ar9300_set_rf_mode(ah, chan);
1993
1994    return AH_TRUE;
1995}
1996
1997/* ar9300_setup_calibration
1998 * Setup HW to collect samples used for current cal
1999 */
2000inline static void
2001ar9300_setup_calibration(struct ath_hal *ah, HAL_CAL_LIST *curr_cal)
2002{
2003    /* Select calibration to run */
2004    switch (curr_cal->cal_data->cal_type) {
2005    case IQ_MISMATCH_CAL:
2006        /* Start calibration w/ 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples */
2007        OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4,
2008            AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX,
2009            curr_cal->cal_data->cal_count_max);
2010        OS_REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
2011
2012        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2013            "%s: starting IQ Mismatch Calibration\n", __func__);
2014
2015        /* Kick-off cal */
2016        OS_REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
2017
2018        break;
2019    case TEMP_COMP_CAL:
2020        if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) ||
2021            AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
2022            OS_REG_RMW_FIELD(ah,
2023                AR_HORNET_CH0_THERM, AR_PHY_65NM_CH0_THERM_LOCAL, 1);
2024            OS_REG_RMW_FIELD(ah,
2025                AR_HORNET_CH0_THERM, AR_PHY_65NM_CH0_THERM_START, 1);
2026        } else if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
2027            OS_REG_RMW_FIELD(ah,
2028                AR_PHY_65NM_CH0_THERM_JUPITER, AR_PHY_65NM_CH0_THERM_LOCAL, 1);
2029            OS_REG_RMW_FIELD(ah,
2030                AR_PHY_65NM_CH0_THERM_JUPITER, AR_PHY_65NM_CH0_THERM_START, 1);
2031        } else {
2032            OS_REG_RMW_FIELD(ah,
2033                AR_PHY_65NM_CH0_THERM, AR_PHY_65NM_CH0_THERM_LOCAL, 1);
2034            OS_REG_RMW_FIELD(ah,
2035                AR_PHY_65NM_CH0_THERM, AR_PHY_65NM_CH0_THERM_START, 1);
2036        }
2037
2038        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2039            "%s: starting Temperature Compensation Calibration\n", __func__);
2040        break;
2041    default:
2042        HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
2043            "%s called with incorrect calibration type.\n", __func__);
2044    }
2045}
2046
2047/* ar9300_reset_calibration
2048 * Initialize shared data structures and prepare a cal to be run.
2049 */
2050inline static void
2051ar9300_reset_calibration(struct ath_hal *ah, HAL_CAL_LIST *curr_cal)
2052{
2053    struct ath_hal_9300 *ahp = AH9300(ah);
2054    int i;
2055
2056    /* Setup HW for new calibration */
2057    ar9300_setup_calibration(ah, curr_cal);
2058
2059    /* Change SW state to RUNNING for this calibration */
2060    curr_cal->cal_state = CAL_RUNNING;
2061
2062    /* Reset data structures shared between different calibrations */
2063    for (i = 0; i < AR9300_MAX_CHAINS; i++) {
2064        ahp->ah_meas0.sign[i] = 0;
2065        ahp->ah_meas1.sign[i] = 0;
2066        ahp->ah_meas2.sign[i] = 0;
2067        ahp->ah_meas3.sign[i] = 0;
2068    }
2069
2070    ahp->ah_cal_samples = 0;
2071}
2072
2073#ifdef XXX_UNUSED_FUNCTION
2074/*
2075 * Find out which of the RX chains are enabled
2076 */
2077static u_int32_t
2078ar9300_get_rx_chain_mask(struct ath_hal *ah)
2079{
2080    u_int32_t ret_val = OS_REG_READ(ah, AR_PHY_RX_CHAINMASK);
2081    /* The bits [2:0] indicate the rx chain mask and are to be
2082     * interpreted as follows:
2083     * 00x => Only chain 0 is enabled
2084     * 01x => Chain 1 and 0 enabled
2085     * 1xx => Chain 2,1 and 0 enabled
2086     */
2087    return (ret_val & 0x7);
2088}
2089#endif
2090
2091static void
2092ar9300_get_nf_hist_base(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
2093    int is_scan, int16_t nf[])
2094{
2095    HAL_NFCAL_BASE *h_base;
2096
2097#ifdef ATH_NF_PER_CHAN
2098    h_base = &chan->nf_cal_hist.base;
2099#else
2100    if (is_scan) {
2101        /*
2102         * The channel we are currently on is not the home channel,
2103         * so we shouldn't use the home channel NF buffer's values on
2104         * this channel.  Instead, use the NF single value already
2105         * read for this channel.  (Or, if we haven't read the NF for
2106         * this channel yet, the SW default for this chip/band will
2107         * be used.)
2108         */
2109        h_base = &chan->nf_cal_hist.base;
2110    } else {
2111        /* use the home channel NF info */
2112        h_base = &AH_PRIVATE(ah)->nf_cal_hist.base;
2113    }
2114#endif
2115    OS_MEMCPY(nf, h_base->priv_nf, sizeof(h_base->priv_nf));
2116}
2117
2118HAL_BOOL
2119ar9300_load_nf(struct ath_hal *ah, int16_t nf[])
2120{
2121    int i, j;
2122    int32_t val;
2123    /* XXX where are EXT regs defined */
2124    const u_int32_t ar9300_cca_regs[] = {
2125        AR_PHY_CCA_0,
2126        AR_PHY_CCA_1,
2127        AR_PHY_CCA_2,
2128        AR_PHY_EXT_CCA,
2129        AR_PHY_EXT_CCA_1,
2130        AR_PHY_EXT_CCA_2,
2131    };
2132    u_int8_t chainmask;
2133
2134    /*
2135     * Force NF calibration for all chains, otherwise Vista station
2136     * would conduct a bad performance
2137     */
2138    if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) {
2139        chainmask = 0x9;
2140    } else if (AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah)) {
2141        chainmask = 0x1b;
2142    } else {
2143        chainmask = 0x3F;
2144    }
2145
2146    /*
2147     * Write filtered NF values into max_cca_pwr register parameter
2148     * so we can load below.
2149     */
2150    for (i = 0; i < NUM_NF_READINGS; i++) {
2151        if (chainmask & (1 << i)) {
2152            val = OS_REG_READ(ah, ar9300_cca_regs[i]);
2153            val &= 0xFFFFFE00;
2154            val |= (((u_int32_t)(nf[i]) << 1) & 0x1ff);
2155            OS_REG_WRITE(ah, ar9300_cca_regs[i], val);
2156        }
2157    }
2158
2159    /*
2160     * Load software filtered NF value into baseband internal min_cca_pwr
2161     * variable.
2162     */
2163    OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
2164    OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
2165    OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
2166
2167    /* Wait for load to complete, should be fast, a few 10s of us. */
2168    /* Changed the max delay 250us back to 10000us, since 250us often
2169     * results in NF load timeout and causes deaf condition
2170     * during stress testing 12/12/2009
2171     */
2172    for (j = 0; j < 10000; j++) {
2173        if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0){
2174            break;
2175        }
2176        OS_DELAY(10);
2177    }
2178    if (j == 10000) {
2179        /*
2180         * We timed out waiting for the noisefloor to load, probably
2181         * due to an in-progress rx.  Simply return here and allow
2182         * the load plenty of time to complete before the next
2183         * calibration interval.  We need to avoid trying to load -50
2184         * (which happens below) while the previous load is still in
2185         * progress as this can cause rx deafness (see EV 66368,62830).
2186         * Instead by returning here, the baseband nf cal will
2187         * just be capped by our present noisefloor until the next
2188         * calibration timer.
2189         */
2190        HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE,
2191            "%s: *** TIMEOUT while waiting for nf to load: "
2192            "AR_PHY_AGC_CONTROL=0x%x ***\n",
2193            __func__, OS_REG_READ(ah, AR_PHY_AGC_CONTROL));
2194        return AH_FALSE;
2195    }
2196
2197    /*
2198     * Restore max_cca_power register parameter again so that we're not capped
2199     * by the median we just loaded.  This will be initial (and max) value
2200     * of next noise floor calibration the baseband does.
2201     */
2202    for (i = 0; i < NUM_NF_READINGS; i++) {
2203        if (chainmask & (1 << i)) {
2204            val = OS_REG_READ(ah, ar9300_cca_regs[i]);
2205            val &= 0xFFFFFE00;
2206            val |= (((u_int32_t)(-50) << 1) & 0x1ff);
2207            OS_REG_WRITE(ah, ar9300_cca_regs[i], val);
2208        }
2209    }
2210    return AH_TRUE;
2211}
2212
2213/* ar9300_per_calibration
2214 * Generic calibration routine.
2215 * Recalibrate the lower PHY chips to account for temperature/environment
2216 * changes.
2217 */
2218inline static void
2219ar9300_per_calibration(struct ath_hal *ah,  HAL_CHANNEL_INTERNAL *ichan,
2220    u_int8_t rxchainmask, HAL_CAL_LIST *curr_cal, HAL_BOOL *is_cal_done)
2221{
2222    struct ath_hal_9300 *ahp = AH9300(ah);
2223
2224    /* Cal is assumed not done until explicitly set below */
2225    *is_cal_done = AH_FALSE;
2226
2227    /* Calibration in progress. */
2228    if (curr_cal->cal_state == CAL_RUNNING) {
2229        /* Check to see if it has finished. */
2230        if (!(OS_REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL)) {
2231            int i, num_chains = 0;
2232            for (i = 0; i < AR9300_MAX_CHAINS; i++) {
2233                if (rxchainmask & (1 << i)) {
2234                    num_chains++;
2235                }
2236            }
2237
2238            /*
2239             * Accumulate cal measures for active chains
2240             */
2241            curr_cal->cal_data->cal_collect(ah, num_chains);
2242
2243            ahp->ah_cal_samples++;
2244
2245            if (ahp->ah_cal_samples >= curr_cal->cal_data->cal_num_samples) {
2246                /*
2247                 * Process accumulated data
2248                 */
2249                curr_cal->cal_data->cal_post_proc(ah, num_chains);
2250
2251                /* Calibration has finished. */
2252                ichan->cal_valid |= curr_cal->cal_data->cal_type;
2253                curr_cal->cal_state = CAL_DONE;
2254                *is_cal_done = AH_TRUE;
2255            } else {
2256                /* Set-up collection of another sub-sample until we
2257                 * get desired number
2258                 */
2259                ar9300_setup_calibration(ah, curr_cal);
2260            }
2261        }
2262    } else if (!(ichan->cal_valid & curr_cal->cal_data->cal_type)) {
2263        /* If current cal is marked invalid in channel, kick it off */
2264        ar9300_reset_calibration(ah, curr_cal);
2265    }
2266}
2267
2268static void
2269ar9300_start_nf_cal(struct ath_hal *ah)
2270{
2271    OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
2272    OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
2273    OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
2274    AH9300(ah)->nf_tsf32 = ar9300_get_tsf32(ah);
2275}
2276
2277/* ar9300_calibration
2278 * Wrapper for a more generic Calibration routine. Primarily to abstract to
2279 * upper layers whether there is 1 or more calibrations to be run.
2280 */
2281HAL_BOOL
2282ar9300_calibration(struct ath_hal *ah,  HAL_CHANNEL *chan, u_int8_t rxchainmask,
2283    HAL_BOOL do_nf_cal, HAL_BOOL *is_cal_done, int is_scan,
2284    u_int32_t *sched_cals)
2285{
2286    struct ath_hal_9300 *ahp = AH9300(ah);
2287    HAL_CAL_LIST *curr_cal = ahp->ah_cal_list_curr;
2288    HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
2289    int16_t nf_buf[NUM_NF_READINGS];
2290
2291    *is_cal_done = AH_TRUE;
2292
2293
2294    /* XXX: For initial wasp bringup - disable periodic calibration */
2295    /* Invalid channel check */
2296    if (ichan == AH_NULL) {
2297        HALDEBUG(ah, HAL_DEBUG_CHANNEL,
2298            "%s: invalid channel %u/0x%x; no mapping\n",
2299            __func__, chan->channel, chan->channel_flags);
2300        return AH_FALSE;
2301    }
2302
2303    HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2304        "%s: Entering, Doing NF Cal = %d\n", __func__, do_nf_cal);
2305    HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: Chain 0 Rx IQ Cal Correction 0x%08x\n",
2306        __func__, OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
2307    if (!AR_SREV_HORNET(ah) && !AR_SREV_POSEIDON(ah) && !AR_SREV_APHRODITE(ah)) {
2308        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2309            "%s: Chain 1 Rx IQ Cal Correction 0x%08x\n",
2310            __func__, OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B1));
2311        if (!AR_SREV_WASP(ah) && !AR_SREV_JUPITER(ah)) {
2312            HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2313                "%s: Chain 2 Rx IQ Cal Correction 0x%08x\n",
2314                __func__, OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B2));
2315        }
2316    }
2317
2318    OS_MARK(ah, AH_MARK_PERCAL, chan->channel);
2319
2320    /* For given calibration:
2321     * 1. Call generic cal routine
2322     * 2. When this cal is done (is_cal_done) if we have more cals waiting
2323     *    (eg after reset), mask this to upper layers by not propagating
2324     *    is_cal_done if it is set to TRUE.
2325     *    Instead, change is_cal_done to FALSE and setup the waiting cal(s)
2326     *    to be run.
2327     */
2328    if (curr_cal && (curr_cal->cal_data->cal_type & *sched_cals) &&
2329        (curr_cal->cal_state == CAL_RUNNING ||
2330         curr_cal->cal_state == CAL_WAITING))
2331    {
2332        ar9300_per_calibration(ah, ichan, rxchainmask, curr_cal, is_cal_done);
2333
2334        if (*is_cal_done == AH_TRUE) {
2335            ahp->ah_cal_list_curr = curr_cal = curr_cal->cal_next;
2336
2337            if (curr_cal && curr_cal->cal_state == CAL_WAITING) {
2338                *is_cal_done = AH_FALSE;
2339                ar9300_reset_calibration(ah, curr_cal);
2340            } else {
2341                *sched_cals &= ~IQ_MISMATCH_CAL;
2342            }
2343        }
2344    }
2345
2346    /* Do NF cal only at longer intervals */
2347    if (do_nf_cal) {
2348        int nf_done;
2349
2350        /* Get the value from the previous NF cal and update history buffer */
2351        nf_done = ar9300_store_new_nf(ah, ichan, is_scan);
2352        if (ichan->channel_flags & CHANNEL_CW_INT) {
2353            chan->channel_flags |= CHANNEL_CW_INT;
2354        }
2355        ichan->channel_flags &= (~CHANNEL_CW_INT);
2356
2357        if (nf_done) {
2358            /*
2359             * Load the NF from history buffer of the current channel.
2360             * NF is slow time-variant, so it is OK to use a historical value.
2361             */
2362            ar9300_get_nf_hist_base(ah,
2363                AH_PRIVATE(ah)->ah_curchan, is_scan, nf_buf);
2364            ar9300_load_nf(ah, nf_buf);
2365
2366            /* start NF calibration, without updating BB NF register*/
2367            ar9300_start_nf_cal(ah);
2368        }
2369    }
2370    return AH_TRUE;
2371}
2372
2373/* ar9300_iq_cal_collect
2374 * Collect data from HW to later perform IQ Mismatch Calibration
2375 */
2376void
2377ar9300_iq_cal_collect(struct ath_hal *ah, u_int8_t num_chains)
2378{
2379    struct ath_hal_9300 *ahp = AH9300(ah);
2380    int i;
2381
2382    /*
2383     * Accumulate IQ cal measures for active chains
2384     */
2385    for (i = 0; i < num_chains; i++) {
2386        ahp->ah_total_power_meas_i[i] = OS_REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
2387        ahp->ah_total_power_meas_q[i] = OS_REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
2388        ahp->ah_total_iq_corr_meas[i] =
2389            (int32_t) OS_REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
2390        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2391            "%d: Chn %d "
2392            "Reg Offset(0x%04x)pmi=0x%08x; "
2393            "Reg Offset(0x%04x)pmq=0x%08x; "
2394            "Reg Offset (0x%04x)iqcm=0x%08x;\n",
2395            ahp->ah_cal_samples,
2396            i,
2397            (unsigned) AR_PHY_CAL_MEAS_0(i),
2398            ahp->ah_total_power_meas_i[i],
2399            (unsigned) AR_PHY_CAL_MEAS_1(i),
2400            ahp->ah_total_power_meas_q[i],
2401            (unsigned) AR_PHY_CAL_MEAS_2(i),
2402            ahp->ah_total_iq_corr_meas[i]);
2403    }
2404}
2405
2406/* ar9300_iq_calibration
2407 * Use HW data to perform IQ Mismatch Calibration
2408 */
2409void
2410ar9300_iq_calibration(struct ath_hal *ah, u_int8_t num_chains)
2411{
2412    struct ath_hal_9300 *ahp = AH9300(ah);
2413    u_int32_t power_meas_q, power_meas_i, iq_corr_meas;
2414    u_int32_t q_coff_denom, i_coff_denom;
2415    int32_t q_coff, i_coff;
2416    int iq_corr_neg, i;
2417    static const u_int32_t offset_array[3] = {
2418        AR_PHY_RX_IQCAL_CORR_B0,
2419        AR_PHY_RX_IQCAL_CORR_B1,
2420        AR_PHY_RX_IQCAL_CORR_B2,
2421    };
2422
2423    for (i = 0; i < num_chains; i++) {
2424        power_meas_i = ahp->ah_total_power_meas_i[i];
2425        power_meas_q = ahp->ah_total_power_meas_q[i];
2426        iq_corr_meas = ahp->ah_total_iq_corr_meas[i];
2427
2428        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2429            "Starting IQ Cal and Correction for Chain %d\n", i);
2430        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2431            "Orignal: Chn %diq_corr_meas = 0x%08x\n",
2432            i, ahp->ah_total_iq_corr_meas[i]);
2433
2434        iq_corr_neg = 0;
2435
2436        /* iq_corr_meas is always negative. */
2437        if (iq_corr_meas > 0x80000000)  {
2438            iq_corr_meas = (0xffffffff - iq_corr_meas) + 1;
2439            iq_corr_neg = 1;
2440        }
2441
2442        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2443            "Chn %d pwr_meas_i = 0x%08x\n", i, power_meas_i);
2444        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2445            "Chn %d pwr_meas_q = 0x%08x\n", i, power_meas_q);
2446        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2447            "iq_corr_neg is 0x%08x\n", iq_corr_neg);
2448
2449        i_coff_denom = (power_meas_i / 2 + power_meas_q / 2) / 256;
2450        q_coff_denom = power_meas_q / 64;
2451
2452        /* Protect against divide-by-0 */
2453        if ((i_coff_denom != 0) && (q_coff_denom != 0)) {
2454            /* IQ corr_meas is already negated if iqcorr_neg == 1 */
2455            i_coff = iq_corr_meas / i_coff_denom;
2456            q_coff = power_meas_i / q_coff_denom - 64;
2457            HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2458                "Chn %d i_coff = 0x%08x\n", i, i_coff);
2459            HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2460                "Chn %d q_coff = 0x%08x\n", i, q_coff);
2461
2462            /* Force bounds on i_coff */
2463            if (i_coff >= 63) {
2464                i_coff = 63;
2465            } else if (i_coff <= -63) {
2466                i_coff = -63;
2467            }
2468
2469            /* Negate i_coff if iq_corr_neg == 0 */
2470            if (iq_corr_neg == 0x0) {
2471                i_coff = -i_coff;
2472            }
2473
2474            /* Force bounds on q_coff */
2475            if (q_coff >= 63) {
2476                q_coff = 63;
2477            } else if (q_coff <= -63) {
2478                q_coff = -63;
2479            }
2480
2481            i_coff = i_coff & 0x7f;
2482            q_coff = q_coff & 0x7f;
2483
2484            HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2485                "Chn %d : i_coff = 0x%x  q_coff = 0x%x\n", i, i_coff, q_coff);
2486            HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2487                "Register offset (0x%04x) before update = 0x%x\n",
2488                offset_array[i], OS_REG_READ(ah, offset_array[i]));
2489
2490            OS_REG_RMW_FIELD(ah, offset_array[i],
2491                AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, i_coff);
2492            OS_REG_RMW_FIELD(ah, offset_array[i],
2493                AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, q_coff);
2494
2495            HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2496                "Register offset (0x%04x) QI COFF (bitfields 0x%08x) "
2497                "after update = 0x%x\n",
2498                offset_array[i], AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
2499                OS_REG_READ(ah, offset_array[i]));
2500            HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2501                "Register offset (0x%04x) QQ COFF (bitfields 0x%08x) "
2502                "after update = 0x%x\n",
2503                offset_array[i], AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
2504                OS_REG_READ(ah, offset_array[i]));
2505            HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2506                "IQ Cal and Correction done for Chain %d\n", i);
2507        }
2508    }
2509
2510    OS_REG_SET_BIT(ah,
2511        AR_PHY_RX_IQCAL_CORR_B0, AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE);
2512    HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2513        "IQ Cal and Correction (offset 0x%04x) enabled "
2514        "(bit position 0x%08x). New Value 0x%08x\n",
2515        (unsigned) (AR_PHY_RX_IQCAL_CORR_B0),
2516        AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE,
2517        OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
2518}
2519
2520/*
2521 * Set a limit on the overall output power.  Used for dynamic
2522 * transmit power control and the like.
2523 *
2524 * NB: limit is in units of 0.5 dbM.
2525 */
2526HAL_BOOL
2527ar9300_set_tx_power_limit(struct ath_hal *ah, u_int32_t limit,
2528    u_int16_t extra_txpow, u_int16_t tpc_in_db)
2529{
2530    struct ath_hal_9300 *ahp = AH9300(ah);
2531    struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
2532    HAL_CHANNEL_INTERNAL *ichan = ahpriv->ah_curchan;
2533    HAL_CHANNEL *chan = (HAL_CHANNEL *)ichan;
2534
2535    if (NULL == chan) {
2536        return AH_FALSE;
2537      }
2538    ahpriv->ah_power_limit = AH_MIN(limit, MAX_RATE_POWER);
2539    ahpriv->ah_extra_txpow = extra_txpow;
2540
2541    if(chan == NULL) {
2542        return AH_FALSE;
2543    }
2544    if (ar9300_eeprom_set_transmit_power(ah, &ahp->ah_eeprom, ichan,
2545        ath_hal_getctl(ah, chan), ath_hal_getantennaallowed(ah, chan),
2546        ath_hal_get_twice_max_regpower(ahpriv, ichan, chan),
2547        AH_MIN(MAX_RATE_POWER, ahpriv->ah_power_limit)) != HAL_OK)
2548    {
2549        return AH_FALSE;
2550    }
2551    return AH_TRUE;
2552}
2553
2554/*
2555 * Exported call to check for a recent gain reading and return
2556 * the current state of the thermal calibration gain engine.
2557 */
2558HAL_RFGAIN
2559ar9300_get_rfgain(struct ath_hal *ah)
2560{
2561    return HAL_RFGAIN_INACTIVE;
2562}
2563
2564#define HAL_GREEN_AP_RX_MASK 0x1
2565
2566static inline void
2567ar9300_init_chain_masks(struct ath_hal *ah, int rx_chainmask, int tx_chainmask)
2568{
2569    if (AH_PRIVATE(ah)->green_ap_ps_on ) {
2570        rx_chainmask = HAL_GREEN_AP_RX_MASK;
2571    }
2572    if (rx_chainmask == 0x5) {
2573        OS_REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN);
2574    }
2575    OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
2576    OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
2577
2578    /*
2579     * Adaptive Power Management:
2580     * Some 3 stream chips exceed the PCIe power requirements.
2581     * This workaround will reduce power consumption by using 2 tx chains
2582     * for 1 and 2 stream rates (5 GHz only).
2583     *
2584     * Set the self gen mask to 2 tx chains when APM is enabled.
2585     *
2586     */
2587    if (AH_PRIVATE(ah)->ah_caps.hal_enable_apm && (tx_chainmask == 0x7)) {
2588        OS_REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
2589    }
2590    else {
2591        OS_REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
2592    }
2593
2594    if (tx_chainmask == 0x5) {
2595        OS_REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN);
2596    }
2597}
2598
2599/*
2600 * Override INI values with chip specific configuration.
2601 */
2602static inline void
2603ar9300_override_ini(struct ath_hal *ah, HAL_CHANNEL *chan)
2604{
2605    u_int32_t val;
2606    HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps;
2607
2608    /*
2609     * Set the RX_ABORT and RX_DIS and clear it only after
2610     * RXE is set for MAC. This prevents frames with
2611     * corrupted descriptor status.
2612     */
2613    OS_REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
2614    /*
2615     * For Merlin and above, there is a new feature that allows Multicast
2616     * search based on both MAC Address and Key ID.
2617     * By default, this feature is enabled.
2618     * But since the driver is not using this feature, we switch it off;
2619     * otherwise multicast search based on MAC addr only will fail.
2620     */
2621    val = OS_REG_READ(ah, AR_PCU_MISC_MODE2) & (~AR_ADHOC_MCAST_KEYID_ENABLE);
2622    OS_REG_WRITE(ah, AR_PCU_MISC_MODE2,
2623        val | AR_BUG_58603_FIX_ENABLE | AR_AGG_WEP_ENABLE);
2624
2625
2626    /* Osprey revision specific configuration */
2627
2628    /* Osprey 2.0+ - if SW RAC support is disabled, must also disable
2629     * the Osprey 2.0 hardware RAC fix.
2630     */
2631    if (p_cap->hal_isr_rac_support == AH_FALSE) {
2632        OS_REG_CLR_BIT(ah, AR_CFG, AR_CFG_MISSING_TX_INTR_FIX_ENABLE);
2633    }
2634
2635    /* try to enable old pal if it is needed for h/w green tx */
2636    ar9300_hwgreentx_set_pal_spare(ah, 1);
2637}
2638
2639static inline void
2640ar9300_prog_ini(struct ath_hal *ah, struct ar9300_ini_array *ini_arr,
2641    int column)
2642{
2643    int i, reg_writes = 0;
2644
2645    /* New INI format: Array may be undefined (pre, core, post arrays) */
2646    if (ini_arr->ia_array == NULL) {
2647        return;
2648    }
2649
2650    /*
2651     * New INI format: Pre, core, and post arrays for a given subsystem may be
2652     * modal (> 2 columns) or non-modal (2 columns).
2653     * Determine if the array is non-modal and force the column to 1.
2654     */
2655    if (column >= ini_arr->ia_columns) {
2656        column = 1;
2657    }
2658
2659    for (i = 0; i < ini_arr->ia_rows; i++) {
2660        u_int32_t reg = INI_RA(ini_arr, i, 0);
2661        u_int32_t val = INI_RA(ini_arr, i, column);
2662
2663        /*
2664        ** Determine if this is a shift register value
2665        ** (reg >= 0x16000 && reg < 0x17000 for Osprey) ,
2666        ** and insert the configured delay if so.
2667        ** -this delay is not required for Osprey (EV#71410)
2668        */
2669        OS_REG_WRITE(ah, reg, val);
2670        WAR_6773(reg_writes);
2671
2672    }
2673}
2674
2675static inline HAL_STATUS
2676ar9300_process_ini(struct ath_hal *ah, HAL_CHANNEL *chan,
2677    HAL_CHANNEL_INTERNAL *ichan, HAL_HT_MACMODE macmode)
2678{
2679    int reg_writes = 0;
2680    struct ath_hal_9300 *ahp = AH9300(ah);
2681    u_int modes_index, modes_txgaintable_index = 0;
2682    int i;
2683    HAL_STATUS status;
2684    struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
2685    /* Setup the indices for the next set of register array writes */
2686    /* TODO:
2687     * If the channel marker is indicative of the current mode rather
2688     * than capability, we do not need to check the phy mode below.
2689     */
2690    switch (chan->channel_flags & CHANNEL_ALL) {
2691    case CHANNEL_A:
2692    case CHANNEL_A_HT20:
2693        if (AR_SREV_SCORPION(ah)){
2694            if (chan->channel <= 5350){
2695                modes_txgaintable_index = 1;
2696            }else if ((chan->channel > 5350) && (chan->channel <= 5600)){
2697                modes_txgaintable_index = 3;
2698            }else if (chan->channel > 5600){
2699                modes_txgaintable_index = 5;
2700            }
2701        }
2702        modes_index = 1;
2703        break;
2704
2705    case CHANNEL_A_HT40PLUS:
2706    case CHANNEL_A_HT40MINUS:
2707        if (AR_SREV_SCORPION(ah)){
2708            if (chan->channel <= 5350){
2709                modes_txgaintable_index = 2;
2710            }else if ((chan->channel > 5350) && (chan->channel <= 5600)){
2711                modes_txgaintable_index = 4;
2712            }else if (chan->channel > 5600){
2713                modes_txgaintable_index = 6;
2714            }
2715        }
2716        modes_index = 2;
2717        break;
2718
2719    case CHANNEL_PUREG:
2720    case CHANNEL_G_HT20:
2721    case CHANNEL_B:
2722        if (AR_SREV_SCORPION(ah)){
2723            modes_txgaintable_index = 8;
2724        }
2725        modes_index = 4;
2726        break;
2727
2728    case CHANNEL_G_HT40PLUS:
2729    case CHANNEL_G_HT40MINUS:
2730        if (AR_SREV_SCORPION(ah)){
2731            modes_txgaintable_index = 7;
2732        }
2733        modes_index = 3;
2734        break;
2735
2736    case CHANNEL_108G:
2737        modes_index = 5;
2738        break;
2739
2740    default:
2741        HALASSERT(0);
2742        return HAL_EINVAL;
2743    }
2744
2745#if 0
2746    /* Set correct Baseband to analog shift setting to access analog chips. */
2747    OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
2748#endif
2749
2750    HALDEBUG(ah, HAL_DEBUG_RESET,
2751        "ar9300_process_ini: "
2752        "Skipping OS-REG-WRITE(ah, AR-PHY(0), 0x00000007)\n");
2753    HALDEBUG(ah, HAL_DEBUG_RESET,
2754        "ar9300_process_ini: no ADDac programming\n");
2755
2756
2757    /*
2758     * Osprey 2.0+ - new INI format.
2759     * Each subsystem has a pre, core, and post array.
2760     */
2761    for (i = 0; i < ATH_INI_NUM_SPLIT; i++) {
2762        ar9300_prog_ini(ah, &ahp->ah_ini_soc[i], modes_index);
2763        ar9300_prog_ini(ah, &ahp->ah_ini_mac[i], modes_index);
2764        ar9300_prog_ini(ah, &ahp->ah_ini_bb[i], modes_index);
2765        ar9300_prog_ini(ah, &ahp->ah_ini_radio[i], modes_index);
2766        if ((i == ATH_INI_POST) && (AR_SREV_JUPITER_20(ah) || AR_SREV_APHRODITE(ah))) {
2767            ar9300_prog_ini(ah, &ahp->ah_ini_radio_post_sys2ant, modes_index);
2768        }
2769
2770    }
2771
2772	if (!(AR_SREV_SOC(ah))) {
2773			/* Doubler issue : Some board doesn't work well with MCS15. Turn off doubler after freq locking is complete*/
2774			//ath_hal_printf(ah, "%s[%d] ==== before reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
2775			OS_REG_RMW(ah, AR_PHY_65NM_CH0_RXTX2, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
2776			               1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); /*Set synthon, synthover */
2777			//ath_hal_printf(ah, "%s[%d] ==== after reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
2778
2779			OS_REG_RMW(ah, AR_PHY_65NM_CH1_RXTX2, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
2780			               1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); /*Set synthon, synthover */
2781			OS_REG_RMW(ah, AR_PHY_65NM_CH2_RXTX2, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
2782			               1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); /*Set synthon, synthover */
2783			OS_DELAY(200);
2784
2785			//ath_hal_printf(ah, "%s[%d] ==== before reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
2786			OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH0_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); /* clr synthon */
2787			OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH1_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); /* clr synthon */
2788			OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH2_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); /* clr synthon */
2789			//ath_hal_printf(ah, "%s[%d] ==== after reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
2790
2791			OS_DELAY(1);
2792
2793			//ath_hal_printf(ah, "%s[%d] ==== before reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
2794			OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); /* set synthon */
2795			OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); /* set synthon */
2796			OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); /* set synthon */
2797			//ath_hal_printf(ah, "%s[%d] ==== after reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
2798
2799			OS_DELAY(200);
2800
2801			//ath_hal_printf(ah, "%s[%d] ==== before reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_SYNTH12, OS_REG_READ(ah, AR_PHY_65NM_CH0_SYNTH12));
2802			OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_SYNTH12, AR_PHY_65NM_CH0_SYNTH12_VREFMUL3, 0xf);
2803			//OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH0_SYNTH12, 1<< 16); /* clr charge pump */
2804			//ath_hal_printf(ah, "%s[%d] ==== After  reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_SYNTH12, OS_REG_READ(ah, AR_PHY_65NM_CH0_SYNTH12));
2805
2806			OS_REG_RMW(ah, AR_PHY_65NM_CH0_RXTX2, 0, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
2807			               1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); /*Clr synthon, synthover */
2808			OS_REG_RMW(ah, AR_PHY_65NM_CH1_RXTX2, 0, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
2809			               1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); /*Clr synthon, synthover */
2810			OS_REG_RMW(ah, AR_PHY_65NM_CH2_RXTX2, 0, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
2811			               1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); /*Clr synthon, synthover */
2812			//ath_hal_printf(ah, "%s[%d] ==== after reg[0x%08x] = 0x%08x\n", __func__, __LINE__, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2));
2813		}
2814
2815    /* Write rxgain Array Parameters */
2816    REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain, 1, reg_writes);
2817    HALDEBUG(ah, HAL_DEBUG_RESET, "ar9300_process_ini: Rx Gain programming\n");
2818
2819    if (AR_SREV_SCORPION(ah)) {
2820        /* Write rxgain bounds Array */
2821        REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain_bounds, modes_index, reg_writes);
2822        HALDEBUG(ah, HAL_DEBUG_RESET, "ar9300_process_ini: Rx Gain table bounds programming\n");
2823    }
2824    /* UB124 xLNA settings */
2825    if (AR_SREV_WASP(ah) && ar9300_rx_gain_index_get(ah) == 2) {
2826#define REG_WRITE(_reg,_val)    *((volatile u_int32_t *)(_reg)) = (_val);
2827#define REG_READ(_reg)          *((volatile u_int32_t *)(_reg))
2828        u_int32_t val;
2829        /* B8040000:  bit[0]=0, bit[3]=0; */
2830        val = REG_READ(0xB8040000);
2831        val &= 0xfffffff6;
2832        REG_WRITE(0xB8040000, val);
2833        /* B804002c:  bit[31:24]=0x2e; bit[7:0]=0x2f; */
2834        val = REG_READ(0xB804002c);
2835        val &= 0x00ffff00;
2836        val |= 0x2e00002f;
2837        REG_WRITE(0xB804002c, val);
2838        /* B804006c:  bit[1]=1; */
2839        val = REG_READ(0xB804006c);
2840        val |= 0x2;
2841        REG_WRITE(0xB804006c, val);
2842#undef REG_READ
2843#undef REG_WRITE
2844    }
2845
2846
2847    /* Write txgain Array Parameters */
2848    if (AR_SREV_SCORPION(ah)) {
2849        REG_WRITE_ARRAY(&ahp->ah_ini_modes_txgain, modes_txgaintable_index,
2850            reg_writes);
2851    }else{
2852        REG_WRITE_ARRAY(&ahp->ah_ini_modes_txgain, modes_index, reg_writes);
2853    }
2854    HALDEBUG(ah, HAL_DEBUG_RESET, "ar9300_process_ini: Tx Gain programming\n");
2855
2856
2857    /* For 5GHz channels requiring Fast Clock, apply different modal values */
2858    if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
2859        HALDEBUG(ah, HAL_DEBUG_RESET,
2860            "%s: Fast clock enabled, use special ini values\n", __func__);
2861        REG_WRITE_ARRAY(&ahp->ah_ini_modes_additional, modes_index, reg_writes);
2862    }
2863
2864    if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) {
2865        HALDEBUG(ah, HAL_DEBUG_RESET,
2866            "%s: use xtal ini for AH9300(ah)->clk_25mhz: %d\n",
2867            __func__, AH9300(ah)->clk_25mhz);
2868        REG_WRITE_ARRAY(
2869            &ahp->ah_ini_modes_additional, 1/*modes_index*/, reg_writes);
2870    }
2871
2872    if (AR_SREV_WASP(ah) && (AH9300(ah)->clk_25mhz == 0)) {
2873        HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Apply 40MHz ini settings\n", __func__);
2874        REG_WRITE_ARRAY(
2875            &ahp->ah_ini_modes_additional_40mhz, 1/*modesIndex*/, reg_writes);
2876    }
2877
2878    if (2484 == chan->channel) {
2879        ar9300_prog_ini(ah, &ahp->ah_ini_japan2484, 1);
2880    }
2881
2882#if 0
2883    if (AR_SREV_JUPITER_20(ah) || AR_SREV_APHRODITE(ah)) {
2884        ar9300_prog_ini(ah, &ahp->ah_ini_BTCOEX_MAX_TXPWR, 1);
2885    }
2886#endif
2887
2888    /* Override INI with chip specific configuration */
2889    ar9300_override_ini(ah, chan);
2890
2891    /* Setup 11n MAC/Phy mode registers */
2892    ar9300_set_11n_regs(ah, chan, macmode);
2893
2894    /*
2895     * Moved ar9300_init_chain_masks() here to ensure the swap bit is set before
2896     * the pdadc table is written.  Swap must occur before any radio dependent
2897     * replicated register access.  The pdadc curve addressing in particular
2898     * depends on the consistent setting of the swap bit.
2899     */
2900    ar9300_init_chain_masks(ah, ahp->ah_rx_chainmask, ahp->ah_tx_chainmask);
2901
2902    /*
2903     * Setup the transmit power values.
2904     *
2905     * After the public to private hal channel mapping, ichan contains the
2906     * valid regulatory power value.
2907     * ath_hal_getctl and ath_hal_getantennaallowed look up ichan from chan.
2908     */
2909    status = ar9300_eeprom_set_transmit_power(ah, &ahp->ah_eeprom, ichan,
2910             ath_hal_getctl(ah, chan), ath_hal_getantennaallowed(ah, chan),
2911             ath_hal_get_twice_max_regpower(ahpriv, ichan, chan),
2912             AH_MIN(MAX_RATE_POWER, ahpriv->ah_power_limit));
2913    if (status != HAL_OK) {
2914        HALDEBUG(ah, HAL_DEBUG_POWER_MGMT,
2915            "%s: error init'ing transmit power\n", __func__);
2916        return HAL_EIO;
2917    }
2918
2919
2920    return HAL_OK;
2921#undef N
2922}
2923
2924/* ar9300_is_cal_supp
2925 * Determine if calibration is supported by device and channel flags
2926 */
2927inline static HAL_BOOL
2928ar9300_is_cal_supp(struct ath_hal *ah, HAL_CHANNEL *chan,
2929    HAL_CAL_TYPES cal_type)
2930{
2931    struct ath_hal_9300 *ahp = AH9300(ah);
2932    HAL_BOOL retval = AH_FALSE;
2933
2934    switch (cal_type & ahp->ah_supp_cals) {
2935    case IQ_MISMATCH_CAL:
2936        /* Run IQ Mismatch for non-CCK only */
2937        if (!IS_CHAN_B(chan)) {
2938            retval = AH_TRUE;
2939        }
2940        break;
2941    case TEMP_COMP_CAL:
2942        retval = AH_TRUE;
2943        break;
2944    }
2945
2946    return retval;
2947}
2948
2949
2950#if 0
2951/* ar9285_pa_cal
2952 * PA Calibration for Kite 1.1 and later versions of Kite.
2953 * - from system's team.
2954 */
2955static inline void
2956ar9285_pa_cal(struct ath_hal *ah)
2957{
2958    u_int32_t reg_val;
2959    int i, lo_gn, offs_6_1, offs_0;
2960    u_int8_t reflo;
2961    u_int32_t phy_test2_reg_val, phy_adc_ctl_reg_val;
2962    u_int32_t an_top2_reg_val, phy_tst_dac_reg_val;
2963
2964
2965    /* Kite 1.1 WAR for Bug 35666
2966     * Increase the LDO value to 1.28V before accessing analog Reg */
2967    if (AR_SREV_KITE_11(ah)) {
2968        OS_REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14) );
2969    }
2970    an_top2_reg_val = OS_REG_READ(ah, AR9285_AN_TOP2);
2971
2972    /* set pdv2i pdrxtxbb */
2973    reg_val = OS_REG_READ(ah, AR9285_AN_RXTXBB1);
2974    reg_val |= ((0x1 << 5) | (0x1 << 7));
2975    OS_REG_WRITE(ah, AR9285_AN_RXTXBB1, reg_val);
2976
2977    /* clear pwddb */
2978    reg_val = OS_REG_READ(ah, AR9285_AN_RF2G7);
2979    reg_val &= 0xfffffffd;
2980    OS_REG_WRITE(ah, AR9285_AN_RF2G7, reg_val);
2981
2982    /* clear enpacal */
2983    reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
2984    reg_val &= 0xfffff7ff;
2985    OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
2986
2987    /* set offcal */
2988    reg_val = OS_REG_READ(ah, AR9285_AN_RF2G2);
2989    reg_val |= (0x1 << 12);
2990    OS_REG_WRITE(ah, AR9285_AN_RF2G2, reg_val);
2991
2992    /* set pdpadrv1=pdpadrv2=pdpaout=1 */
2993    reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
2994    reg_val |= (0x7 << 23);
2995    OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
2996
2997    /* Read back reflo, increase it by 1 and write it. */
2998    reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
2999    reflo = ((reg_val >> 26) & 0x7);
3000
3001    if (reflo < 0x7) {
3002        reflo++;
3003    }
3004    reg_val = ((reg_val & 0xe3ffffff) | (reflo << 26));
3005    OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3006
3007    reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3008    reflo = ((reg_val >> 26) & 0x7);
3009
3010    /* use TX single carrier to transmit
3011     * dac const
3012     * reg. 15
3013     */
3014    phy_tst_dac_reg_val = OS_REG_READ(ah, AR_PHY_TSTDAC_CONST);
3015    OS_REG_WRITE(ah, AR_PHY_TSTDAC_CONST, ((0x7ff << 11) | 0x7ff));
3016    reg_val = OS_REG_READ(ah, AR_PHY_TSTDAC_CONST);
3017
3018    /* source is dac const
3019     * reg. 2
3020     */
3021    phy_test2_reg_val = OS_REG_READ(ah, AR_PHY_TEST2);
3022    OS_REG_WRITE(ah, AR_PHY_TEST2, ((0x1 << 7) | (0x1 << 1)));
3023    reg_val = OS_REG_READ(ah, AR_PHY_TEST2);
3024
3025    /* set dac on
3026     * reg. 11
3027     */
3028    phy_adc_ctl_reg_val = OS_REG_READ(ah, AR_PHY_ADC_CTL);
3029    OS_REG_WRITE(ah, AR_PHY_ADC_CTL, 0x80008000);
3030    reg_val = OS_REG_READ(ah, AR_PHY_ADC_CTL);
3031
3032    OS_REG_WRITE(ah, AR9285_AN_TOP2, (0x1 << 27) | (0x1 << 17) | (0x1 << 16) |
3033              (0x1 << 14) | (0x1 << 12) | (0x1 << 11) |
3034              (0x1 << 7) | (0x1 << 5));
3035
3036    OS_DELAY(10); /* 10 usec */
3037
3038    /* clear off[6:0] */
3039    reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6);
3040    reg_val &= 0xfc0fffff;
3041    OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val);
3042    reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3043    reg_val &= 0xfdffffff;
3044    OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3045
3046    offs_6_1 = 0;
3047    for (i = 6; i > 0; i--) {
3048        /* sef off[$k]==1 */
3049        reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6);
3050        reg_val &= 0xfc0fffff;
3051        reg_val = reg_val | (0x1 << (19 + i)) | ((offs_6_1) << 20);
3052        OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val);
3053        lo_gn = (OS_REG_READ(ah, AR9285_AN_RF2G9)) & 0x1;
3054        offs_6_1 = offs_6_1 | (lo_gn << (i - 1));
3055    }
3056
3057    reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6);
3058    reg_val &= 0xfc0fffff;
3059    reg_val = reg_val | ((offs_6_1 - 1) << 20);
3060    OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val);
3061
3062    /* set off_0=1; */
3063    reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3064    reg_val &= 0xfdffffff;
3065    reg_val = reg_val | (0x1 << 25);
3066    OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3067
3068    lo_gn = OS_REG_READ(ah, AR9285_AN_RF2G9) & 0x1;
3069    offs_0 = lo_gn;
3070
3071    reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3072    reg_val &= 0xfdffffff;
3073    reg_val = reg_val | (offs_0 << 25);
3074    OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3075
3076    /* clear pdv2i */
3077    reg_val = OS_REG_READ(ah, AR9285_AN_RXTXBB1);
3078    reg_val &= 0xffffff5f;
3079    OS_REG_WRITE(ah, AR9285_AN_RXTXBB1, reg_val);
3080
3081    /* set enpacal */
3082    reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3083    reg_val |= (0x1 << 11);
3084    OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3085
3086    /* clear offcal */
3087    reg_val = OS_REG_READ(ah, AR9285_AN_RF2G2);
3088    reg_val &= 0xffffefff;
3089    OS_REG_WRITE(ah, AR9285_AN_RF2G2, reg_val);
3090
3091    /* set pdpadrv1=pdpadrv2=pdpaout=0 */
3092    reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3093    reg_val &= 0xfc7fffff;
3094    OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3095
3096    /* Read back reflo, decrease it by 1 and write it. */
3097    reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3098    reflo = (reg_val >> 26) & 0x7;
3099    if (reflo) {
3100        reflo--;
3101    }
3102    reg_val = ((reg_val & 0xe3ffffff) | (reflo << 26));
3103    OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3104    reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3105    reflo = (reg_val >> 26) & 0x7;
3106
3107    /* write back registers */
3108    OS_REG_WRITE(ah, AR_PHY_TSTDAC_CONST, phy_tst_dac_reg_val);
3109    OS_REG_WRITE(ah, AR_PHY_TEST2, phy_test2_reg_val);
3110    OS_REG_WRITE(ah, AR_PHY_ADC_CTL, phy_adc_ctl_reg_val);
3111    OS_REG_WRITE(ah, AR9285_AN_TOP2, an_top2_reg_val);
3112
3113    /* Kite 1.1 WAR for Bug 35666
3114     * Decrease the LDO value back to 1.20V */
3115    if (AR_SREV_KITE_11(ah)) {
3116        OS_REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
3117    }
3118}
3119#endif
3120
3121/* ar9300_run_init_cals
3122 * Runs non-periodic calibrations
3123 */
3124inline static HAL_BOOL
3125ar9300_run_init_cals(struct ath_hal *ah, int init_cal_count)
3126{
3127    struct ath_hal_9300 *ahp = AH9300(ah);
3128    HAL_CHANNEL_INTERNAL ichan; /* bogus */
3129    HAL_BOOL is_cal_done;
3130    HAL_CAL_LIST *curr_cal;
3131    int i;
3132
3133    curr_cal = ahp->ah_cal_list_curr;
3134    if (curr_cal == AH_NULL) {
3135        return AH_FALSE;
3136    }
3137    ichan.cal_valid = 0;
3138
3139    for (i = 0; i < init_cal_count; i++) {
3140        /* Reset this Cal */
3141        ar9300_reset_calibration(ah, curr_cal);
3142        /* Poll for offset calibration complete */
3143        if (!ath_hal_wait(
3144                ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL, 0, AH_WAIT_TIMEOUT))
3145        {
3146            HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3147                "%s: Cal %d failed to complete in 100ms.\n",
3148                __func__, curr_cal->cal_data->cal_type);
3149            /* Re-initialize list pointers for periodic cals */
3150            ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr
3151                = AH_NULL;
3152            return AH_FALSE;
3153        }
3154        /* Run this cal */
3155        ar9300_per_calibration(
3156            ah, &ichan, ahp->ah_rx_chainmask, curr_cal, &is_cal_done);
3157        if (is_cal_done == AH_FALSE) {
3158            HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3159                "%s: Not able to run Init Cal %d.\n", __func__,
3160                curr_cal->cal_data->cal_type);
3161        }
3162        if (curr_cal->cal_next) {
3163            curr_cal = curr_cal->cal_next;
3164        }
3165    }
3166
3167    /* Re-initialize list pointers for periodic cals */
3168    ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = AH_NULL;
3169    return AH_TRUE;
3170}
3171
3172#if 0
3173static void
3174ar9300_tx_carrier_leak_war(struct ath_hal *ah)
3175{
3176    unsigned long tx_gain_table_max;
3177    unsigned long reg_bb_cl_map_0_b0 = 0xffffffff;
3178    unsigned long reg_bb_cl_map_1_b0 = 0xffffffff;
3179    unsigned long reg_bb_cl_map_2_b0 = 0xffffffff;
3180    unsigned long reg_bb_cl_map_3_b0 = 0xffffffff;
3181    unsigned long tx_gain, cal_run = 0;
3182    unsigned long cal_gain[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1];
3183    unsigned long cal_gain_index[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1];
3184    unsigned long new_gain[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1];
3185    int i, j;
3186
3187    OS_MEMSET(new_gain, 0, sizeof(new_gain));
3188    /*printf("     Running TxCarrierLeakWAR\n");*/
3189
3190    /* process tx gain table, we use cl_map_hw_gen=0. */
3191    OS_REG_RMW_FIELD(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_MAP_HW_GEN, 0);
3192
3193	//the table we used is txbb_gc[2:0], 1dB[2:1].
3194    tx_gain_table_max = OS_REG_READ_FIELD(ah,
3195        AR_PHY_TPC_7, AR_PHY_TPC_7_TX_GAIN_TABLE_MAX);
3196
3197    for (i = 0; i <= tx_gain_table_max; i++) {
3198        tx_gain = OS_REG_READ(ah, AR_PHY_TXGAIN_TAB(1) + i * 4);
3199        cal_gain[i] = (((tx_gain >> 5)& 0x7) << 2) |
3200            (((tx_gain >> 1) & 0x3) << 0);
3201        if (i == 0) {
3202            cal_gain_index[i] = cal_run;
3203            new_gain[i] = 1;
3204            cal_run++;
3205        } else {
3206            new_gain[i] = 1;
3207            for (j = 0; j < i; j++) {
3208                /*
3209                printf("i=%d, j=%d cal_gain[$i]=0x%04x\n", i, j, cal_gain[i]);
3210                 */
3211                if (new_gain[i]) {
3212                    if ((cal_gain[i] != cal_gain[j])) {
3213                        new_gain[i] = 1;
3214                    } else {
3215                        /* if old gain found, use old cal_run value. */
3216                        new_gain[i] = 0;
3217                        cal_gain_index[i] = cal_gain_index[j];
3218                    }
3219                }
3220            }
3221            /* if new gain found, increase cal_run */
3222            if (new_gain[i] == 1) {
3223                cal_gain_index[i] = cal_run;
3224                cal_run++;
3225            }
3226        }
3227
3228        reg_bb_cl_map_0_b0 = (reg_bb_cl_map_0_b0 & ~(0x1 << i)) |
3229            ((cal_gain_index[i] >> 0 & 0x1) << i);
3230        reg_bb_cl_map_1_b0 = (reg_bb_cl_map_1_b0 & ~(0x1 << i)) |
3231            ((cal_gain_index[i] >> 1 & 0x1) << i);
3232        reg_bb_cl_map_2_b0 = (reg_bb_cl_map_2_b0 & ~(0x1 << i)) |
3233            ((cal_gain_index[i] >> 2 & 0x1) << i);
3234        reg_bb_cl_map_3_b0 = (reg_bb_cl_map_3_b0 & ~(0x1 << i)) |
3235            ((cal_gain_index[i] >> 3 & 0x1) << i);
3236
3237        /*
3238        printf("i=%2d, cal_gain[$i]= 0x%04x, cal_run= %d, "
3239            "cal_gain_index[i]=%d, new_gain[i] = %d\n",
3240            i, cal_gain[i], cal_run, cal_gain_index[i], new_gain[i]);
3241         */
3242    }
3243    OS_REG_WRITE(ah, AR_PHY_CL_MAP_0_B0, reg_bb_cl_map_0_b0);
3244    OS_REG_WRITE(ah, AR_PHY_CL_MAP_1_B0, reg_bb_cl_map_1_b0);
3245    OS_REG_WRITE(ah, AR_PHY_CL_MAP_2_B0, reg_bb_cl_map_2_b0);
3246    OS_REG_WRITE(ah, AR_PHY_CL_MAP_3_B0, reg_bb_cl_map_3_b0);
3247    if (AR_SREV_WASP(ah)) {
3248        OS_REG_WRITE(ah, AR_PHY_CL_MAP_0_B1, reg_bb_cl_map_0_b0);
3249        OS_REG_WRITE(ah, AR_PHY_CL_MAP_1_B1, reg_bb_cl_map_1_b0);
3250        OS_REG_WRITE(ah, AR_PHY_CL_MAP_2_B1, reg_bb_cl_map_2_b0);
3251        OS_REG_WRITE(ah, AR_PHY_CL_MAP_3_B1, reg_bb_cl_map_3_b0);
3252    }
3253}
3254#endif
3255
3256
3257static inline void
3258ar9300_invalidate_saved_cals(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
3259{
3260#if ATH_SUPPORT_CAL_REUSE
3261    if (AH_PRIVATE(ah)->ah_config.ath_hal_cal_reuse &
3262        ATH_CAL_REUSE_REDO_IN_FULL_RESET)
3263    {
3264        ichan->one_time_txiqcal_done = AH_FALSE;
3265        ichan->one_time_txclcal_done = AH_FALSE;
3266    }
3267#endif
3268}
3269
3270static inline HAL_BOOL
3271ar9300_restore_rtt_cals(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
3272{
3273    HAL_BOOL restore_status = AH_FALSE;
3274
3275    return restore_status;
3276}
3277
3278/* ar9300_init_cal
3279 * Initialize Calibration infrastructure
3280 */
3281static inline HAL_BOOL
3282ar9300_init_cal_internal(struct ath_hal *ah, HAL_CHANNEL *chan,
3283                         HAL_CHANNEL_INTERNAL *ichan, HAL_BOOL enable_rtt,
3284                         HAL_BOOL do_rtt_cal, HAL_BOOL skip_if_none, HAL_BOOL apply_last_iqcorr)
3285{
3286    struct ath_hal_9300 *ahp = AH9300(ah);
3287    HAL_BOOL txiqcal_success_flag = AH_FALSE;
3288    HAL_BOOL cal_done = AH_FALSE;
3289    int iqcal_idx = 0;
3290    HAL_BOOL do_sep_iq_cal = AH_FALSE;
3291    HAL_BOOL do_agc_cal = do_rtt_cal;
3292    HAL_BOOL is_cal_reusable = AH_TRUE;
3293#if ATH_SUPPORT_CAL_REUSE
3294    HAL_BOOL      cal_reuse_enable = AH_PRIVATE(ah)->ah_config.ath_hal_cal_reuse &
3295                                 ATH_CAL_REUSE_ENABLE;
3296    HAL_BOOL      clc_success = AH_FALSE;
3297    int32_t   ch_idx, j, cl_tab_reg;
3298    u_int32_t BB_cl_tab_entry = MAX_BB_CL_TABLE_ENTRY;
3299    u_int32_t BB_cl_tab_b[AR9300_MAX_CHAINS] = {
3300                    AR_PHY_CL_TAB_0,
3301                    AR_PHY_CL_TAB_1,
3302                    AR_PHY_CL_TAB_2
3303                };
3304#endif
3305
3306    if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) {
3307        /* Hornet: 1 x 1 */
3308        ahp->ah_rx_cal_chainmask = 0x1;
3309        ahp->ah_tx_cal_chainmask = 0x1;
3310    } else if (AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah)) {
3311        /* Wasp/Jupiter: 2 x 2 */
3312        ahp->ah_rx_cal_chainmask = 0x3;
3313        ahp->ah_tx_cal_chainmask = 0x3;
3314    } else {
3315        /*
3316         * Osprey needs to be configured for the correct chain mode
3317         * before running AGC/TxIQ cals.
3318         */
3319        if (ahp->ah_enterprise_mode & AR_ENT_OTP_CHAIN2_DISABLE) {
3320            /* chain 2 disabled - 2 chain mode */
3321            ahp->ah_rx_cal_chainmask = 0x3;
3322            ahp->ah_tx_cal_chainmask = 0x3;
3323        } else {
3324            ahp->ah_rx_cal_chainmask = 0x7;
3325            ahp->ah_tx_cal_chainmask = 0x7;
3326        }
3327    }
3328        ar9300_init_chain_masks(ah, ahp->ah_rx_cal_chainmask, ahp->ah_tx_cal_chainmask);
3329
3330
3331    if (ahp->tx_cl_cal_enable) {
3332#if ATH_SUPPORT_CAL_REUSE
3333        /* disable Carrie Leak or set do_agc_cal accordingly */
3334        if (cal_reuse_enable && ichan->one_time_txclcal_done)
3335        {
3336            OS_REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
3337        } else
3338#endif /* ATH_SUPPORT_CAL_REUSE */
3339        {
3340            OS_REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
3341            do_agc_cal = AH_TRUE;
3342        }
3343    }
3344
3345    /* Do Tx IQ Calibration here for osprey hornet and wasp */
3346    /* XXX: For initial wasp bringup - check and enable this */
3347    /* EV 74233: Tx IQ fails to complete for half/quarter rates */
3348    if (!(IS_CHAN_HALF_RATE(ichan) || IS_CHAN_QUARTER_RATE(ichan))) {
3349        if (ahp->tx_iq_cal_enable) {
3350            /* this should be eventually moved to INI file */
3351            OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1(ah),
3352                AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, DELPT);
3353
3354            /*
3355             * For poseidon and later chips,
3356             * Tx IQ cal HW run will be a part of AGC calibration
3357             */
3358            if (ahp->tx_iq_cal_during_agc_cal) {
3359                /*
3360                 * txiqcal_success_flag always set to 1 to run
3361                 *     ar9300_tx_iq_cal_post_proc
3362                 * if following AGC cal passes
3363                */
3364#if ATH_SUPPORT_CAL_REUSE
3365                if (!cal_reuse_enable || !ichan->one_time_txiqcal_done)
3366                {
3367                    txiqcal_success_flag = AH_TRUE;
3368                    OS_REG_WRITE(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah),
3369                        OS_REG_READ(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah)) |
3370                        AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
3371                } else {
3372                    OS_REG_WRITE(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah),
3373                        OS_REG_READ(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah)) &
3374                        (~AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL));
3375                }
3376#else
3377		if (OS_REG_READ_FIELD(ah,
3378					AR_PHY_TX_IQCAL_CONTROL_0(ah),
3379					AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)){
3380			if (apply_last_iqcorr == AH_TRUE) {
3381				OS_REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah),
3382						AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
3383				txiqcal_success_flag = AH_FALSE;
3384			} else {
3385				txiqcal_success_flag = AH_TRUE;
3386			}
3387		}else{
3388			txiqcal_success_flag = AH_FALSE;
3389		}
3390#endif
3391                if (txiqcal_success_flag) {
3392                    do_agc_cal = AH_TRUE;
3393                }
3394            } else
3395#if ATH_SUPPORT_CAL_REUSE
3396            if (!cal_reuse_enable || !ichan->one_time_txiqcal_done)
3397#endif
3398            {
3399                do_sep_iq_cal = AH_TRUE;
3400                do_agc_cal = AH_TRUE;
3401            }
3402        }
3403    }
3404
3405#if ATH_SUPPORT_MCI
3406    if (AH_PRIVATE(ah)->ah_caps.hal_mci_support &&
3407        IS_CHAN_2GHZ(ichan) &&
3408        (ahp->ah_mci_bt_state == MCI_BT_AWAKE) &&
3409        do_agc_cal &&
3410        !(AH_PRIVATE(ah)->ah_config.ath_hal_mci_config &
3411        ATH_MCI_CONFIG_DISABLE_MCI_CAL))
3412    {
3413        u_int32_t payload[4] = {0, 0, 0, 0};
3414
3415        /* Send CAL_REQ only when BT is AWAKE. */
3416        HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Send WLAN_CAL_REQ 0x%X\n",
3417            __func__, ahp->ah_mci_wlan_cal_seq);
3418        MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_REQ);
3419        payload[MCI_GPM_WLAN_CAL_W_SEQUENCE] = ahp->ah_mci_wlan_cal_seq++;
3420        ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE);
3421
3422        /* Wait BT_CAL_GRANT for 50ms */
3423        HALDEBUG(ah, HAL_DEBUG_BT_COEX,
3424            "(MCI) %s: Wait for BT_CAL_GRANT\n", __func__);
3425        if (ar9300_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000))
3426        {
3427            HALDEBUG(ah, HAL_DEBUG_BT_COEX,
3428                "(MCI) %s: Got BT_CAL_GRANT.\n", __func__);
3429        }
3430        else {
3431            is_cal_reusable = AH_FALSE;
3432            HALDEBUG(ah, HAL_DEBUG_BT_COEX,
3433                "(MCI) %s: BT is not responding.\n", __func__);
3434        }
3435    }
3436#endif /* ATH_SUPPORT_MCI */
3437
3438    if (do_sep_iq_cal)
3439    {
3440        /* enable Tx IQ Calibration HW for osprey/hornet/wasp */
3441        txiqcal_success_flag = ar9300_tx_iq_cal_hw_run(ah);
3442        OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
3443        OS_DELAY(5);
3444        OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
3445    }
3446#if 0
3447    if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) {
3448        ar9300_tx_carrier_leak_war(ah);
3449    }
3450#endif
3451    /*
3452     * Calibrate the AGC
3453     *
3454     * Tx IQ cal is a part of AGC cal for Jupiter/Poseidon, etc.
3455     * please enable the bit of txiqcal_control_0[31] in INI file
3456     * for Jupiter/Poseidon/etc.
3457     */
3458    if(!AR_SREV_SCORPION(ah)) {
3459        if (do_agc_cal || !skip_if_none) {
3460            OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3461                OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
3462
3463            /* Poll for offset calibration complete */
3464            cal_done = ath_hal_wait(ah,
3465                    AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT);
3466            if (!cal_done) {
3467                HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3468                    "(FCS) CAL NOT DONE!!! - %d\n", ichan->channel);
3469            }
3470        } else {
3471            cal_done = AH_TRUE;
3472        }
3473            /*
3474             * Tx IQ cal post-processing in SW
3475             * This part of code should be common to all chips,
3476             * no chip specific code for Jupiter/Posdeion except for register names.
3477             */
3478            if (txiqcal_success_flag) {
3479                ar9300_tx_iq_cal_post_proc(ah,ichan, 1, 1,is_cal_reusable,false);
3480            }
3481    } else {
3482        if (!txiqcal_success_flag) {
3483            OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3484                OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
3485            if (!ath_hal_wait( ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
3486                    0, AH_WAIT_TIMEOUT)) {
3487                HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3488                    "%s: offset calibration failed to complete in 1ms; "
3489                    "noisy environment?\n", __func__);
3490                return AH_FALSE;
3491            }
3492            if (apply_last_iqcorr == AH_TRUE) {
3493                ar9300_tx_iq_cal_post_proc(ah, ichan, 0, 0, is_cal_reusable, AH_TRUE);
3494            }
3495        } else {
3496            for (iqcal_idx=0;iqcal_idx<MAXIQCAL;iqcal_idx++) {
3497                OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3498                    OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
3499
3500                /* Poll for offset calibration complete */
3501                if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL,
3502                        AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
3503                    HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3504                        "%s: offset calibration failed to complete in 1ms; "
3505                        "noisy environment?\n", __func__);
3506                    return AH_FALSE;
3507                }
3508                /*
3509                 * Tx IQ cal post-processing in SW
3510                 * This part of code should be common to all chips,
3511                 * no chip specific code for Jupiter/Posdeion except for register names.
3512                 */
3513                ar9300_tx_iq_cal_post_proc(ah, ichan, iqcal_idx+1, MAXIQCAL, is_cal_reusable, AH_FALSE);
3514            }
3515       }
3516    }
3517
3518
3519#if ATH_SUPPORT_MCI
3520    if (AH_PRIVATE(ah)->ah_caps.hal_mci_support &&
3521        IS_CHAN_2GHZ(ichan) &&
3522        (ahp->ah_mci_bt_state == MCI_BT_AWAKE) &&
3523        do_agc_cal &&
3524        !(AH_PRIVATE(ah)->ah_config.ath_hal_mci_config &
3525        ATH_MCI_CONFIG_DISABLE_MCI_CAL))
3526    {
3527        u_int32_t payload[4] = {0, 0, 0, 0};
3528
3529        HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Send WLAN_CAL_DONE 0x%X\n",
3530            __func__, ahp->ah_mci_wlan_cal_done);
3531        MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_DONE);
3532        payload[MCI_GPM_WLAN_CAL_W_SEQUENCE] = ahp->ah_mci_wlan_cal_done++;
3533        ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE);
3534    }
3535#endif /* ATH_SUPPORT_MCI */
3536
3537
3538    if (!cal_done && !AR_SREV_SCORPION(ah) )
3539    {
3540        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3541            "%s: offset calibration failed to complete in 1ms; "
3542            "noisy environment?\n", __func__);
3543        return AH_FALSE;
3544    }
3545
3546#if 0
3547     /* Beacon stuck fix, refer to EV 120056 */
3548    if(IS_CHAN_2GHZ(chan) && AR_SREV_SCORPION(ah))
3549        OS_REG_WRITE(ah, AR_PHY_TIMING5, OS_REG_READ(ah,AR_PHY_TIMING5) & ~AR_PHY_TIMING5_CYCPWR_THR1_ENABLE);
3550#endif
3551
3552#if 0
3553    /* Do PA Calibration */
3554    if (AR_SREV_KITE(ah) && AR_SREV_KITE_11_OR_LATER(ah)) {
3555        ar9285_pa_cal(ah);
3556    }
3557#endif
3558
3559#if ATH_SUPPORT_CAL_REUSE
3560     if (ichan->one_time_txiqcal_done) {
3561        ar9300_tx_iq_cal_apply(ah, ichan);
3562        HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3563            "(FCS) TXIQCAL applied - %d\n", ichan->channel);
3564    }
3565#endif /* ATH_SUPPORT_CAL_REUSE */
3566
3567#if ATH_SUPPORT_CAL_REUSE
3568    if (cal_reuse_enable && ahp->tx_cl_cal_enable)
3569    {
3570        clc_success = (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) &
3571                  AR_PHY_AGC_CONTROL_CLC_SUCCESS) ? 1 : 0;
3572
3573        if (ichan->one_time_txclcal_done)
3574        {
3575            /* reapply CL cal results */
3576            for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
3577                if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) {
3578                    continue;
3579                }
3580                cl_tab_reg = BB_cl_tab_b[ch_idx];
3581                for (j = 0; j < BB_cl_tab_entry; j++) {
3582                    OS_REG_WRITE(ah, cl_tab_reg, ichan->tx_clcal[ch_idx][j]);
3583                    cl_tab_reg += 4;;
3584                }
3585            }
3586            HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3587                "(FCS) TX CL CAL applied - %d\n", ichan->channel);
3588        }
3589        else if (is_cal_reusable && clc_success) {
3590            /* save CL cal results */
3591            for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
3592                if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) {
3593                    continue;
3594                }
3595                cl_tab_reg = BB_cl_tab_b[ch_idx];
3596                for (j = 0; j < BB_cl_tab_entry; j++) {
3597                    ichan->tx_clcal[ch_idx][j] = OS_REG_READ(ah, cl_tab_reg);
3598                    cl_tab_reg += 4;
3599                }
3600            }
3601            ichan->one_time_txclcal_done = AH_TRUE;
3602            HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3603                "(FCS) TX CL CAL saved - %d\n", ichan->channel);
3604        }
3605    }
3606#endif /* ATH_SUPPORT_CAL_REUSE */
3607
3608
3609    /* Revert chainmasks to their original values before NF cal */
3610    ar9300_init_chain_masks(ah, ahp->ah_rx_chainmask, ahp->ah_tx_chainmask);
3611
3612#if !FIX_NOISE_FLOOR
3613    /*
3614     * Do NF calibration after DC offset and other CALs.
3615     * Per system engineers, noise floor value can sometimes be 20 dB
3616     * higher than normal value if DC offset and noise floor cal are
3617     * triggered at the same time.
3618     */
3619    OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3620        OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
3621#endif
3622
3623    /* Initialize list pointers */
3624    ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = AH_NULL;
3625
3626    /*
3627     * Enable IQ, ADC Gain, ADC DC Offset Cals
3628     */
3629    /* Setup all non-periodic, init time only calibrations */
3630    /* XXX: Init DC Offset not working yet */
3631#ifdef not_yet
3632    if (AH_TRUE == ar9300_is_cal_supp(ah, chan, ADC_DC_INIT_CAL)) {
3633        INIT_CAL(&ahp->ah_adc_dc_cal_init_data);
3634        INSERT_CAL(ahp, &ahp->ah_adc_dc_cal_init_data);
3635    }
3636
3637    /* Initialize current pointer to first element in list */
3638    ahp->ah_cal_list_curr = ahp->ah_cal_list;
3639
3640    if (ahp->ah_cal_list_curr) {
3641        if (ar9300_run_init_cals(ah, 0) == AH_FALSE) {
3642            return AH_FALSE;
3643        }
3644    }
3645#endif
3646    /* end - Init time calibrations */
3647
3648    /* If Cals are supported, add them to list via INIT/INSERT_CAL */
3649    if (AH_TRUE == ar9300_is_cal_supp(ah, chan, IQ_MISMATCH_CAL)) {
3650        INIT_CAL(&ahp->ah_iq_cal_data);
3651        INSERT_CAL(ahp, &ahp->ah_iq_cal_data);
3652        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3653            "%s: enabling IQ Calibration.\n", __func__);
3654    }
3655    if (AH_TRUE == ar9300_is_cal_supp(ah, chan, TEMP_COMP_CAL)) {
3656        INIT_CAL(&ahp->ah_temp_comp_cal_data);
3657        INSERT_CAL(ahp, &ahp->ah_temp_comp_cal_data);
3658        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3659            "%s: enabling Temperature Compensation Calibration.\n", __func__);
3660    }
3661
3662    /* Initialize current pointer to first element in list */
3663    ahp->ah_cal_list_curr = ahp->ah_cal_list;
3664
3665    /* Reset state within current cal */
3666    if (ahp->ah_cal_list_curr) {
3667        ar9300_reset_calibration(ah, ahp->ah_cal_list_curr);
3668    }
3669
3670    /* Mark all calibrations on this channel as being invalid */
3671    ichan->cal_valid = 0;
3672
3673    return AH_TRUE;
3674}
3675
3676static inline HAL_BOOL
3677ar9300_init_cal(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL skip_if_none, HAL_BOOL apply_last_iqcorr)
3678{
3679    HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
3680    HAL_BOOL do_rtt_cal = AH_TRUE;
3681    HAL_BOOL enable_rtt = AH_FALSE;
3682
3683    HALASSERT(ichan);
3684
3685
3686
3687    return ar9300_init_cal_internal(ah, chan, ichan, enable_rtt, do_rtt_cal, skip_if_none, apply_last_iqcorr);
3688}
3689
3690/* ar9300_reset_cal_valid
3691 * Entry point for upper layers to restart current cal.
3692 * Reset the calibration valid bit in channel.
3693 */
3694void
3695ar9300_reset_cal_valid(struct ath_hal *ah, HAL_CHANNEL *chan,
3696    HAL_BOOL *is_cal_done, u_int32_t cal_type)
3697{
3698    struct ath_hal_9300 *ahp = AH9300(ah);
3699    HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
3700    HAL_CAL_LIST *curr_cal = ahp->ah_cal_list_curr;
3701
3702    *is_cal_done = AH_TRUE;
3703
3704    if (curr_cal == AH_NULL) {
3705        return;
3706    }
3707    if (ichan == AH_NULL) {
3708        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3709            "%s: invalid channel %u/0x%x; no mapping\n",
3710            __func__, chan->channel, chan->channel_flags);
3711        return;
3712    }
3713
3714    if (!(cal_type & IQ_MISMATCH_CAL)) {
3715        *is_cal_done = AH_FALSE;
3716        return;
3717    }
3718
3719    /* Expected that this calibration has run before, post-reset.
3720     * Current state should be done
3721     */
3722    if (curr_cal->cal_state != CAL_DONE) {
3723        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3724            "%s: Calibration state incorrect, %d\n",
3725            __func__, curr_cal->cal_state);
3726        return;
3727    }
3728
3729    /* Verify Cal is supported on this channel */
3730    if (ar9300_is_cal_supp(ah, chan, curr_cal->cal_data->cal_type) == AH_FALSE) {
3731        return;
3732    }
3733
3734    HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3735        "%s: Resetting Cal %d state for channel %u/0x%x\n", __func__,
3736        curr_cal->cal_data->cal_type, chan->channel, chan->channel_flags);
3737
3738    /* Disable cal validity in channel */
3739    ichan->cal_valid &= ~curr_cal->cal_data->cal_type;
3740    curr_cal->cal_state = CAL_WAITING;
3741    /* Indicate to upper layers that we need polling */
3742    *is_cal_done = AH_FALSE;
3743}
3744
3745static inline void
3746ar9300_set_dma(struct ath_hal *ah)
3747{
3748    u_int32_t   regval;
3749    struct ath_hal_9300 *ahp = AH9300(ah);
3750
3751#if 0
3752    /*
3753     * set AHB_MODE not to do cacheline prefetches
3754     */
3755    regval = OS_REG_READ(ah, AR_AHB_MODE);
3756    OS_REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
3757#endif
3758
3759    /*
3760     * let mac dma reads be in 128 byte chunks
3761     */
3762    regval = OS_REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
3763    OS_REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
3764
3765    /*
3766     * Restore TX Trigger Level to its pre-reset value.
3767     * The initial value depends on whether aggregation is enabled, and is
3768     * adjusted whenever underruns are detected.
3769     */
3770    /*
3771    OS_REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, AH_PRIVATE(ah)->ah_tx_trig_level);
3772     */
3773    /*
3774     * Osprey 1.0 bug (EV 61936). Don't change trigger level from .ini default.
3775     * Osprey 2.0 - hardware recommends using the default INI settings.
3776     */
3777#if 0
3778    OS_REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, 0x3f);
3779#endif
3780    /*
3781     * let mac dma writes be in 128 byte chunks
3782     */
3783    regval = OS_REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
3784    OS_REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
3785
3786    /*
3787     * Setup receive FIFO threshold to hold off TX activities
3788     */
3789    OS_REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
3790
3791    /*
3792     * reduce the number of usable entries in PCU TXBUF to avoid
3793     * wrap around bugs. (bug 20428)
3794     */
3795
3796    if (AR_SREV_WASP(ah) &&
3797        (AH_PRIVATE((ah))->ah_macRev > AR_SREV_REVISION_WASP_12)) {
3798        /* Wasp 1.3 fix for EV#85395 requires usable entries
3799         * to be set to 0x500
3800         */
3801        OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, 0x500);
3802    } else {
3803        OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, AR_PCU_TXBUF_CTRL_USABLE_SIZE);
3804    }
3805
3806    /*
3807     * Enable HPQ for UAPSD
3808     */
3809    if (AH_PRIVATE(ah)->ah_opmode == HAL_M_HOSTAP) {
3810        OS_REG_WRITE(ah, AR_HP_Q_CONTROL,
3811            AR_HPQ_ENABLE | AR_HPQ_UAPSD | AR_HPQ_UAPSD_TRIGGER_EN);
3812    }
3813
3814    /*
3815     * set the transmit status ring
3816     */
3817    ar9300_reset_tx_status_ring(ah);
3818
3819    /*
3820     * set rxbp threshold.  Must be non-zero for RX_EOL to occur.
3821     * For Osprey 2.0+, keep the original thresholds
3822     * otherwise performance is lost due to excessive RX EOL interrupts.
3823     */
3824    OS_REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_HP, 0x1);
3825    OS_REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_LP, 0x1);
3826
3827    /*
3828     * set receive buffer size.
3829     */
3830    if (ahp->rx_buf_size) {
3831        OS_REG_WRITE(ah, AR_DATABUF, ahp->rx_buf_size);
3832    }
3833}
3834
3835static inline void
3836ar9300_init_bb(struct ath_hal *ah, HAL_CHANNEL *chan)
3837{
3838    u_int32_t synth_delay;
3839
3840    /*
3841     * Wait for the frequency synth to settle (synth goes on
3842     * via AR_PHY_ACTIVE_EN).  Read the phy active delay register.
3843     * Value is in 100ns increments.
3844     */
3845    synth_delay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
3846    if (IS_CHAN_CCK(chan)) {
3847        synth_delay = (4 * synth_delay) / 22;
3848    } else {
3849        synth_delay /= 10;
3850    }
3851
3852    /* Activate the PHY (includes baseband activate + synthesizer on) */
3853    OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
3854
3855    /*
3856     * There is an issue if the AP starts the calibration before
3857     * the base band timeout completes.  This could result in the
3858     * rx_clear AH_FALSE triggering.  As a workaround we add delay an
3859     * extra BASE_ACTIVATE_DELAY usecs to ensure this condition
3860     * does not happen.
3861     */
3862    OS_DELAY(synth_delay + BASE_ACTIVATE_DELAY);
3863}
3864
3865static inline void
3866ar9300_init_interrupt_masks(struct ath_hal *ah, HAL_OPMODE opmode)
3867{
3868    struct ath_hal_9300 *ahp = AH9300(ah);
3869    u_int32_t msi_cfg = 0;
3870    u_int32_t sync_en_def = AR9300_INTR_SYNC_DEFAULT;
3871
3872    /*
3873     * Setup interrupt handling.  Note that ar9300_reset_tx_queue
3874     * manipulates the secondary IMR's as queues are enabled
3875     * and disabled.  This is done with RMW ops to insure the
3876     * settings we make here are preserved.
3877     */
3878    ahp->ah_mask_reg =
3879        AR_IMR_TXERR | AR_IMR_TXURN |
3880        AR_IMR_RXERR | AR_IMR_RXORN |
3881        AR_IMR_BCNMISC;
3882
3883    if (ahp->ah_intr_mitigation_rx) {
3884        /* enable interrupt mitigation for rx */
3885        ahp->ah_mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR | AR_IMR_RXOK_HP;
3886        msi_cfg |= AR_INTCFG_MSI_RXINTM | AR_INTCFG_MSI_RXMINTR;
3887    } else {
3888        ahp->ah_mask_reg |= AR_IMR_RXOK_LP | AR_IMR_RXOK_HP;
3889        msi_cfg |= AR_INTCFG_MSI_RXOK;
3890    }
3891    if (ahp->ah_intr_mitigation_tx) {
3892        /* enable interrupt mitigation for tx */
3893        ahp->ah_mask_reg |= AR_IMR_TXINTM | AR_IMR_TXMINTR;
3894        msi_cfg |= AR_INTCFG_MSI_TXINTM | AR_INTCFG_MSI_TXMINTR;
3895    } else {
3896        ahp->ah_mask_reg |= AR_IMR_TXOK;
3897        msi_cfg |= AR_INTCFG_MSI_TXOK;
3898    }
3899    if (opmode == HAL_M_HOSTAP) {
3900        ahp->ah_mask_reg |= AR_IMR_MIB;
3901    }
3902
3903    OS_REG_WRITE(ah, AR_IMR, ahp->ah_mask_reg);
3904    OS_REG_WRITE(ah, AR_IMR_S2, OS_REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
3905    ahp->ah_mask2Reg = OS_REG_READ(ah, AR_IMR_S2);
3906
3907    if (AH_PRIVATE(ah)->ah_config.ath_hal_enable_msi) {
3908        /* Cache MSI register value */
3909        ahp->ah_msi_reg = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_PCIE_MSI));
3910        ahp->ah_msi_reg |= AR_PCIE_MSI_HW_DBI_WR_EN;
3911        if (AR_SREV_POSEIDON(ah)) {
3912            ahp->ah_msi_reg &= AR_PCIE_MSI_HW_INT_PENDING_ADDR_MSI_64;
3913        } else {
3914            ahp->ah_msi_reg &= AR_PCIE_MSI_HW_INT_PENDING_ADDR;
3915        }
3916        /* Program MSI configuration */
3917        OS_REG_WRITE(ah, AR_INTCFG, msi_cfg);
3918    }
3919
3920    /*
3921     * debug - enable to see all synchronous interrupts status
3922     */
3923    /* Clear any pending sync cause interrupts */
3924    OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE), 0xFFFFFFFF);
3925
3926    /* Allow host interface sync interrupt sources to set cause bit */
3927    if (AR_SREV_POSEIDON(ah)) {
3928        sync_en_def = AR9300_INTR_SYNC_DEF_NO_HOST1_PERR;
3929    }
3930    else if (AR_SREV_WASP(ah)) {
3931        sync_en_def = AR9340_INTR_SYNC_DEFAULT;
3932    }
3933    OS_REG_WRITE(ah,
3934        AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), sync_en_def);
3935
3936    /* _Disable_ host interface sync interrupt when cause bits set */
3937    OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_MASK), 0);
3938
3939    OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_ENABLE), 0);
3940    OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_MASK), 0);
3941    OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_SYNC_ENABLE), 0);
3942    OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_SYNC_MASK), 0);
3943}
3944
3945static inline void
3946ar9300_init_qos(struct ath_hal *ah)
3947{
3948    OS_REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);  /* XXX magic */
3949    OS_REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);    /* XXX magic */
3950
3951    /* Turn on NOACK Support for QoS packets */
3952    OS_REG_WRITE(ah, AR_QOS_NO_ACK,
3953        SM(2, AR_QOS_NO_ACK_TWO_BIT) |
3954        SM(5, AR_QOS_NO_ACK_BIT_OFF) |
3955        SM(0, AR_QOS_NO_ACK_BYTE_OFF));
3956
3957    /*
3958     * initialize TXOP for all TIDs
3959     */
3960    OS_REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL);
3961    OS_REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF);
3962    OS_REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
3963    OS_REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
3964    OS_REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
3965}
3966
3967static inline void
3968ar9300_init_user_settings(struct ath_hal *ah)
3969{
3970    struct ath_hal_9300 *ahp = AH9300(ah);
3971
3972    /* Restore user-specified settings */
3973    HALDEBUG(ah, HAL_DEBUG_RESET,
3974        "--AP %s ahp->ah_misc_mode 0x%x\n", __func__, ahp->ah_misc_mode);
3975    if (ahp->ah_misc_mode != 0) {
3976        OS_REG_WRITE(ah,
3977            AR_PCU_MISC, OS_REG_READ(ah, AR_PCU_MISC) | ahp->ah_misc_mode);
3978    }
3979    if (ahp->ah_get_plcp_hdr) {
3980        OS_REG_CLR_BIT(ah, AR_PCU_MISC, AR_PCU_SEL_EVM);
3981    }
3982    if (ahp->ah_slot_time != (u_int) -1) {
3983        ar9300_set_slot_time(ah, ahp->ah_slot_time);
3984    }
3985    if (ahp->ah_ack_timeout != (u_int) -1) {
3986        ar9300_set_ack_timeout(ah, ahp->ah_ack_timeout);
3987    }
3988    if (AH_PRIVATE(ah)->ah_diagreg != 0) {
3989        OS_REG_SET_BIT(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);
3990    }
3991    if (ahp->ah_beacon_rssi_threshold != 0) {
3992        ar9300_set_hw_beacon_rssi_threshold(ah, ahp->ah_beacon_rssi_threshold);
3993    }
3994#ifdef ATH_SUPPORT_DFS
3995    if (ahp->ah_cac_quiet_enabled) {
3996        ar9300_cac_tx_quiet(ah, 1);
3997    }
3998#endif /* ATH_SUPPORT_DFS */
3999}
4000
4001int
4002ar9300_get_spur_info(struct ath_hal * ah, int *enable, int len, u_int16_t *freq)
4003{
4004    struct ath_hal_private *ap = AH_PRIVATE(ah);
4005    int i, j;
4006
4007    for (i = 0; i < len; i++) {
4008        freq[i] =  0;
4009    }
4010
4011    *enable = ap->ah_config.ath_hal_spur_mode;
4012    for (i = 0, j = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4013        if (ap->ah_config.ath_hal_spur_chans[i][0] != AR_NO_SPUR) {
4014            freq[j++] = ap->ah_config.ath_hal_spur_chans[i][0];
4015            HALDEBUG(ah, HAL_DEBUG_ANI,
4016                "1. get spur %d\n", ap->ah_config.ath_hal_spur_chans[i][0]);
4017        }
4018        if (ap->ah_config.ath_hal_spur_chans[i][1] != AR_NO_SPUR) {
4019            freq[j++] = ap->ah_config.ath_hal_spur_chans[i][1];
4020            HALDEBUG(ah, HAL_DEBUG_ANI,
4021                "2. get spur %d\n", ap->ah_config.ath_hal_spur_chans[i][1]);
4022        }
4023    }
4024
4025    return 0;
4026}
4027
4028#define ATH_HAL_2GHZ_FREQ_MIN   20000
4029#define ATH_HAL_2GHZ_FREQ_MAX   29999
4030#define ATH_HAL_5GHZ_FREQ_MIN   50000
4031#define ATH_HAL_5GHZ_FREQ_MAX   59999
4032
4033int
4034ar9300_set_spur_info(struct ath_hal * ah, int enable, int len, u_int16_t *freq)
4035{
4036    struct ath_hal_private *ap = AH_PRIVATE(ah);
4037    int i, j, k;
4038
4039    ap->ah_config.ath_hal_spur_mode = enable;
4040
4041    if (ap->ah_config.ath_hal_spur_mode == SPUR_ENABLE_IOCTL) {
4042        for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4043            ap->ah_config.ath_hal_spur_chans[i][0] = AR_NO_SPUR;
4044            ap->ah_config.ath_hal_spur_chans[i][1] = AR_NO_SPUR;
4045        }
4046        for (i = 0, j = 0, k = 0; i < len; i++) {
4047            if (freq[i] > ATH_HAL_2GHZ_FREQ_MIN &&
4048                freq[i] < ATH_HAL_2GHZ_FREQ_MAX)
4049            {
4050                /* 2GHz Spur */
4051                if (j < AR_EEPROM_MODAL_SPURS) {
4052                    ap->ah_config.ath_hal_spur_chans[j++][1] =  freq[i];
4053                    HALDEBUG(ah, HAL_DEBUG_ANI, "1 set spur %d\n", freq[i]);
4054                }
4055            } else if (freq[i] > ATH_HAL_5GHZ_FREQ_MIN &&
4056                       freq[i] < ATH_HAL_5GHZ_FREQ_MAX)
4057            {
4058                /* 5Ghz Spur */
4059                if (k < AR_EEPROM_MODAL_SPURS) {
4060                    ap->ah_config.ath_hal_spur_chans[k++][0] =  freq[i];
4061                    HALDEBUG(ah, HAL_DEBUG_ANI, "2 set spur %d\n", freq[i]);
4062                }
4063            }
4064        }
4065    }
4066
4067    return 0;
4068}
4069
4070#define ar9300_check_op_mode(_opmode) \
4071    ((_opmode == HAL_M_STA) || (_opmode == HAL_M_IBSS) ||\
4072     (_opmode == HAL_M_HOSTAP) || (_opmode == HAL_M_MONITOR))
4073
4074
4075
4076
4077#ifndef ATH_NF_PER_CHAN
4078/*
4079* To fixed first reset noise floor value not correct issue
4080* For ART need it to fixed low rate sens too low issue
4081*/
4082static int
4083First_NFCal(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan,
4084	int is_scan, HAL_CHANNEL *chan)
4085{
4086    HAL_NFCAL_HIST_FULL *nfh;
4087    int i, j, k;
4088    int16_t nfarray[NUM_NF_READINGS] = {0};
4089    int is_2g = 0;
4090    int nf_hist_len;
4091    int stats = 0;
4092
4093    int16_t nf_buf[NUM_NF_READINGS];
4094#define IS(_c, _f)       (((_c)->channel_flags & _f) || 0)
4095
4096
4097    if ((!is_scan) &&
4098        chan->channel == AH_PRIVATE(ah)->ah_curchan->channel)
4099    {
4100        nfh = &AH_PRIVATE(ah)->nf_cal_hist;
4101    } else {
4102        nfh = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist;
4103    }
4104
4105    ar9300_start_nf_cal(ah);
4106    for (j = 0; j < 10000; j++) {
4107        if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0){
4108            break;
4109		}
4110        OS_DELAY(10);
4111    }
4112	if (j < 10000) {
4113        is_2g = IS(ichan, CHANNEL_2GHZ);
4114        ar9300_upload_noise_floor(ah, is_2g, nfarray);
4115
4116	    if (is_scan) {
4117			/*
4118			 * This channel's NF cal info is just a HAL_NFCAL_HIST_SMALL struct
4119			 * rather than a HAL_NFCAL_HIST_FULL struct.
4120			 * As long as we only use the first history element of nf_cal_buffer
4121			 * (nf_cal_buffer[0][0:NUM_NF_READINGS-1]), we can use
4122			 * HAL_NFCAL_HIST_SMALL and HAL_NFCAL_HIST_FULL interchangeably.
4123			 */
4124            nfh = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist;
4125            nf_hist_len = HAL_NF_CAL_HIST_LEN_SMALL;
4126		} else {
4127            nfh = &AH_PRIVATE(ah)->nf_cal_hist;
4128            nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
4129		}
4130
4131  	    for (i = 0; i < NUM_NF_READINGS; i ++) {
4132    		for (k = 0; k < HAL_NF_CAL_HIST_LEN_FULL; k++) {
4133                nfh->nf_cal_buffer[k][i] = nfarray[i];
4134            }
4135            nfh->base.priv_nf[i] = ar9300_limit_nf_range(ah,
4136							ar9300_get_nf_hist_mid(ah, nfh, i, nf_hist_len));
4137  		}
4138
4139
4140		//ar9300StoreNewNf(ah, ichan, is_scan);
4141
4142		/*
4143		 * See if the NF value from the old channel should be
4144		 * retained when switching to a new channel.
4145		 * TBD: this may need to be changed, as it wipes out the
4146		 * purpose of saving NF values for each channel.
4147		 */
4148		for (i = 0; i < NUM_NF_READINGS; i++)
4149		{
4150    		if (IS_CHAN_2GHZ(chan))
4151    		{
4152    			if (nfh->nf_cal_buffer[0][i] <
4153					AR_PHY_CCA_MAX_GOOD_VAL_OSPREY_2GHZ)
4154                {
4155                    ichan->nf_cal_hist.nf_cal_buffer[0][i] =
4156							AH_PRIVATE(ah)->nf_cal_hist.nf_cal_buffer[0][i];
4157				}
4158    		} else {
4159                if (AR_SREV_AR9580(ah)) {
4160                    if (nfh->nf_cal_buffer[0][i] <
4161                        AR_PHY_CCA_NOM_VAL_PEACOCK_5GHZ)
4162                    {
4163                       ichan->nf_cal_hist.nf_cal_buffer[0][i] =
4164                       AH_PRIVATE(ah)->nf_cal_hist.nf_cal_buffer[0][i];
4165                    }
4166                } else {
4167                   if (nfh->nf_cal_buffer[0][i] <
4168                       AR_PHY_CCA_NOM_VAL_OSPREY_5GHZ)
4169                    {
4170                        ichan->nf_cal_hist.nf_cal_buffer[0][i] =
4171                            AH_PRIVATE(ah)->nf_cal_hist.nf_cal_buffer[0][i];
4172                     }
4173                }
4174            }
4175        }
4176		/*
4177		 * Copy the channel's NF buffer, which may have been modified
4178		 * just above here, to the full NF history buffer.
4179		 */
4180        ar9300_reset_nf_hist_buff(ah, ichan);
4181        ar9300_get_nf_hist_base(ah,
4182                    AH_PRIVATE(ah)->ah_curchan, is_scan, nf_buf);
4183        ar9300_load_nf(ah, nf_buf);
4184        stats = 0;
4185	} else {
4186        stats = 1;
4187	}
4188#undef IS
4189    return stats;
4190}
4191#endif
4192
4193
4194/*
4195 * Places the device in and out of reset and then places sane
4196 * values in the registers based on EEPROM config, initialization
4197 * vectors (as determined by the mode), and station configuration
4198 *
4199 * b_channel_change is used to preserve DMA/PCU registers across
4200 * a HW Reset during channel change.
4201 */
4202HAL_BOOL
4203ar9300_reset(struct ath_hal *ah, HAL_OPMODE opmode, HAL_CHANNEL *chan,
4204    HAL_HT_MACMODE macmode, u_int8_t txchainmask, u_int8_t rxchainmask,
4205    HAL_HT_EXTPROTSPACING extprotspacing, HAL_BOOL b_channel_change,
4206    HAL_STATUS *status, int is_scan)
4207{
4208#define FAIL(_code)     do { ecode = _code; goto bad; } while (0)
4209    u_int32_t               save_led_state;
4210    struct ath_hal_9300     *ahp = AH9300(ah);
4211    struct ath_hal_private  *ap  = AH_PRIVATE(ah);
4212    HAL_CHANNEL_INTERNAL    *ichan;
4213    HAL_CHANNEL_INTERNAL    *curchan = ap->ah_curchan;
4214#if ATH_SUPPORT_MCI
4215    HAL_BOOL                    save_full_sleep = ahp->ah_chip_full_sleep;
4216#endif
4217    u_int32_t               save_def_antenna;
4218    u_int32_t               mac_sta_id1;
4219    HAL_STATUS              ecode;
4220    int                     i, rx_chainmask;
4221    int                     nf_hist_buff_reset = 0;
4222    int16_t                 nf_buf[NUM_NF_READINGS];
4223#ifdef ATH_FORCE_PPM
4224    u_int32_t               save_force_val, tmp_reg;
4225#endif
4226    HAL_BOOL                    stopped, cal_ret;
4227    HAL_BOOL                    apply_last_iqcorr = AH_FALSE;
4228
4229    if (OS_REG_READ(ah, AR_IER) == AR_IER_ENABLE) {
4230        HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, "** Reset called with WLAN "
4231                "interrupt enabled %08x **\n", ar9300_get_interrupts(ah));
4232    }
4233
4234    /*
4235     * Set the status to "ok" by default to cover the cases
4236     * where we return AH_FALSE without going to "bad"
4237     */
4238    HALASSERT(status);
4239    *status = HAL_OK;
4240    if ((AH_PRIVATE(ah)->ah_config.ath_hal_sta_update_tx_pwr_enable)) {
4241        AH_PRIVATE(ah)->green_tx_status = HAL_RSSI_TX_POWER_NONE;
4242    }
4243
4244#if ATH_SUPPORT_MCI
4245    if (AH_PRIVATE(ah)->ah_caps.hal_mci_support &&
4246        (AR_SREV_JUPITER_20(ah) || AR_SREV_APHRODITE(ah)))
4247    {
4248        ar9300_mci_2g5g_changed(ah, IS_CHAN_2GHZ(chan));
4249    }
4250#endif
4251
4252    ahp->ah_ext_prot_spacing = extprotspacing;
4253    ahp->ah_tx_chainmask = txchainmask & ap->ah_caps.hal_tx_chain_mask;
4254    ahp->ah_rx_chainmask = rxchainmask & ap->ah_caps.hal_rx_chain_mask;
4255    ahp->ah_tx_cal_chainmask = ap->ah_caps.hal_tx_chain_mask;
4256    ahp->ah_rx_cal_chainmask = ap->ah_caps.hal_rx_chain_mask;
4257    HALASSERT(ar9300_check_op_mode(opmode));
4258
4259    OS_MARK(ah, AH_MARK_RESET, b_channel_change);
4260
4261    /*
4262     * Map public channel to private.
4263     */
4264    ichan = ar9300_check_chan(ah, chan);
4265    if (ichan == AH_NULL) {
4266        HALDEBUG(ah, HAL_DEBUG_CHANNEL,
4267            "%s: invalid channel %u/0x%x; no mapping\n",
4268            __func__, chan->channel, chan->channel_flags);
4269        FAIL(HAL_EINVAL);
4270    }
4271
4272    ichan->paprd_table_write_done = 0;  /* Clear PAPRD table write flag */
4273    chan->paprd_table_write_done = 0;  /* Clear PAPRD table write flag */
4274
4275    if (ar9300_get_power_mode(ah) != HAL_PM_FULL_SLEEP) {
4276        /* Need to stop RX DMA before reset otherwise chip might hang */
4277        stopped = ar9300_set_rx_abort(ah, AH_TRUE); /* abort and disable PCU */
4278        ar9300_set_rx_filter(ah, 0);
4279        stopped &= ar9300_stop_dma_receive(ah, 0); /* stop and disable RX DMA */
4280        if (!stopped) {
4281            /*
4282             * During the transition from full sleep to reset,
4283             * recv DMA regs are not available to be read
4284             */
4285            HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
4286                "%s[%d]: ar9300_stop_dma_receive failed\n", __func__, __LINE__);
4287            b_channel_change = AH_FALSE;
4288        }
4289    } else {
4290        HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
4291            "%s[%d]: Chip is already in full sleep\n", __func__, __LINE__);
4292    }
4293
4294#if ATH_SUPPORT_MCI
4295    if ((AH_PRIVATE(ah)->ah_caps.hal_mci_support) &&
4296        (ahp->ah_mci_bt_state == MCI_BT_CAL_START))
4297    {
4298        u_int32_t payload[4] = {0, 0, 0, 0};
4299
4300        HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4301            "(MCI) %s: Stop rx for BT cal.\n", __func__);
4302        ahp->ah_mci_bt_state = MCI_BT_CAL;
4303
4304        /*
4305         * MCIFIX: disable mci interrupt here. This is to avoid SW_MSG_DONE or
4306         * RX_MSG bits to trigger MCI_INT and lead to mci_intr reentry.
4307         */
4308        ar9300_mci_disable_interrupt(ah);
4309
4310        HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4311            "(MCI) %s: Send WLAN_CAL_GRANT\n", __func__);
4312        MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT);
4313        ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE);
4314
4315        /* Wait BT calibration to be completed for 25ms */
4316        HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4317            "(MCI) %s: BT is calibrating.\n", __func__);
4318        if (ar9300_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_DONE, 0, 25000)) {
4319            HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4320                "(MCI) %s: Got BT_CAL_DONE.\n", __func__);
4321        }
4322        else {
4323            HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4324                "(MCI) %s: ### BT cal takes too long. Force bt_state to be bt_awake.\n",
4325                __func__);
4326        }
4327        ahp->ah_mci_bt_state = MCI_BT_AWAKE;
4328        /* MCIFIX: enable mci interrupt here */
4329        ar9300_mci_enable_interrupt(ah);
4330
4331        return AH_TRUE;
4332    }
4333#endif
4334
4335    /* Bring out of sleep mode */
4336    if (!ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE)) {
4337        *status = HAL_INV_PMODE;
4338        return AH_FALSE;
4339    }
4340
4341    /* Check the Rx mitigation config again, it might have changed
4342     * during attach in ath_vap_attach.
4343     */
4344    if (AH_PRIVATE(ah)->ah_config.ath_hal_intr_mitigation_rx != 0) {
4345        ahp->ah_intr_mitigation_rx = AH_TRUE;
4346    } else {
4347        ahp->ah_intr_mitigation_rx = AH_FALSE;
4348    }
4349
4350    /* Get the value from the previous NF cal and update history buffer */
4351    if (curchan && (ahp->ah_chip_full_sleep != AH_TRUE)) {
4352        ar9300_store_new_nf(ah, curchan, is_scan);
4353    }
4354
4355    /*
4356     * Account for the effect of being in either the 2 GHz or 5 GHz band
4357     * on the nominal, max allowable, and min allowable noise floor values.
4358     */
4359    ap->nfp = IS_CHAN_2GHZ(chan) ? &ap->nf_2GHz : &ap->nf_5GHz;
4360
4361    if (AR_SREV_SCORPION(ah) && curchan && (chan->channel == curchan->channel) &&
4362        ((chan->channel_flags & (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)) ==
4363         (curchan->channel_flags &
4364          (CHANNEL_ALL | CHANNEL_HALF | CHANNEL_QUARTER)))) {
4365            apply_last_iqcorr = AH_TRUE;
4366    }
4367
4368#ifndef ATH_NF_PER_CHAN
4369    /*
4370     * If there's only one full-size home-channel NF history buffer
4371     * rather than a full-size NF history buffer per channel, decide
4372     * whether to (re)initialize the home-channel NF buffer.
4373     * If this is just a channel change for a scan, or if the channel
4374     * is not being changed, don't mess up the home channel NF history
4375     * buffer with NF values from this scanned channel.  If we're
4376     * changing the home channel to a new channel, reset the home-channel
4377     * NF history buffer with the most accurate NF known for the new channel.
4378     */
4379    if (!is_scan && (!ap->ah_curchan ||
4380        ap->ah_curchan->channel != chan->channel ||
4381        ap->ah_curchan->channel_flags != chan->channel_flags))
4382    {
4383        nf_hist_buff_reset = 1;
4384        ar9300_reset_nf_hist_buff(ah, ichan);
4385    }
4386#endif
4387    /*
4388     * Fast channel change (Change synthesizer based on channel freq
4389     * without resetting chip)
4390     * Don't do it when
4391     *   - Flag is not set
4392     *   - Chip is just coming out of full sleep
4393     *   - Channel to be set is same as current channel
4394     *   - Channel flags are different, like when moving from 2GHz to 5GHz
4395     *     channels
4396     *   - Merlin: Switching in/out of fast clock enabled channels
4397     *             (not currently coded, since fast clock is enabled
4398     *             across the 5GHz band
4399     *             and we already do a full reset when switching in/out
4400     *             of 5GHz channels)
4401     */
4402    if (b_channel_change &&
4403        (ahp->ah_chip_full_sleep != AH_TRUE) &&
4404        (AH_PRIVATE(ah)->ah_curchan != AH_NULL) &&
4405        ((chan->channel != AH_PRIVATE(ah)->ah_curchan->channel) &&
4406        (((CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) & chan->channel_flags) ==
4407        ((CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) & AH_PRIVATE(ah)->ah_curchan->channel_flags))))
4408    {
4409        if (ar9300_channel_change(ah, chan, ichan, macmode)) {
4410            chan->channel_flags = ichan->channel_flags;
4411            chan->priv_flags = ichan->priv_flags;
4412            AH_PRIVATE(ah)->ah_curchan->ah_channel_time = 0;
4413            AH_PRIVATE(ah)->ah_curchan->ah_tsf_last = ar9300_get_tsf64(ah);
4414
4415            /*
4416             * Load the NF from history buffer of the current channel.
4417             * NF is slow time-variant, so it is OK to use a historical value.
4418             */
4419            ar9300_get_nf_hist_base(ah,
4420                AH_PRIVATE(ah)->ah_curchan, is_scan, nf_buf);
4421            ar9300_load_nf(ah, nf_buf);
4422
4423            /* start NF calibration, without updating BB NF register*/
4424            ar9300_start_nf_cal(ah);
4425
4426            /*
4427             * If channel_change completed and DMA was stopped
4428             * successfully - skip the rest of reset
4429             */
4430            if (AH9300(ah)->ah_dma_stuck != AH_TRUE) {
4431                WAR_USB_DISABLE_PLL_LOCK_DETECT(ah);
4432#if ATH_SUPPORT_MCI
4433                if (AH_PRIVATE(ah)->ah_caps.hal_mci_support && ahp->ah_mci_ready)
4434                {
4435                    ar9300_mci_2g5g_switch(ah, AH_TRUE);
4436                }
4437#endif
4438                return AH_TRUE;
4439            }
4440         }
4441    }
4442
4443#if ATH_SUPPORT_MCI
4444    if (AH_PRIVATE(ah)->ah_caps.hal_mci_support) {
4445        ar9300_mci_disable_interrupt(ah);
4446        if (ahp->ah_mci_ready && !save_full_sleep) {
4447            ar9300_mci_mute_bt(ah);
4448            OS_DELAY(20);
4449            OS_REG_WRITE(ah, AR_BTCOEX_CTRL, 0);
4450        }
4451
4452        ahp->ah_mci_bt_state = MCI_BT_SLEEP;
4453        ahp->ah_mci_ready = AH_FALSE;
4454    }
4455#endif
4456
4457    AH9300(ah)->ah_dma_stuck = AH_FALSE;
4458#ifdef ATH_FORCE_PPM
4459    /* Preserve force ppm state */
4460    save_force_val =
4461        OS_REG_READ(ah, AR_PHY_TIMING2) &
4462        (AR_PHY_TIMING2_USE_FORCE | AR_PHY_TIMING2_FORCE_VAL);
4463#endif
4464    /*
4465     * Preserve the antenna on a channel change
4466     */
4467    save_def_antenna = OS_REG_READ(ah, AR_DEF_ANTENNA);
4468    if (0 == ahp->ah_smartantenna_enable )
4469    {
4470        if (save_def_antenna == 0) {
4471            save_def_antenna = 1;
4472        }
4473    }
4474
4475    /* Save hardware flag before chip reset clears the register */
4476    mac_sta_id1 = OS_REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
4477
4478    /* Save led state from pci config register */
4479    save_led_state = OS_REG_READ(ah, AR_CFG_LED) &
4480        (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
4481        AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
4482
4483    /* Mark PHY inactive prior to reset, to be undone in ar9300_init_bb () */
4484    ar9300_mark_phy_inactive(ah);
4485
4486    if (!ar9300_chip_reset(ah, chan)) {
4487        HALDEBUG(ah, HAL_DEBUG_RESET, "%s: chip reset failed\n", __func__);
4488        FAIL(HAL_EIO);
4489    }
4490
4491    OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
4492
4493
4494    /* Disable JTAG */
4495    OS_REG_SET_BIT(ah,
4496        AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL), AR_GPIO_JTAG_DISABLE);
4497
4498    /*
4499     * Note that ar9300_init_chain_masks() is called from within
4500     * ar9300_process_ini() to ensure the swap bit is set before
4501     * the pdadc table is written.
4502     */
4503    ecode = ar9300_process_ini(ah, chan, ichan, macmode);
4504    if (ecode != HAL_OK) {
4505        goto bad;
4506    }
4507
4508    ahp->ah_immunity_on = AH_FALSE;
4509
4510    if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
4511        ahp->tx_iq_cal_enable = OS_REG_READ_FIELD(ah,
4512                                AR_PHY_TX_IQCAL_CONTROL_0(ah),
4513                                AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL) ?
4514                                1 : 0;
4515    }
4516    ahp->tx_cl_cal_enable = (OS_REG_READ(ah, AR_PHY_CL_CAL_CTL) &
4517                                AR_PHY_CL_CAL_ENABLE) ? 1 : 0;
4518
4519    /* For devices with full HW RIFS Rx support (Sowl/Howl/Merlin, etc),
4520     * restore register settings from prior to reset.
4521     */
4522    if ((AH_PRIVATE(ah)->ah_curchan != AH_NULL) &&
4523        (ar9300_get_capability(ah, HAL_CAP_LDPCWAR, 0, AH_NULL) == HAL_OK))
4524    {
4525        /* Re-program RIFS Rx policy after reset */
4526        ar9300_set_rifs_delay(ah, ahp->ah_rifs_enabled);
4527    }
4528
4529#if ATH_SUPPORT_MCI
4530    if (AH_PRIVATE(ah)->ah_caps.hal_mci_support) {
4531        ar9300_mci_reset(ah, AH_FALSE, IS_CHAN_2GHZ(chan), save_full_sleep);
4532    }
4533#endif
4534
4535    /* Initialize Management Frame Protection */
4536    ar9300_init_mfp(ah);
4537
4538    ahp->ah_immunity_vals[0] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW,
4539        AR_PHY_SFCORR_LOW_M1_THRESH_LOW);
4540    ahp->ah_immunity_vals[1] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW,
4541        AR_PHY_SFCORR_LOW_M2_THRESH_LOW);
4542    ahp->ah_immunity_vals[2] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR,
4543        AR_PHY_SFCORR_M1_THRESH);
4544    ahp->ah_immunity_vals[3] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR,
4545        AR_PHY_SFCORR_M2_THRESH);
4546    ahp->ah_immunity_vals[4] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR,
4547        AR_PHY_SFCORR_M2COUNT_THR);
4548    ahp->ah_immunity_vals[5] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW,
4549        AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW);
4550
4551    /* Write delta slope for OFDM enabled modes (A, G, Turbo) */
4552    if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) {
4553        ar9300_set_delta_slope(ah, ichan);
4554    }
4555
4556    ar9300_spur_mitigate(ah, chan);
4557    if (!ar9300_eeprom_set_board_values(ah, ichan)) {
4558        HALDEBUG(ah, HAL_DEBUG_EEPROM,
4559            "%s: error setting board options\n", __func__);
4560        FAIL(HAL_EIO);
4561    }
4562
4563#ifdef ATH_HAL_WAR_REG16284_APH128
4564    /* temp work around, will be removed. */
4565    if (AR_SREV_WASP(ah)) {
4566        OS_REG_WRITE(ah, 0x16284, 0x1553e000);
4567    }
4568#endif
4569
4570    OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
4571
4572    OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr));
4573    OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4)
4574            | mac_sta_id1
4575            | AR_STA_ID1_RTS_USE_DEF
4576            | (ap->ah_config.ath_hal_6mb_ack ? AR_STA_ID1_ACKCTS_6MB : 0)
4577            | ahp->ah_sta_id1_defaults
4578    );
4579    ar9300_set_operating_mode(ah, opmode);
4580
4581    /* Set Venice BSSID mask according to current state */
4582    OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssid_mask));
4583    OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssid_mask + 4));
4584
4585    /* Restore previous antenna */
4586    OS_REG_WRITE(ah, AR_DEF_ANTENNA, save_def_antenna);
4587#ifdef ATH_FORCE_PPM
4588    /* Restore force ppm state */
4589    tmp_reg = OS_REG_READ(ah, AR_PHY_TIMING2) &
4590        ~(AR_PHY_TIMING2_USE_FORCE | AR_PHY_TIMING2_FORCE_VAL);
4591    OS_REG_WRITE(ah, AR_PHY_TIMING2, tmp_reg | save_force_val);
4592#endif
4593
4594    /* then our BSSID and assocID */
4595    OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
4596    OS_REG_WRITE(ah, AR_BSS_ID1,
4597        LE_READ_2(ahp->ah_bssid + 4) |
4598        ((ahp->ah_assoc_id & 0x3fff) << AR_BSS_ID1_AID_S));
4599
4600    OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */
4601
4602    OS_REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR, INIT_RSSI_THR);
4603
4604    /* HW beacon processing */
4605    OS_REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_BCN_WEIGHT,
4606            INIT_RSSI_BEACON_WEIGHT);
4607    OS_REG_SET_BIT(ah, AR_HWBCNPROC1, AR_HWBCNPROC1_CRC_ENABLE |
4608            AR_HWBCNPROC1_EXCLUDE_TIM_ELM);
4609    if (AH_PRIVATE(ah)->ah_config.ath_hal_beacon_filter_interval) {
4610        OS_REG_RMW_FIELD(ah, AR_HWBCNPROC2, AR_HWBCNPROC2_FILTER_INTERVAL,
4611                AH_PRIVATE(ah)->ah_config.ath_hal_beacon_filter_interval);
4612        OS_REG_SET_BIT(ah, AR_HWBCNPROC2,
4613                AR_HWBCNPROC2_FILTER_INTERVAL_ENABLE);
4614    }
4615
4616
4617    /*
4618     * Set Channel now modifies bank 6 parameters for FOWL workaround
4619     * to force rf_pwd_icsyndiv bias current as function of synth
4620     * frequency.Thus must be called after ar9300_process_ini() to ensure
4621     * analog register cache is valid.
4622     */
4623    if (!ahp->ah_rf_hal.set_channel(ah, ichan)) {
4624        FAIL(HAL_EIO);
4625    }
4626
4627
4628    OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
4629
4630    /* Set 1:1 QCU to DCU mapping for all queues */
4631    for (i = 0; i < AR_NUM_DCU; i++) {
4632        OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
4633    }
4634
4635    ahp->ah_intr_txqs = 0;
4636    for (i = 0; i < AH_PRIVATE(ah)->ah_caps.hal_total_queues; i++) {
4637        ar9300_reset_tx_queue(ah, i);
4638    }
4639
4640    ar9300_init_interrupt_masks(ah, opmode);
4641
4642    /* Reset ier reference count to disabled */
4643    OS_ATOMIC_SET(&ahp->ah_ier_ref_count, 1);
4644    if (ath_hal_isrfkillenabled(ah)) {
4645        ar9300_enable_rf_kill(ah);
4646    }
4647
4648    /* must be called AFTER ini is processed */
4649    ar9300_ani_init_defaults(ah, macmode);
4650
4651    ar9300_init_qos(ah);
4652
4653    ar9300_init_user_settings(ah);
4654
4655
4656    AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */
4657
4658    OS_MARK(ah, AH_MARK_RESET_DONE, 0);
4659
4660    /*
4661     * disable seq number generation in hw
4662     */
4663    OS_REG_WRITE(ah, AR_STA_ID1,
4664        OS_REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
4665
4666    ar9300_set_dma(ah);
4667
4668    /*
4669     * program OBS bus to see MAC interrupts
4670     */
4671#if ATH_SUPPORT_MCI
4672    if (!AH_PRIVATE(ah)->ah_caps.hal_mci_support) {
4673        OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_OBS), 8);
4674    }
4675#else
4676    OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_OBS), 8);
4677#endif
4678
4679
4680    /* enabling AR_GTTM_IGNORE_IDLE in GTTM register so that
4681       GTT timer will not increment if the channel idle indicates
4682       the air is busy or NAV is still counting down */
4683    OS_REG_WRITE(ah, AR_GTTM, AR_GTTM_IGNORE_IDLE);
4684
4685    /*
4686     * GTT debug mode setting
4687     */
4688    /*
4689    OS_REG_WRITE(ah, 0x64, 0x00320000);
4690    OS_REG_WRITE(ah, 0x68, 7);
4691    OS_REG_WRITE(ah, 0x4080, 0xC);
4692     */
4693    /*
4694     * Disable general interrupt mitigation by setting MIRT = 0x0
4695     * Rx and tx interrupt mitigation are conditionally enabled below.
4696     */
4697    OS_REG_WRITE(ah, AR_MIRT, 0);
4698    if (ahp->ah_intr_mitigation_rx) {
4699        /*
4700         * Enable Interrupt Mitigation for Rx.
4701         * If no build-specific limits for the rx interrupt mitigation
4702         * timer have been specified, use conservative defaults.
4703         */
4704        #ifndef AH_RIMT_VAL_LAST
4705            #define AH_RIMT_LAST_MICROSEC 500
4706        #endif
4707        #ifndef AH_RIMT_VAL_FIRST
4708            #define AH_RIMT_FIRST_MICROSEC 2000
4709        #endif
4710#ifndef HOST_OFFLOAD
4711        OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, AH_RIMT_LAST_MICROSEC);
4712        OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, AH_RIMT_FIRST_MICROSEC);
4713#else
4714        /* lower mitigation level to reduce latency for offload arch. */
4715        OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST,
4716            (AH_RIMT_LAST_MICROSEC >> 2));
4717        OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST,
4718            (AH_RIMT_FIRST_MICROSEC >> 2));
4719#endif
4720    }
4721
4722    if (ahp->ah_intr_mitigation_tx) {
4723        /*
4724         * Enable Interrupt Mitigation for Tx.
4725         * If no build-specific limits for the tx interrupt mitigation
4726         * timer have been specified, use the values preferred for
4727         * the carrier group's products.
4728         */
4729        #ifndef AH_TIMT_LAST
4730            #define AH_TIMT_LAST_MICROSEC 300
4731        #endif
4732        #ifndef AH_TIMT_FIRST
4733            #define AH_TIMT_FIRST_MICROSEC 750
4734        #endif
4735        OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, AH_TIMT_LAST_MICROSEC);
4736        OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, AH_TIMT_FIRST_MICROSEC);
4737    }
4738
4739    rx_chainmask = ahp->ah_rx_chainmask;
4740
4741    OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
4742    OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
4743
4744    ar9300_init_bb(ah, chan);
4745
4746    /* BB Step 7: Calibration */
4747    ar9300_invalidate_saved_cals(ah, ichan);
4748    cal_ret = ar9300_init_cal(ah, chan, AH_FALSE, apply_last_iqcorr);
4749
4750#if ATH_SUPPORT_MCI
4751    if (AH_PRIVATE(ah)->ah_caps.hal_mci_support && ahp->ah_mci_ready) {
4752        if (IS_CHAN_2GHZ(chan) &&
4753            (ahp->ah_mci_bt_state == MCI_BT_SLEEP))
4754        {
4755            if (ar9300_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) ||
4756                ar9300_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE))
4757            {
4758                /*
4759                 * BT is sleeping. Check if BT wakes up duing WLAN
4760                 * calibration. If BT wakes up during WLAN calibration, need
4761                 * to go through all message exchanges again and recal.
4762                 */
4763                HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4764                    "(MCI) ### %s: BT wakes up during WLAN calibration.\n",
4765                    __func__);
4766                OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
4767                        AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET |
4768                        AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE);
4769                HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) send REMOTE_RESET\n");
4770                ar9300_mci_remote_reset(ah, AH_TRUE);
4771                ar9300_mci_send_sys_waking(ah, AH_TRUE);
4772                OS_DELAY(1);
4773                if (IS_CHAN_2GHZ(chan)) {
4774                    ar9300_mci_send_lna_transfer(ah, AH_TRUE);
4775                }
4776                ahp->ah_mci_bt_state = MCI_BT_AWAKE;
4777
4778                /* Redo calibration */
4779                HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Re-calibrate.\n",
4780                    __func__);
4781                ar9300_invalidate_saved_cals(ah, ichan);
4782                cal_ret = ar9300_init_cal(ah, chan, AH_FALSE, ar9300_init_cal);
4783            }
4784        }
4785        ar9300_mci_enable_interrupt(ah);
4786    }
4787#endif
4788
4789    if (!cal_ret) {
4790        HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Init Cal Failed\n", __func__);
4791        FAIL(HAL_ESELFTEST);
4792    }
4793
4794    ar9300_init_txbf(ah);
4795#if 0
4796    /*
4797     * WAR for owl 1.0 - restore chain mask for 2-chain cfgs after cal
4798     */
4799    rx_chainmask = ahp->ah_rx_chainmask;
4800    if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
4801        OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
4802        OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
4803    }
4804#endif
4805
4806    /* Restore previous led state */
4807    OS_REG_WRITE(ah, AR_CFG_LED, save_led_state | AR_CFG_SCLK_32KHZ);
4808
4809#ifdef ATH_BT_COEX
4810    if (ahp->ah_bt_coex_config_type != HAL_BT_COEX_CFG_NONE) {
4811        ar9300_init_bt_coex(ah);
4812
4813#if ATH_SUPPORT_MCI
4814        if (AH_PRIVATE(ah)->ah_caps.hal_mci_support && ahp->ah_mci_ready) {
4815            /* Check BT state again to make sure it's not changed. */
4816            ar9300_mci_sync_bt_state(ah);
4817            ar9300_mci_2g5g_switch(ah, AH_TRUE);
4818
4819            if ((ahp->ah_mci_bt_state == MCI_BT_AWAKE) &&
4820                (ahp->ah_mci_query_bt == AH_TRUE))
4821            {
4822                ahp->ah_mci_need_flush_btinfo = AH_TRUE;
4823            }
4824        }
4825#endif
4826    }
4827#endif
4828
4829    /* Start TSF2 for generic timer 8-15. */
4830    ar9300_start_tsf2(ah);
4831
4832    /* MIMO Power save setting */
4833    if (ar9300_get_capability(ah, HAL_CAP_DYNAMIC_SMPS, 0, AH_NULL) == HAL_OK) {
4834        ar9300_set_sm_power_mode(ah, ahp->ah_sm_power_mode);
4835    }
4836
4837    /*
4838     * For big endian systems turn on swapping for descriptors
4839     */
4840#if AH_BYTE_ORDER == AH_BIG_ENDIAN
4841    if (AR_SREV_HORNET(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
4842        OS_REG_RMW(ah, AR_CFG, AR_CFG_SWTB | AR_CFG_SWRB, 0);
4843    } else {
4844        ar9300_init_cfg_reg(ah);
4845    }
4846#endif
4847
4848    if ( AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
4849        OS_REG_RMW(ah, AR_CFG_LED, AR_CFG_LED_ASSOC_CTL, AR_CFG_LED_ASSOC_CTL);
4850    }
4851
4852#if !(defined(ART_BUILD)) && defined(ATH_SUPPORT_LED)
4853#define REG_WRITE(_reg, _val)   *((volatile u_int32_t *)(_reg)) = (_val);
4854#define REG_READ(_reg)          *((volatile u_int32_t *)(_reg))
4855#define ATH_GPIO_OUT_FUNCTION3  0xB8040038
4856#define ATH_GPIO_OE             0xB8040000
4857    if ( AR_SREV_WASP(ah)) {
4858        if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) {
4859            REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff << 8))) | (0x33 << 8) );
4860            REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) & (~(0x1 << 13) )));
4861        }
4862        else {
4863
4864            /* Disable 2G WLAN LED. During ath_open, reset function is called even before channel is set.
4865            So 2GHz is taken as default and it also blinks. Hence
4866            to avoid both from blinking, disable 2G led while in 5G mode */
4867
4868            REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) | (1 << 13) ));
4869            REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff))) | (0x33) );
4870            REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) & (~(0x1 << 12) )));
4871        }
4872
4873    }
4874    else if (AR_SREV_SCORPION(ah)) {
4875        if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) {
4876            REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff << 8))) | (0x2F << 8) );
4877    	    REG_WRITE(ATH_GPIO_OE, (( REG_READ(ATH_GPIO_OE) & (~(0x1 << 13) )) | (0x1 << 12)));
4878        } else if (IS_CHAN_5GHZ((AH_PRIVATE(ah)->ah_curchan))) {
4879            REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff))) | (0x2F) );
4880    	    REG_WRITE(ATH_GPIO_OE, (( REG_READ(ATH_GPIO_OE) & (~(0x1 << 12) )) | (0x1 << 13)));
4881        }
4882    }
4883#undef REG_READ
4884#undef REG_WRITE
4885#endif
4886
4887    chan->channel_flags = ichan->channel_flags;
4888    chan->priv_flags = ichan->priv_flags;
4889
4890#if FIX_NOISE_FLOOR
4891    ar9300_get_nf_hist_base(ah, AH_PRIVATE(ah)->ah_curchan, is_scan, nf_buf);
4892    ar9300_load_nf(ah, nf_buf);
4893    if (nf_hist_buff_reset == 1)
4894    {
4895        nf_hist_buff_reset = 0;
4896    #ifndef ATH_NF_PER_CHAN
4897	    if (First_NFCal(ah, ichan, is_scan, chan)){
4898        }
4899    #endif /* ATH_NF_PER_CHAN */
4900    }
4901    else{
4902        ar9300_start_nf_cal(ah);
4903    }
4904#endif
4905
4906#ifdef AH_SUPPORT_AR9300
4907    /* BB Panic Watchdog */
4908    if (ar9300_get_capability(ah, HAL_CAP_BB_PANIC_WATCHDOG, 0, AH_NULL) ==
4909        HAL_OK)
4910    {
4911        ar9300_config_bb_panic_watchdog(ah);
4912    }
4913#endif
4914
4915    /* While receiving unsupported rate frame receive state machine
4916     * gets into a state 0xb and if phy_restart happens when rx
4917     * state machine is in 0xb state, BB would go hang, if we
4918     * see 0xb state after first bb panic, make sure that we
4919     * disable the phy_restart.
4920     *
4921     * There may be multiple panics, make sure that we always do
4922     * this if we see this panic at least once. This is required
4923     * because reset seems to be writing from INI file.
4924     */
4925    if ((ar9300_get_capability(ah, HAL_CAP_PHYRESTART_CLR_WAR, 0, AH_NULL)
4926         == HAL_OK) && (((MS((AH_PRIVATE(ah)->ah_bb_panic_last_status),
4927                AR_PHY_BB_WD_RX_OFDM_SM)) == 0xb) ||
4928            AH_PRIVATE(ah)->ah_phyrestart_disabled) )
4929    {
4930        ar9300_disable_phy_restart(ah, 1);
4931    }
4932
4933
4934
4935    ahp->ah_radar1 = MS(OS_REG_READ(ah, AR_PHY_RADAR_1),
4936                        AR_PHY_RADAR_1_CF_BIN_THRESH);
4937    ahp->ah_dc_offset = MS(OS_REG_READ(ah, AR_PHY_TIMING2),
4938                        AR_PHY_TIMING2_DC_OFFSET);
4939    ahp->ah_disable_cck = MS(OS_REG_READ(ah, AR_PHY_MODE),
4940                        AR_PHY_MODE_DISABLE_CCK);
4941
4942    if (ap->ah_enable_keysearch_always) {
4943        ar9300_enable_keysearch_always(ah, 1);
4944    }
4945
4946#if ATH_LOW_POWER_ENABLE
4947#define REG_WRITE(_reg, _val)   *((volatile u_int32_t *)(_reg)) = (_val)
4948#define REG_READ(_reg)      *((volatile u_int32_t *)(_reg))
4949    if (AR_SREV_OSPREY(ah)) {
4950        REG_WRITE(0xb4000080, REG_READ(0xb4000080) | 3);
4951        OS_REG_WRITE(ah, AR_RTC_RESET, 1);
4952        OS_REG_SET_BIT(ah, AR_HOSTIF_REG(ah, AR_PCIE_PM_CTRL),
4953                        AR_PCIE_PM_CTRL_ENA);
4954        OS_REG_SET_BIT(ah, AR_HOSTIF_REG(ah, AR_SPARE), 0xffffffff);
4955    }
4956#undef REG_READ
4957#undef REG_WRITE
4958#endif  /* ATH_LOW_POWER_ENABLE */
4959
4960    WAR_USB_DISABLE_PLL_LOCK_DETECT(ah);
4961
4962    /* H/W Green TX */
4963    ar9300_control_signals_for_green_tx_mode(ah);
4964    /* Smart Antenna, only for 5GHz on Scropion */
4965    if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan)) && AR_SREV_SCORPION(ah)) {
4966        ahp->ah_smartantenna_enable = 0;
4967    }
4968
4969    ar9300_set_smart_antenna(ah, ahp->ah_smartantenna_enable);
4970
4971
4972    return AH_TRUE;
4973bad:
4974    OS_MARK(ah, AH_MARK_RESET_DONE, ecode);
4975    *status = ecode;
4976
4977    return AH_FALSE;
4978#undef FAIL
4979}
4980
4981void
4982ar9300_green_ap_ps_on_off( struct ath_hal *ah, u_int16_t on_off)
4983{
4984    /* Set/reset the ps flag */
4985    AH_PRIVATE(ah)->green_ap_ps_on = !!on_off;
4986}
4987
4988/*
4989 * This function returns 1, where it is possible to do
4990 * single-chain power save.
4991 */
4992u_int16_t
4993ar9300_is_single_ant_power_save_possible(struct ath_hal *ah)
4994{
4995    return AH_TRUE;
4996}
4997
4998/* To avoid compilation warnings. Functions not used when EMULATION. */
4999/*
5000 * ar9300_find_mag_approx()
5001 */
5002static int32_t
5003ar9300_find_mag_approx(struct ath_hal *ah, int32_t in_re, int32_t in_im)
5004{
5005    int32_t abs_i = abs(in_re);
5006    int32_t abs_q = abs(in_im);
5007    int32_t max_abs, min_abs;
5008
5009    if (abs_i > abs_q) {
5010        max_abs = abs_i;
5011        min_abs = abs_q;
5012    } else {
5013        max_abs = abs_q;
5014        min_abs = abs_i;
5015    }
5016
5017    return (max_abs - (max_abs / 32) + (min_abs / 8) + (min_abs / 4));
5018}
5019
5020/*
5021 * ar9300_solve_iq_cal()
5022 * solve 4x4 linear equation used in loopback iq cal.
5023 */
5024static HAL_BOOL
5025ar9300_solve_iq_cal(
5026    struct ath_hal *ah,
5027    int32_t sin_2phi_1,
5028    int32_t cos_2phi_1,
5029    int32_t sin_2phi_2,
5030    int32_t cos_2phi_2,
5031    int32_t mag_a0_d0,
5032    int32_t phs_a0_d0,
5033    int32_t mag_a1_d0,
5034    int32_t phs_a1_d0,
5035    int32_t solved_eq[])
5036{
5037    int32_t f1 = cos_2phi_1 - cos_2phi_2;
5038    int32_t f3 = sin_2phi_1 - sin_2phi_2;
5039    int32_t f2;
5040    int32_t mag_tx, phs_tx, mag_rx, phs_rx;
5041    const int32_t result_shift = 1 << 15;
5042
5043    f2 = (((int64_t)f1 * (int64_t)f1) / result_shift) + (((int64_t)f3 * (int64_t)f3) / result_shift);
5044
5045    if (0 == f2) {
5046        HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: Divide by 0(%d).\n",
5047            __func__, __LINE__);
5048        return AH_FALSE;
5049    }
5050
5051    /* magnitude mismatch, tx */
5052    mag_tx = f1 * (mag_a0_d0  - mag_a1_d0) + f3 * (phs_a0_d0 - phs_a1_d0);
5053    /* phase mismatch, tx */
5054    phs_tx = f3 * (-mag_a0_d0 + mag_a1_d0) + f1 * (phs_a0_d0 - phs_a1_d0);
5055
5056    mag_tx = (mag_tx / f2);
5057    phs_tx = (phs_tx / f2);
5058
5059    /* magnitude mismatch, rx */
5060    mag_rx =
5061        mag_a0_d0 - (cos_2phi_1 * mag_tx + sin_2phi_1 * phs_tx) / result_shift;
5062    /* phase mismatch, rx */
5063    phs_rx =
5064        phs_a0_d0 + (sin_2phi_1 * mag_tx - cos_2phi_1 * phs_tx) / result_shift;
5065
5066    solved_eq[0] = mag_tx;
5067    solved_eq[1] = phs_tx;
5068    solved_eq[2] = mag_rx;
5069    solved_eq[3] = phs_rx;
5070
5071    return AH_TRUE;
5072}
5073
5074/*
5075 * ar9300_calc_iq_corr()
5076 */
5077static HAL_BOOL
5078ar9300_calc_iq_corr(struct ath_hal *ah, int32_t chain_idx,
5079    const int32_t iq_res[], int32_t iqc_coeff[])
5080{
5081    int32_t i2_m_q2_a0_d0, i2_p_q2_a0_d0, iq_corr_a0_d0;
5082    int32_t i2_m_q2_a0_d1, i2_p_q2_a0_d1, iq_corr_a0_d1;
5083    int32_t i2_m_q2_a1_d0, i2_p_q2_a1_d0, iq_corr_a1_d0;
5084    int32_t i2_m_q2_a1_d1, i2_p_q2_a1_d1, iq_corr_a1_d1;
5085    int32_t mag_a0_d0, mag_a1_d0, mag_a0_d1, mag_a1_d1;
5086    int32_t phs_a0_d0, phs_a1_d0, phs_a0_d1, phs_a1_d1;
5087    int32_t sin_2phi_1, cos_2phi_1, sin_2phi_2, cos_2phi_2;
5088    int32_t mag_tx, phs_tx, mag_rx, phs_rx;
5089    int32_t solved_eq[4], mag_corr_tx, phs_corr_tx, mag_corr_rx, phs_corr_rx;
5090    int32_t q_q_coff, q_i_coff;
5091    const int32_t res_scale = 1 << 15;
5092    const int32_t delpt_shift = 1 << 8;
5093    int32_t mag1, mag2;
5094
5095    i2_m_q2_a0_d0 = iq_res[0] & 0xfff;
5096    i2_p_q2_a0_d0 = (iq_res[0] >> 12) & 0xfff;
5097    iq_corr_a0_d0 = ((iq_res[0] >> 24) & 0xff) + ((iq_res[1] & 0xf) << 8);
5098
5099    if (i2_m_q2_a0_d0 > 0x800)  {
5100        i2_m_q2_a0_d0 = -((0xfff - i2_m_q2_a0_d0) + 1);
5101    }
5102    if (iq_corr_a0_d0 > 0x800)  {
5103        iq_corr_a0_d0 = -((0xfff - iq_corr_a0_d0) + 1);
5104    }
5105
5106    i2_m_q2_a0_d1 = (iq_res[1] >> 4) & 0xfff;
5107    i2_p_q2_a0_d1 = (iq_res[2] & 0xfff);
5108    iq_corr_a0_d1 = (iq_res[2] >> 12) & 0xfff;
5109
5110    if (i2_m_q2_a0_d1 > 0x800)  {
5111        i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1);
5112    }
5113    if (iq_corr_a0_d1 > 0x800)  {
5114        iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1);
5115    }
5116
5117    i2_m_q2_a1_d0 = ((iq_res[2] >> 24) & 0xff) + ((iq_res[3] & 0xf) << 8);
5118    i2_p_q2_a1_d0 = (iq_res[3] >> 4) & 0xfff;
5119    iq_corr_a1_d0 = iq_res[4] & 0xfff;
5120
5121    if (i2_m_q2_a1_d0 > 0x800)  {
5122        i2_m_q2_a1_d0 = -((0xfff - i2_m_q2_a1_d0) + 1);
5123    }
5124    if (iq_corr_a1_d0 > 0x800)  {
5125        iq_corr_a1_d0 = -((0xfff - iq_corr_a1_d0) + 1);
5126    }
5127
5128    i2_m_q2_a1_d1 = (iq_res[4] >> 12) & 0xfff;
5129    i2_p_q2_a1_d1 = ((iq_res[4] >> 24) & 0xff) + ((iq_res[5] & 0xf) << 8);
5130    iq_corr_a1_d1 = (iq_res[5] >> 4) & 0xfff;
5131
5132    if (i2_m_q2_a1_d1 > 0x800)  {
5133        i2_m_q2_a1_d1 = -((0xfff - i2_m_q2_a1_d1) + 1);
5134    }
5135    if (iq_corr_a1_d1 > 0x800)  {
5136        iq_corr_a1_d1 = -((0xfff - iq_corr_a1_d1) + 1);
5137    }
5138
5139    if ((i2_p_q2_a0_d0 == 0) ||
5140        (i2_p_q2_a0_d1 == 0) ||
5141        (i2_p_q2_a1_d0 == 0) ||
5142        (i2_p_q2_a1_d1 == 0)) {
5143        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5144            "%s: Divide by 0(%d):\na0_d0=%d\na0_d1=%d\na2_d0=%d\na1_d1=%d\n",
5145            __func__, __LINE__,
5146            i2_p_q2_a0_d0, i2_p_q2_a0_d1, i2_p_q2_a1_d0, i2_p_q2_a1_d1);
5147        return AH_FALSE;
5148    }
5149
5150    if ((i2_p_q2_a0_d0 <= 1024) || (i2_p_q2_a0_d0 > 2047) ||
5151            (i2_p_q2_a1_d0 < 0) || (i2_p_q2_a1_d1 < 0) ||
5152            (i2_p_q2_a0_d0 <= i2_m_q2_a0_d0) ||
5153            (i2_p_q2_a0_d0 <= iq_corr_a0_d0) ||
5154            (i2_p_q2_a0_d1 <= i2_m_q2_a0_d1) ||
5155            (i2_p_q2_a0_d1 <= iq_corr_a0_d1) ||
5156            (i2_p_q2_a1_d0 <= i2_m_q2_a1_d0) ||
5157            (i2_p_q2_a1_d0 <= iq_corr_a1_d0) ||
5158            (i2_p_q2_a1_d1 <= i2_m_q2_a1_d1) ||
5159            (i2_p_q2_a1_d1 <= iq_corr_a1_d1)) {
5160        return AH_FALSE;
5161    }
5162
5163    mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0;
5164    phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0;
5165
5166    mag_a0_d1 = (i2_m_q2_a0_d1 * res_scale) / i2_p_q2_a0_d1;
5167    phs_a0_d1 = (iq_corr_a0_d1 * res_scale) / i2_p_q2_a0_d1;
5168
5169    mag_a1_d0 = (i2_m_q2_a1_d0 * res_scale) / i2_p_q2_a1_d0;
5170    phs_a1_d0 = (iq_corr_a1_d0 * res_scale) / i2_p_q2_a1_d0;
5171
5172    mag_a1_d1 = (i2_m_q2_a1_d1 * res_scale) / i2_p_q2_a1_d1;
5173    phs_a1_d1 = (iq_corr_a1_d1 * res_scale) / i2_p_q2_a1_d1;
5174
5175    /* without analog phase shift */
5176    sin_2phi_1 = (((mag_a0_d0 - mag_a0_d1) * delpt_shift) / DELPT);
5177    /* without analog phase shift */
5178    cos_2phi_1 = (((phs_a0_d1 - phs_a0_d0) * delpt_shift) / DELPT);
5179    /* with  analog phase shift */
5180    sin_2phi_2 = (((mag_a1_d0 - mag_a1_d1) * delpt_shift) / DELPT);
5181    /* with analog phase shift */
5182    cos_2phi_2 = (((phs_a1_d1 - phs_a1_d0) * delpt_shift) / DELPT);
5183
5184    /* force sin^2 + cos^2 = 1; */
5185    /* find magnitude by approximation */
5186    mag1 = ar9300_find_mag_approx(ah, cos_2phi_1, sin_2phi_1);
5187    mag2 = ar9300_find_mag_approx(ah, cos_2phi_2, sin_2phi_2);
5188
5189    if ((mag1 == 0) || (mag2 == 0)) {
5190        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5191            "%s: Divide by 0(%d): mag1=%d, mag2=%d\n",
5192            __func__, __LINE__, mag1, mag2);
5193        return AH_FALSE;
5194    }
5195
5196    /* normalization sin and cos by mag */
5197    sin_2phi_1 = (sin_2phi_1 * res_scale / mag1);
5198    cos_2phi_1 = (cos_2phi_1 * res_scale / mag1);
5199    sin_2phi_2 = (sin_2phi_2 * res_scale / mag2);
5200    cos_2phi_2 = (cos_2phi_2 * res_scale / mag2);
5201
5202    /* calculate IQ mismatch */
5203    if (AH_FALSE== ar9300_solve_iq_cal(ah,
5204            sin_2phi_1, cos_2phi_1, sin_2phi_2, cos_2phi_2, mag_a0_d0,
5205            phs_a0_d0, mag_a1_d0, phs_a1_d0, solved_eq))
5206    {
5207        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5208            "%s: Call to ar9300_solve_iq_cal failed.\n", __func__);
5209        return AH_FALSE;
5210    }
5211
5212    mag_tx = solved_eq[0];
5213    phs_tx = solved_eq[1];
5214    mag_rx = solved_eq[2];
5215    phs_rx = solved_eq[3];
5216
5217    HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5218        "%s: chain %d: mag mismatch=%d phase mismatch=%d\n",
5219        __func__, chain_idx, mag_tx / res_scale, phs_tx / res_scale);
5220
5221    if (res_scale == mag_tx) {
5222        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5223            "%s: Divide by 0(%d): mag_tx=%d, res_scale=%d\n",
5224            __func__, __LINE__, mag_tx, res_scale);
5225        return AH_FALSE;
5226    }
5227
5228    /* calculate and quantize Tx IQ correction factor */
5229    mag_corr_tx = (mag_tx * res_scale) / (res_scale - mag_tx);
5230    phs_corr_tx = -phs_tx;
5231
5232    q_q_coff = (mag_corr_tx * 128 / res_scale);
5233    q_i_coff = (phs_corr_tx * 256 / res_scale);
5234
5235    HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5236        "%s: tx chain %d: mag corr=%d  phase corr=%d\n",
5237        __func__, chain_idx, q_q_coff, q_i_coff);
5238
5239    if (q_i_coff < -63) {
5240        q_i_coff = -63;
5241    }
5242    if (q_i_coff > 63) {
5243        q_i_coff = 63;
5244    }
5245    if (q_q_coff < -63) {
5246        q_q_coff = -63;
5247    }
5248    if (q_q_coff > 63) {
5249        q_q_coff = 63;
5250    }
5251
5252    iqc_coeff[0] = (q_q_coff * 128) + (0x7f & q_i_coff);
5253
5254    HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: tx chain %d: iq corr coeff=%x\n",
5255        __func__, chain_idx, iqc_coeff[0]);
5256
5257    if (-mag_rx == res_scale) {
5258        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5259            "%s: Divide by 0(%d): mag_rx=%d, res_scale=%d\n",
5260            __func__, __LINE__, mag_rx, res_scale);
5261        return AH_FALSE;
5262    }
5263
5264    /* calculate and quantize Rx IQ correction factors */
5265    mag_corr_rx = (-mag_rx * res_scale) / (res_scale + mag_rx);
5266    phs_corr_rx = -phs_rx;
5267
5268    q_q_coff = (mag_corr_rx * 128 / res_scale);
5269    q_i_coff = (phs_corr_rx * 256 / res_scale);
5270
5271    HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5272        "%s: rx chain %d: mag corr=%d  phase corr=%d\n",
5273        __func__, chain_idx, q_q_coff, q_i_coff);
5274
5275    if (q_i_coff < -63) {
5276        q_i_coff = -63;
5277    }
5278    if (q_i_coff > 63) {
5279        q_i_coff = 63;
5280    }
5281    if (q_q_coff < -63) {
5282        q_q_coff = -63;
5283    }
5284    if (q_q_coff > 63) {
5285        q_q_coff = 63;
5286    }
5287
5288    iqc_coeff[1] = (q_q_coff * 128) + (0x7f & q_i_coff);
5289
5290    HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: rx chain %d: iq corr coeff=%x\n",
5291        __func__, chain_idx, iqc_coeff[1]);
5292
5293    return AH_TRUE;
5294}
5295
5296#define MAX_MAG_DELTA 11 //maximum magnitude mismatch delta across gains
5297#define MAX_PHS_DELTA 10 //maximum phase mismatch delta across gains
5298#define ABS(x) ((x) >= 0 ? (x) : (-(x)))
5299
5300    u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = {
5301    {   AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5302        AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5303        AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5304    {   AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5305        AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5306        AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5307    {   AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5308        AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5309        AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5310    {   AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5311        AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5312        AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5313    {   AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5314        AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5315        AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5316    {   AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5317        AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5318        AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5319    {   AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5320        AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5321        AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5322    {   AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5323        AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5324        AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5325    };
5326
5327static void
5328ar9300_tx_iq_cal_outlier_detection(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan, u_int32_t num_chains,
5329    struct coeff_t *coeff,HAL_BOOL is_cal_reusable)
5330{
5331    int nmeasurement, ch_idx, im;
5332    int32_t magnitude, phase;
5333    int32_t magnitude_max, phase_max;
5334    int32_t magnitude_min, phase_min;
5335
5336    int32_t magnitude_max_idx, phase_max_idx;
5337    int32_t magnitude_min_idx, phase_min_idx;
5338
5339    int32_t magnitude_avg, phase_avg;
5340    int32_t outlier_mag_idx = 0;
5341    int32_t outlier_phs_idx = 0;
5342
5343
5344    if (AR_SREV_POSEIDON(ah)) {
5345        HALASSERT(num_chains == 0x1);
5346
5347        tx_corr_coeff[0][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5348        tx_corr_coeff[1][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5349        tx_corr_coeff[2][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5350        tx_corr_coeff[3][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5351        tx_corr_coeff[4][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5352        tx_corr_coeff[5][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5353        tx_corr_coeff[6][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5354        tx_corr_coeff[7][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5355    }
5356
5357    for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
5358        nmeasurement = OS_REG_READ_FIELD(ah,
5359            AR_PHY_TX_IQCAL_STATUS_B0(ah), AR_PHY_CALIBRATED_GAINS_0);
5360        if (nmeasurement > MAX_MEASUREMENT) {
5361            nmeasurement = MAX_MEASUREMENT;
5362        }
5363
5364        if (!AR_SREV_SCORPION(ah)) {
5365            /*
5366             * reset max/min variable to min/max values so that
5367             * we always start with 1st calibrated gain value
5368             */
5369            magnitude_max = -64;
5370            phase_max     = -64;
5371            magnitude_min = 63;
5372            phase_min     = 63;
5373            magnitude_avg = 0;
5374            phase_avg     = 0;
5375            magnitude_max_idx = 0;
5376            magnitude_min_idx = 0;
5377            phase_max_idx = 0;
5378            phase_min_idx = 0;
5379
5380            /* detect outlier only if nmeasurement > 1 */
5381            if (nmeasurement > 1) {
5382                /* printf("----------- start outlier detection -----------\n"); */
5383                /*
5384                 * find max/min and phase/mag mismatch across all calibrated gains
5385                 */
5386                for (im = 0; im < nmeasurement; im++) {
5387                    magnitude = coeff->mag_coeff[ch_idx][im][0];
5388                    phase = coeff->phs_coeff[ch_idx][im][0];
5389
5390                    magnitude_avg = magnitude_avg + magnitude;
5391                    phase_avg = phase_avg + phase;
5392                    if (magnitude > magnitude_max) {
5393                        magnitude_max = magnitude;
5394                        magnitude_max_idx = im;
5395                    }
5396                    if (magnitude < magnitude_min) {
5397                        magnitude_min = magnitude;
5398                        magnitude_min_idx = im;
5399                    }
5400                    if (phase > phase_max) {
5401                        phase_max = phase;
5402                        phase_max_idx = im;
5403                    }
5404                    if (phase < phase_min) {
5405                        phase_min = phase;
5406                        phase_min_idx = im;
5407                    }
5408                }
5409                /* find average (exclude max abs value) */
5410                for (im = 0; im < nmeasurement; im++) {
5411                    magnitude = coeff->mag_coeff[ch_idx][im][0];
5412                    phase = coeff->phs_coeff[ch_idx][im][0];
5413                    if ((ABS(magnitude) < ABS(magnitude_max)) ||
5414                        (ABS(magnitude) < ABS(magnitude_min)))
5415                    {
5416                        magnitude_avg = magnitude_avg + magnitude;
5417                    }
5418                    if ((ABS(phase) < ABS(phase_max)) ||
5419                        (ABS(phase) < ABS(phase_min)))
5420                    {
5421                        phase_avg = phase_avg + phase;
5422                    }
5423                }
5424                magnitude_avg = magnitude_avg / (nmeasurement - 1);
5425                phase_avg = phase_avg / (nmeasurement - 1);
5426
5427                /* detect magnitude outlier */
5428                if (ABS(magnitude_max - magnitude_min) > MAX_MAG_DELTA) {
5429                    if (ABS(magnitude_max - magnitude_avg) >
5430                        ABS(magnitude_min - magnitude_avg))
5431                    {
5432                        /* max is outlier, force to avg */
5433                        outlier_mag_idx = magnitude_max_idx;
5434                    } else {
5435                        /* min is outlier, force to avg */
5436                        outlier_mag_idx = magnitude_min_idx;
5437                    }
5438                    coeff->mag_coeff[ch_idx][outlier_mag_idx][0] = magnitude_avg;
5439                    coeff->phs_coeff[ch_idx][outlier_mag_idx][0] = phase_avg;
5440                    HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5441                        "[ch%d][outlier mag gain%d]:: "
5442                        "mag_avg = %d (/128), phase_avg = %d (/256)\n",
5443                        ch_idx, outlier_mag_idx, magnitude_avg, phase_avg);
5444                }
5445                /* detect phase outlier */
5446                if (ABS(phase_max - phase_min) > MAX_PHS_DELTA) {
5447                    if (ABS(phase_max-phase_avg) > ABS(phase_min - phase_avg)) {
5448                        /* max is outlier, force to avg */
5449                        outlier_phs_idx = phase_max_idx;
5450                    } else{
5451                        /* min is outlier, force to avg */
5452                        outlier_phs_idx = phase_min_idx;
5453                    }
5454                    coeff->mag_coeff[ch_idx][outlier_phs_idx][0] = magnitude_avg;
5455                    coeff->phs_coeff[ch_idx][outlier_phs_idx][0] = phase_avg;
5456                    HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5457                        "[ch%d][outlier phs gain%d]:: "
5458                        "mag_avg = %d (/128), phase_avg = %d (/256)\n",
5459                        ch_idx, outlier_phs_idx, magnitude_avg, phase_avg);
5460                }
5461            }
5462        }
5463
5464        /*printf("------------ after outlier detection -------------\n");*/
5465        for (im = 0; im < nmeasurement; im++) {
5466            magnitude = coeff->mag_coeff[ch_idx][im][0];
5467            phase = coeff->phs_coeff[ch_idx][im][0];
5468
5469            #if 0
5470            printf("[ch%d][gain%d]:: mag = %d (/128), phase = %d (/256)\n",
5471                ch_idx, im, magnitude, phase);
5472            #endif
5473
5474            coeff->iqc_coeff[0] = (phase & 0x7f) | ((magnitude & 0x7f) << 7);
5475
5476            if ((im % 2) == 0) {
5477                OS_REG_RMW_FIELD(ah,
5478                    tx_corr_coeff[im][ch_idx],
5479                    AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
5480                    coeff->iqc_coeff[0]);
5481            } else {
5482                OS_REG_RMW_FIELD(ah,
5483                    tx_corr_coeff[im][ch_idx],
5484                    AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
5485                    coeff->iqc_coeff[0]);
5486            }
5487#if ATH_SUPPORT_CAL_REUSE
5488            ichan->tx_corr_coeff[im][ch_idx] = coeff->iqc_coeff[0];
5489#endif
5490        }
5491#if ATH_SUPPORT_CAL_REUSE
5492        ichan->num_measures[ch_idx] = nmeasurement;
5493#endif
5494    }
5495
5496    OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
5497                     AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
5498    OS_REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
5499                     AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
5500
5501#if ATH_SUPPORT_CAL_REUSE
5502    if (is_cal_reusable) {
5503        ichan->one_time_txiqcal_done = AH_TRUE;
5504        HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
5505            "(FCS) TXIQCAL saved - %d\n", ichan->channel);
5506    }
5507#endif
5508}
5509
5510#if ATH_SUPPORT_CAL_REUSE
5511static void
5512ar9300_tx_iq_cal_apply(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
5513{
5514    struct ath_hal_9300 *ahp = AH9300(ah);
5515    int nmeasurement, ch_idx, im;
5516
5517    u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = {
5518        {   AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5519            AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5520            AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5521        {   AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5522            AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5523            AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5524        {   AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5525            AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5526            AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5527        {   AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5528            AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5529            AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5530        {   AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5531            AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5532            AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5533        {   AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5534            AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5535            AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5536        {   AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5537            AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5538            AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5539        {   AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5540            AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5541            AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5542    };
5543
5544    if (AR_SREV_POSEIDON(ah)) {
5545        HALASSERT(ahp->ah_tx_cal_chainmask == 0x1);
5546
5547        tx_corr_coeff[0][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5548        tx_corr_coeff[1][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5549        tx_corr_coeff[2][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5550        tx_corr_coeff[3][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5551        tx_corr_coeff[4][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5552        tx_corr_coeff[5][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5553        tx_corr_coeff[6][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5554        tx_corr_coeff[7][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5555    }
5556
5557    for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
5558        if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) {
5559            continue;
5560        }
5561        nmeasurement = ichan->num_measures[ch_idx];
5562
5563        for (im = 0; im < nmeasurement; im++) {
5564            if ((im % 2) == 0) {
5565                OS_REG_RMW_FIELD(ah,
5566                    tx_corr_coeff[im][ch_idx],
5567                    AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
5568                    ichan->tx_corr_coeff[im][ch_idx]);
5569            } else {
5570                OS_REG_RMW_FIELD(ah,
5571                    tx_corr_coeff[im][ch_idx],
5572                    AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
5573                    ichan->tx_corr_coeff[im][ch_idx]);
5574            }
5575        }
5576    }
5577
5578    OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
5579                     AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
5580    OS_REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
5581                     AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
5582}
5583#endif
5584
5585/*
5586 * ar9300_tx_iq_cal_hw_run is only needed for osprey/wasp/hornet
5587 * It is not needed for jupiter/poseidon.
5588 */
5589HAL_BOOL
5590ar9300_tx_iq_cal_hw_run(struct ath_hal *ah)
5591{
5592    int is_tx_gain_forced;
5593
5594    is_tx_gain_forced = OS_REG_READ_FIELD(ah,
5595        AR_PHY_TX_FORCED_GAIN, AR_PHY_TXGAIN_FORCE);
5596    if (is_tx_gain_forced) {
5597        /*printf("Tx gain can not be forced during tx I/Q cal!\n");*/
5598        OS_REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, AR_PHY_TXGAIN_FORCE, 0);
5599    }
5600
5601    /* enable tx IQ cal */
5602    OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START(ah),
5603        AR_PHY_TX_IQCAL_START_DO_CAL, AR_PHY_TX_IQCAL_START_DO_CAL);
5604
5605    if (!ath_hal_wait(ah,
5606            AR_PHY_TX_IQCAL_START(ah), AR_PHY_TX_IQCAL_START_DO_CAL, 0,
5607            AH_WAIT_TIMEOUT))
5608    {
5609        HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5610            "%s: Tx IQ Cal is never completed.\n", __func__);
5611        return AH_FALSE;
5612    }
5613    return AH_TRUE;
5614}
5615
5616static void
5617ar9300_tx_iq_cal_post_proc(struct ath_hal *ah,HAL_CHANNEL_INTERNAL *ichan,
5618                           int iqcal_idx, int max_iqcal,HAL_BOOL is_cal_reusable, HAL_BOOL apply_last_corr)
5619{
5620    int nmeasurement=0, im, ix, iy, temp;
5621    struct ath_hal_9300     *ahp = AH9300(ah);
5622    u_int32_t txiqcal_status[AR9300_MAX_CHAINS] = {
5623        AR_PHY_TX_IQCAL_STATUS_B0(ah),
5624        AR_PHY_TX_IQCAL_STATUS_B1,
5625        AR_PHY_TX_IQCAL_STATUS_B2,
5626    };
5627    const u_int32_t chan_info_tab[] = {
5628        AR_PHY_CHAN_INFO_TAB_0,
5629        AR_PHY_CHAN_INFO_TAB_1,
5630        AR_PHY_CHAN_INFO_TAB_2,
5631    };
5632    int32_t iq_res[6];
5633    int32_t ch_idx, j;
5634    u_int32_t num_chains = 0;
5635    static struct coeff_t coeff;
5636    txiqcal_status[0] = AR_PHY_TX_IQCAL_STATUS_B0(ah);
5637
5638    for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
5639        if (ahp->ah_tx_chainmask & (1 << ch_idx)) {
5640            num_chains++;
5641        }
5642    }
5643
5644    if (apply_last_corr) {
5645	    if (coeff.last_cal == AH_TRUE) {
5646		    int32_t magnitude, phase;
5647		    int ch_idx, im;
5648		    u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = {
5649			    {   AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5650				    AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5651				    AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5652			    {   AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5653				    AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5654				    AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5655			    {   AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5656				    AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5657				    AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5658			    {   AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5659				    AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5660				    AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5661			    {   AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5662				    AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5663				    AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5664			    {   AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5665				    AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5666				    AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5667			    {   AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5668				    AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5669				    AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5670			    {   AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5671				    AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5672				    AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5673		    };
5674		    for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
5675			    for (im = 0; im < coeff.last_nmeasurement; im++) {
5676				    magnitude = coeff.mag_coeff[ch_idx][im][0];
5677				    phase = coeff.phs_coeff[ch_idx][im][0];
5678
5679#if 0
5680				    printf("[ch%d][gain%d]:: mag = %d (/128), phase = %d (/256)\n",
5681						    ch_idx, im, magnitude, phase);
5682#endif
5683
5684				    coeff.iqc_coeff[0] = (phase & 0x7f) | ((magnitude & 0x7f) << 7);
5685				    if ((im % 2) == 0) {
5686					    OS_REG_RMW_FIELD(ah,
5687							    tx_corr_coeff[im][ch_idx],
5688							    AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
5689							    coeff.iqc_coeff[0]);
5690				    } else {
5691					    OS_REG_RMW_FIELD(ah,
5692							    tx_corr_coeff[im][ch_idx],
5693							    AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
5694							    coeff.iqc_coeff[0]);
5695				    }
5696			    }
5697		    }
5698		    OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
5699				    AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
5700	    }
5701	    return;
5702    }
5703
5704
5705    for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
5706        nmeasurement = OS_REG_READ_FIELD(ah,
5707            AR_PHY_TX_IQCAL_STATUS_B0(ah), AR_PHY_CALIBRATED_GAINS_0);
5708        if (nmeasurement > MAX_MEASUREMENT) {
5709            nmeasurement = MAX_MEASUREMENT;
5710        }
5711
5712        for (im = 0; im < nmeasurement; im++) {
5713            HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5714                "%s: Doing Tx IQ Cal for chain %d.\n", __func__, ch_idx);
5715            if (OS_REG_READ(ah, txiqcal_status[ch_idx]) &
5716                AR_PHY_TX_IQCAL_STATUS_FAILED)
5717            {
5718                HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5719                    "%s: Tx IQ Cal failed for chain %d.\n", __func__, ch_idx);
5720                goto TX_IQ_CAL_FAILED_;
5721            }
5722
5723            for (j = 0; j < 3; j++) {
5724                u_int32_t idx = 2 * j;
5725                /* 3 registers for each calibration result */
5726                u_int32_t offset = 4 * (3 * im + j);
5727
5728                OS_REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
5729                    AR_PHY_CHAN_INFO_TAB_S2_READ, 0);
5730                /* 32 bits */
5731                iq_res[idx] = OS_REG_READ(ah, chan_info_tab[ch_idx] + offset);
5732                OS_REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
5733                    AR_PHY_CHAN_INFO_TAB_S2_READ, 1);
5734                /* 16 bits */
5735                iq_res[idx + 1] = 0xffff &
5736                    OS_REG_READ(ah, chan_info_tab[ch_idx] + offset);
5737
5738                HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5739                    "%s: IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
5740                    __func__, idx, iq_res[idx], idx + 1, iq_res[idx + 1]);
5741            }
5742
5743            if (AH_FALSE== ar9300_calc_iq_corr(
5744                             ah, ch_idx, iq_res, coeff.iqc_coeff))
5745            {
5746                HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5747                    "%s: Failed in calculation of IQ correction.\n",
5748                     __func__);
5749                goto TX_IQ_CAL_FAILED_;
5750            }
5751
5752            coeff.phs_coeff[ch_idx][im][iqcal_idx-1] = coeff.iqc_coeff[0] & 0x7f;
5753            coeff.mag_coeff[ch_idx][im][iqcal_idx-1] = (coeff.iqc_coeff[0] >> 7) & 0x7f;
5754            if (coeff.mag_coeff[ch_idx][im][iqcal_idx-1] > 63) {
5755                coeff.mag_coeff[ch_idx][im][iqcal_idx-1] -= 128;
5756            }
5757            if (coeff.phs_coeff[ch_idx][im][iqcal_idx-1] > 63) {
5758                coeff.phs_coeff[ch_idx][im][iqcal_idx-1] -= 128;
5759            }
5760#if 0
5761            ath_hal_printf(ah, "IQCAL::[ch%d][gain%d]:: mag = %d phase = %d \n",
5762                ch_idx, im, coeff.mag_coeff[ch_idx][im][iqcal_idx-1],
5763                coeff.phs_coeff[ch_idx][im][iqcal_idx-1]);
5764#endif
5765        }
5766    }
5767    //last iteration; calculate mag and phs
5768    if (iqcal_idx == max_iqcal) {
5769        if (max_iqcal>1) {
5770            for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
5771                for (im = 0; im < nmeasurement; im++) {
5772                    //sort mag and phs
5773                    for( ix=0;ix<max_iqcal-1;ix++){
5774                        for( iy=ix+1;iy<=max_iqcal-1;iy++){
5775                            if(coeff.mag_coeff[ch_idx][im][iy] <
5776                                coeff.mag_coeff[ch_idx][im][ix]) {
5777                                //swap
5778                                temp=coeff.mag_coeff[ch_idx][im][ix];
5779                                coeff.mag_coeff[ch_idx][im][ix] = coeff.mag_coeff[ch_idx][im][iy];
5780                                coeff.mag_coeff[ch_idx][im][iy] = temp;
5781                            }
5782                            if(coeff.phs_coeff[ch_idx][im][iy] <
5783                                coeff.phs_coeff[ch_idx][im][ix]){
5784                                //swap
5785                                temp=coeff.phs_coeff[ch_idx][im][ix];
5786                                coeff.phs_coeff[ch_idx][im][ix]=coeff.phs_coeff[ch_idx][im][iy];
5787                                coeff.phs_coeff[ch_idx][im][iy]=temp;
5788                            }
5789                        }
5790                    }
5791                    //select median; 3rd entry in the sorted array
5792                    coeff.mag_coeff[ch_idx][im][0] =
5793                        coeff.mag_coeff[ch_idx][im][max_iqcal/2];
5794                    coeff.phs_coeff[ch_idx][im][0] =
5795                        coeff.phs_coeff[ch_idx][im][max_iqcal/2];
5796                    HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5797                        "IQCAL: Median [ch%d][gain%d]:: mag = %d phase = %d \n",
5798                        ch_idx, im,coeff.mag_coeff[ch_idx][im][0],
5799                        coeff.phs_coeff[ch_idx][im][0]);
5800                }
5801            }
5802        }
5803        ar9300_tx_iq_cal_outlier_detection(ah,ichan, num_chains, &coeff,is_cal_reusable);
5804    }
5805
5806
5807    coeff.last_nmeasurement = nmeasurement;
5808    coeff.last_cal = AH_TRUE;
5809
5810    return;
5811
5812TX_IQ_CAL_FAILED_:
5813    /* no need to print this, it is AGC failure not chip stuck */
5814    /*ath_hal_printf(ah, "Tx IQ Cal failed(%d)\n", line);*/
5815    coeff.last_cal = AH_FALSE;
5816    return;
5817}
5818
5819
5820/*
5821 * ar9300_disable_phy_restart
5822 *
5823 * In some BBpanics, we can disable the phyrestart
5824 * disable_phy_restart
5825 *      != 0, disable the phy restart in h/w
5826 *      == 0, enable the phy restart in h/w
5827 */
5828void ar9300_disable_phy_restart(struct ath_hal *ah, int disable_phy_restart)
5829{
5830    u_int32_t val;
5831
5832    val = OS_REG_READ(ah, AR_PHY_RESTART);
5833    if (disable_phy_restart) {
5834        val &= ~AR_PHY_RESTART_ENA;
5835        AH_PRIVATE(ah)->ah_phyrestart_disabled = 1;
5836    } else {
5837        val |= AR_PHY_RESTART_ENA;
5838        AH_PRIVATE(ah)->ah_phyrestart_disabled = 0;
5839    }
5840    OS_REG_WRITE(ah, AR_PHY_RESTART, val);
5841
5842    val = OS_REG_READ(ah, AR_PHY_RESTART);
5843}
5844
5845HAL_BOOL
5846ar9300_interference_is_present(struct ath_hal *ah)
5847{
5848    int i;
5849    struct ath_hal_private  *ahpriv = AH_PRIVATE(ah);
5850
5851    /* This function is called after a stuck beacon, if EACS is enabled.
5852     * If CW interference is severe, then HW goes into a loop of continuous
5853     * stuck beacons and resets. On reset the NF cal history is cleared.
5854     * So the median value of the history cannot be used -
5855     * hence check if any value (Chain 0/Primary Channel)
5856     * is outside the bounds.
5857     */
5858    HAL_NFCAL_HIST_FULL *h = AH_HOME_CHAN_NFCAL_HIST(ah);
5859    for (i = 0; i < HAL_NF_CAL_HIST_LEN_FULL; i++) {
5860        if (h->nf_cal_buffer[i][0] >
5861            ahpriv->nfp->nominal + ahpriv->nf_cw_int_delta)
5862        {
5863            return AH_TRUE;
5864        }
5865
5866    }
5867    return AH_FALSE;
5868}
5869
5870#if ATH_SUPPORT_CRDC
5871void
5872ar9300_crdc_rx_notify(struct ath_hal *ah, struct ath_rx_status *rxs)
5873{
5874    struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
5875    int rssi_index;
5876
5877    if ((!AR_SREV_WASP(ah)) ||
5878        (!ahpriv->ah_config.ath_hal_crdc_enable)) {
5879        return;
5880    }
5881
5882    if (rxs->rs_isaggr && rxs->rs_moreaggr) {
5883        return;
5884    }
5885
5886    if ((rxs->rs_rssi_ctl0 >= HAL_RSSI_BAD) ||
5887        (rxs->rs_rssi_ctl1 >= HAL_RSSI_BAD)) {
5888        return;
5889    }
5890
5891    rssi_index = ah->ah_crdc_rssi_ptr % HAL_MAX_CRDC_RSSI_SAMPLE;
5892
5893    ah->ah_crdc_rssi_sample[0][rssi_index] = rxs->rs_rssi_ctl0;
5894    ah->ah_crdc_rssi_sample[1][rssi_index] = rxs->rs_rssi_ctl1;
5895
5896    ah->ah_crdc_rssi_ptr++;
5897}
5898
5899static int
5900ar9300_crdc_avg_rssi(struct ath_hal *ah, int chain)
5901{
5902    int crdc_rssi_sum = 0;
5903    int crdc_rssi_ptr = ah->ah_crdc_rssi_ptr, i;
5904    struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
5905    int crdc_window = ahpriv->ah_config.ath_hal_crdc_window;
5906
5907    if (crdc_window > HAL_MAX_CRDC_RSSI_SAMPLE) {
5908        crdc_window = HAL_MAX_CRDC_RSSI_SAMPLE;
5909    }
5910
5911    for (i = 1; i <= crdc_window; i++) {
5912        crdc_rssi_sum +=
5913            ah->ah_crdc_rssi_sample[chain]
5914            [(crdc_rssi_ptr - i) % HAL_MAX_CRDC_RSSI_SAMPLE];
5915    }
5916
5917    return crdc_rssi_sum / crdc_window;
5918}
5919
5920static void
5921ar9300_crdc_activate(struct ath_hal *ah, int rssi_diff, int enable)
5922{
5923    int val, orig_val;
5924    struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
5925    int crdc_numerator = ahpriv->ah_config.ath_hal_crdc_numerator;
5926    int crdc_denominator = ahpriv->ah_config.ath_hal_crdc_denominator;
5927    int c = (rssi_diff * crdc_numerator) / crdc_denominator;
5928
5929    val = orig_val = OS_REG_READ(ah, AR_PHY_MULTICHAIN_CTRL);
5930    val &= 0xffffff00;
5931    if (enable) {
5932        val |= 0x1;
5933        val |= ((c << 1) & 0xff);
5934    }
5935    OS_REG_WRITE(ah, AR_PHY_MULTICHAIN_CTRL, val);
5936    HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "diff: %02d comp: %02d reg: %08x %08x\n",
5937        rssi_diff, c, orig_val, val);
5938}
5939
5940
5941void ar9300_chain_rssi_diff_compensation(struct ath_hal *ah)
5942{
5943    struct ath_hal_private  *ahpriv = AH_PRIVATE(ah);
5944    int crdc_window = ahpriv->ah_config.ath_hal_crdc_window;
5945    int crdc_rssi_ptr = ah->ah_crdc_rssi_ptr;
5946    int crdc_rssi_thresh = ahpriv->ah_config.ath_hal_crdc_rssithresh;
5947    int crdc_diff_thresh = ahpriv->ah_config.ath_hal_crdc_diffthresh;
5948    int avg_rssi[2], avg_rssi_diff;
5949
5950    if ((!AR_SREV_WASP(ah)) ||
5951        (!ahpriv->ah_config.ath_hal_crdc_enable)) {
5952        if (ah->ah_crdc_rssi_ptr) {
5953            ar9300_crdc_activate(ah, 0, 0);
5954            ah->ah_crdc_rssi_ptr = 0;
5955        }
5956        return;
5957    }
5958
5959    if (crdc_window > HAL_MAX_CRDC_RSSI_SAMPLE) {
5960        crdc_window = HAL_MAX_CRDC_RSSI_SAMPLE;
5961    }
5962
5963    if (crdc_rssi_ptr < crdc_window) {
5964        return;
5965    }
5966
5967    avg_rssi[0] = ar9300_crdc_avg_rssi(ah, 0);
5968    avg_rssi[1] = ar9300_crdc_avg_rssi(ah, 1);
5969    avg_rssi_diff = avg_rssi[1] - avg_rssi[0];
5970
5971    HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "crdc: avg: %02d %02d ",
5972        avg_rssi[0], avg_rssi[1]);
5973
5974    if ((avg_rssi[0] < crdc_rssi_thresh) &&
5975        (avg_rssi[1] < crdc_rssi_thresh)) {
5976        ar9300_crdc_activate(ah, 0, 0);
5977    } else {
5978        if (ABS(avg_rssi_diff) >= crdc_diff_thresh) {
5979            ar9300_crdc_activate(ah, avg_rssi_diff, 1);
5980        } else {
5981            ar9300_crdc_activate(ah, 0, 1);
5982        }
5983    }
5984}
5985#endif
5986
5987#if ATH_ANT_DIV_COMB
5988HAL_BOOL
5989ar9300_ant_ctrl_set_lna_div_use_bt_ant(struct ath_hal *ah, HAL_BOOL enable, HAL_CHANNEL *chan)
5990{
5991    u_int32_t value;
5992    u_int32_t regval;
5993    struct ath_hal_9300 *ahp = AH9300(ah);
5994    HAL_CHANNEL_INTERNAL *ichan;
5995    struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
5996    HAL_CAPABILITIES *pcap = &ahpriv->ah_caps;
5997
5998    if (AR_SREV_POSEIDON(ah)) {
5999        // Make sure this scheme is only used for WB225(Astra)
6000        ahp->ah_lna_div_use_bt_ant_enable = enable;
6001
6002        ichan = ar9300_check_chan(ah, chan);
6003        if ( ichan == AH_NULL ) {
6004            HALDEBUG(ah, HAL_DEBUG_CHANNEL, "%s: invalid channel %u/0x%x; no mapping\n",
6005                     __func__, chan->channel, chan->channel_flags);
6006            return AH_FALSE;
6007        }
6008
6009        if ( enable == TRUE ) {
6010            pcap->hal_ant_div_comb_support = TRUE;
6011        } else {
6012            pcap->hal_ant_div_comb_support = pcap->hal_ant_div_comb_support_org;
6013        }
6014
6015#define AR_SWITCH_TABLE_COM2_ALL (0xffffff)
6016#define AR_SWITCH_TABLE_COM2_ALL_S (0)
6017        value = ar9300_ant_ctrl_common2_get(ah, IS_CHAN_2GHZ(ichan));
6018        if ( enable == TRUE ) {
6019            value &= ~AR_SWITCH_TABLE_COM2_ALL;
6020            value |= ahpriv->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable;
6021        }
6022        OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
6023
6024        value = ar9300_eeprom_get(ahp, EEP_ANTDIV_control);
6025        /* main_lnaconf, alt_lnaconf, main_tb, alt_tb */
6026        regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
6027        regval &= (~ANT_DIV_CONTROL_ALL); /* clear bit 25~30 */
6028        regval |= (value & 0x3f) << ANT_DIV_CONTROL_ALL_S;
6029        /* enable_lnadiv */
6030        regval &= (~MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__MASK);
6031        regval |= ((value >> 6) & 0x1) <<
6032                  MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__SHIFT;
6033        if ( enable == TRUE ) {
6034            regval |= ANT_DIV_ENABLE;
6035        }
6036        OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
6037
6038        /* enable fast_div */
6039        regval = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
6040        regval &= (~BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__MASK);
6041        regval |= ((value >> 7) & 0x1) <<
6042                  BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__SHIFT;
6043        if ( enable == TRUE ) {
6044            regval |= FAST_DIV_ENABLE;
6045        }
6046        OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
6047
6048        if ( AR_SREV_POSEIDON_11_OR_LATER(ah) ) {
6049            if (pcap->hal_ant_div_comb_support) {
6050                /* If support DivComb, set MAIN to LNA1 and ALT to LNA2 at the first beginning */
6051                regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
6052                /* clear bit 25~30 main_lnaconf, alt_lnaconf, main_tb, alt_tb */
6053                regval &= (~(MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__MASK |
6054                             MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__MASK |
6055                             MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_GAINTB__MASK |
6056                             MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_GAINTB__MASK));
6057                regval |= (HAL_ANT_DIV_COMB_LNA1 <<
6058                           MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT);
6059                regval |= (HAL_ANT_DIV_COMB_LNA2 <<
6060                           MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT);
6061                OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
6062            }
6063        }
6064
6065        return AH_TRUE;
6066    } else {
6067        return AH_TRUE;
6068    }
6069}
6070#endif /* ATH_ANT_DIV_COMB */
6071
6072#endif /* AH_SUPPORT_AR9300 */
6073