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