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