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