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