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