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