xref: /freebsd/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c (revision 57e129b18cfc348b6c91abe2f9ab7df05e72271e)
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             /*
2497              * Load the NF from history buffer of the current channel.
2498              * NF is slow time-variant, so it is OK to use a historical value.
2499              */
2500             ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf);
2501             ar9300_load_nf(ah, nf_buf);
2502 
2503             /* start NF calibration, without updating BB NF register*/
2504             ar9300_start_nf_cal(ah);
2505         }
2506     }
2507     return AH_TRUE;
2508 }
2509 
2510 /* ar9300_iq_cal_collect
2511  * Collect data from HW to later perform IQ Mismatch Calibration
2512  */
2513 void
2514 ar9300_iq_cal_collect(struct ath_hal *ah, u_int8_t num_chains)
2515 {
2516     struct ath_hal_9300 *ahp = AH9300(ah);
2517     int i;
2518 
2519     /*
2520      * Accumulate IQ cal measures for active chains
2521      */
2522     for (i = 0; i < num_chains; i++) {
2523         ahp->ah_total_power_meas_i[i] = OS_REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
2524         ahp->ah_total_power_meas_q[i] = OS_REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
2525         ahp->ah_total_iq_corr_meas[i] =
2526             (int32_t) OS_REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
2527         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2528             "%d: Chn %d "
2529             "Reg Offset(0x%04x)pmi=0x%08x; "
2530             "Reg Offset(0x%04x)pmq=0x%08x; "
2531             "Reg Offset (0x%04x)iqcm=0x%08x;\n",
2532             ahp->ah_cal_samples,
2533             i,
2534             (unsigned) AR_PHY_CAL_MEAS_0(i),
2535             ahp->ah_total_power_meas_i[i],
2536             (unsigned) AR_PHY_CAL_MEAS_1(i),
2537             ahp->ah_total_power_meas_q[i],
2538             (unsigned) AR_PHY_CAL_MEAS_2(i),
2539             ahp->ah_total_iq_corr_meas[i]);
2540     }
2541 }
2542 
2543 /* ar9300_iq_calibration
2544  * Use HW data to perform IQ Mismatch Calibration
2545  */
2546 void
2547 ar9300_iq_calibration(struct ath_hal *ah, u_int8_t num_chains)
2548 {
2549     struct ath_hal_9300 *ahp = AH9300(ah);
2550     u_int32_t power_meas_q, power_meas_i, iq_corr_meas;
2551     u_int32_t q_coff_denom, i_coff_denom;
2552     int32_t q_coff, i_coff;
2553     int iq_corr_neg, i;
2554     HAL_CHANNEL_INTERNAL *ichan;
2555     static const u_int32_t offset_array[3] = {
2556         AR_PHY_RX_IQCAL_CORR_B0,
2557         AR_PHY_RX_IQCAL_CORR_B1,
2558         AR_PHY_RX_IQCAL_CORR_B2,
2559     };
2560 
2561     ichan = ath_hal_checkchannel(ah, AH_PRIVATE(ah)->ah_curchan);
2562 
2563     for (i = 0; i < num_chains; i++) {
2564         power_meas_i = ahp->ah_total_power_meas_i[i];
2565         power_meas_q = ahp->ah_total_power_meas_q[i];
2566         iq_corr_meas = ahp->ah_total_iq_corr_meas[i];
2567 
2568         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2569             "Starting IQ Cal and Correction for Chain %d\n", i);
2570         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2571             "Orignal: Chn %diq_corr_meas = 0x%08x\n",
2572             i, ahp->ah_total_iq_corr_meas[i]);
2573 
2574         iq_corr_neg = 0;
2575 
2576         /* iq_corr_meas is always negative. */
2577         if (iq_corr_meas > 0x80000000)  {
2578             iq_corr_meas = (0xffffffff - iq_corr_meas) + 1;
2579             iq_corr_neg = 1;
2580         }
2581 
2582         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2583             "Chn %d pwr_meas_i = 0x%08x\n", i, power_meas_i);
2584         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2585             "Chn %d pwr_meas_q = 0x%08x\n", i, power_meas_q);
2586         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2587             "iq_corr_neg is 0x%08x\n", iq_corr_neg);
2588 
2589         i_coff_denom = (power_meas_i / 2 + power_meas_q / 2) / 256;
2590         q_coff_denom = power_meas_q / 64;
2591 
2592         /* Protect against divide-by-0 */
2593         if ((i_coff_denom != 0) && (q_coff_denom != 0)) {
2594             /* IQ corr_meas is already negated if iqcorr_neg == 1 */
2595             i_coff = iq_corr_meas / i_coff_denom;
2596             q_coff = power_meas_i / q_coff_denom - 64;
2597             HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2598                 "Chn %d i_coff = 0x%08x\n", i, i_coff);
2599             HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2600                 "Chn %d q_coff = 0x%08x\n", i, q_coff);
2601 
2602             /* Force bounds on i_coff */
2603             if (i_coff >= 63) {
2604                 i_coff = 63;
2605             } else if (i_coff <= -63) {
2606                 i_coff = -63;
2607             }
2608 
2609             /* Negate i_coff if iq_corr_neg == 0 */
2610             if (iq_corr_neg == 0x0) {
2611                 i_coff = -i_coff;
2612             }
2613 
2614             /* Force bounds on q_coff */
2615             if (q_coff >= 63) {
2616                 q_coff = 63;
2617             } else if (q_coff <= -63) {
2618                 q_coff = -63;
2619             }
2620 
2621             i_coff = i_coff & 0x7f;
2622             q_coff = q_coff & 0x7f;
2623 
2624             HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2625                 "Chn %d : i_coff = 0x%x  q_coff = 0x%x\n", i, i_coff, q_coff);
2626             HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2627                 "Register offset (0x%04x) before update = 0x%x\n",
2628                 offset_array[i], OS_REG_READ(ah, offset_array[i]));
2629 
2630             OS_REG_RMW_FIELD(ah, offset_array[i],
2631                 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, i_coff);
2632             OS_REG_RMW_FIELD(ah, offset_array[i],
2633                 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, q_coff);
2634 
2635             /* store the RX cal results */
2636 	    if (ichan != NULL) {
2637             ahp->ah_rx_cal_corr[i] = OS_REG_READ(ah, offset_array[i]) & 0x7fff;
2638             ahp->ah_rx_cal_complete = AH_TRUE;
2639             ahp->ah_rx_cal_chan = ichan->channel;
2640 //            ahp->ah_rx_cal_chan_flag = ichan->channel_flags &~ CHANNEL_PASSIVE;
2641             ahp->ah_rx_cal_chan_flag = 0; /* XXX */
2642 	    } else {
2643 	        /* XXX? Is this what I should do? */
2644             	ahp->ah_rx_cal_complete = AH_FALSE;
2645 
2646 	    }
2647 
2648             HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2649                 "Register offset (0x%04x) QI COFF (bitfields 0x%08x) "
2650                 "after update = 0x%x\n",
2651                 offset_array[i], AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
2652                 OS_REG_READ(ah, offset_array[i]));
2653             HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2654                 "Register offset (0x%04x) QQ COFF (bitfields 0x%08x) "
2655                 "after update = 0x%x\n",
2656                 offset_array[i], AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
2657                 OS_REG_READ(ah, offset_array[i]));
2658             HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2659                 "IQ Cal and Correction done for Chain %d\n", i);
2660         }
2661     }
2662 
2663     OS_REG_SET_BIT(ah,
2664         AR_PHY_RX_IQCAL_CORR_B0, AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE);
2665     HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2666         "IQ Cal and Correction (offset 0x%04x) enabled "
2667         "(bit position 0x%08x). New Value 0x%08x\n",
2668         (unsigned) (AR_PHY_RX_IQCAL_CORR_B0),
2669         AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE,
2670         OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
2671 }
2672 
2673 /*
2674  * When coming back from offchan, we do not perform RX IQ Cal.
2675  * But the chip reset will clear all previous results
2676  * We store the previous results and restore here.
2677  */
2678 static void
2679 ar9300_rx_iq_cal_restore(struct ath_hal *ah)
2680 {
2681     struct ath_hal_9300 *ahp = AH9300(ah);
2682     u_int32_t   i_coff, q_coff;
2683     HAL_BOOL is_restore = AH_FALSE;
2684     int i;
2685     static const u_int32_t offset_array[3] = {
2686         AR_PHY_RX_IQCAL_CORR_B0,
2687         AR_PHY_RX_IQCAL_CORR_B1,
2688         AR_PHY_RX_IQCAL_CORR_B2,
2689     };
2690 
2691     for (i=0; i<AR9300_MAX_CHAINS; i++) {
2692         if (ahp->ah_rx_cal_corr[i]) {
2693             i_coff = (ahp->ah_rx_cal_corr[i] &
2694                         AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF) >>
2695                         AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF_S;
2696             q_coff = (ahp->ah_rx_cal_corr[i] &
2697                         AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF) >>
2698                         AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF_S;
2699 
2700             OS_REG_RMW_FIELD(ah, offset_array[i],
2701                 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, i_coff);
2702             OS_REG_RMW_FIELD(ah, offset_array[i],
2703                 AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, q_coff);
2704 
2705             is_restore = AH_TRUE;
2706         }
2707     }
2708 
2709     if (is_restore)
2710         OS_REG_SET_BIT(ah,
2711             AR_PHY_RX_IQCAL_CORR_B0, AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE);
2712 
2713     HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
2714         "%s: IQ Cal and Correction (offset 0x%04x) enabled "
2715         "(bit position 0x%08x). New Value 0x%08x\n",
2716         __func__,
2717         (unsigned) (AR_PHY_RX_IQCAL_CORR_B0),
2718         AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE,
2719         OS_REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
2720 }
2721 
2722 /*
2723  * Set a limit on the overall output power.  Used for dynamic
2724  * transmit power control and the like.
2725  *
2726  * NB: limit is in units of 0.5 dbM.
2727  */
2728 HAL_BOOL
2729 ar9300_set_tx_power_limit(struct ath_hal *ah, u_int32_t limit,
2730     u_int16_t extra_txpow, u_int16_t tpc_in_db)
2731 {
2732     struct ath_hal_9300 *ahp = AH9300(ah);
2733     struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
2734     const struct ieee80211_channel *chan = ahpriv->ah_curchan;
2735     HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
2736 
2737     if (NULL == chan) {
2738         return AH_FALSE;
2739     }
2740 
2741     ahpriv->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER);
2742     ahpriv->ah_extraTxPow = extra_txpow;
2743 
2744     if(chan == NULL) {
2745         return AH_FALSE;
2746     }
2747     if (ar9300_eeprom_set_transmit_power(ah, &ahp->ah_eeprom, chan,
2748         ath_hal_getctl(ah, chan), ath_hal_getantennaallowed(ah, chan),
2749         ath_hal_get_twice_max_regpower(ahpriv, ichan, chan),
2750         AH_MIN(MAX_RATE_POWER, ahpriv->ah_powerLimit)) != HAL_OK)
2751     {
2752         return AH_FALSE;
2753     }
2754     return AH_TRUE;
2755 }
2756 
2757 /*
2758  * Exported call to check for a recent gain reading and return
2759  * the current state of the thermal calibration gain engine.
2760  */
2761 HAL_RFGAIN
2762 ar9300_get_rfgain(struct ath_hal *ah)
2763 {
2764     return HAL_RFGAIN_INACTIVE;
2765 }
2766 
2767 #define HAL_GREEN_AP_RX_MASK 0x1
2768 
2769 static inline void
2770 ar9300_init_chain_masks(struct ath_hal *ah, int rx_chainmask, int tx_chainmask)
2771 {
2772     if (AH9300(ah)->green_ap_ps_on) {
2773         rx_chainmask = HAL_GREEN_AP_RX_MASK;
2774     }
2775     if (rx_chainmask == 0x5) {
2776         OS_REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN);
2777     }
2778     OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
2779     OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
2780 
2781     /*
2782      * Adaptive Power Management:
2783      * Some 3 stream chips exceed the PCIe power requirements.
2784      * This workaround will reduce power consumption by using 2 tx chains
2785      * for 1 and 2 stream rates (5 GHz only).
2786      *
2787      * Set the self gen mask to 2 tx chains when APM is enabled.
2788      *
2789      */
2790     if (AH_PRIVATE(ah)->ah_caps.halApmEnable && (tx_chainmask == 0x7)) {
2791         OS_REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
2792     }
2793     else {
2794         OS_REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
2795     }
2796 
2797     if (tx_chainmask == 0x5) {
2798         OS_REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN);
2799     }
2800 }
2801 
2802 /*
2803  * Override INI values with chip specific configuration.
2804  */
2805 static inline void
2806 ar9300_override_ini(struct ath_hal *ah, struct ieee80211_channel *chan)
2807 {
2808     u_int32_t val;
2809     HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps;
2810 
2811     /*
2812      * Set the RX_ABORT and RX_DIS and clear it only after
2813      * RXE is set for MAC. This prevents frames with
2814      * corrupted descriptor status.
2815      */
2816     OS_REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
2817     /*
2818      * For Merlin and above, there is a new feature that allows Multicast
2819      * search based on both MAC Address and Key ID.
2820      * By default, this feature is enabled.
2821      * But since the driver is not using this feature, we switch it off;
2822      * otherwise multicast search based on MAC addr only will fail.
2823      */
2824     val = OS_REG_READ(ah, AR_PCU_MISC_MODE2) & (~AR_ADHOC_MCAST_KEYID_ENABLE);
2825     OS_REG_WRITE(ah, AR_PCU_MISC_MODE2,
2826         val | AR_BUG_58603_FIX_ENABLE | AR_AGG_WEP_ENABLE);
2827 
2828 
2829     /* Osprey revision specific configuration */
2830 
2831     /* Osprey 2.0+ - if SW RAC support is disabled, must also disable
2832      * the Osprey 2.0 hardware RAC fix.
2833      */
2834     if (p_cap->halIsrRacSupport == AH_FALSE) {
2835         OS_REG_CLR_BIT(ah, AR_CFG, AR_CFG_MISSING_TX_INTR_FIX_ENABLE);
2836     }
2837 
2838     /* try to enable old pal if it is needed for h/w green tx */
2839     ar9300_hwgreentx_set_pal_spare(ah, 1);
2840 }
2841 
2842 static inline void
2843 ar9300_prog_ini(struct ath_hal *ah, struct ar9300_ini_array *ini_arr,
2844     int column)
2845 {
2846     int i, reg_writes = 0;
2847 
2848     /* New INI format: Array may be undefined (pre, core, post arrays) */
2849     if (ini_arr->ia_array == NULL) {
2850         return;
2851     }
2852 
2853     /*
2854      * New INI format: Pre, core, and post arrays for a given subsystem may be
2855      * modal (> 2 columns) or non-modal (2 columns).
2856      * Determine if the array is non-modal and force the column to 1.
2857      */
2858     if (column >= ini_arr->ia_columns) {
2859         column = 1;
2860     }
2861 
2862     for (i = 0; i < ini_arr->ia_rows; i++) {
2863         u_int32_t reg = INI_RA(ini_arr, i, 0);
2864         u_int32_t val = INI_RA(ini_arr, i, column);
2865 
2866         /*
2867         ** Determine if this is a shift register value
2868         ** (reg >= 0x16000 && reg < 0x17000 for Osprey) ,
2869         ** and insert the configured delay if so.
2870         ** -this delay is not required for Osprey (EV#71410)
2871         */
2872         OS_REG_WRITE(ah, reg, val);
2873         WAR_6773(reg_writes);
2874 
2875     }
2876 }
2877 
2878 static inline HAL_STATUS
2879 ar9300_process_ini(struct ath_hal *ah, struct ieee80211_channel *chan,
2880     HAL_CHANNEL_INTERNAL *ichan, HAL_HT_MACMODE macmode)
2881 {
2882     int reg_writes = 0;
2883     struct ath_hal_9300 *ahp = AH9300(ah);
2884     u_int modes_index, modes_txgaintable_index = 0;
2885     int i;
2886     HAL_STATUS status;
2887     struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
2888     /* Setup the indices for the next set of register array writes */
2889     /* TODO:
2890      * If the channel marker is indicative of the current mode rather
2891      * than capability, we do not need to check the phy mode below.
2892      */
2893 #if 0
2894     switch (chan->channel_flags & CHANNEL_ALL) {
2895     case CHANNEL_A:
2896     case CHANNEL_A_HT20:
2897         if (AR_SREV_SCORPION(ah)){
2898             if (chan->channel <= 5350){
2899                 modes_txgaintable_index = 1;
2900             }else if ((chan->channel > 5350) && (chan->channel <= 5600)){
2901                 modes_txgaintable_index = 3;
2902             }else if (chan->channel > 5600){
2903                 modes_txgaintable_index = 5;
2904             }
2905         }
2906         modes_index = 1;
2907         freq_index  = 1;
2908         break;
2909 
2910     case CHANNEL_A_HT40PLUS:
2911     case CHANNEL_A_HT40MINUS:
2912         if (AR_SREV_SCORPION(ah)){
2913             if (chan->channel <= 5350){
2914                 modes_txgaintable_index = 2;
2915             }else if ((chan->channel > 5350) && (chan->channel <= 5600)){
2916                 modes_txgaintable_index = 4;
2917             }else if (chan->channel > 5600){
2918                 modes_txgaintable_index = 6;
2919             }
2920         }
2921         modes_index = 2;
2922         freq_index  = 1;
2923         break;
2924 
2925     case CHANNEL_PUREG:
2926     case CHANNEL_G_HT20:
2927     case CHANNEL_B:
2928         if (AR_SREV_SCORPION(ah)){
2929             modes_txgaintable_index = 8;
2930         }else if (AR_SREV_HONEYBEE(ah)){
2931 	    modes_txgaintable_index = 1;
2932 	}
2933         modes_index = 4;
2934         freq_index  = 2;
2935         break;
2936 
2937     case CHANNEL_G_HT40PLUS:
2938     case CHANNEL_G_HT40MINUS:
2939         if (AR_SREV_SCORPION(ah)){
2940             modes_txgaintable_index = 7;
2941         }else if (AR_SREV_HONEYBEE(ah)){
2942             modes_txgaintable_index = 1;
2943         }
2944         modes_index = 3;
2945         freq_index  = 2;
2946         break;
2947 
2948     case CHANNEL_108G:
2949         modes_index = 5;
2950         freq_index  = 2;
2951         break;
2952 
2953     default:
2954         HALASSERT(0);
2955         return HAL_EINVAL;
2956     }
2957 #endif
2958 
2959     /* FreeBSD */
2960     if (IS_CHAN_5GHZ(ichan)) {
2961         if (IEEE80211_IS_CHAN_HT40U(chan) || IEEE80211_IS_CHAN_HT40D(chan)) {
2962             if (AR_SREV_SCORPION(ah)){
2963                 if (ichan->channel <= 5350){
2964                     modes_txgaintable_index = 2;
2965                 }else if ((ichan->channel > 5350) && (ichan->channel <= 5600)){
2966                     modes_txgaintable_index = 4;
2967                 }else if (ichan->channel > 5600){
2968                     modes_txgaintable_index = 6;
2969                 }
2970             }
2971             modes_index = 2;
2972         } else if (IEEE80211_IS_CHAN_A(chan) || IEEE80211_IS_CHAN_HT20(chan)) {
2973             if (AR_SREV_SCORPION(ah)){
2974                 if (ichan->channel <= 5350){
2975                     modes_txgaintable_index = 1;
2976                 }else if ((ichan->channel > 5350) && (ichan->channel <= 5600)){
2977                     modes_txgaintable_index = 3;
2978                 }else if (ichan->channel > 5600){
2979                     modes_txgaintable_index = 5;
2980                 }
2981             }
2982             modes_index = 1;
2983         } else
2984             return HAL_EINVAL;
2985     } else if (IS_CHAN_2GHZ(ichan)) {
2986         if (IEEE80211_IS_CHAN_108G(chan)) {
2987             modes_index = 5;
2988         } else if (IEEE80211_IS_CHAN_HT40U(chan) || IEEE80211_IS_CHAN_HT40D(chan)) {
2989             if (AR_SREV_SCORPION(ah)){
2990                 modes_txgaintable_index = 7;
2991             } else if (AR_SREV_HONEYBEE(ah)){
2992                 modes_txgaintable_index = 1;
2993             }
2994             modes_index = 3;
2995         } else if (IEEE80211_IS_CHAN_HT20(chan) || IEEE80211_IS_CHAN_G(chan) || IEEE80211_IS_CHAN_B(chan) || IEEE80211_IS_CHAN_PUREG(chan)) {
2996             if (AR_SREV_SCORPION(ah)){
2997                 modes_txgaintable_index = 8;
2998             } else if (AR_SREV_HONEYBEE(ah)){
2999                 modes_txgaintable_index = 1;
3000             }
3001             modes_index = 4;
3002         } else
3003             return HAL_EINVAL;
3004     } else
3005             return HAL_EINVAL;
3006 
3007 #if 0
3008     /* Set correct Baseband to analog shift setting to access analog chips. */
3009     OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
3010 #endif
3011 
3012     HALDEBUG(ah, HAL_DEBUG_RESET,
3013         "ar9300_process_ini: "
3014         "Skipping OS-REG-WRITE(ah, AR-PHY(0), 0x00000007)\n");
3015     HALDEBUG(ah, HAL_DEBUG_RESET,
3016         "ar9300_process_ini: no ADDac programming\n");
3017 
3018 
3019     /*
3020      * Osprey 2.0+ - new INI format.
3021      * Each subsystem has a pre, core, and post array.
3022      */
3023     for (i = 0; i < ATH_INI_NUM_SPLIT; i++) {
3024         ar9300_prog_ini(ah, &ahp->ah_ini_soc[i], modes_index);
3025         ar9300_prog_ini(ah, &ahp->ah_ini_mac[i], modes_index);
3026         ar9300_prog_ini(ah, &ahp->ah_ini_bb[i], modes_index);
3027         ar9300_prog_ini(ah, &ahp->ah_ini_radio[i], modes_index);
3028         if ((i == ATH_INI_POST) && (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah))) {
3029             ar9300_prog_ini(ah, &ahp->ah_ini_radio_post_sys2ant, modes_index);
3030         }
3031 
3032     }
3033 
3034 	if (!(AR_SREV_SOC(ah))) {
3035 			/* Doubler issue : Some board doesn't work well with MCS15. Turn off doubler after freq locking is complete*/
3036 			//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));
3037 			OS_REG_RMW(ah, AR_PHY_65NM_CH0_RXTX2, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
3038 			               1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); /*Set synthon, synthover */
3039 			//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));
3040 
3041 			OS_REG_RMW(ah, AR_PHY_65NM_CH1_RXTX2, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
3042 			               1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); /*Set synthon, synthover */
3043 			OS_REG_RMW(ah, AR_PHY_65NM_CH2_RXTX2, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
3044 			               1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); /*Set synthon, synthover */
3045 			OS_DELAY(200);
3046 
3047 			//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));
3048 			OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH0_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); /* clr synthon */
3049 			OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH1_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); /* clr synthon */
3050 			OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH2_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); /* clr synthon */
3051 			//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));
3052 
3053 			OS_DELAY(1);
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_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); /* set synthon */
3057 			OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); /* set synthon */
3058 			OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX2, AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); /* set 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(200);
3062 
3063 			//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));
3064 			OS_REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_SYNTH12, AR_PHY_65NM_CH0_SYNTH12_VREFMUL3, 0xf);
3065 			//OS_REG_CLR_BIT(ah, AR_PHY_65NM_CH0_SYNTH12, 1<< 16); /* clr charge pump */
3066 			//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));
3067 
3068 			OS_REG_RMW(ah, AR_PHY_65NM_CH0_RXTX2, 0, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
3069 			               1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); /*Clr synthon, synthover */
3070 			OS_REG_RMW(ah, AR_PHY_65NM_CH1_RXTX2, 0, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
3071 			               1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); /*Clr synthon, synthover */
3072 			OS_REG_RMW(ah, AR_PHY_65NM_CH2_RXTX2, 0, 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
3073 			               1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); /*Clr synthon, synthover */
3074 			//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));
3075 		}
3076 
3077     /* Write rxgain Array Parameters */
3078     REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain, 1, reg_writes);
3079     HALDEBUG(ah, HAL_DEBUG_RESET, "ar9300_process_ini: Rx Gain programming\n");
3080 
3081     if (AR_SREV_JUPITER_20_OR_LATER(ah)) {
3082         /*
3083          * CUS217 mix LNA mode.
3084          */
3085         if (ar9300_rx_gain_index_get(ah) == 2) {
3086             REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain_bb_core, 1, reg_writes);
3087             REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain_bb_postamble,
3088                 modes_index, reg_writes);
3089         }
3090 
3091         /*
3092          * 5G-XLNA
3093          */
3094         if ((ar9300_rx_gain_index_get(ah) == 2) ||
3095             (ar9300_rx_gain_index_get(ah) == 3)) {
3096             REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain_xlna, modes_index,
3097               reg_writes);
3098         }
3099     }
3100 
3101     if (AR_SREV_SCORPION(ah)) {
3102         /* Write rxgain bounds Array */
3103         REG_WRITE_ARRAY(&ahp->ah_ini_modes_rxgain_bounds, modes_index, reg_writes);
3104         HALDEBUG(ah, HAL_DEBUG_RESET, "ar9300_process_ini: Rx Gain table bounds programming\n");
3105     }
3106     /* UB124 xLNA settings */
3107     if (AR_SREV_WASP(ah) && ar9300_rx_gain_index_get(ah) == 2) {
3108 #define REG_WRITE(_reg,_val)    *((volatile u_int32_t *)(_reg)) = (_val);
3109 #define REG_READ(_reg)          *((volatile u_int32_t *)(_reg))
3110         u_int32_t val;
3111         /* B8040000:  bit[0]=0, bit[3]=0; */
3112         val = REG_READ(0xB8040000);
3113         val &= 0xfffffff6;
3114         REG_WRITE(0xB8040000, val);
3115         /* B804002c:  bit[31:24]=0x2e; bit[7:0]=0x2f; */
3116         val = REG_READ(0xB804002c);
3117         val &= 0x00ffff00;
3118         val |= 0x2e00002f;
3119         REG_WRITE(0xB804002c, val);
3120         /* B804006c:  bit[1]=1; */
3121         val = REG_READ(0xB804006c);
3122         val |= 0x2;
3123         REG_WRITE(0xB804006c, val);
3124 #undef REG_READ
3125 #undef REG_WRITE
3126     }
3127 
3128 
3129     /* Write txgain Array Parameters */
3130     if (AR_SREV_SCORPION(ah) || AR_SREV_HONEYBEE(ah)) {
3131         REG_WRITE_ARRAY(&ahp->ah_ini_modes_txgain, modes_txgaintable_index,
3132             reg_writes);
3133     }else{
3134         REG_WRITE_ARRAY(&ahp->ah_ini_modes_txgain, modes_index, reg_writes);
3135     }
3136     HALDEBUG(ah, HAL_DEBUG_RESET, "ar9300_process_ini: Tx Gain programming\n");
3137 
3138 
3139     /* For 5GHz channels requiring Fast Clock, apply different modal values */
3140     if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
3141         HALDEBUG(ah, HAL_DEBUG_RESET,
3142             "%s: Fast clock enabled, use special ini values\n", __func__);
3143         REG_WRITE_ARRAY(&ahp->ah_ini_modes_additional, modes_index, reg_writes);
3144     }
3145 
3146     if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) {
3147         HALDEBUG(ah, HAL_DEBUG_RESET,
3148             "%s: use xtal ini for AH9300(ah)->clk_25mhz: %d\n",
3149             __func__, AH9300(ah)->clk_25mhz);
3150         REG_WRITE_ARRAY(
3151             &ahp->ah_ini_modes_additional, 1/*modes_index*/, reg_writes);
3152     }
3153 
3154     if (AR_SREV_WASP(ah) && (AH9300(ah)->clk_25mhz == 0)) {
3155         HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Apply 40MHz ini settings\n", __func__);
3156         REG_WRITE_ARRAY(
3157             &ahp->ah_ini_modes_additional_40mhz, 1/*modesIndex*/, reg_writes);
3158     }
3159 
3160     /* Handle Japan Channel 14 channel spreading */
3161     if (2484 == ichan->channel) {
3162         ar9300_prog_ini(ah, &ahp->ah_ini_japan2484, 1);
3163     }
3164 
3165 #if 0
3166     /* XXX TODO! */
3167     if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) {
3168         ar9300_prog_ini(ah, &ahp->ah_ini_BTCOEX_MAX_TXPWR, 1);
3169     }
3170 #endif
3171 
3172     /* Override INI with chip specific configuration */
3173     ar9300_override_ini(ah, chan);
3174 
3175     /* Setup 11n MAC/Phy mode registers */
3176     ar9300_set_11n_regs(ah, chan, macmode);
3177 
3178     /*
3179      * Moved ar9300_init_chain_masks() here to ensure the swap bit is set before
3180      * the pdadc table is written.  Swap must occur before any radio dependent
3181      * replicated register access.  The pdadc curve addressing in particular
3182      * depends on the consistent setting of the swap bit.
3183      */
3184     ar9300_init_chain_masks(ah, ahp->ah_rx_chainmask, ahp->ah_tx_chainmask);
3185 
3186     /*
3187      * Setup the transmit power values.
3188      *
3189      * After the public to private hal channel mapping, ichan contains the
3190      * valid regulatory power value.
3191      * ath_hal_getctl and ath_hal_getantennaallowed look up ichan from chan.
3192      */
3193     status = ar9300_eeprom_set_transmit_power(ah, &ahp->ah_eeprom, chan,
3194              ath_hal_getctl(ah, chan), ath_hal_getantennaallowed(ah, chan),
3195              ath_hal_get_twice_max_regpower(ahpriv, ichan, chan),
3196              AH_MIN(MAX_RATE_POWER, ahpriv->ah_powerLimit));
3197     if (status != HAL_OK) {
3198         HALDEBUG(ah, HAL_DEBUG_POWER_MGMT,
3199             "%s: error init'ing transmit power\n", __func__);
3200         return HAL_EIO;
3201     }
3202 
3203 
3204     return HAL_OK;
3205 #undef N
3206 }
3207 
3208 /* ar9300_is_cal_supp
3209  * Determine if calibration is supported by device and channel flags
3210  */
3211 inline static HAL_BOOL
3212 ar9300_is_cal_supp(struct ath_hal *ah, const struct ieee80211_channel *chan,
3213     HAL_CAL_TYPES cal_type)
3214 {
3215     struct ath_hal_9300 *ahp = AH9300(ah);
3216     HAL_BOOL retval = AH_FALSE;
3217 
3218     switch (cal_type & ahp->ah_supp_cals) {
3219     case IQ_MISMATCH_CAL:
3220         /* Run IQ Mismatch for non-CCK only */
3221         if (!IEEE80211_IS_CHAN_B(chan)) {
3222             retval = AH_TRUE;
3223         }
3224         break;
3225     case TEMP_COMP_CAL:
3226         retval = AH_TRUE;
3227         break;
3228     }
3229 
3230     return retval;
3231 }
3232 
3233 
3234 #if 0
3235 /* ar9285_pa_cal
3236  * PA Calibration for Kite 1.1 and later versions of Kite.
3237  * - from system's team.
3238  */
3239 static inline void
3240 ar9285_pa_cal(struct ath_hal *ah)
3241 {
3242     u_int32_t reg_val;
3243     int i, lo_gn, offs_6_1, offs_0;
3244     u_int8_t reflo;
3245     u_int32_t phy_test2_reg_val, phy_adc_ctl_reg_val;
3246     u_int32_t an_top2_reg_val, phy_tst_dac_reg_val;
3247 
3248 
3249     /* Kite 1.1 WAR for Bug 35666
3250      * Increase the LDO value to 1.28V before accessing analog Reg */
3251     if (AR_SREV_KITE_11(ah)) {
3252         OS_REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14) );
3253     }
3254     an_top2_reg_val = OS_REG_READ(ah, AR9285_AN_TOP2);
3255 
3256     /* set pdv2i pdrxtxbb */
3257     reg_val = OS_REG_READ(ah, AR9285_AN_RXTXBB1);
3258     reg_val |= ((0x1 << 5) | (0x1 << 7));
3259     OS_REG_WRITE(ah, AR9285_AN_RXTXBB1, reg_val);
3260 
3261     /* clear pwddb */
3262     reg_val = OS_REG_READ(ah, AR9285_AN_RF2G7);
3263     reg_val &= 0xfffffffd;
3264     OS_REG_WRITE(ah, AR9285_AN_RF2G7, reg_val);
3265 
3266     /* clear enpacal */
3267     reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3268     reg_val &= 0xfffff7ff;
3269     OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3270 
3271     /* set offcal */
3272     reg_val = OS_REG_READ(ah, AR9285_AN_RF2G2);
3273     reg_val |= (0x1 << 12);
3274     OS_REG_WRITE(ah, AR9285_AN_RF2G2, reg_val);
3275 
3276     /* set pdpadrv1=pdpadrv2=pdpaout=1 */
3277     reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3278     reg_val |= (0x7 << 23);
3279     OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3280 
3281     /* Read back reflo, increase it by 1 and write it. */
3282     reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3283     reflo = ((reg_val >> 26) & 0x7);
3284 
3285     if (reflo < 0x7) {
3286         reflo++;
3287     }
3288     reg_val = ((reg_val & 0xe3ffffff) | (reflo << 26));
3289     OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3290 
3291     reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3292     reflo = ((reg_val >> 26) & 0x7);
3293 
3294     /* use TX single carrier to transmit
3295      * dac const
3296      * reg. 15
3297      */
3298     phy_tst_dac_reg_val = OS_REG_READ(ah, AR_PHY_TSTDAC_CONST);
3299     OS_REG_WRITE(ah, AR_PHY_TSTDAC_CONST, ((0x7ff << 11) | 0x7ff));
3300     reg_val = OS_REG_READ(ah, AR_PHY_TSTDAC_CONST);
3301 
3302     /* source is dac const
3303      * reg. 2
3304      */
3305     phy_test2_reg_val = OS_REG_READ(ah, AR_PHY_TEST2);
3306     OS_REG_WRITE(ah, AR_PHY_TEST2, ((0x1 << 7) | (0x1 << 1)));
3307     reg_val = OS_REG_READ(ah, AR_PHY_TEST2);
3308 
3309     /* set dac on
3310      * reg. 11
3311      */
3312     phy_adc_ctl_reg_val = OS_REG_READ(ah, AR_PHY_ADC_CTL);
3313     OS_REG_WRITE(ah, AR_PHY_ADC_CTL, 0x80008000);
3314     reg_val = OS_REG_READ(ah, AR_PHY_ADC_CTL);
3315 
3316     OS_REG_WRITE(ah, AR9285_AN_TOP2, (0x1 << 27) | (0x1 << 17) | (0x1 << 16) |
3317               (0x1 << 14) | (0x1 << 12) | (0x1 << 11) |
3318               (0x1 << 7) | (0x1 << 5));
3319 
3320     OS_DELAY(10); /* 10 usec */
3321 
3322     /* clear off[6:0] */
3323     reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6);
3324     reg_val &= 0xfc0fffff;
3325     OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val);
3326     reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3327     reg_val &= 0xfdffffff;
3328     OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3329 
3330     offs_6_1 = 0;
3331     for (i = 6; i > 0; i--) {
3332         /* sef off[$k]==1 */
3333         reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6);
3334         reg_val &= 0xfc0fffff;
3335         reg_val = reg_val | (0x1 << (19 + i)) | ((offs_6_1) << 20);
3336         OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val);
3337         lo_gn = (OS_REG_READ(ah, AR9285_AN_RF2G9)) & 0x1;
3338         offs_6_1 = offs_6_1 | (lo_gn << (i - 1));
3339     }
3340 
3341     reg_val = OS_REG_READ(ah, AR9285_AN_RF2G6);
3342     reg_val &= 0xfc0fffff;
3343     reg_val = reg_val | ((offs_6_1 - 1) << 20);
3344     OS_REG_WRITE(ah, AR9285_AN_RF2G6, reg_val);
3345 
3346     /* set off_0=1; */
3347     reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3348     reg_val &= 0xfdffffff;
3349     reg_val = reg_val | (0x1 << 25);
3350     OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3351 
3352     lo_gn = OS_REG_READ(ah, AR9285_AN_RF2G9) & 0x1;
3353     offs_0 = lo_gn;
3354 
3355     reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3356     reg_val &= 0xfdffffff;
3357     reg_val = reg_val | (offs_0 << 25);
3358     OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3359 
3360     /* clear pdv2i */
3361     reg_val = OS_REG_READ(ah, AR9285_AN_RXTXBB1);
3362     reg_val &= 0xffffff5f;
3363     OS_REG_WRITE(ah, AR9285_AN_RXTXBB1, reg_val);
3364 
3365     /* set enpacal */
3366     reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3367     reg_val |= (0x1 << 11);
3368     OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3369 
3370     /* clear offcal */
3371     reg_val = OS_REG_READ(ah, AR9285_AN_RF2G2);
3372     reg_val &= 0xffffefff;
3373     OS_REG_WRITE(ah, AR9285_AN_RF2G2, reg_val);
3374 
3375     /* set pdpadrv1=pdpadrv2=pdpaout=0 */
3376     reg_val = OS_REG_READ(ah, AR9285_AN_RF2G1);
3377     reg_val &= 0xfc7fffff;
3378     OS_REG_WRITE(ah, AR9285_AN_RF2G1, reg_val);
3379 
3380     /* Read back reflo, decrease it by 1 and write it. */
3381     reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3382     reflo = (reg_val >> 26) & 0x7;
3383     if (reflo) {
3384         reflo--;
3385     }
3386     reg_val = ((reg_val & 0xe3ffffff) | (reflo << 26));
3387     OS_REG_WRITE(ah, AR9285_AN_RF2G3, reg_val);
3388     reg_val = OS_REG_READ(ah, AR9285_AN_RF2G3);
3389     reflo = (reg_val >> 26) & 0x7;
3390 
3391     /* write back registers */
3392     OS_REG_WRITE(ah, AR_PHY_TSTDAC_CONST, phy_tst_dac_reg_val);
3393     OS_REG_WRITE(ah, AR_PHY_TEST2, phy_test2_reg_val);
3394     OS_REG_WRITE(ah, AR_PHY_ADC_CTL, phy_adc_ctl_reg_val);
3395     OS_REG_WRITE(ah, AR9285_AN_TOP2, an_top2_reg_val);
3396 
3397     /* Kite 1.1 WAR for Bug 35666
3398      * Decrease the LDO value back to 1.20V */
3399     if (AR_SREV_KITE_11(ah)) {
3400         OS_REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
3401     }
3402 }
3403 #endif
3404 
3405 /* ar9300_run_init_cals
3406  * Runs non-periodic calibrations
3407  */
3408 inline static HAL_BOOL
3409 ar9300_run_init_cals(struct ath_hal *ah, int init_cal_count)
3410 {
3411     struct ath_hal_9300 *ahp = AH9300(ah);
3412     HAL_CHANNEL_INTERNAL ichan; /* bogus */
3413     HAL_BOOL is_cal_done;
3414     HAL_CAL_LIST *curr_cal;
3415     const HAL_PERCAL_DATA *cal_data;
3416     int i;
3417 
3418     curr_cal = ahp->ah_cal_list_curr;
3419     if (curr_cal == AH_NULL) {
3420         return AH_FALSE;
3421     }
3422     cal_data = curr_cal->cal_data;
3423     ichan.calValid = 0;
3424 
3425     for (i = 0; i < init_cal_count; i++) {
3426         /* Reset this Cal */
3427         ar9300_reset_calibration(ah, curr_cal);
3428         /* Poll for offset calibration complete */
3429         if (!ath_hal_wait(
3430                 ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL, 0))
3431         {
3432             HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3433                 "%s: Cal %d failed to complete in 100ms.\n",
3434                 __func__, curr_cal->cal_data->cal_type);
3435             /* Re-initialize list pointers for periodic cals */
3436             ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr
3437                 = AH_NULL;
3438             return AH_FALSE;
3439         }
3440         /* Run this cal */
3441         ar9300_per_calibration(
3442             ah, &ichan, ahp->ah_rx_chainmask, curr_cal, &is_cal_done);
3443         if (is_cal_done == AH_FALSE) {
3444             HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3445                 "%s: Not able to run Init Cal %d.\n", __func__,
3446                 curr_cal->cal_data->cal_type);
3447         }
3448         if (curr_cal->cal_next) {
3449             curr_cal = curr_cal->cal_next;
3450         }
3451     }
3452 
3453     /* Re-initialize list pointers for periodic cals */
3454     ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = AH_NULL;
3455     return AH_TRUE;
3456 }
3457 
3458 #if 0
3459 static void
3460 ar9300_tx_carrier_leak_war(struct ath_hal *ah)
3461 {
3462     unsigned long tx_gain_table_max;
3463     unsigned long reg_bb_cl_map_0_b0 = 0xffffffff;
3464     unsigned long reg_bb_cl_map_1_b0 = 0xffffffff;
3465     unsigned long reg_bb_cl_map_2_b0 = 0xffffffff;
3466     unsigned long reg_bb_cl_map_3_b0 = 0xffffffff;
3467     unsigned long tx_gain, cal_run = 0;
3468     unsigned long cal_gain[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1];
3469     unsigned long cal_gain_index[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1];
3470     unsigned long new_gain[AR_PHY_TPC_7_TX_GAIN_TABLE_MAX + 1];
3471     int i, j;
3472 
3473     OS_MEMSET(new_gain, 0, sizeof(new_gain));
3474     /*printf("     Running TxCarrierLeakWAR\n");*/
3475 
3476     /* process tx gain table, we use cl_map_hw_gen=0. */
3477     OS_REG_RMW_FIELD(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_MAP_HW_GEN, 0);
3478 
3479 	//the table we used is txbb_gc[2:0], 1dB[2:1].
3480     tx_gain_table_max = OS_REG_READ_FIELD(ah,
3481         AR_PHY_TPC_7, AR_PHY_TPC_7_TX_GAIN_TABLE_MAX);
3482 
3483     for (i = 0; i <= tx_gain_table_max; i++) {
3484         tx_gain = OS_REG_READ(ah, AR_PHY_TXGAIN_TAB(1) + i * 4);
3485         cal_gain[i] = (((tx_gain >> 5)& 0x7) << 2) |
3486             (((tx_gain >> 1) & 0x3) << 0);
3487         if (i == 0) {
3488             cal_gain_index[i] = cal_run;
3489             new_gain[i] = 1;
3490             cal_run++;
3491         } else {
3492             new_gain[i] = 1;
3493             for (j = 0; j < i; j++) {
3494                 /*
3495                 printf("i=%d, j=%d cal_gain[$i]=0x%04x\n", i, j, cal_gain[i]);
3496                  */
3497                 if (new_gain[i]) {
3498                     if ((cal_gain[i] != cal_gain[j])) {
3499                         new_gain[i] = 1;
3500                     } else {
3501                         /* if old gain found, use old cal_run value. */
3502                         new_gain[i] = 0;
3503                         cal_gain_index[i] = cal_gain_index[j];
3504                     }
3505                 }
3506             }
3507             /* if new gain found, increase cal_run */
3508             if (new_gain[i] == 1) {
3509                 cal_gain_index[i] = cal_run;
3510                 cal_run++;
3511             }
3512         }
3513 
3514         reg_bb_cl_map_0_b0 = (reg_bb_cl_map_0_b0 & ~(0x1 << i)) |
3515             ((cal_gain_index[i] >> 0 & 0x1) << i);
3516         reg_bb_cl_map_1_b0 = (reg_bb_cl_map_1_b0 & ~(0x1 << i)) |
3517             ((cal_gain_index[i] >> 1 & 0x1) << i);
3518         reg_bb_cl_map_2_b0 = (reg_bb_cl_map_2_b0 & ~(0x1 << i)) |
3519             ((cal_gain_index[i] >> 2 & 0x1) << i);
3520         reg_bb_cl_map_3_b0 = (reg_bb_cl_map_3_b0 & ~(0x1 << i)) |
3521             ((cal_gain_index[i] >> 3 & 0x1) << i);
3522 
3523         /*
3524         printf("i=%2d, cal_gain[$i]= 0x%04x, cal_run= %d, "
3525             "cal_gain_index[i]=%d, new_gain[i] = %d\n",
3526             i, cal_gain[i], cal_run, cal_gain_index[i], new_gain[i]);
3527          */
3528     }
3529     OS_REG_WRITE(ah, AR_PHY_CL_MAP_0_B0, reg_bb_cl_map_0_b0);
3530     OS_REG_WRITE(ah, AR_PHY_CL_MAP_1_B0, reg_bb_cl_map_1_b0);
3531     OS_REG_WRITE(ah, AR_PHY_CL_MAP_2_B0, reg_bb_cl_map_2_b0);
3532     OS_REG_WRITE(ah, AR_PHY_CL_MAP_3_B0, reg_bb_cl_map_3_b0);
3533     if (AR_SREV_WASP(ah)) {
3534         OS_REG_WRITE(ah, AR_PHY_CL_MAP_0_B1, reg_bb_cl_map_0_b0);
3535         OS_REG_WRITE(ah, AR_PHY_CL_MAP_1_B1, reg_bb_cl_map_1_b0);
3536         OS_REG_WRITE(ah, AR_PHY_CL_MAP_2_B1, reg_bb_cl_map_2_b0);
3537         OS_REG_WRITE(ah, AR_PHY_CL_MAP_3_B1, reg_bb_cl_map_3_b0);
3538     }
3539 }
3540 #endif
3541 
3542 
3543 static inline void
3544 ar9300_invalidate_saved_cals(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
3545 {
3546 #if ATH_SUPPORT_CAL_REUSE
3547     if (AH_PRIVATE(ah)->ah_config.ath_hal_cal_reuse &
3548         ATH_CAL_REUSE_REDO_IN_FULL_RESET)
3549     {
3550         ichan->one_time_txiqcal_done = AH_FALSE;
3551         ichan->one_time_txclcal_done = AH_FALSE;
3552     }
3553 #endif
3554 }
3555 
3556 static inline HAL_BOOL
3557 ar9300_restore_rtt_cals(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
3558 {
3559     HAL_BOOL restore_status = AH_FALSE;
3560 
3561     return restore_status;
3562 }
3563 
3564 /* ar9300_init_cal
3565  * Initialize Calibration infrastructure
3566  */
3567 static inline HAL_BOOL
3568 ar9300_init_cal_internal(struct ath_hal *ah, struct ieee80211_channel *chan,
3569                          HAL_CHANNEL_INTERNAL *ichan,
3570                          HAL_BOOL enable_rtt, HAL_BOOL do_rtt_cal, HAL_BOOL skip_if_none, HAL_BOOL apply_last_iqcorr)
3571 {
3572     struct ath_hal_9300 *ahp = AH9300(ah);
3573     HAL_BOOL txiqcal_success_flag = AH_FALSE;
3574     HAL_BOOL cal_done = AH_FALSE;
3575     int iqcal_idx = 0;
3576     HAL_BOOL do_sep_iq_cal = AH_FALSE;
3577     HAL_BOOL do_agc_cal = do_rtt_cal;
3578     HAL_BOOL is_cal_reusable = AH_TRUE;
3579 #if ATH_SUPPORT_CAL_REUSE
3580     HAL_BOOL      cal_reuse_enable = AH_PRIVATE(ah)->ah_config.ath_hal_cal_reuse &
3581                                  ATH_CAL_REUSE_ENABLE;
3582     HAL_BOOL      clc_success = AH_FALSE;
3583     int32_t   ch_idx, j, cl_tab_reg;
3584     u_int32_t BB_cl_tab_entry = MAX_BB_CL_TABLE_ENTRY;
3585     u_int32_t BB_cl_tab_b[AR9300_MAX_CHAINS] = {
3586                     AR_PHY_CL_TAB_0,
3587                     AR_PHY_CL_TAB_1,
3588                     AR_PHY_CL_TAB_2
3589                 };
3590 #endif
3591 
3592     if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) {
3593         /* Hornet: 1 x 1 */
3594         ahp->ah_rx_cal_chainmask = 0x1;
3595         ahp->ah_tx_cal_chainmask = 0x1;
3596     } else if (AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah) || AR_SREV_HONEYBEE(ah)) {
3597         /* Wasp/Jupiter: 2 x 2 */
3598         ahp->ah_rx_cal_chainmask = 0x3;
3599         ahp->ah_tx_cal_chainmask = 0x3;
3600     } else {
3601         /*
3602          * Osprey needs to be configured for the correct chain mode
3603          * before running AGC/TxIQ cals.
3604          */
3605         if (ahp->ah_enterprise_mode & AR_ENT_OTP_CHAIN2_DISABLE) {
3606             /* chain 2 disabled - 2 chain mode */
3607             ahp->ah_rx_cal_chainmask = 0x3;
3608             ahp->ah_tx_cal_chainmask = 0x3;
3609         } else {
3610             ahp->ah_rx_cal_chainmask = 0x7;
3611             ahp->ah_tx_cal_chainmask = 0x7;
3612         }
3613     }
3614         ar9300_init_chain_masks(ah, ahp->ah_rx_cal_chainmask, ahp->ah_tx_cal_chainmask);
3615 
3616 
3617     if (ahp->tx_cl_cal_enable) {
3618 #if ATH_SUPPORT_CAL_REUSE
3619         /* disable Carrie Leak or set do_agc_cal accordingly */
3620         if (cal_reuse_enable && ichan->one_time_txclcal_done)
3621         {
3622             OS_REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
3623         } else
3624 #endif /* ATH_SUPPORT_CAL_REUSE */
3625         {
3626             OS_REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
3627             do_agc_cal = AH_TRUE;
3628         }
3629     }
3630 
3631     /* Do Tx IQ Calibration here for osprey hornet and wasp */
3632     /* XXX: For initial wasp bringup - check and enable this */
3633     /* EV 74233: Tx IQ fails to complete for half/quarter rates */
3634     if (!(IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan))) {
3635         if (ahp->tx_iq_cal_enable) {
3636             /* this should be eventually moved to INI file */
3637             OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1(ah),
3638                 AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, DELPT);
3639 
3640             /*
3641              * For poseidon and later chips,
3642              * Tx IQ cal HW run will be a part of AGC calibration
3643              */
3644             if (ahp->tx_iq_cal_during_agc_cal) {
3645                 /*
3646                  * txiqcal_success_flag always set to 1 to run
3647                  *     ar9300_tx_iq_cal_post_proc
3648                  * if following AGC cal passes
3649                 */
3650 #if ATH_SUPPORT_CAL_REUSE
3651                 if (!cal_reuse_enable || !ichan->one_time_txiqcal_done)
3652                 {
3653                     txiqcal_success_flag = AH_TRUE;
3654                     OS_REG_WRITE(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah),
3655                         OS_REG_READ(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah)) |
3656                         AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
3657                 } else {
3658                     OS_REG_WRITE(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah),
3659                         OS_REG_READ(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah)) &
3660                         (~AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL));
3661                 }
3662 #else
3663 		if (OS_REG_READ_FIELD(ah,
3664 					AR_PHY_TX_IQCAL_CONTROL_0(ah),
3665 					AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)){
3666 			if (apply_last_iqcorr == AH_TRUE) {
3667 				OS_REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0(ah),
3668 						AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
3669 				txiqcal_success_flag = AH_FALSE;
3670 			} else {
3671 				txiqcal_success_flag = AH_TRUE;
3672 			}
3673 		}else{
3674 			txiqcal_success_flag = AH_FALSE;
3675 		}
3676 #endif
3677                 if (txiqcal_success_flag) {
3678                     do_agc_cal = AH_TRUE;
3679                 }
3680             } else
3681 #if ATH_SUPPORT_CAL_REUSE
3682             if (!cal_reuse_enable || !ichan->one_time_txiqcal_done)
3683 #endif
3684             {
3685                 do_sep_iq_cal = AH_TRUE;
3686                 do_agc_cal = AH_TRUE;
3687             }
3688         }
3689     }
3690 
3691 #if ATH_SUPPORT_MCI
3692     if (AH_PRIVATE(ah)->ah_caps.halMciSupport &&
3693         IS_CHAN_2GHZ(ichan) &&
3694         (ahp->ah_mci_bt_state == MCI_BT_AWAKE) &&
3695         do_agc_cal &&
3696         !(ah->ah_config.ath_hal_mci_config &
3697         ATH_MCI_CONFIG_DISABLE_MCI_CAL))
3698     {
3699         u_int32_t payload[4] = {0, 0, 0, 0};
3700 
3701         /* Send CAL_REQ only when BT is AWAKE. */
3702         HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Send WLAN_CAL_REQ 0x%X\n",
3703             __func__, ahp->ah_mci_wlan_cal_seq);
3704         MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_REQ);
3705         payload[MCI_GPM_WLAN_CAL_W_SEQUENCE] = ahp->ah_mci_wlan_cal_seq++;
3706         ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE);
3707 
3708         /* Wait BT_CAL_GRANT for 50ms */
3709         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
3710             "(MCI) %s: Wait for BT_CAL_GRANT\n", __func__);
3711         if (ar9300_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000))
3712         {
3713             HALDEBUG(ah, HAL_DEBUG_BT_COEX,
3714                 "(MCI) %s: Got BT_CAL_GRANT.\n", __func__);
3715         }
3716         else {
3717             is_cal_reusable = AH_FALSE;
3718             HALDEBUG(ah, HAL_DEBUG_BT_COEX,
3719                 "(MCI) %s: BT is not responding.\n", __func__);
3720         }
3721     }
3722 #endif /* ATH_SUPPORT_MCI */
3723 
3724     if (do_sep_iq_cal)
3725     {
3726         /* enable Tx IQ Calibration HW for osprey/hornet/wasp */
3727         txiqcal_success_flag = ar9300_tx_iq_cal_hw_run(ah);
3728         OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
3729         OS_DELAY(5);
3730         OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
3731     }
3732 #if 0
3733     if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah)) {
3734         ar9300_tx_carrier_leak_war(ah);
3735     }
3736 #endif
3737     /*
3738      * Calibrate the AGC
3739      *
3740      * Tx IQ cal is a part of AGC cal for Jupiter/Poseidon, etc.
3741      * please enable the bit of txiqcal_control_0[31] in INI file
3742      * for Jupiter/Poseidon/etc.
3743      */
3744     if(!AR_SREV_SCORPION(ah)) {
3745         if (do_agc_cal || !skip_if_none) {
3746             OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3747                 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
3748 
3749             /* Poll for offset calibration complete */
3750             cal_done = ath_hal_wait(ah,
3751                     AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0);
3752             if (!cal_done) {
3753                 HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3754                     "(FCS) CAL NOT DONE!!! - %d\n", ichan->channel);
3755             }
3756         } else {
3757             cal_done = AH_TRUE;
3758         }
3759             /*
3760              * Tx IQ cal post-processing in SW
3761              * This part of code should be common to all chips,
3762              * no chip specific code for Jupiter/Posdeion except for register names.
3763              */
3764             if (txiqcal_success_flag) {
3765                 ar9300_tx_iq_cal_post_proc(ah,ichan, 1, 1,is_cal_reusable, AH_FALSE);
3766             }
3767     } else {
3768         if (!txiqcal_success_flag) {
3769             OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3770                 OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
3771             if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
3772                     0)) {
3773                 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3774                     "%s: offset calibration failed to complete in 1ms; "
3775                     "noisy environment?\n", __func__);
3776                 return AH_FALSE;
3777             }
3778             if (apply_last_iqcorr == AH_TRUE) {
3779                 ar9300_tx_iq_cal_post_proc(ah, ichan, 0, 0, is_cal_reusable, AH_TRUE);
3780             }
3781         } else {
3782             for (iqcal_idx=0;iqcal_idx<MAXIQCAL;iqcal_idx++) {
3783                 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3784                     OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);
3785 
3786                 /* Poll for offset calibration complete */
3787                 if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL,
3788                         AR_PHY_AGC_CONTROL_CAL, 0)) {
3789                     HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3790                         "%s: offset calibration failed to complete in 1ms; "
3791                         "noisy environment?\n", __func__);
3792                     return AH_FALSE;
3793                 }
3794                 /*
3795                  * Tx IQ cal post-processing in SW
3796                  * This part of code should be common to all chips,
3797                  * no chip specific code for Jupiter/Posdeion except for register names.
3798                  */
3799                 ar9300_tx_iq_cal_post_proc(ah, ichan, iqcal_idx+1, MAXIQCAL, is_cal_reusable, AH_FALSE);
3800             }
3801        }
3802     }
3803 
3804 
3805 #if ATH_SUPPORT_MCI
3806     if (AH_PRIVATE(ah)->ah_caps.halMciSupport &&
3807         IS_CHAN_2GHZ(ichan) &&
3808         (ahp->ah_mci_bt_state == MCI_BT_AWAKE) &&
3809         do_agc_cal &&
3810         !(ah->ah_config.ath_hal_mci_config &
3811         ATH_MCI_CONFIG_DISABLE_MCI_CAL))
3812     {
3813         u_int32_t payload[4] = {0, 0, 0, 0};
3814 
3815         HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Send WLAN_CAL_DONE 0x%X\n",
3816             __func__, ahp->ah_mci_wlan_cal_done);
3817         MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_DONE);
3818         payload[MCI_GPM_WLAN_CAL_W_SEQUENCE] = ahp->ah_mci_wlan_cal_done++;
3819         ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE);
3820     }
3821 #endif /* ATH_SUPPORT_MCI */
3822 
3823 
3824     if (!cal_done && !AR_SREV_SCORPION(ah) )
3825     {
3826         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3827             "%s: offset calibration failed to complete in 1ms; "
3828             "noisy environment?\n", __func__);
3829         return AH_FALSE;
3830     }
3831 
3832 #if 0
3833      /* Beacon stuck fix, refer to EV 120056 */
3834     if(IS_CHAN_2GHZ(chan) && AR_SREV_SCORPION(ah))
3835         OS_REG_WRITE(ah, AR_PHY_TIMING5, OS_REG_READ(ah,AR_PHY_TIMING5) & ~AR_PHY_TIMING5_CYCPWR_THR1_ENABLE);
3836 #endif
3837 
3838 #if 0
3839     /* Do PA Calibration */
3840     if (AR_SREV_KITE(ah) && AR_SREV_KITE_11_OR_LATER(ah)) {
3841         ar9285_pa_cal(ah);
3842     }
3843 #endif
3844 
3845 #if ATH_SUPPORT_CAL_REUSE
3846      if (ichan->one_time_txiqcal_done) {
3847         ar9300_tx_iq_cal_apply(ah, ichan);
3848         HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3849             "(FCS) TXIQCAL applied - %d\n", ichan->channel);
3850     }
3851 #endif /* ATH_SUPPORT_CAL_REUSE */
3852 
3853 #if ATH_SUPPORT_CAL_REUSE
3854     if (cal_reuse_enable && ahp->tx_cl_cal_enable)
3855     {
3856         clc_success = (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) &
3857                   AR_PHY_AGC_CONTROL_CLC_SUCCESS) ? 1 : 0;
3858 
3859         if (ichan->one_time_txclcal_done)
3860         {
3861             /* reapply CL cal results */
3862             for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
3863                 if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) {
3864                     continue;
3865                 }
3866                 cl_tab_reg = BB_cl_tab_b[ch_idx];
3867                 for (j = 0; j < BB_cl_tab_entry; j++) {
3868                     OS_REG_WRITE(ah, cl_tab_reg, ichan->tx_clcal[ch_idx][j]);
3869                     cl_tab_reg += 4;;
3870                 }
3871             }
3872             HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3873                 "(FCS) TX CL CAL applied - %d\n", ichan->channel);
3874         }
3875         else if (is_cal_reusable && clc_success) {
3876             /* save CL cal results */
3877             for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
3878                 if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) {
3879                     continue;
3880                 }
3881                 cl_tab_reg = BB_cl_tab_b[ch_idx];
3882                 for (j = 0; j < BB_cl_tab_entry; j++) {
3883                     ichan->tx_clcal[ch_idx][j] = OS_REG_READ(ah, cl_tab_reg);
3884                     cl_tab_reg += 4;
3885                 }
3886             }
3887             ichan->one_time_txclcal_done = AH_TRUE;
3888             HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
3889                 "(FCS) TX CL CAL saved - %d\n", ichan->channel);
3890         }
3891     }
3892 #endif /* ATH_SUPPORT_CAL_REUSE */
3893 
3894     /* Revert chainmasks to their original values before NF cal */
3895     ar9300_init_chain_masks(ah, ahp->ah_rx_chainmask, ahp->ah_tx_chainmask);
3896 
3897 #if !FIX_NOISE_FLOOR
3898     /*
3899      * Do NF calibration after DC offset and other CALs.
3900      * Per system engineers, noise floor value can sometimes be 20 dB
3901      * higher than normal value if DC offset and noise floor cal are
3902      * triggered at the same time.
3903      */
3904     OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
3905         OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
3906 #endif
3907 
3908     /* Initialize list pointers */
3909     ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = AH_NULL;
3910 
3911     /*
3912      * Enable IQ, ADC Gain, ADC DC Offset Cals
3913      */
3914     /* Setup all non-periodic, init time only calibrations */
3915     /* XXX: Init DC Offset not working yet */
3916 #ifdef not_yet
3917     if (AH_TRUE == ar9300_is_cal_supp(ah, chan, ADC_DC_INIT_CAL)) {
3918         INIT_CAL(&ahp->ah_adc_dc_cal_init_data);
3919         INSERT_CAL(ahp, &ahp->ah_adc_dc_cal_init_data);
3920     }
3921 
3922     /* Initialize current pointer to first element in list */
3923     ahp->ah_cal_list_curr = ahp->ah_cal_list;
3924 
3925     if (ahp->ah_cal_list_curr) {
3926         if (ar9300_run_init_cals(ah, 0) == AH_FALSE) {
3927             return AH_FALSE;
3928         }
3929     }
3930 #endif
3931     /* end - Init time calibrations */
3932 
3933     /* Do not do RX cal in case of offchan, or cal data already exists on same channel*/
3934     if (ahp->ah_skip_rx_iq_cal) {
3935         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3936                 "Skip RX IQ Cal\n");
3937         return AH_TRUE;
3938     }
3939 
3940     /* If Cals are supported, add them to list via INIT/INSERT_CAL */
3941     if (AH_TRUE == ar9300_is_cal_supp(ah, chan, IQ_MISMATCH_CAL)) {
3942         INIT_CAL(&ahp->ah_iq_cal_data);
3943         INSERT_CAL(ahp, &ahp->ah_iq_cal_data);
3944         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3945             "%s: enabling IQ Calibration.\n", __func__);
3946     }
3947     if (AH_TRUE == ar9300_is_cal_supp(ah, chan, TEMP_COMP_CAL)) {
3948         INIT_CAL(&ahp->ah_temp_comp_cal_data);
3949         INSERT_CAL(ahp, &ahp->ah_temp_comp_cal_data);
3950         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3951             "%s: enabling Temperature Compensation Calibration.\n", __func__);
3952     }
3953 
3954     /* Initialize current pointer to first element in list */
3955     ahp->ah_cal_list_curr = ahp->ah_cal_list;
3956 
3957     /* Reset state within current cal */
3958     if (ahp->ah_cal_list_curr) {
3959         ar9300_reset_calibration(ah, ahp->ah_cal_list_curr);
3960     }
3961 
3962     /* Mark all calibrations on this channel as being invalid */
3963     ichan->calValid = 0;
3964 
3965     return AH_TRUE;
3966 }
3967 
3968 static inline HAL_BOOL
3969 ar9300_init_cal(struct ath_hal *ah, struct ieee80211_channel *chan, HAL_BOOL skip_if_none, HAL_BOOL apply_last_iqcorr)
3970 {
3971     HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
3972     HAL_BOOL do_rtt_cal = AH_TRUE;
3973     HAL_BOOL enable_rtt = AH_FALSE;
3974 
3975     HALASSERT(ichan);
3976 
3977     return ar9300_init_cal_internal(ah, chan, ichan, enable_rtt, do_rtt_cal, skip_if_none, apply_last_iqcorr);
3978 }
3979 
3980 /* ar9300_reset_cal_valid
3981  * Entry point for upper layers to restart current cal.
3982  * Reset the calibration valid bit in channel.
3983  */
3984 void
3985 ar9300_reset_cal_valid(struct ath_hal *ah, const struct ieee80211_channel *chan,
3986     HAL_BOOL *is_cal_done, u_int32_t cal_type)
3987 {
3988     struct ath_hal_9300 *ahp = AH9300(ah);
3989     HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
3990     HAL_CAL_LIST *curr_cal = ahp->ah_cal_list_curr;
3991 
3992     *is_cal_done = AH_TRUE;
3993 
3994     if (curr_cal == AH_NULL) {
3995         return;
3996     }
3997     if (ichan == AH_NULL) {
3998         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
3999             "%s: invalid channel %u/0x%x; no mapping\n",
4000             __func__, chan->ic_freq, chan->ic_flags);
4001         return;
4002     }
4003 
4004     if (!(cal_type & IQ_MISMATCH_CAL)) {
4005         *is_cal_done = AH_FALSE;
4006         return;
4007     }
4008 
4009     /* Expected that this calibration has run before, post-reset.
4010      * Current state should be done
4011      */
4012     if (curr_cal->cal_state != CAL_DONE) {
4013         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
4014             "%s: Calibration state incorrect, %d\n",
4015             __func__, curr_cal->cal_state);
4016         return;
4017     }
4018 
4019     /* Verify Cal is supported on this channel */
4020     if (ar9300_is_cal_supp(ah, chan, curr_cal->cal_data->cal_type) == AH_FALSE) {
4021         return;
4022     }
4023 
4024     HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
4025         "%s: Resetting Cal %d state for channel %u/0x%x\n", __func__,
4026         curr_cal->cal_data->cal_type, chan->ic_freq, chan->ic_flags);
4027 
4028     /* Disable cal validity in channel */
4029     ichan->calValid &= ~curr_cal->cal_data->cal_type;
4030     curr_cal->cal_state = CAL_WAITING;
4031     /* Indicate to upper layers that we need polling */
4032     *is_cal_done = AH_FALSE;
4033 }
4034 
4035 static inline void
4036 ar9300_set_dma(struct ath_hal *ah)
4037 {
4038     u_int32_t   regval;
4039     struct ath_hal_9300 *ahp = AH9300(ah);
4040     struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
4041     HAL_CAPABILITIES *pCap = &ahpriv->ah_caps;
4042 
4043 #if 0
4044     /*
4045      * set AHB_MODE not to do cacheline prefetches
4046      */
4047     regval = OS_REG_READ(ah, AR_AHB_MODE);
4048     OS_REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
4049 #endif
4050 
4051     /*
4052      * let mac dma reads be in 128 byte chunks
4053      */
4054     regval = OS_REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
4055     OS_REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
4056 
4057     /*
4058      * Restore TX Trigger Level to its pre-reset value.
4059      * The initial value depends on whether aggregation is enabled, and is
4060      * adjusted whenever underruns are detected.
4061      */
4062     /*
4063     OS_REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, AH_PRIVATE(ah)->ah_tx_trig_level);
4064      */
4065     /*
4066      * Osprey 1.0 bug (EV 61936). Don't change trigger level from .ini default.
4067      * Osprey 2.0 - hardware recommends using the default INI settings.
4068      */
4069 #if 0
4070     OS_REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, 0x3f);
4071 #endif
4072     /*
4073      * let mac dma writes be in 128 byte chunks
4074      */
4075     regval = OS_REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
4076     OS_REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
4077 
4078     /*
4079      * Setup receive FIFO threshold to hold off TX activities
4080      */
4081     OS_REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
4082 
4083     /*
4084      * reduce the number of usable entries in PCU TXBUF to avoid
4085      * wrap around bugs. (bug 20428)
4086      */
4087 
4088     if (AR_SREV_WASP(ah) &&
4089         (AH_PRIVATE((ah))->ah_macRev > AR_SREV_REVISION_WASP_12)) {
4090         /* Wasp 1.3 fix for EV#85395 requires usable entries
4091          * to be set to 0x500
4092          */
4093         OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, 0x500);
4094     } else {
4095         OS_REG_WRITE(ah, AR_PCU_TXBUF_CTRL, AR_PCU_TXBUF_CTRL_USABLE_SIZE);
4096     }
4097 
4098     /*
4099      * Enable HPQ for UAPSD
4100      */
4101     if (pCap->halHwUapsdTrig == AH_TRUE) {
4102     /* Only enable this if HAL capabilities says it is OK */
4103         if (AH_PRIVATE(ah)->ah_opmode == HAL_M_HOSTAP) {
4104             OS_REG_WRITE(ah, AR_HP_Q_CONTROL,
4105                     AR_HPQ_ENABLE | AR_HPQ_UAPSD | AR_HPQ_UAPSD_TRIGGER_EN);
4106         }
4107     } else {
4108         /* use default value from ini file - which disable HPQ queue usage */
4109     }
4110 
4111     /*
4112      * set the transmit status ring
4113      */
4114     ar9300_reset_tx_status_ring(ah);
4115 
4116     /*
4117      * set rxbp threshold.  Must be non-zero for RX_EOL to occur.
4118      * For Osprey 2.0+, keep the original thresholds
4119      * otherwise performance is lost due to excessive RX EOL interrupts.
4120      */
4121     OS_REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_HP, 0x1);
4122     OS_REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_LP, 0x1);
4123 
4124     /*
4125      * set receive buffer size.
4126      */
4127     if (ahp->rx_buf_size) {
4128         OS_REG_WRITE(ah, AR_DATABUF, ahp->rx_buf_size);
4129     }
4130 }
4131 
4132 static inline void
4133 ar9300_init_bb(struct ath_hal *ah, struct ieee80211_channel *chan)
4134 {
4135     u_int32_t synth_delay;
4136 
4137     /*
4138      * Wait for the frequency synth to settle (synth goes on
4139      * via AR_PHY_ACTIVE_EN).  Read the phy active delay register.
4140      * Value is in 100ns increments.
4141      */
4142     synth_delay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
4143     if (IEEE80211_IS_CHAN_CCK(chan)) {
4144         synth_delay = (4 * synth_delay) / 22;
4145     } else {
4146         synth_delay /= 10;
4147     }
4148 
4149     /* Activate the PHY (includes baseband activate + synthesizer on) */
4150     OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
4151 
4152     /*
4153      * There is an issue if the AP starts the calibration before
4154      * the base band timeout completes.  This could result in the
4155      * rx_clear false triggering.  As a workaround we add delay an
4156      * extra BASE_ACTIVATE_DELAY usecs to ensure this condition
4157      * does not happen.
4158      */
4159     OS_DELAY(synth_delay + BASE_ACTIVATE_DELAY);
4160 }
4161 
4162 static inline void
4163 ar9300_init_interrupt_masks(struct ath_hal *ah, HAL_OPMODE opmode)
4164 {
4165     struct ath_hal_9300 *ahp = AH9300(ah);
4166     u_int32_t msi_cfg = 0;
4167     u_int32_t sync_en_def = AR9300_INTR_SYNC_DEFAULT;
4168 
4169     /*
4170      * Setup interrupt handling.  Note that ar9300_reset_tx_queue
4171      * manipulates the secondary IMR's as queues are enabled
4172      * and disabled.  This is done with RMW ops to insure the
4173      * settings we make here are preserved.
4174      */
4175     ahp->ah_mask_reg =
4176         AR_IMR_TXERR | AR_IMR_TXURN |
4177         AR_IMR_RXERR | AR_IMR_RXORN |
4178         AR_IMR_BCNMISC;
4179 
4180     if (ahp->ah_intr_mitigation_rx) {
4181         /* enable interrupt mitigation for rx */
4182         ahp->ah_mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR | AR_IMR_RXOK_HP;
4183         msi_cfg |= AR_INTCFG_MSI_RXINTM | AR_INTCFG_MSI_RXMINTR;
4184     } else {
4185         ahp->ah_mask_reg |= AR_IMR_RXOK_LP | AR_IMR_RXOK_HP;
4186         msi_cfg |= AR_INTCFG_MSI_RXOK;
4187     }
4188     if (ahp->ah_intr_mitigation_tx) {
4189         /* enable interrupt mitigation for tx */
4190         ahp->ah_mask_reg |= AR_IMR_TXINTM | AR_IMR_TXMINTR;
4191         msi_cfg |= AR_INTCFG_MSI_TXINTM | AR_INTCFG_MSI_TXMINTR;
4192     } else {
4193         ahp->ah_mask_reg |= AR_IMR_TXOK;
4194         msi_cfg |= AR_INTCFG_MSI_TXOK;
4195     }
4196     if (opmode == HAL_M_HOSTAP) {
4197         ahp->ah_mask_reg |= AR_IMR_MIB;
4198     }
4199 
4200     OS_REG_WRITE(ah, AR_IMR, ahp->ah_mask_reg);
4201     OS_REG_WRITE(ah, AR_IMR_S2, OS_REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
4202     ahp->ah_mask2Reg = OS_REG_READ(ah, AR_IMR_S2);
4203 
4204     if (ah->ah_config.ath_hal_enable_msi) {
4205         /* Cache MSI register value */
4206         ahp->ah_msi_reg = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_PCIE_MSI));
4207         ahp->ah_msi_reg |= AR_PCIE_MSI_HW_DBI_WR_EN;
4208         if (AR_SREV_POSEIDON(ah)) {
4209             ahp->ah_msi_reg &= AR_PCIE_MSI_HW_INT_PENDING_ADDR_MSI_64;
4210         } else {
4211             ahp->ah_msi_reg &= AR_PCIE_MSI_HW_INT_PENDING_ADDR;
4212         }
4213         /* Program MSI configuration */
4214         OS_REG_WRITE(ah, AR_INTCFG, msi_cfg);
4215     }
4216 
4217     /*
4218      * debug - enable to see all synchronous interrupts status
4219      */
4220     /* Clear any pending sync cause interrupts */
4221     OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE), 0xFFFFFFFF);
4222 
4223     /* Allow host interface sync interrupt sources to set cause bit */
4224     if (AR_SREV_POSEIDON(ah)) {
4225         sync_en_def = AR9300_INTR_SYNC_DEF_NO_HOST1_PERR;
4226     }
4227     else if (AR_SREV_WASP(ah)) {
4228         sync_en_def = AR9340_INTR_SYNC_DEFAULT;
4229     }
4230     OS_REG_WRITE(ah,
4231         AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), sync_en_def);
4232 
4233     /* _Disable_ host interface sync interrupt when cause bits set */
4234     OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_MASK), 0);
4235 
4236     OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_ENABLE), 0);
4237     OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_MASK), 0);
4238     OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_SYNC_ENABLE), 0);
4239     OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_SYNC_MASK), 0);
4240 }
4241 
4242 static inline void
4243 ar9300_init_qos(struct ath_hal *ah)
4244 {
4245     OS_REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);  /* XXX magic */
4246     OS_REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);    /* XXX magic */
4247 
4248     /* Turn on NOACK Support for QoS packets */
4249     OS_REG_WRITE(ah, AR_QOS_NO_ACK,
4250         SM(2, AR_QOS_NO_ACK_TWO_BIT) |
4251         SM(5, AR_QOS_NO_ACK_BIT_OFF) |
4252         SM(0, AR_QOS_NO_ACK_BYTE_OFF));
4253 
4254     /*
4255      * initialize TXOP for all TIDs
4256      */
4257     OS_REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL);
4258     OS_REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF);
4259     OS_REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
4260     OS_REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
4261     OS_REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
4262 }
4263 
4264 static inline void
4265 ar9300_init_user_settings(struct ath_hal *ah)
4266 {
4267     struct ath_hal_9300 *ahp = AH9300(ah);
4268 
4269     /* Restore user-specified settings */
4270     HALDEBUG(ah, HAL_DEBUG_RESET,
4271         "--AP %s ahp->ah_misc_mode 0x%x\n", __func__, ahp->ah_misc_mode);
4272     if (ahp->ah_misc_mode != 0) {
4273         OS_REG_WRITE(ah,
4274             AR_PCU_MISC, OS_REG_READ(ah, AR_PCU_MISC) | ahp->ah_misc_mode);
4275     }
4276     if (ahp->ah_get_plcp_hdr) {
4277         OS_REG_CLR_BIT(ah, AR_PCU_MISC, AR_PCU_SEL_EVM);
4278     }
4279     if (ahp->ah_slot_time != (u_int) -1) {
4280         ar9300_set_slot_time(ah, ahp->ah_slot_time);
4281     }
4282     if (ahp->ah_ack_timeout != (u_int) -1) {
4283         ar9300_set_ack_timeout(ah, ahp->ah_ack_timeout);
4284     }
4285     if (AH_PRIVATE(ah)->ah_diagreg != 0) {
4286         OS_REG_SET_BIT(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);
4287     }
4288     if (ahp->ah_beacon_rssi_threshold != 0) {
4289         ar9300_set_hw_beacon_rssi_threshold(ah, ahp->ah_beacon_rssi_threshold);
4290     }
4291 //#ifdef ATH_SUPPORT_DFS
4292     if (ahp->ah_cac_quiet_enabled) {
4293         ar9300_cac_tx_quiet(ah, 1);
4294     }
4295 //#endif /* ATH_SUPPORT_DFS */
4296 }
4297 
4298 int
4299 ar9300_get_spur_info(struct ath_hal * ah, int *enable, int len, u_int16_t *freq)
4300 {
4301 //    struct ath_hal_private *ap = AH_PRIVATE(ah);
4302     int i, j;
4303 
4304     for (i = 0; i < len; i++) {
4305         freq[i] =  0;
4306     }
4307 
4308     *enable = ah->ah_config.ath_hal_spur_mode;
4309     for (i = 0, j = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4310         if (AH9300(ah)->ath_hal_spur_chans[i][0] != AR_NO_SPUR) {
4311             freq[j++] = AH9300(ah)->ath_hal_spur_chans[i][0];
4312             HALDEBUG(ah, HAL_DEBUG_ANI,
4313                 "1. get spur %d\n", AH9300(ah)->ath_hal_spur_chans[i][0]);
4314         }
4315         if (AH9300(ah)->ath_hal_spur_chans[i][1] != AR_NO_SPUR) {
4316             freq[j++] = AH9300(ah)->ath_hal_spur_chans[i][1];
4317             HALDEBUG(ah, HAL_DEBUG_ANI,
4318                 "2. get spur %d\n", AH9300(ah)->ath_hal_spur_chans[i][1]);
4319         }
4320     }
4321 
4322     return 0;
4323 }
4324 
4325 #define ATH_HAL_2GHZ_FREQ_MIN   20000
4326 #define ATH_HAL_2GHZ_FREQ_MAX   29999
4327 #define ATH_HAL_5GHZ_FREQ_MIN   50000
4328 #define ATH_HAL_5GHZ_FREQ_MAX   59999
4329 
4330 #if 0
4331 int
4332 ar9300_set_spur_info(struct ath_hal * ah, int enable, int len, u_int16_t *freq)
4333 {
4334     struct ath_hal_private *ap = AH_PRIVATE(ah);
4335     int i, j, k;
4336 
4337     ap->ah_config.ath_hal_spur_mode = enable;
4338 
4339     if (ap->ah_config.ath_hal_spur_mode == SPUR_ENABLE_IOCTL) {
4340         for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4341             AH9300(ah)->ath_hal_spur_chans[i][0] = AR_NO_SPUR;
4342             AH9300(ah)->ath_hal_spur_chans[i][1] = AR_NO_SPUR;
4343         }
4344         for (i = 0, j = 0, k = 0; i < len; i++) {
4345             if (freq[i] > ATH_HAL_2GHZ_FREQ_MIN &&
4346                 freq[i] < ATH_HAL_2GHZ_FREQ_MAX)
4347             {
4348                 /* 2GHz Spur */
4349                 if (j < AR_EEPROM_MODAL_SPURS) {
4350                     AH9300(ah)->ath_hal_spur_chans[j++][1] =  freq[i];
4351                     HALDEBUG(ah, HAL_DEBUG_ANI, "1 set spur %d\n", freq[i]);
4352                 }
4353             } else if (freq[i] > ATH_HAL_5GHZ_FREQ_MIN &&
4354                        freq[i] < ATH_HAL_5GHZ_FREQ_MAX)
4355             {
4356                 /* 5Ghz Spur */
4357                 if (k < AR_EEPROM_MODAL_SPURS) {
4358                     AH9300(ah)->ath_hal_spur_chans[k++][0] =  freq[i];
4359                     HALDEBUG(ah, HAL_DEBUG_ANI, "2 set spur %d\n", freq[i]);
4360                 }
4361             }
4362         }
4363     }
4364 
4365     return 0;
4366 }
4367 #endif
4368 
4369 #define ar9300_check_op_mode(_opmode) \
4370     ((_opmode == HAL_M_STA) || (_opmode == HAL_M_IBSS) ||\
4371      (_opmode == HAL_M_HOSTAP) || (_opmode == HAL_M_MONITOR))
4372 
4373 
4374 
4375 
4376 #ifndef ATH_NF_PER_CHAN
4377 /*
4378 * To fixed first reset noise floor value not correct issue
4379 * For ART need it to fixed low rate sens too low issue
4380 */
4381 static int
4382 First_NFCal(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan,
4383     int is_scan, struct ieee80211_channel *chan)
4384 {
4385     HAL_NFCAL_HIST_FULL *nfh;
4386     int i, j, k;
4387     int16_t nfarray[HAL_NUM_NF_READINGS] = {0};
4388     int is_2g = 0;
4389     int nf_hist_len;
4390     int stats = 0;
4391 
4392     int16_t nf_buf[HAL_NUM_NF_READINGS];
4393 #define IS(_c, _f)       (((_c)->channel_flags & _f) || 0)
4394 
4395 
4396     if ((!is_scan) &&
4397         chan->ic_freq == AH_PRIVATE(ah)->ah_curchan->ic_freq)
4398     {
4399         nfh = &AH_PRIVATE(ah)->nf_cal_hist;
4400     } else {
4401         nfh = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist;
4402     }
4403 
4404     ar9300_start_nf_cal(ah);
4405     for (j = 0; j < 10000; j++) {
4406         if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0){
4407             break;
4408 		}
4409         OS_DELAY(10);
4410     }
4411 	if (j < 10000) {
4412         is_2g = IEEE80211_IS_CHAN_2GHZ(chan);
4413         ar9300_upload_noise_floor(ah, is_2g, nfarray);
4414 
4415 	    if (is_scan) {
4416 			/*
4417 			 * This channel's NF cal info is just a HAL_NFCAL_HIST_SMALL struct
4418 			 * rather than a HAL_NFCAL_HIST_FULL struct.
4419 			 * As long as we only use the first history element of nf_cal_buffer
4420 			 * (nf_cal_buffer[0][0:HAL_NUM_NF_READINGS-1]), we can use
4421 			 * HAL_NFCAL_HIST_SMALL and HAL_NFCAL_HIST_FULL interchangeably.
4422 			 */
4423             nfh = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist;
4424             nf_hist_len = HAL_NF_CAL_HIST_LEN_SMALL;
4425 		} else {
4426             nfh = &AH_PRIVATE(ah)->nf_cal_hist;
4427             nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
4428 		}
4429 
4430   	    for (i = 0; i < HAL_NUM_NF_READINGS; i ++) {
4431     		for (k = 0; k < HAL_NF_CAL_HIST_LEN_FULL; k++) {
4432                 nfh->nf_cal_buffer[k][i] = nfarray[i];
4433             }
4434             nfh->base.priv_nf[i] = ar9300_limit_nf_range(ah,
4435 							ar9300_get_nf_hist_mid(ah, nfh, i, nf_hist_len));
4436   		}
4437 
4438 
4439 		//ar9300StoreNewNf(ah, ichan, is_scan);
4440 
4441 		/*
4442 		 * See if the NF value from the old channel should be
4443 		 * retained when switching to a new channel.
4444 		 * TBD: this may need to be changed, as it wipes out the
4445 		 * purpose of saving NF values for each channel.
4446 		 */
4447 		for (i = 0; i < HAL_NUM_NF_READINGS; i++)
4448 		{
4449     		if (IEEE80211_IS_CHAN_2GHZ(chan))
4450     		{
4451     			if (nfh->nf_cal_buffer[0][i] <
4452 					AR_PHY_CCA_MAX_GOOD_VAL_OSPREY_2GHZ)
4453                 {
4454                     ichan->nf_cal_hist.nf_cal_buffer[0][i] =
4455 							AH_PRIVATE(ah)->nf_cal_hist.nf_cal_buffer[0][i];
4456 				}
4457     		} else {
4458                 if (AR_SREV_AR9580(ah)) {
4459                     if (nfh->nf_cal_buffer[0][i] <
4460                         AR_PHY_CCA_NOM_VAL_PEACOCK_5GHZ)
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 (nfh->nf_cal_buffer[0][i] <
4467                        AR_PHY_CCA_NOM_VAL_OSPREY_5GHZ)
4468                     {
4469                         ichan->nf_cal_hist.nf_cal_buffer[0][i] =
4470                             AH_PRIVATE(ah)->nf_cal_hist.nf_cal_buffer[0][i];
4471                      }
4472                 }
4473             }
4474         }
4475 		/*
4476 		 * Copy the channel's NF buffer, which may have been modified
4477 		 * just above here, to the full NF history buffer.
4478 		 */
4479         ar9300_reset_nf_hist_buff(ah, ichan);
4480         ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf);
4481         ar9300_load_nf(ah, nf_buf);
4482         stats = 0;
4483 	} else {
4484         stats = 1;
4485 	}
4486 #undef IS
4487     return stats;
4488 }
4489 #endif
4490 
4491 
4492 /*
4493  * Places the device in and out of reset and then places sane
4494  * values in the registers based on EEPROM config, initialization
4495  * vectors (as determined by the mode), and station configuration
4496  *
4497  * b_channel_change is used to preserve DMA/PCU registers across
4498  * a HW Reset during channel change.
4499  */
4500 HAL_BOOL
4501 ar9300_reset(struct ath_hal *ah, HAL_OPMODE opmode, struct ieee80211_channel *chan,
4502     HAL_HT_MACMODE macmode, u_int8_t txchainmask, u_int8_t rxchainmask,
4503     HAL_HT_EXTPROTSPACING extprotspacing, HAL_BOOL b_channel_change,
4504     HAL_STATUS *status, int is_scan)
4505 {
4506 #define FAIL(_code)     do { ecode = _code; goto bad; } while (0)
4507     u_int32_t               save_led_state;
4508     struct ath_hal_9300     *ahp = AH9300(ah);
4509     struct ath_hal_private  *ap  = AH_PRIVATE(ah);
4510     HAL_CHANNEL_INTERNAL    *ichan;
4511     //const struct ieee80211_channel *curchan = ap->ah_curchan;
4512 #if ATH_SUPPORT_MCI
4513     HAL_BOOL                    save_full_sleep = ahp->ah_chip_full_sleep;
4514 #endif
4515     u_int32_t               save_def_antenna;
4516     u_int32_t               mac_sta_id1;
4517     HAL_STATUS              ecode;
4518     int                     i, rx_chainmask;
4519     int                     nf_hist_buff_reset = 0;
4520     int16_t                 nf_buf[HAL_NUM_NF_READINGS];
4521 #ifdef ATH_FORCE_PPM
4522     u_int32_t               save_force_val, tmp_reg;
4523 #endif
4524     u_int8_t                clk_25mhz = AH9300(ah)->clk_25mhz;
4525     HAL_BOOL                    stopped, cal_ret;
4526     HAL_BOOL                    apply_last_iqcorr = AH_FALSE;
4527 
4528 
4529     if (OS_REG_READ(ah, AR_IER) == AR_IER_ENABLE) {
4530         HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, "** Reset called with WLAN "
4531                 "interrupt enabled %08x **\n", ar9300_get_interrupts(ah));
4532     }
4533 
4534     /*
4535      * Set the status to "ok" by default to cover the cases
4536      * where we return false without going to "bad"
4537      */
4538     HALASSERT(status);
4539     *status = HAL_OK;
4540     if ((ah->ah_config.ath_hal_sta_update_tx_pwr_enable)) {
4541         AH9300(ah)->green_tx_status = HAL_RSSI_TX_POWER_NONE;
4542     }
4543 
4544 #if ATH_SUPPORT_MCI
4545     if (AH_PRIVATE(ah)->ah_caps.halMciSupport &&
4546         (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)))
4547     {
4548         ar9300_mci_2g5g_changed(ah, IEEE80211_IS_CHAN_2GHZ(chan));
4549     }
4550 #endif
4551 
4552     ahp->ah_ext_prot_spacing = extprotspacing;
4553     ahp->ah_tx_chainmask = txchainmask & ap->ah_caps.halTxChainMask;
4554     ahp->ah_rx_chainmask = rxchainmask & ap->ah_caps.halRxChainMask;
4555     ahp->ah_tx_cal_chainmask = ap->ah_caps.halTxChainMask;
4556     ahp->ah_rx_cal_chainmask = ap->ah_caps.halRxChainMask;
4557 
4558     /*
4559      * Keep the previous optinal txchainmask value
4560      */
4561 
4562     HALASSERT(ar9300_check_op_mode(opmode));
4563 
4564     OS_MARK(ah, AH_MARK_RESET, b_channel_change);
4565 
4566     /*
4567      * Map public channel to private.
4568      */
4569     ichan = ar9300_check_chan(ah, chan);
4570     if (ichan == AH_NULL) {
4571         HALDEBUG(ah, HAL_DEBUG_CHANNEL,
4572             "%s: invalid channel %u/0x%x; no mapping\n",
4573             __func__, chan->ic_freq, chan->ic_flags);
4574         FAIL(HAL_EINVAL);
4575     }
4576 
4577     ichan->paprd_table_write_done = 0;  /* Clear PAPRD table write flag */
4578 #if 0
4579     chan->paprd_table_write_done = 0;  /* Clear PAPRD table write flag */
4580 #endif
4581 
4582     if (ar9300_get_power_mode(ah) != HAL_PM_FULL_SLEEP) {
4583         /* Need to stop RX DMA before reset otherwise chip might hang */
4584         stopped = ar9300_set_rx_abort(ah, AH_TRUE); /* abort and disable PCU */
4585         ar9300_set_rx_filter(ah, 0);
4586         stopped &= ar9300_stop_dma_receive(ah, 0); /* stop and disable RX DMA */
4587         if (!stopped) {
4588             /*
4589              * During the transition from full sleep to reset,
4590              * recv DMA regs are not available to be read
4591              */
4592             HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
4593                 "%s[%d]: ar9300_stop_dma_receive failed\n", __func__, __LINE__);
4594             b_channel_change = AH_FALSE;
4595         }
4596     } else {
4597         HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
4598             "%s[%d]: Chip is already in full sleep\n", __func__, __LINE__);
4599     }
4600 
4601 #if ATH_SUPPORT_MCI
4602     if ((AH_PRIVATE(ah)->ah_caps.halMciSupport) &&
4603         (ahp->ah_mci_bt_state == MCI_BT_CAL_START))
4604     {
4605         u_int32_t payload[4] = {0, 0, 0, 0};
4606 
4607         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4608             "(MCI) %s: Stop rx for BT cal.\n", __func__);
4609         ahp->ah_mci_bt_state = MCI_BT_CAL;
4610 
4611         /*
4612          * MCIFIX: disable mci interrupt here. This is to avoid SW_MSG_DONE or
4613          * RX_MSG bits to trigger MCI_INT and lead to mci_intr reentry.
4614          */
4615         ar9300_mci_disable_interrupt(ah);
4616 
4617         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4618             "(MCI) %s: Send WLAN_CAL_GRANT\n", __func__);
4619         MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT);
4620         ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, AH_TRUE, AH_FALSE);
4621 
4622         /* Wait BT calibration to be completed for 25ms */
4623         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4624             "(MCI) %s: BT is calibrating.\n", __func__);
4625         if (ar9300_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_DONE, 0, 25000)) {
4626             HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4627                 "(MCI) %s: Got BT_CAL_DONE.\n", __func__);
4628         }
4629         else {
4630             HALDEBUG(ah, HAL_DEBUG_BT_COEX,
4631                 "(MCI) %s: ### BT cal takes too long. Force bt_state to be bt_awake.\n",
4632                 __func__);
4633         }
4634         ahp->ah_mci_bt_state = MCI_BT_AWAKE;
4635         /* MCIFIX: enable mci interrupt here */
4636         ar9300_mci_enable_interrupt(ah);
4637 
4638         return AH_TRUE;
4639     }
4640 #endif
4641 
4642     /* Bring out of sleep mode */
4643     if (!ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE)) {
4644         *status = HAL_INV_PMODE;
4645         return AH_FALSE;
4646     }
4647 
4648     /* Check the Rx mitigation config again, it might have changed
4649      * during attach in ath_vap_attach.
4650      */
4651     if (ah->ah_config.ath_hal_intr_mitigation_rx != 0) {
4652         ahp->ah_intr_mitigation_rx = AH_TRUE;
4653     } else {
4654         ahp->ah_intr_mitigation_rx = AH_FALSE;
4655     }
4656 
4657     /*
4658      * XXX TODO FreeBSD:
4659      *
4660      * This is painful because we don't have a non-const channel pointer
4661      * at this stage.
4662      *
4663      * Make sure this gets fixed!
4664      */
4665 #if 0
4666     /* Get the value from the previous NF cal and update history buffer */
4667     if (curchan && (ahp->ah_chip_full_sleep != AH_TRUE)) {
4668 
4669         if(ahp->ah_chip_reset_done){
4670             ahp->ah_chip_reset_done = 0;
4671         } else {
4672         	/*
4673          	 * is_scan controls updating NF for home channel or off channel.
4674          	 * Home -> Off, update home channel
4675          	 * Off -> Home, update off channel
4676          	 * Home -> Home, uppdate home channel
4677          	 */
4678         	if (ap->ah_curchan->channel != chan->channel)
4679             	ar9300_store_new_nf(ah, curchan, !is_scan);
4680         	else
4681             	ar9300_store_new_nf(ah, curchan, is_scan);
4682         }
4683     }
4684 #endif
4685 
4686     /*
4687      * Account for the effect of being in either the 2 GHz or 5 GHz band
4688      * on the nominal, max allowable, and min allowable noise floor values.
4689      */
4690     AH9300(ah)->nfp = IS_CHAN_2GHZ(ichan) ? &ahp->nf_2GHz : &ahp->nf_5GHz;
4691 
4692     /*
4693      * XXX FreeBSD For now, don't apply the last IQ correction.
4694      *
4695      * This should be done when scorpion is enabled on FreeBSD; just be
4696      * sure to fix this channel match code so it uses net80211 flags
4697      * instead.
4698      */
4699 #if 0
4700     if (AR_SREV_SCORPION(ah) && curchan && (chan->channel == curchan->channel) &&
4701         ((chan->channel_flags & (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)) ==
4702          (curchan->channel_flags &
4703           (CHANNEL_ALL | CHANNEL_HALF | CHANNEL_QUARTER)))) {
4704             apply_last_iqcorr = AH_TRUE;
4705     }
4706 #endif
4707     apply_last_iqcorr = AH_FALSE;
4708 
4709 
4710 #ifndef ATH_NF_PER_CHAN
4711     /*
4712      * If there's only one full-size home-channel NF history buffer
4713      * rather than a full-size NF history buffer per channel, decide
4714      * whether to (re)initialize the home-channel NF buffer.
4715      * If this is just a channel change for a scan, or if the channel
4716      * is not being changed, don't mess up the home channel NF history
4717      * buffer with NF values from this scanned channel.  If we're
4718      * changing the home channel to a new channel, reset the home-channel
4719      * NF history buffer with the most accurate NF known for the new channel.
4720      */
4721     if (!is_scan && (!ap->ah_curchan ||
4722         ap->ah_curchan->ic_freq != chan->ic_freq)) // ||
4723 //        ap->ah_curchan->channel_flags != chan->channel_flags))
4724     {
4725         nf_hist_buff_reset = 1;
4726         ar9300_reset_nf_hist_buff(ah, ichan);
4727     }
4728 #endif
4729     /*
4730      * In case of
4731      * - offchan scan, or
4732      * - same channel and RX IQ Cal already available
4733      * disable RX IQ Cal.
4734      */
4735     if (is_scan) {
4736         ahp->ah_skip_rx_iq_cal = AH_TRUE;
4737         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
4738                 "Skip RX IQ Cal due to scanning\n");
4739     } else {
4740 #if 0
4741         /* XXX FreeBSD: always just do the RX IQ cal */
4742 	/* XXX I think it's just going to speed things up; I don't think it's to avoid chan bugs */
4743         if (ahp->ah_rx_cal_complete &&
4744             ahp->ah_rx_cal_chan == ichan->channel &&
4745             ahp->ah_rx_cal_chan_flag == chan->channel_flags) {
4746             ahp->ah_skip_rx_iq_cal = AH_TRUE;
4747             HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
4748                     "Skip RX IQ Cal due to same channel with completed RX IQ Cal\n");
4749         } else
4750 #endif
4751             ahp->ah_skip_rx_iq_cal = AH_FALSE;
4752     }
4753 
4754     /* FreeBSD: clear the channel survey data */
4755     ath_hal_survey_clear(ah);
4756 
4757     /*
4758      * Fast channel change (Change synthesizer based on channel freq
4759      * without resetting chip)
4760      * Don't do it when
4761      *   - Flag is not set
4762      *   - Chip is just coming out of full sleep
4763      *   - Channel to be set is same as current channel
4764      *   - Channel flags are different, like when moving from 2GHz to 5GHz
4765      *     channels
4766      *   - Merlin: Switching in/out of fast clock enabled channels
4767      *             (not currently coded, since fast clock is enabled
4768      *             across the 5GHz band
4769      *             and we already do a full reset when switching in/out
4770      *             of 5GHz channels)
4771      */
4772 #if 0
4773     if (b_channel_change &&
4774         (ahp->ah_chip_full_sleep != AH_TRUE) &&
4775         (AH_PRIVATE(ah)->ah_curchan != AH_NULL) &&
4776         ((chan->channel != AH_PRIVATE(ah)->ah_curchan->channel) &&
4777         (((CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) & chan->channel_flags) ==
4778         ((CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) & AH_PRIVATE(ah)->ah_curchan->channel_flags))))
4779     {
4780         if (ar9300_channel_change(ah, chan, ichan, macmode)) {
4781             chan->channel_flags = ichan->channel_flags;
4782             chan->priv_flags = ichan->priv_flags;
4783             AH_PRIVATE(ah)->ah_curchan->ah_channel_time = 0;
4784             AH_PRIVATE(ah)->ah_curchan->ah_tsf_last = ar9300_get_tsf64(ah);
4785 
4786             /*
4787              * Load the NF from history buffer of the current channel.
4788              * NF is slow time-variant, so it is OK to use a historical value.
4789              */
4790             ar9300_get_nf_hist_base(ah,
4791                 AH_PRIVATE(ah)->ah_curchan, is_scan, nf_buf);
4792             ar9300_load_nf(ah, nf_buf);
4793 
4794             /* start NF calibration, without updating BB NF register*/
4795             ar9300_start_nf_cal(ah);
4796 
4797             /*
4798              * If channel_change completed and DMA was stopped
4799              * successfully - skip the rest of reset
4800              */
4801             if (AH9300(ah)->ah_dma_stuck != AH_TRUE) {
4802                 ar9300_disable_pll_lock_detect(ah);
4803 #if ATH_SUPPORT_MCI
4804                 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready)
4805                 {
4806                     ar9300_mci_2g5g_switch(ah, AH_TRUE);
4807                 }
4808 #endif
4809                 return HAL_OK;
4810             }
4811          }
4812     }
4813 #endif /* #if 0 */
4814 
4815 #if ATH_SUPPORT_MCI
4816     if (AH_PRIVATE(ah)->ah_caps.halMciSupport) {
4817         ar9300_mci_disable_interrupt(ah);
4818         if (ahp->ah_mci_ready && !save_full_sleep) {
4819             ar9300_mci_mute_bt(ah);
4820             OS_DELAY(20);
4821             OS_REG_WRITE(ah, AR_BTCOEX_CTRL, 0);
4822         }
4823 
4824         ahp->ah_mci_bt_state = MCI_BT_SLEEP;
4825         ahp->ah_mci_ready = AH_FALSE;
4826     }
4827 #endif
4828 
4829     AH9300(ah)->ah_dma_stuck = AH_FALSE;
4830 #ifdef ATH_FORCE_PPM
4831     /* Preserve force ppm state */
4832     save_force_val =
4833         OS_REG_READ(ah, AR_PHY_TIMING2) &
4834         (AR_PHY_TIMING2_USE_FORCE | AR_PHY_TIMING2_FORCE_VAL);
4835 #endif
4836     /*
4837      * Preserve the antenna on a channel change
4838      */
4839     save_def_antenna = OS_REG_READ(ah, AR_DEF_ANTENNA);
4840     if (0 == ahp->ah_smartantenna_enable )
4841     {
4842         if (save_def_antenna == 0) {
4843             save_def_antenna = 1;
4844         }
4845     }
4846 
4847     /* Save hardware flag before chip reset clears the register */
4848     mac_sta_id1 = OS_REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
4849 
4850     /* Save led state from pci config register */
4851     save_led_state = OS_REG_READ(ah, AR_CFG_LED) &
4852         (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
4853         AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
4854 
4855     /* Mark PHY inactive prior to reset, to be undone in ar9300_init_bb () */
4856     ar9300_mark_phy_inactive(ah);
4857 
4858     if (!ar9300_chip_reset(ah, chan)) {
4859         HALDEBUG(ah, HAL_DEBUG_RESET, "%s: chip reset failed\n", __func__);
4860         FAIL(HAL_EIO);
4861     }
4862 
4863     OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
4864 
4865 
4866     /* Disable JTAG */
4867     OS_REG_SET_BIT(ah,
4868         AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL), AR_GPIO_JTAG_DISABLE);
4869 
4870     /*
4871      * Note that ar9300_init_chain_masks() is called from within
4872      * ar9300_process_ini() to ensure the swap bit is set before
4873      * the pdadc table is written.
4874      */
4875     ecode = ar9300_process_ini(ah, chan, ichan, macmode);
4876     if (ecode != HAL_OK) {
4877         goto bad;
4878     }
4879 
4880     /*
4881      * Configuring WMAC PLL values for 25/40 MHz
4882      */
4883     if(AR_SREV_WASP(ah) || AR_SREV_HONEYBEE(ah) || AR_SREV_SCORPION(ah) ) {
4884         if(clk_25mhz) {
4885             OS_REG_WRITE(ah, AR_RTC_DERIVED_RTC_CLK, (0x17c << 1)); // 32KHz sleep clk
4886         } else {
4887             OS_REG_WRITE(ah, AR_RTC_DERIVED_RTC_CLK, (0x261 << 1)); // 32KHz sleep clk
4888         }
4889         OS_DELAY(100);
4890     }
4891 
4892     ahp->ah_immunity_on = AH_FALSE;
4893 
4894     if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
4895         ahp->tx_iq_cal_enable = OS_REG_READ_FIELD(ah,
4896                                 AR_PHY_TX_IQCAL_CONTROL_0(ah),
4897                                 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL) ?
4898                                 1 : 0;
4899     }
4900     ahp->tx_cl_cal_enable = (OS_REG_READ(ah, AR_PHY_CL_CAL_CTL) &
4901                                 AR_PHY_CL_CAL_ENABLE) ? 1 : 0;
4902 
4903     /* For devices with full HW RIFS Rx support (Sowl/Howl/Merlin, etc),
4904      * restore register settings from prior to reset.
4905      */
4906     if ((AH_PRIVATE(ah)->ah_curchan != AH_NULL) &&
4907         (ar9300_get_capability(ah, HAL_CAP_LDPCWAR, 0, AH_NULL) == HAL_OK))
4908     {
4909         /* Re-program RIFS Rx policy after reset */
4910         ar9300_set_rifs_delay(ah, ahp->ah_rifs_enabled);
4911     }
4912 
4913 #if ATH_SUPPORT_MCI
4914     if (AH_PRIVATE(ah)->ah_caps.halMciSupport) {
4915         ar9300_mci_reset(ah, AH_FALSE, IS_CHAN_2GHZ(ichan), save_full_sleep);
4916     }
4917 #endif
4918 
4919     /* Initialize Management Frame Protection */
4920     ar9300_init_mfp(ah);
4921 
4922     ahp->ah_immunity_vals[0] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW,
4923         AR_PHY_SFCORR_LOW_M1_THRESH_LOW);
4924     ahp->ah_immunity_vals[1] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW,
4925         AR_PHY_SFCORR_LOW_M2_THRESH_LOW);
4926     ahp->ah_immunity_vals[2] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR,
4927         AR_PHY_SFCORR_M1_THRESH);
4928     ahp->ah_immunity_vals[3] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR,
4929         AR_PHY_SFCORR_M2_THRESH);
4930     ahp->ah_immunity_vals[4] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR,
4931         AR_PHY_SFCORR_M2COUNT_THR);
4932     ahp->ah_immunity_vals[5] = OS_REG_READ_FIELD(ah, AR_PHY_SFCORR_LOW,
4933         AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW);
4934 
4935     /* Write delta slope for OFDM enabled modes (A, G, Turbo) */
4936     if (IEEE80211_IS_CHAN_OFDM(chan) || IEEE80211_IS_CHAN_HT(chan)) {
4937         ar9300_set_delta_slope(ah, chan);
4938     }
4939 
4940     ar9300_spur_mitigate(ah, chan);
4941     if (!ar9300_eeprom_set_board_values(ah, chan)) {
4942         HALDEBUG(ah, HAL_DEBUG_EEPROM,
4943             "%s: error setting board options\n", __func__);
4944         FAIL(HAL_EIO);
4945     }
4946 
4947 #ifdef ATH_HAL_WAR_REG16284_APH128
4948     /* temp work around, will be removed. */
4949     if (AR_SREV_WASP(ah)) {
4950         OS_REG_WRITE(ah, 0x16284, 0x1553e000);
4951     }
4952 #endif
4953 
4954     OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
4955 
4956     OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr));
4957     OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4)
4958             | mac_sta_id1
4959             | AR_STA_ID1_RTS_USE_DEF
4960             | (ah->ah_config.ath_hal_6mb_ack ? AR_STA_ID1_ACKCTS_6MB : 0)
4961             | ahp->ah_sta_id1_defaults
4962     );
4963     ar9300_set_operating_mode(ah, opmode);
4964 
4965     /* Set Venice BSSID mask according to current state */
4966     OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssid_mask));
4967     OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssid_mask + 4));
4968 
4969     /* Restore previous antenna */
4970     OS_REG_WRITE(ah, AR_DEF_ANTENNA, save_def_antenna);
4971 #ifdef ATH_FORCE_PPM
4972     /* Restore force ppm state */
4973     tmp_reg = OS_REG_READ(ah, AR_PHY_TIMING2) &
4974         ~(AR_PHY_TIMING2_USE_FORCE | AR_PHY_TIMING2_FORCE_VAL);
4975     OS_REG_WRITE(ah, AR_PHY_TIMING2, tmp_reg | save_force_val);
4976 #endif
4977 
4978     /* then our BSSID and assocID */
4979     OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
4980     OS_REG_WRITE(ah, AR_BSS_ID1,
4981         LE_READ_2(ahp->ah_bssid + 4) |
4982         ((ahp->ah_assoc_id & 0x3fff) << AR_BSS_ID1_AID_S));
4983 
4984     OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */
4985 
4986     OS_REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR, INIT_RSSI_THR);
4987 
4988     /* HW beacon processing */
4989     /*
4990      * XXX what happens if I just leave filter_interval=0?
4991      * it stays disabled?
4992      */
4993     OS_REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_BCN_WEIGHT,
4994             INIT_RSSI_BEACON_WEIGHT);
4995     OS_REG_SET_BIT(ah, AR_HWBCNPROC1, AR_HWBCNPROC1_CRC_ENABLE |
4996             AR_HWBCNPROC1_EXCLUDE_TIM_ELM);
4997     if (ah->ah_config.ath_hal_beacon_filter_interval) {
4998         OS_REG_RMW_FIELD(ah, AR_HWBCNPROC2, AR_HWBCNPROC2_FILTER_INTERVAL,
4999                 ah->ah_config.ath_hal_beacon_filter_interval);
5000         OS_REG_SET_BIT(ah, AR_HWBCNPROC2,
5001                 AR_HWBCNPROC2_FILTER_INTERVAL_ENABLE);
5002     }
5003 
5004 
5005     /*
5006      * Set Channel now modifies bank 6 parameters for FOWL workaround
5007      * to force rf_pwd_icsyndiv bias current as function of synth
5008      * frequency.Thus must be called after ar9300_process_ini() to ensure
5009      * analog register cache is valid.
5010      */
5011     if (!ahp->ah_rf_hal.set_channel(ah, chan)) {
5012         FAIL(HAL_EIO);
5013     }
5014 
5015 
5016     OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
5017 
5018     /* Set 1:1 QCU to DCU mapping for all queues */
5019     for (i = 0; i < AR_NUM_DCU; i++) {
5020         OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
5021     }
5022 
5023     ahp->ah_intr_txqs = 0;
5024     for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++) {
5025         ar9300_reset_tx_queue(ah, i);
5026     }
5027 
5028     ar9300_init_interrupt_masks(ah, opmode);
5029 
5030     /* Reset ier reference count to disabled */
5031 //    OS_ATOMIC_SET(&ahp->ah_ier_ref_count, 1);
5032     if (ath_hal_isrfkillenabled(ah)) {
5033         ar9300_enable_rf_kill(ah);
5034     }
5035 
5036     /* must be called AFTER ini is processed */
5037     ar9300_ani_init_defaults(ah, macmode);
5038 
5039     ar9300_init_qos(ah);
5040 
5041     ar9300_init_user_settings(ah);
5042 
5043 
5044     AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */
5045 
5046     OS_MARK(ah, AH_MARK_RESET_DONE, 0);
5047 
5048     /*
5049      * disable seq number generation in hw
5050      */
5051     OS_REG_WRITE(ah, AR_STA_ID1,
5052         OS_REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
5053 
5054     ar9300_set_dma(ah);
5055 
5056     /*
5057      * program OBS bus to see MAC interrupts
5058      */
5059 #if ATH_SUPPORT_MCI
5060     if (!AH_PRIVATE(ah)->ah_caps.halMciSupport) {
5061         OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_OBS), 8);
5062     }
5063 #else
5064     OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_OBS), 8);
5065 #endif
5066 
5067 
5068     /* enabling AR_GTTM_IGNORE_IDLE in GTTM register so that
5069        GTT timer will not increment if the channel idle indicates
5070        the air is busy or NAV is still counting down */
5071     OS_REG_WRITE(ah, AR_GTTM, AR_GTTM_IGNORE_IDLE);
5072 
5073     /*
5074      * GTT debug mode setting
5075      */
5076     /*
5077     OS_REG_WRITE(ah, 0x64, 0x00320000);
5078     OS_REG_WRITE(ah, 0x68, 7);
5079     OS_REG_WRITE(ah, 0x4080, 0xC);
5080      */
5081     /*
5082      * Disable general interrupt mitigation by setting MIRT = 0x0
5083      * Rx and tx interrupt mitigation are conditionally enabled below.
5084      */
5085     OS_REG_WRITE(ah, AR_MIRT, 0);
5086     if (ahp->ah_intr_mitigation_rx) {
5087         /*
5088          * Enable Interrupt Mitigation for Rx.
5089          * If no build-specific limits for the rx interrupt mitigation
5090          * timer have been specified, use conservative defaults.
5091          */
5092         #ifndef AH_RIMT_VAL_LAST
5093             #define AH_RIMT_LAST_MICROSEC 500
5094         #endif
5095         #ifndef AH_RIMT_VAL_FIRST
5096             #define AH_RIMT_FIRST_MICROSEC 2000
5097         #endif
5098 #ifndef HOST_OFFLOAD
5099         OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, AH_RIMT_LAST_MICROSEC);
5100         OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, AH_RIMT_FIRST_MICROSEC);
5101 #else
5102         /* lower mitigation level to reduce latency for offload arch. */
5103         OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST,
5104             (AH_RIMT_LAST_MICROSEC >> 2));
5105         OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST,
5106             (AH_RIMT_FIRST_MICROSEC >> 2));
5107 #endif
5108     }
5109 
5110     if (ahp->ah_intr_mitigation_tx) {
5111         /*
5112          * Enable Interrupt Mitigation for Tx.
5113          * If no build-specific limits for the tx interrupt mitigation
5114          * timer have been specified, use the values preferred for
5115          * the carrier group's products.
5116          */
5117         #ifndef AH_TIMT_LAST
5118             #define AH_TIMT_LAST_MICROSEC 300
5119         #endif
5120         #ifndef AH_TIMT_FIRST
5121             #define AH_TIMT_FIRST_MICROSEC 750
5122         #endif
5123         OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, AH_TIMT_LAST_MICROSEC);
5124         OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, AH_TIMT_FIRST_MICROSEC);
5125     }
5126 
5127     rx_chainmask = ahp->ah_rx_chainmask;
5128 
5129     OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
5130     OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
5131 
5132     ar9300_init_bb(ah, chan);
5133 
5134     /* BB Step 7: Calibration */
5135     /*
5136      * Only kick off calibration not on offchan.
5137      * If coming back from offchan, restore prevous Cal results
5138      * since chip reset will clear existings.
5139      */
5140     if (!ahp->ah_skip_rx_iq_cal) {
5141         int i;
5142         /* clear existing RX cal data */
5143         for (i=0; i<AR9300_MAX_CHAINS; i++)
5144             ahp->ah_rx_cal_corr[i] = 0;
5145 
5146         ahp->ah_rx_cal_complete = AH_FALSE;
5147 //        ahp->ah_rx_cal_chan = chan->channel;
5148 //        ahp->ah_rx_cal_chan_flag = ichan->channel_flags;
5149         ahp->ah_rx_cal_chan = 0;
5150         ahp->ah_rx_cal_chan_flag = 0; /* XXX FreeBSD */
5151     }
5152     ar9300_invalidate_saved_cals(ah, ichan);
5153     cal_ret = ar9300_init_cal(ah, chan, AH_FALSE, apply_last_iqcorr);
5154 
5155 #if ATH_SUPPORT_MCI
5156     if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready) {
5157         if (IS_CHAN_2GHZ(ichan) &&
5158             (ahp->ah_mci_bt_state == MCI_BT_SLEEP))
5159         {
5160             if (ar9300_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) ||
5161                 ar9300_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE))
5162             {
5163                 /*
5164                  * BT is sleeping. Check if BT wakes up duing WLAN
5165                  * calibration. If BT wakes up during WLAN calibration, need
5166                  * to go through all message exchanges again and recal.
5167                  */
5168                 HALDEBUG(ah, HAL_DEBUG_BT_COEX,
5169                     "(MCI) ### %s: BT wakes up during WLAN calibration.\n",
5170                     __func__);
5171                 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
5172                         AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET |
5173                         AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE);
5174                 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) send REMOTE_RESET\n");
5175                 ar9300_mci_remote_reset(ah, AH_TRUE);
5176                 ar9300_mci_send_sys_waking(ah, AH_TRUE);
5177                 OS_DELAY(1);
5178                 if (IS_CHAN_2GHZ(ichan)) {
5179                     ar9300_mci_send_lna_transfer(ah, AH_TRUE);
5180                 }
5181                 ahp->ah_mci_bt_state = MCI_BT_AWAKE;
5182 
5183                 /* Redo calibration */
5184                 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Re-calibrate.\n",
5185                     __func__);
5186                 ar9300_invalidate_saved_cals(ah, ichan);
5187                 cal_ret = ar9300_init_cal(ah, chan, AH_FALSE, apply_last_iqcorr);
5188             }
5189         }
5190         ar9300_mci_enable_interrupt(ah);
5191     }
5192 #endif
5193 
5194     if (!cal_ret) {
5195         HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Init Cal Failed\n", __func__);
5196         FAIL(HAL_ESELFTEST);
5197     }
5198 
5199     ar9300_init_txbf(ah);
5200 #if 0
5201     /*
5202      * WAR for owl 1.0 - restore chain mask for 2-chain cfgs after cal
5203      */
5204     rx_chainmask = ahp->ah_rx_chainmask;
5205     if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
5206         OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
5207         OS_REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
5208     }
5209 #endif
5210 
5211     /* Restore previous led state */
5212     OS_REG_WRITE(ah, AR_CFG_LED, save_led_state | AR_CFG_SCLK_32KHZ);
5213 
5214 #if ATH_BT_COEX
5215     if (ahp->ah_bt_coex_config_type != HAL_BT_COEX_CFG_NONE) {
5216         ar9300_init_bt_coex(ah);
5217 
5218 #if ATH_SUPPORT_MCI
5219         if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready) {
5220             /* Check BT state again to make sure it's not changed. */
5221             ar9300_mci_sync_bt_state(ah);
5222             ar9300_mci_2g5g_switch(ah, AH_TRUE);
5223 
5224             if ((ahp->ah_mci_bt_state == MCI_BT_AWAKE) &&
5225                 (ahp->ah_mci_query_bt == AH_TRUE))
5226             {
5227                 ahp->ah_mci_need_flush_btinfo = AH_TRUE;
5228             }
5229         }
5230 #endif
5231     }
5232 #endif
5233 
5234     /* Start TSF2 for generic timer 8-15. */
5235     ar9300_start_tsf2(ah);
5236 
5237     /* MIMO Power save setting */
5238     if (ar9300_get_capability(ah, HAL_CAP_DYNAMIC_SMPS, 0, AH_NULL) == HAL_OK) {
5239         ar9300_set_sm_power_mode(ah, ahp->ah_sm_power_mode);
5240     }
5241 
5242     /*
5243      * For big endian systems turn on swapping for descriptors
5244      */
5245 #if AH_BYTE_ORDER == AH_BIG_ENDIAN
5246     if (AR_SREV_HORNET(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah) || AR_SREV_HONEYBEE(ah)) {
5247         OS_REG_RMW(ah, AR_CFG, AR_CFG_SWTB | AR_CFG_SWRB, 0);
5248     } else {
5249         ar9300_init_cfg_reg(ah);
5250     }
5251 #endif
5252 
5253     if ( AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah) || AR_SREV_HONEYBEE(ah) ) {
5254         OS_REG_RMW(ah, AR_CFG_LED, AR_CFG_LED_ASSOC_CTL, AR_CFG_LED_ASSOC_CTL);
5255     }
5256 
5257 #if !(defined(ART_BUILD)) && defined(ATH_SUPPORT_LED)
5258 #define REG_WRITE(_reg, _val)   *((volatile u_int32_t *)(_reg)) = (_val);
5259 #define REG_READ(_reg)          *((volatile u_int32_t *)(_reg))
5260 #define ATH_GPIO_OUT_FUNCTION3  0xB8040038
5261 #define ATH_GPIO_OE             0xB8040000
5262     if ( AR_SREV_WASP(ah)) {
5263         if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) {
5264             REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff << 8))) | (0x33 << 8) );
5265             REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) & (~(0x1 << 13) )));
5266         }
5267         else {
5268 
5269             /* Disable 2G WLAN LED. During ath_open, reset function is called even before channel is set.
5270             So 2GHz is taken as default and it also blinks. Hence
5271             to avoid both from blinking, disable 2G led while in 5G mode */
5272 
5273             REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) | (1 << 13) ));
5274             REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff))) | (0x33) );
5275             REG_WRITE(ATH_GPIO_OE, ( REG_READ(ATH_GPIO_OE) & (~(0x1 << 12) )));
5276         }
5277 
5278     }
5279     else if (AR_SREV_SCORPION(ah)) {
5280         if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) {
5281             REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff << 8))) | (0x2F << 8) );
5282     	    REG_WRITE(ATH_GPIO_OE, (( REG_READ(ATH_GPIO_OE) & (~(0x1 << 13) )) | (0x1 << 12)));
5283         } else if (IS_CHAN_5GHZ((AH_PRIVATE(ah)->ah_curchan))) {
5284             REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff))) | (0x2F) );
5285     	    REG_WRITE(ATH_GPIO_OE, (( REG_READ(ATH_GPIO_OE) & (~(0x1 << 12) )) | (0x1 << 13)));
5286         }
5287     }
5288     else if (AR_SREV_HONEYBEE(ah)) {
5289             REG_WRITE(ATH_GPIO_OUT_FUNCTION3, ( REG_READ(ATH_GPIO_OUT_FUNCTION3) & (~(0xff))) | (0x32) );
5290             REG_WRITE(ATH_GPIO_OE, (( REG_READ(ATH_GPIO_OE) & (~(0x1 << 12) ))));
5291     }
5292 #undef REG_READ
5293 #undef REG_WRITE
5294 #endif
5295 
5296     /* XXX FreeBSD What's this? -adrian */
5297 #if 0
5298     chan->channel_flags = ichan->channel_flags;
5299     chan->priv_flags = ichan->priv_flags;
5300 #endif
5301 
5302 #if FIX_NOISE_FLOOR
5303     /* XXX FreeBSD is ichan appropariate? It was curchan.. */
5304     ar9300_get_nf_hist_base(ah, ichan, is_scan, nf_buf);
5305     ar9300_load_nf(ah, nf_buf);
5306     if (nf_hist_buff_reset == 1)
5307     {
5308         nf_hist_buff_reset = 0;
5309     #ifndef ATH_NF_PER_CHAN
5310 	    if (First_NFCal(ah, ichan, is_scan, chan)){
5311             if (ahp->ah_skip_rx_iq_cal && !is_scan) {
5312                 /* restore RX Cal result if existing */
5313                 ar9300_rx_iq_cal_restore(ah);
5314                 ahp->ah_skip_rx_iq_cal = AH_FALSE;
5315             }
5316         }
5317     #endif /* ATH_NF_PER_CHAN */
5318     }
5319     else{
5320         ar9300_start_nf_cal(ah);
5321     }
5322 #endif
5323 
5324 #ifdef AH_SUPPORT_AR9300
5325     /* BB Panic Watchdog */
5326     if (ar9300_get_capability(ah, HAL_CAP_BB_PANIC_WATCHDOG, 0, AH_NULL) ==
5327         HAL_OK)
5328     {
5329         ar9300_config_bb_panic_watchdog(ah);
5330     }
5331 #endif
5332 
5333     /* While receiving unsupported rate frame receive state machine
5334      * gets into a state 0xb and if phy_restart happens when rx
5335      * state machine is in 0xb state, BB would go hang, if we
5336      * see 0xb state after first bb panic, make sure that we
5337      * disable the phy_restart.
5338      *
5339      * There may be multiple panics, make sure that we always do
5340      * this if we see this panic at least once. This is required
5341      * because reset seems to be writing from INI file.
5342      */
5343     if ((ar9300_get_capability(ah, HAL_CAP_PHYRESTART_CLR_WAR, 0, AH_NULL)
5344          == HAL_OK) && (((MS((AH9300(ah)->ah_bb_panic_last_status),
5345                 AR_PHY_BB_WD_RX_OFDM_SM)) == 0xb) ||
5346             AH9300(ah)->ah_phyrestart_disabled) )
5347     {
5348         ar9300_disable_phy_restart(ah, 1);
5349     }
5350 
5351 
5352 
5353     ahp->ah_radar1 = MS(OS_REG_READ(ah, AR_PHY_RADAR_1),
5354                         AR_PHY_RADAR_1_CF_BIN_THRESH);
5355     ahp->ah_dc_offset = MS(OS_REG_READ(ah, AR_PHY_TIMING2),
5356                         AR_PHY_TIMING2_DC_OFFSET);
5357     ahp->ah_disable_cck = MS(OS_REG_READ(ah, AR_PHY_MODE),
5358                         AR_PHY_MODE_DISABLE_CCK);
5359 
5360     if (AH9300(ah)->ah_enable_keysearch_always) {
5361         ar9300_enable_keysearch_always(ah, 1);
5362     }
5363 
5364 #if ATH_LOW_POWER_ENABLE
5365 #define REG_WRITE(_reg, _val)   *((volatile u_int32_t *)(_reg)) = (_val)
5366 #define REG_READ(_reg)      *((volatile u_int32_t *)(_reg))
5367     if (AR_SREV_OSPREY(ah)) {
5368         REG_WRITE(0xb4000080, REG_READ(0xb4000080) | 3);
5369         OS_REG_WRITE(ah, AR_RTC_RESET, 1);
5370         OS_REG_SET_BIT(ah, AR_HOSTIF_REG(ah, AR_PCIE_PM_CTRL),
5371                         AR_PCIE_PM_CTRL_ENA);
5372         OS_REG_SET_BIT(ah, AR_HOSTIF_REG(ah, AR_SPARE), 0xffffffff);
5373     }
5374 #undef REG_READ
5375 #undef REG_WRITE
5376 #endif  /* ATH_LOW_POWER_ENABLE */
5377 
5378     ar9300_disable_pll_lock_detect(ah);
5379 
5380     /* H/W Green TX */
5381     ar9300_control_signals_for_green_tx_mode(ah);
5382     /* Smart Antenna, only for 5GHz on Scropion */
5383     if (IEEE80211_IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan)) && AR_SREV_SCORPION(ah)) {
5384         ahp->ah_smartantenna_enable = 0;
5385     }
5386 
5387     ar9300_set_smart_antenna(ah, ahp->ah_smartantenna_enable);
5388 
5389     if (AR_SREV_APHRODITE(ah) && ahp->ah_lna_div_use_bt_ant_enable)
5390         OS_REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
5391 
5392     if (ahp->ah_skip_rx_iq_cal && !is_scan) {
5393         /* restore RX Cal result if existing */
5394         ar9300_rx_iq_cal_restore(ah);
5395         ahp->ah_skip_rx_iq_cal = AH_FALSE;
5396     }
5397 
5398 
5399     return AH_TRUE;
5400 bad:
5401     OS_MARK(ah, AH_MARK_RESET_DONE, ecode);
5402     *status = ecode;
5403 
5404     if (ahp->ah_skip_rx_iq_cal && !is_scan) {
5405         /* restore RX Cal result if existing */
5406         ar9300_rx_iq_cal_restore(ah);
5407         ahp->ah_skip_rx_iq_cal = AH_FALSE;
5408     }
5409 
5410     return AH_FALSE;
5411 #undef FAIL
5412 }
5413 
5414 void
5415 ar9300_green_ap_ps_on_off( struct ath_hal *ah, u_int16_t on_off)
5416 {
5417     /* Set/reset the ps flag */
5418     AH9300(ah)->green_ap_ps_on = !!on_off;
5419 }
5420 
5421 /*
5422  * This function returns 1, where it is possible to do
5423  * single-chain power save.
5424  */
5425 u_int16_t
5426 ar9300_is_single_ant_power_save_possible(struct ath_hal *ah)
5427 {
5428     return AH_TRUE;
5429 }
5430 
5431 /* To avoid compilation warnings. Functions not used when EMULATION. */
5432 /*
5433  * ar9300_find_mag_approx()
5434  */
5435 static int32_t
5436 ar9300_find_mag_approx(struct ath_hal *ah, int32_t in_re, int32_t in_im)
5437 {
5438     int32_t abs_i = abs(in_re);
5439     int32_t abs_q = abs(in_im);
5440     int32_t max_abs, min_abs;
5441 
5442     if (abs_i > abs_q) {
5443         max_abs = abs_i;
5444         min_abs = abs_q;
5445     } else {
5446         max_abs = abs_q;
5447         min_abs = abs_i;
5448     }
5449 
5450     return (max_abs - (max_abs / 32) + (min_abs / 8) + (min_abs / 4));
5451 }
5452 
5453 /*
5454  * ar9300_solve_iq_cal()
5455  * solve 4x4 linear equation used in loopback iq cal.
5456  */
5457 static HAL_BOOL
5458 ar9300_solve_iq_cal(
5459     struct ath_hal *ah,
5460     int32_t sin_2phi_1,
5461     int32_t cos_2phi_1,
5462     int32_t sin_2phi_2,
5463     int32_t cos_2phi_2,
5464     int32_t mag_a0_d0,
5465     int32_t phs_a0_d0,
5466     int32_t mag_a1_d0,
5467     int32_t phs_a1_d0,
5468     int32_t solved_eq[])
5469 {
5470     int32_t f1 = cos_2phi_1 - cos_2phi_2;
5471     int32_t f3 = sin_2phi_1 - sin_2phi_2;
5472     int32_t f2;
5473     int32_t mag_tx, phs_tx, mag_rx, phs_rx;
5474     const int32_t result_shift = 1 << 15;
5475 
5476     f2 = (((int64_t)f1 * (int64_t)f1) / result_shift) + (((int64_t)f3 * (int64_t)f3) / result_shift);
5477 
5478     if (0 == f2) {
5479         HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: Divide by 0(%d).\n",
5480             __func__, __LINE__);
5481         return AH_FALSE;
5482     }
5483 
5484     /* magnitude mismatch, tx */
5485     mag_tx = f1 * (mag_a0_d0  - mag_a1_d0) + f3 * (phs_a0_d0 - phs_a1_d0);
5486     /* phase mismatch, tx */
5487     phs_tx = f3 * (-mag_a0_d0 + mag_a1_d0) + f1 * (phs_a0_d0 - phs_a1_d0);
5488 
5489     mag_tx = (mag_tx / f2);
5490     phs_tx = (phs_tx / f2);
5491 
5492     /* magnitude mismatch, rx */
5493     mag_rx =
5494         mag_a0_d0 - (cos_2phi_1 * mag_tx + sin_2phi_1 * phs_tx) / result_shift;
5495     /* phase mismatch, rx */
5496     phs_rx =
5497         phs_a0_d0 + (sin_2phi_1 * mag_tx - cos_2phi_1 * phs_tx) / result_shift;
5498 
5499     solved_eq[0] = mag_tx;
5500     solved_eq[1] = phs_tx;
5501     solved_eq[2] = mag_rx;
5502     solved_eq[3] = phs_rx;
5503 
5504     return AH_TRUE;
5505 }
5506 
5507 /*
5508  * ar9300_calc_iq_corr()
5509  */
5510 static HAL_BOOL
5511 ar9300_calc_iq_corr(struct ath_hal *ah, int32_t chain_idx,
5512     const int32_t iq_res[], int32_t iqc_coeff[])
5513 {
5514     int32_t i2_m_q2_a0_d0, i2_p_q2_a0_d0, iq_corr_a0_d0;
5515     int32_t i2_m_q2_a0_d1, i2_p_q2_a0_d1, iq_corr_a0_d1;
5516     int32_t i2_m_q2_a1_d0, i2_p_q2_a1_d0, iq_corr_a1_d0;
5517     int32_t i2_m_q2_a1_d1, i2_p_q2_a1_d1, iq_corr_a1_d1;
5518     int32_t mag_a0_d0, mag_a1_d0, mag_a0_d1, mag_a1_d1;
5519     int32_t phs_a0_d0, phs_a1_d0, phs_a0_d1, phs_a1_d1;
5520     int32_t sin_2phi_1, cos_2phi_1, sin_2phi_2, cos_2phi_2;
5521     int32_t mag_tx, phs_tx, mag_rx, phs_rx;
5522     int32_t solved_eq[4], mag_corr_tx, phs_corr_tx, mag_corr_rx, phs_corr_rx;
5523     int32_t q_q_coff, q_i_coff;
5524     const int32_t res_scale = 1 << 15;
5525     const int32_t delpt_shift = 1 << 8;
5526     int32_t mag1, mag2;
5527 
5528     i2_m_q2_a0_d0 = iq_res[0] & 0xfff;
5529     i2_p_q2_a0_d0 = (iq_res[0] >> 12) & 0xfff;
5530     iq_corr_a0_d0 = ((iq_res[0] >> 24) & 0xff) + ((iq_res[1] & 0xf) << 8);
5531 
5532     if (i2_m_q2_a0_d0 > 0x800)  {
5533         i2_m_q2_a0_d0 = -((0xfff - i2_m_q2_a0_d0) + 1);
5534     }
5535     if (iq_corr_a0_d0 > 0x800)  {
5536         iq_corr_a0_d0 = -((0xfff - iq_corr_a0_d0) + 1);
5537     }
5538 
5539     i2_m_q2_a0_d1 = (iq_res[1] >> 4) & 0xfff;
5540     i2_p_q2_a0_d1 = (iq_res[2] & 0xfff);
5541     iq_corr_a0_d1 = (iq_res[2] >> 12) & 0xfff;
5542 
5543     if (i2_m_q2_a0_d1 > 0x800)  {
5544         i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1);
5545     }
5546     if (iq_corr_a0_d1 > 0x800)  {
5547         iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1);
5548     }
5549 
5550     i2_m_q2_a1_d0 = ((iq_res[2] >> 24) & 0xff) + ((iq_res[3] & 0xf) << 8);
5551     i2_p_q2_a1_d0 = (iq_res[3] >> 4) & 0xfff;
5552     iq_corr_a1_d0 = iq_res[4] & 0xfff;
5553 
5554     if (i2_m_q2_a1_d0 > 0x800)  {
5555         i2_m_q2_a1_d0 = -((0xfff - i2_m_q2_a1_d0) + 1);
5556     }
5557     if (iq_corr_a1_d0 > 0x800)  {
5558         iq_corr_a1_d0 = -((0xfff - iq_corr_a1_d0) + 1);
5559     }
5560 
5561     i2_m_q2_a1_d1 = (iq_res[4] >> 12) & 0xfff;
5562     i2_p_q2_a1_d1 = ((iq_res[4] >> 24) & 0xff) + ((iq_res[5] & 0xf) << 8);
5563     iq_corr_a1_d1 = (iq_res[5] >> 4) & 0xfff;
5564 
5565     if (i2_m_q2_a1_d1 > 0x800)  {
5566         i2_m_q2_a1_d1 = -((0xfff - i2_m_q2_a1_d1) + 1);
5567     }
5568     if (iq_corr_a1_d1 > 0x800)  {
5569         iq_corr_a1_d1 = -((0xfff - iq_corr_a1_d1) + 1);
5570     }
5571 
5572     if ((i2_p_q2_a0_d0 == 0) ||
5573         (i2_p_q2_a0_d1 == 0) ||
5574         (i2_p_q2_a1_d0 == 0) ||
5575         (i2_p_q2_a1_d1 == 0)) {
5576         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5577             "%s: Divide by 0(%d):\na0_d0=%d\na0_d1=%d\na2_d0=%d\na1_d1=%d\n",
5578             __func__, __LINE__,
5579             i2_p_q2_a0_d0, i2_p_q2_a0_d1, i2_p_q2_a1_d0, i2_p_q2_a1_d1);
5580         return AH_FALSE;
5581     }
5582 
5583     if ((i2_p_q2_a0_d0 <= 1024) || (i2_p_q2_a0_d0 > 2047) ||
5584             (i2_p_q2_a1_d0 < 0) || (i2_p_q2_a1_d1 < 0) ||
5585             (i2_p_q2_a0_d0 <= i2_m_q2_a0_d0) ||
5586             (i2_p_q2_a0_d0 <= iq_corr_a0_d0) ||
5587             (i2_p_q2_a0_d1 <= i2_m_q2_a0_d1) ||
5588             (i2_p_q2_a0_d1 <= iq_corr_a0_d1) ||
5589             (i2_p_q2_a1_d0 <= i2_m_q2_a1_d0) ||
5590             (i2_p_q2_a1_d0 <= iq_corr_a1_d0) ||
5591             (i2_p_q2_a1_d1 <= i2_m_q2_a1_d1) ||
5592             (i2_p_q2_a1_d1 <= iq_corr_a1_d1)) {
5593         return AH_FALSE;
5594     }
5595 
5596     mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0;
5597     phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0;
5598 
5599     mag_a0_d1 = (i2_m_q2_a0_d1 * res_scale) / i2_p_q2_a0_d1;
5600     phs_a0_d1 = (iq_corr_a0_d1 * res_scale) / i2_p_q2_a0_d1;
5601 
5602     mag_a1_d0 = (i2_m_q2_a1_d0 * res_scale) / i2_p_q2_a1_d0;
5603     phs_a1_d0 = (iq_corr_a1_d0 * res_scale) / i2_p_q2_a1_d0;
5604 
5605     mag_a1_d1 = (i2_m_q2_a1_d1 * res_scale) / i2_p_q2_a1_d1;
5606     phs_a1_d1 = (iq_corr_a1_d1 * res_scale) / i2_p_q2_a1_d1;
5607 
5608     /* without analog phase shift */
5609     sin_2phi_1 = (((mag_a0_d0 - mag_a0_d1) * delpt_shift) / DELPT);
5610     /* without analog phase shift */
5611     cos_2phi_1 = (((phs_a0_d1 - phs_a0_d0) * delpt_shift) / DELPT);
5612     /* with  analog phase shift */
5613     sin_2phi_2 = (((mag_a1_d0 - mag_a1_d1) * delpt_shift) / DELPT);
5614     /* with analog phase shift */
5615     cos_2phi_2 = (((phs_a1_d1 - phs_a1_d0) * delpt_shift) / DELPT);
5616 
5617     /* force sin^2 + cos^2 = 1; */
5618     /* find magnitude by approximation */
5619     mag1 = ar9300_find_mag_approx(ah, cos_2phi_1, sin_2phi_1);
5620     mag2 = ar9300_find_mag_approx(ah, cos_2phi_2, sin_2phi_2);
5621 
5622     if ((mag1 == 0) || (mag2 == 0)) {
5623         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5624             "%s: Divide by 0(%d): mag1=%d, mag2=%d\n",
5625             __func__, __LINE__, mag1, mag2);
5626         return AH_FALSE;
5627     }
5628 
5629     /* normalization sin and cos by mag */
5630     sin_2phi_1 = (sin_2phi_1 * res_scale / mag1);
5631     cos_2phi_1 = (cos_2phi_1 * res_scale / mag1);
5632     sin_2phi_2 = (sin_2phi_2 * res_scale / mag2);
5633     cos_2phi_2 = (cos_2phi_2 * res_scale / mag2);
5634 
5635     /* calculate IQ mismatch */
5636     if (AH_FALSE == ar9300_solve_iq_cal(ah,
5637             sin_2phi_1, cos_2phi_1, sin_2phi_2, cos_2phi_2, mag_a0_d0,
5638             phs_a0_d0, mag_a1_d0, phs_a1_d0, solved_eq))
5639     {
5640         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5641             "%s: Call to ar9300_solve_iq_cal failed.\n", __func__);
5642         return AH_FALSE;
5643     }
5644 
5645     mag_tx = solved_eq[0];
5646     phs_tx = solved_eq[1];
5647     mag_rx = solved_eq[2];
5648     phs_rx = solved_eq[3];
5649 
5650     HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5651         "%s: chain %d: mag mismatch=%d phase mismatch=%d\n",
5652         __func__, chain_idx, mag_tx / res_scale, phs_tx / res_scale);
5653 
5654     if (res_scale == mag_tx) {
5655         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5656             "%s: Divide by 0(%d): mag_tx=%d, res_scale=%d\n",
5657             __func__, __LINE__, mag_tx, res_scale);
5658         return AH_FALSE;
5659     }
5660 
5661     /* calculate and quantize Tx IQ correction factor */
5662     mag_corr_tx = (mag_tx * res_scale) / (res_scale - mag_tx);
5663     phs_corr_tx = -phs_tx;
5664 
5665     q_q_coff = (mag_corr_tx * 128 / res_scale);
5666     q_i_coff = (phs_corr_tx * 256 / res_scale);
5667 
5668     HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5669         "%s: tx chain %d: mag corr=%d  phase corr=%d\n",
5670         __func__, chain_idx, q_q_coff, q_i_coff);
5671 
5672     if (q_i_coff < -63) {
5673         q_i_coff = -63;
5674     }
5675     if (q_i_coff > 63) {
5676         q_i_coff = 63;
5677     }
5678     if (q_q_coff < -63) {
5679         q_q_coff = -63;
5680     }
5681     if (q_q_coff > 63) {
5682         q_q_coff = 63;
5683     }
5684 
5685     iqc_coeff[0] = (q_q_coff * 128) + (0x7f & q_i_coff);
5686 
5687     HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: tx chain %d: iq corr coeff=%x\n",
5688         __func__, chain_idx, iqc_coeff[0]);
5689 
5690     if (-mag_rx == res_scale) {
5691         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5692             "%s: Divide by 0(%d): mag_rx=%d, res_scale=%d\n",
5693             __func__, __LINE__, mag_rx, res_scale);
5694         return AH_FALSE;
5695     }
5696 
5697     /* calculate and quantize Rx IQ correction factors */
5698     mag_corr_rx = (-mag_rx * res_scale) / (res_scale + mag_rx);
5699     phs_corr_rx = -phs_rx;
5700 
5701     q_q_coff = (mag_corr_rx * 128 / res_scale);
5702     q_i_coff = (phs_corr_rx * 256 / res_scale);
5703 
5704     HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5705         "%s: rx chain %d: mag corr=%d  phase corr=%d\n",
5706         __func__, chain_idx, q_q_coff, q_i_coff);
5707 
5708     if (q_i_coff < -63) {
5709         q_i_coff = -63;
5710     }
5711     if (q_i_coff > 63) {
5712         q_i_coff = 63;
5713     }
5714     if (q_q_coff < -63) {
5715         q_q_coff = -63;
5716     }
5717     if (q_q_coff > 63) {
5718         q_q_coff = 63;
5719     }
5720 
5721     iqc_coeff[1] = (q_q_coff * 128) + (0x7f & q_i_coff);
5722 
5723     HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "%s: rx chain %d: iq corr coeff=%x\n",
5724         __func__, chain_idx, iqc_coeff[1]);
5725 
5726     return AH_TRUE;
5727 }
5728 
5729 #define MAX_MAG_DELTA 11 //maximum magnitude mismatch delta across gains
5730 #define MAX_PHS_DELTA 10 //maximum phase mismatch delta across gains
5731 #define ABS(x) ((x) >= 0 ? (x) : (-(x)))
5732 
5733     u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = {
5734     {   AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5735         AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5736         AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5737     {   AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5738         AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5739         AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5740     {   AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5741         AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5742         AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5743     {   AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5744         AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5745         AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5746     {   AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5747         AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5748         AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5749     {   AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5750         AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5751         AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5752     {   AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5753         AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5754         AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5755     {   AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5756         AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5757         AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5758     };
5759 
5760 static void
5761 ar9300_tx_iq_cal_outlier_detection(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan, u_int32_t num_chains,
5762     struct coeff_t *coeff, HAL_BOOL is_cal_reusable)
5763 {
5764     int nmeasurement, ch_idx, im;
5765     int32_t magnitude, phase;
5766     int32_t magnitude_max, phase_max;
5767     int32_t magnitude_min, phase_min;
5768 
5769     int32_t magnitude_max_idx, phase_max_idx;
5770     int32_t magnitude_min_idx, phase_min_idx;
5771 
5772     int32_t magnitude_avg, phase_avg;
5773     int32_t outlier_mag_idx = 0;
5774     int32_t outlier_phs_idx = 0;
5775 
5776 
5777     if (AR_SREV_POSEIDON(ah)) {
5778         HALASSERT(num_chains == 0x1);
5779 
5780         tx_corr_coeff[0][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5781         tx_corr_coeff[1][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5782         tx_corr_coeff[2][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5783         tx_corr_coeff[3][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5784         tx_corr_coeff[4][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5785         tx_corr_coeff[5][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5786         tx_corr_coeff[6][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5787         tx_corr_coeff[7][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5788     }
5789 
5790     for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
5791         nmeasurement = OS_REG_READ_FIELD(ah,
5792             AR_PHY_TX_IQCAL_STATUS_B0(ah), AR_PHY_CALIBRATED_GAINS_0);
5793         if (nmeasurement > MAX_MEASUREMENT) {
5794             nmeasurement = MAX_MEASUREMENT;
5795         }
5796 
5797         if (!AR_SREV_SCORPION(ah)) {
5798             /*
5799              * reset max/min variable to min/max values so that
5800              * we always start with 1st calibrated gain value
5801              */
5802             magnitude_max = -64;
5803             phase_max     = -64;
5804             magnitude_min = 63;
5805             phase_min     = 63;
5806             magnitude_avg = 0;
5807             phase_avg     = 0;
5808             magnitude_max_idx = 0;
5809             magnitude_min_idx = 0;
5810             phase_max_idx = 0;
5811             phase_min_idx = 0;
5812 
5813             /* detect outlier only if nmeasurement > 1 */
5814             if (nmeasurement > 1) {
5815                 /* printf("----------- start outlier detection -----------\n"); */
5816                 /*
5817                  * find max/min and phase/mag mismatch across all calibrated gains
5818                  */
5819                 for (im = 0; im < nmeasurement; im++) {
5820                     magnitude = coeff->mag_coeff[ch_idx][im][0];
5821                     phase = coeff->phs_coeff[ch_idx][im][0];
5822 
5823                     magnitude_avg = magnitude_avg + magnitude;
5824                     phase_avg = phase_avg + phase;
5825                     if (magnitude > magnitude_max) {
5826                         magnitude_max = magnitude;
5827                         magnitude_max_idx = im;
5828                     }
5829                     if (magnitude < magnitude_min) {
5830                         magnitude_min = magnitude;
5831                         magnitude_min_idx = im;
5832                     }
5833                     if (phase > phase_max) {
5834                         phase_max = phase;
5835                         phase_max_idx = im;
5836                     }
5837                     if (phase < phase_min) {
5838                         phase_min = phase;
5839                         phase_min_idx = im;
5840                     }
5841                 }
5842                 /* find average (exclude max abs value) */
5843                 for (im = 0; im < nmeasurement; im++) {
5844                     magnitude = coeff->mag_coeff[ch_idx][im][0];
5845                     phase = coeff->phs_coeff[ch_idx][im][0];
5846                     if ((ABS(magnitude) < ABS(magnitude_max)) ||
5847                         (ABS(magnitude) < ABS(magnitude_min)))
5848                     {
5849                         magnitude_avg = magnitude_avg + magnitude;
5850                     }
5851                     if ((ABS(phase) < ABS(phase_max)) ||
5852                         (ABS(phase) < ABS(phase_min)))
5853                     {
5854                         phase_avg = phase_avg + phase;
5855                     }
5856                 }
5857                 magnitude_avg = magnitude_avg / (nmeasurement - 1);
5858                 phase_avg = phase_avg / (nmeasurement - 1);
5859 
5860                 /* detect magnitude outlier */
5861                 if (ABS(magnitude_max - magnitude_min) > MAX_MAG_DELTA) {
5862                     if (ABS(magnitude_max - magnitude_avg) >
5863                         ABS(magnitude_min - magnitude_avg))
5864                     {
5865                         /* max is outlier, force to avg */
5866                         outlier_mag_idx = magnitude_max_idx;
5867                     } else {
5868                         /* min is outlier, force to avg */
5869                         outlier_mag_idx = magnitude_min_idx;
5870                     }
5871                     coeff->mag_coeff[ch_idx][outlier_mag_idx][0] = magnitude_avg;
5872                     coeff->phs_coeff[ch_idx][outlier_mag_idx][0] = phase_avg;
5873                     HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5874                         "[ch%d][outlier mag gain%d]:: "
5875                         "mag_avg = %d (/128), phase_avg = %d (/256)\n",
5876                         ch_idx, outlier_mag_idx, magnitude_avg, phase_avg);
5877                 }
5878                 /* detect phase outlier */
5879                 if (ABS(phase_max - phase_min) > MAX_PHS_DELTA) {
5880                     if (ABS(phase_max-phase_avg) > ABS(phase_min - phase_avg)) {
5881                         /* max is outlier, force to avg */
5882                         outlier_phs_idx = phase_max_idx;
5883                     } else{
5884                         /* min is outlier, force to avg */
5885                         outlier_phs_idx = phase_min_idx;
5886                     }
5887                     coeff->mag_coeff[ch_idx][outlier_phs_idx][0] = magnitude_avg;
5888                     coeff->phs_coeff[ch_idx][outlier_phs_idx][0] = phase_avg;
5889                     HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
5890                         "[ch%d][outlier phs gain%d]:: "
5891                         "mag_avg = %d (/128), phase_avg = %d (/256)\n",
5892                         ch_idx, outlier_phs_idx, magnitude_avg, phase_avg);
5893                 }
5894             }
5895         }
5896 
5897         /*printf("------------ after outlier detection -------------\n");*/
5898         for (im = 0; im < nmeasurement; im++) {
5899             magnitude = coeff->mag_coeff[ch_idx][im][0];
5900             phase = coeff->phs_coeff[ch_idx][im][0];
5901 
5902             #if 0
5903             printf("[ch%d][gain%d]:: mag = %d (/128), phase = %d (/256)\n",
5904                 ch_idx, im, magnitude, phase);
5905             #endif
5906 
5907             coeff->iqc_coeff[0] = (phase & 0x7f) | ((magnitude & 0x7f) << 7);
5908 
5909             if ((im % 2) == 0) {
5910                 OS_REG_RMW_FIELD(ah,
5911                     tx_corr_coeff[im][ch_idx],
5912                     AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
5913                     coeff->iqc_coeff[0]);
5914             } else {
5915                 OS_REG_RMW_FIELD(ah,
5916                     tx_corr_coeff[im][ch_idx],
5917                     AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
5918                     coeff->iqc_coeff[0]);
5919             }
5920 #if ATH_SUPPORT_CAL_REUSE
5921             ichan->tx_corr_coeff[im][ch_idx] = coeff->iqc_coeff[0];
5922 #endif
5923         }
5924 #if ATH_SUPPORT_CAL_REUSE
5925         ichan->num_measures[ch_idx] = nmeasurement;
5926 #endif
5927     }
5928 
5929     OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
5930                      AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
5931     OS_REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
5932                      AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
5933 
5934 #if ATH_SUPPORT_CAL_REUSE
5935     if (is_cal_reusable) {
5936         ichan->one_time_txiqcal_done = AH_TRUE;
5937         HALDEBUG(ah, HAL_DEBUG_FCS_RTT,
5938             "(FCS) TXIQCAL saved - %d\n", ichan->channel);
5939     }
5940 #endif
5941 }
5942 
5943 #if ATH_SUPPORT_CAL_REUSE
5944 static void
5945 ar9300_tx_iq_cal_apply(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
5946 {
5947     struct ath_hal_9300 *ahp = AH9300(ah);
5948     int nmeasurement, ch_idx, im;
5949 
5950     u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = {
5951         {   AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5952             AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5953             AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5954         {   AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
5955             AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
5956             AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
5957         {   AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5958             AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5959             AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5960         {   AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
5961             AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
5962             AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
5963         {   AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5964             AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5965             AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5966         {   AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
5967             AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
5968             AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
5969         {   AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5970             AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5971             AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5972         {   AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
5973             AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
5974             AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
5975     };
5976 
5977     if (AR_SREV_POSEIDON(ah)) {
5978         HALASSERT(ahp->ah_tx_cal_chainmask == 0x1);
5979 
5980         tx_corr_coeff[0][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5981         tx_corr_coeff[1][0] = AR_PHY_TX_IQCAL_CORR_COEFF_01_B0_POSEIDON;
5982         tx_corr_coeff[2][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5983         tx_corr_coeff[3][0] = AR_PHY_TX_IQCAL_CORR_COEFF_23_B0_POSEIDON;
5984         tx_corr_coeff[4][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5985         tx_corr_coeff[5][0] = AR_PHY_TX_IQCAL_CORR_COEFF_45_B0_POSEIDON;
5986         tx_corr_coeff[6][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5987         tx_corr_coeff[7][0] = AR_PHY_TX_IQCAL_CORR_COEFF_67_B0_POSEIDON;
5988     }
5989 
5990     for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
5991         if ((ahp->ah_tx_cal_chainmask & (1 << ch_idx)) == 0) {
5992             continue;
5993         }
5994         nmeasurement = ichan->num_measures[ch_idx];
5995 
5996         for (im = 0; im < nmeasurement; im++) {
5997             if ((im % 2) == 0) {
5998                 OS_REG_RMW_FIELD(ah,
5999                     tx_corr_coeff[im][ch_idx],
6000                     AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
6001                     ichan->tx_corr_coeff[im][ch_idx]);
6002             } else {
6003                 OS_REG_RMW_FIELD(ah,
6004                     tx_corr_coeff[im][ch_idx],
6005                     AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
6006                     ichan->tx_corr_coeff[im][ch_idx]);
6007             }
6008         }
6009     }
6010 
6011     OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
6012                      AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
6013     OS_REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
6014                      AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
6015 }
6016 #endif
6017 
6018 /*
6019  * ar9300_tx_iq_cal_hw_run is only needed for osprey/wasp/hornet
6020  * It is not needed for jupiter/poseidon.
6021  */
6022 HAL_BOOL
6023 ar9300_tx_iq_cal_hw_run(struct ath_hal *ah)
6024 {
6025     int is_tx_gain_forced;
6026 
6027     is_tx_gain_forced = OS_REG_READ_FIELD(ah,
6028         AR_PHY_TX_FORCED_GAIN, AR_PHY_TXGAIN_FORCE);
6029     if (is_tx_gain_forced) {
6030         /*printf("Tx gain can not be forced during tx I/Q cal!\n");*/
6031         OS_REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, AR_PHY_TXGAIN_FORCE, 0);
6032     }
6033 
6034     /* enable tx IQ cal */
6035     OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START(ah),
6036         AR_PHY_TX_IQCAL_START_DO_CAL, AR_PHY_TX_IQCAL_START_DO_CAL);
6037 
6038     if (!ath_hal_wait(ah,
6039             AR_PHY_TX_IQCAL_START(ah), AR_PHY_TX_IQCAL_START_DO_CAL, 0))
6040     {
6041         HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
6042             "%s: Tx IQ Cal is never completed.\n", __func__);
6043         return AH_FALSE;
6044     }
6045     return AH_TRUE;
6046 }
6047 
6048 static void
6049 ar9300_tx_iq_cal_post_proc(struct ath_hal *ah,HAL_CHANNEL_INTERNAL *ichan,
6050                            int iqcal_idx, int max_iqcal,HAL_BOOL is_cal_reusable, HAL_BOOL apply_last_corr)
6051 {
6052     int nmeasurement=0, im, ix, iy, temp;
6053     struct ath_hal_9300     *ahp = AH9300(ah);
6054     u_int32_t txiqcal_status[AR9300_MAX_CHAINS] = {
6055         AR_PHY_TX_IQCAL_STATUS_B0(ah),
6056         AR_PHY_TX_IQCAL_STATUS_B1,
6057         AR_PHY_TX_IQCAL_STATUS_B2,
6058     };
6059     const u_int32_t chan_info_tab[] = {
6060         AR_PHY_CHAN_INFO_TAB_0,
6061         AR_PHY_CHAN_INFO_TAB_1,
6062         AR_PHY_CHAN_INFO_TAB_2,
6063     };
6064     int32_t iq_res[6];
6065     int32_t ch_idx, j;
6066     u_int32_t num_chains = 0;
6067     static struct coeff_t coeff;
6068     txiqcal_status[0] = AR_PHY_TX_IQCAL_STATUS_B0(ah);
6069 
6070     for (ch_idx = 0; ch_idx < AR9300_MAX_CHAINS; ch_idx++) {
6071         if (ahp->ah_tx_chainmask & (1 << ch_idx)) {
6072             num_chains++;
6073         }
6074     }
6075 
6076     if (apply_last_corr) {
6077 	    if (coeff.last_cal == AH_TRUE) {
6078 		    int32_t magnitude, phase;
6079 		    int ch_idx, im;
6080 		    u_int32_t tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS] = {
6081 			    {   AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
6082 				    AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
6083 				    AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
6084 			    {   AR_PHY_TX_IQCAL_CORR_COEFF_01_B0,
6085 				    AR_PHY_TX_IQCAL_CORR_COEFF_01_B1,
6086 				    AR_PHY_TX_IQCAL_CORR_COEFF_01_B2},
6087 			    {   AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
6088 				    AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
6089 				    AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
6090 			    {   AR_PHY_TX_IQCAL_CORR_COEFF_23_B0,
6091 				    AR_PHY_TX_IQCAL_CORR_COEFF_23_B1,
6092 				    AR_PHY_TX_IQCAL_CORR_COEFF_23_B2},
6093 			    {   AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
6094 				    AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
6095 				    AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
6096 			    {   AR_PHY_TX_IQCAL_CORR_COEFF_45_B0,
6097 				    AR_PHY_TX_IQCAL_CORR_COEFF_45_B1,
6098 				    AR_PHY_TX_IQCAL_CORR_COEFF_45_B2},
6099 			    {   AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
6100 				    AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
6101 				    AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
6102 			    {   AR_PHY_TX_IQCAL_CORR_COEFF_67_B0,
6103 				    AR_PHY_TX_IQCAL_CORR_COEFF_67_B1,
6104 				    AR_PHY_TX_IQCAL_CORR_COEFF_67_B2},
6105 		    };
6106 		    for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
6107 			    for (im = 0; im < coeff.last_nmeasurement; im++) {
6108 				    magnitude = coeff.mag_coeff[ch_idx][im][0];
6109 				    phase = coeff.phs_coeff[ch_idx][im][0];
6110 
6111 #if 0
6112 				    printf("[ch%d][gain%d]:: mag = %d (/128), phase = %d (/256)\n",
6113 						    ch_idx, im, magnitude, phase);
6114 #endif
6115 
6116 				    coeff.iqc_coeff[0] = (phase & 0x7f) | ((magnitude & 0x7f) << 7);
6117 				    if ((im % 2) == 0) {
6118 					    OS_REG_RMW_FIELD(ah,
6119 							    tx_corr_coeff[im][ch_idx],
6120 							    AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
6121 							    coeff.iqc_coeff[0]);
6122 				    } else {
6123 					    OS_REG_RMW_FIELD(ah,
6124 							    tx_corr_coeff[im][ch_idx],
6125 							    AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
6126 							    coeff.iqc_coeff[0]);
6127 				    }
6128 			    }
6129 		    }
6130 		    OS_REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
6131 				    AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
6132 	    }
6133 	    return;
6134     }
6135 
6136 
6137     for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
6138         nmeasurement = OS_REG_READ_FIELD(ah,
6139             AR_PHY_TX_IQCAL_STATUS_B0(ah), AR_PHY_CALIBRATED_GAINS_0);
6140         if (nmeasurement > MAX_MEASUREMENT) {
6141             nmeasurement = MAX_MEASUREMENT;
6142         }
6143 
6144         for (im = 0; im < nmeasurement; im++) {
6145             HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
6146                 "%s: Doing Tx IQ Cal for chain %d.\n", __func__, ch_idx);
6147             if (OS_REG_READ(ah, txiqcal_status[ch_idx]) &
6148                 AR_PHY_TX_IQCAL_STATUS_FAILED)
6149             {
6150                 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
6151                     "%s: Tx IQ Cal failed for chain %d.\n", __func__, ch_idx);
6152                 goto TX_IQ_CAL_FAILED_;
6153             }
6154 
6155             for (j = 0; j < 3; j++) {
6156                 u_int32_t idx = 2 * j;
6157                 /* 3 registers for each calibration result */
6158                 u_int32_t offset = 4 * (3 * im + j);
6159 
6160                 OS_REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
6161                     AR_PHY_CHAN_INFO_TAB_S2_READ, 0);
6162                 /* 32 bits */
6163                 iq_res[idx] = OS_REG_READ(ah, chan_info_tab[ch_idx] + offset);
6164                 OS_REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
6165                     AR_PHY_CHAN_INFO_TAB_S2_READ, 1);
6166                 /* 16 bits */
6167                 iq_res[idx + 1] = 0xffff &
6168                     OS_REG_READ(ah, chan_info_tab[ch_idx] + offset);
6169 
6170                 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
6171                     "%s: IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
6172                     __func__, idx, iq_res[idx], idx + 1, iq_res[idx + 1]);
6173             }
6174 
6175             if (AH_FALSE == ar9300_calc_iq_corr(
6176                              ah, ch_idx, iq_res, coeff.iqc_coeff))
6177             {
6178                 HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
6179                     "%s: Failed in calculation of IQ correction.\n",
6180                      __func__);
6181                 goto TX_IQ_CAL_FAILED_;
6182             }
6183 
6184             coeff.phs_coeff[ch_idx][im][iqcal_idx-1] = coeff.iqc_coeff[0] & 0x7f;
6185             coeff.mag_coeff[ch_idx][im][iqcal_idx-1] = (coeff.iqc_coeff[0] >> 7) & 0x7f;
6186             if (coeff.mag_coeff[ch_idx][im][iqcal_idx-1] > 63) {
6187                 coeff.mag_coeff[ch_idx][im][iqcal_idx-1] -= 128;
6188             }
6189             if (coeff.phs_coeff[ch_idx][im][iqcal_idx-1] > 63) {
6190                 coeff.phs_coeff[ch_idx][im][iqcal_idx-1] -= 128;
6191             }
6192 #if 0
6193             ath_hal_printf(ah, "IQCAL::[ch%d][gain%d]:: mag = %d phase = %d \n",
6194                 ch_idx, im, coeff.mag_coeff[ch_idx][im][iqcal_idx-1],
6195                 coeff.phs_coeff[ch_idx][im][iqcal_idx-1]);
6196 #endif
6197         }
6198     }
6199     //last iteration; calculate mag and phs
6200     if (iqcal_idx == max_iqcal) {
6201         if (max_iqcal>1) {
6202             for (ch_idx = 0; ch_idx < num_chains; ch_idx++) {
6203                 for (im = 0; im < nmeasurement; im++) {
6204                     //sort mag and phs
6205                     for( ix=0;ix<max_iqcal-1;ix++){
6206                         for( iy=ix+1;iy<=max_iqcal-1;iy++){
6207                             if(coeff.mag_coeff[ch_idx][im][iy] <
6208                                 coeff.mag_coeff[ch_idx][im][ix]) {
6209                                 //swap
6210                                 temp=coeff.mag_coeff[ch_idx][im][ix];
6211                                 coeff.mag_coeff[ch_idx][im][ix] = coeff.mag_coeff[ch_idx][im][iy];
6212                                 coeff.mag_coeff[ch_idx][im][iy] = temp;
6213                             }
6214                             if(coeff.phs_coeff[ch_idx][im][iy] <
6215                                 coeff.phs_coeff[ch_idx][im][ix]){
6216                                 //swap
6217                                 temp=coeff.phs_coeff[ch_idx][im][ix];
6218                                 coeff.phs_coeff[ch_idx][im][ix]=coeff.phs_coeff[ch_idx][im][iy];
6219                                 coeff.phs_coeff[ch_idx][im][iy]=temp;
6220                             }
6221                         }
6222                     }
6223                     //select median; 3rd entry in the sorted array
6224                     coeff.mag_coeff[ch_idx][im][0] =
6225                         coeff.mag_coeff[ch_idx][im][max_iqcal/2];
6226                     coeff.phs_coeff[ch_idx][im][0] =
6227                         coeff.phs_coeff[ch_idx][im][max_iqcal/2];
6228                     HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
6229                         "IQCAL: Median [ch%d][gain%d]:: mag = %d phase = %d \n",
6230                         ch_idx, im,coeff.mag_coeff[ch_idx][im][0],
6231                         coeff.phs_coeff[ch_idx][im][0]);
6232                 }
6233             }
6234         }
6235         ar9300_tx_iq_cal_outlier_detection(ah,ichan, num_chains, &coeff,is_cal_reusable);
6236     }
6237 
6238 
6239     coeff.last_nmeasurement = nmeasurement;
6240     coeff.last_cal = AH_TRUE;
6241 
6242     return;
6243 
6244 TX_IQ_CAL_FAILED_:
6245     /* no need to print this, it is AGC failure not chip stuck */
6246     /*ath_hal_printf(ah, "Tx IQ Cal failed(%d)\n", line);*/
6247     coeff.last_cal = AH_FALSE;
6248     return;
6249 }
6250 
6251 
6252 /*
6253  * ar9300_disable_phy_restart
6254  *
6255  * In some BBpanics, we can disable the phyrestart
6256  * disable_phy_restart
6257  *      != 0, disable the phy restart in h/w
6258  *      == 0, enable the phy restart in h/w
6259  */
6260 void ar9300_disable_phy_restart(struct ath_hal *ah, int disable_phy_restart)
6261 {
6262     u_int32_t val;
6263 
6264     val = OS_REG_READ(ah, AR_PHY_RESTART);
6265     if (disable_phy_restart) {
6266         val &= ~AR_PHY_RESTART_ENA;
6267         AH9300(ah)->ah_phyrestart_disabled = 1;
6268     } else {
6269         val |= AR_PHY_RESTART_ENA;
6270         AH9300(ah)->ah_phyrestart_disabled = 0;
6271     }
6272     OS_REG_WRITE(ah, AR_PHY_RESTART, val);
6273 
6274     val = OS_REG_READ(ah, AR_PHY_RESTART);
6275 }
6276 
6277 HAL_BOOL
6278 ar9300_interference_is_present(struct ath_hal *ah)
6279 {
6280     int i;
6281     struct ath_hal_private  *ahpriv = AH_PRIVATE(ah);
6282     const struct ieee80211_channel *chan = ahpriv->ah_curchan;
6283     HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
6284 
6285     if (ichan == NULL) {
6286         ath_hal_printf(ah, "%s: called with ichan=NULL\n", __func__);
6287         return AH_FALSE;
6288     }
6289 
6290     /* This function is called after a stuck beacon, if EACS is enabled.
6291      * If CW interference is severe, then HW goes into a loop of continuous
6292      * stuck beacons and resets. On reset the NF cal history is cleared.
6293      * So the median value of the history cannot be used -
6294      * hence check if any value (Chain 0/Primary Channel)
6295      * is outside the bounds.
6296      */
6297     HAL_NFCAL_HIST_FULL *h = AH_HOME_CHAN_NFCAL_HIST(ah, ichan);
6298     for (i = 0; i < HAL_NF_CAL_HIST_LEN_FULL; i++) {
6299         if (h->nf_cal_buffer[i][0] >
6300             AH9300(ah)->nfp->nominal + AH9300(ah)->nf_cw_int_delta)
6301         {
6302             return AH_TRUE;
6303         }
6304 
6305     }
6306     return AH_FALSE;
6307 }
6308 
6309 #if ATH_SUPPORT_CRDC
6310 void
6311 ar9300_crdc_rx_notify(struct ath_hal *ah, struct ath_rx_status *rxs)
6312 {
6313     struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6314     int rssi_index;
6315 
6316     if ((!AR_SREV_WASP(ah)) ||
6317         (!ahpriv->ah_config.ath_hal_crdc_enable)) {
6318         return;
6319     }
6320 
6321     if (rxs->rs_isaggr && rxs->rs_moreaggr) {
6322         return;
6323     }
6324 
6325     if ((rxs->rs_rssi_ctl0 >= HAL_RSSI_BAD) ||
6326         (rxs->rs_rssi_ctl1 >= HAL_RSSI_BAD)) {
6327         return;
6328     }
6329 
6330     rssi_index = ah->ah_crdc_rssi_ptr % HAL_MAX_CRDC_RSSI_SAMPLE;
6331 
6332     ah->ah_crdc_rssi_sample[0][rssi_index] = rxs->rs_rssi_ctl0;
6333     ah->ah_crdc_rssi_sample[1][rssi_index] = rxs->rs_rssi_ctl1;
6334 
6335     ah->ah_crdc_rssi_ptr++;
6336 }
6337 
6338 static int
6339 ar9300_crdc_avg_rssi(struct ath_hal *ah, int chain)
6340 {
6341     int crdc_rssi_sum = 0;
6342     int crdc_rssi_ptr = ah->ah_crdc_rssi_ptr, i;
6343     struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6344     int crdc_window = ahpriv->ah_config.ath_hal_crdc_window;
6345 
6346     if (crdc_window > HAL_MAX_CRDC_RSSI_SAMPLE) {
6347         crdc_window = HAL_MAX_CRDC_RSSI_SAMPLE;
6348     }
6349 
6350     for (i = 1; i <= crdc_window; i++) {
6351         crdc_rssi_sum +=
6352             ah->ah_crdc_rssi_sample[chain]
6353             [(crdc_rssi_ptr - i) % HAL_MAX_CRDC_RSSI_SAMPLE];
6354     }
6355 
6356     return crdc_rssi_sum / crdc_window;
6357 }
6358 
6359 static void
6360 ar9300_crdc_activate(struct ath_hal *ah, int rssi_diff, int enable)
6361 {
6362     int val, orig_val;
6363     struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6364     int crdc_numerator = ahpriv->ah_config.ath_hal_crdc_numerator;
6365     int crdc_denominator = ahpriv->ah_config.ath_hal_crdc_denominator;
6366     int c = (rssi_diff * crdc_numerator) / crdc_denominator;
6367 
6368     val = orig_val = OS_REG_READ(ah, AR_PHY_MULTICHAIN_CTRL);
6369     val &= 0xffffff00;
6370     if (enable) {
6371         val |= 0x1;
6372         val |= ((c << 1) & 0xff);
6373     }
6374     OS_REG_WRITE(ah, AR_PHY_MULTICHAIN_CTRL, val);
6375     HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "diff: %02d comp: %02d reg: %08x %08x\n",
6376         rssi_diff, c, orig_val, val);
6377 }
6378 
6379 
6380 void ar9300_chain_rssi_diff_compensation(struct ath_hal *ah)
6381 {
6382     struct ath_hal_private  *ahpriv = AH_PRIVATE(ah);
6383     int crdc_window = ahpriv->ah_config.ath_hal_crdc_window;
6384     int crdc_rssi_ptr = ah->ah_crdc_rssi_ptr;
6385     int crdc_rssi_thresh = ahpriv->ah_config.ath_hal_crdc_rssithresh;
6386     int crdc_diff_thresh = ahpriv->ah_config.ath_hal_crdc_diffthresh;
6387     int avg_rssi[2], avg_rssi_diff;
6388 
6389     if ((!AR_SREV_WASP(ah)) ||
6390         (!ahpriv->ah_config.ath_hal_crdc_enable)) {
6391         if (ah->ah_crdc_rssi_ptr) {
6392             ar9300_crdc_activate(ah, 0, 0);
6393             ah->ah_crdc_rssi_ptr = 0;
6394         }
6395         return;
6396     }
6397 
6398     if (crdc_window > HAL_MAX_CRDC_RSSI_SAMPLE) {
6399         crdc_window = HAL_MAX_CRDC_RSSI_SAMPLE;
6400     }
6401 
6402     if (crdc_rssi_ptr < crdc_window) {
6403         return;
6404     }
6405 
6406     avg_rssi[0] = ar9300_crdc_avg_rssi(ah, 0);
6407     avg_rssi[1] = ar9300_crdc_avg_rssi(ah, 1);
6408     avg_rssi_diff = avg_rssi[1] - avg_rssi[0];
6409 
6410     HALDEBUG(ah, HAL_DEBUG_CALIBRATE, "crdc: avg: %02d %02d ",
6411         avg_rssi[0], avg_rssi[1]);
6412 
6413     if ((avg_rssi[0] < crdc_rssi_thresh) &&
6414         (avg_rssi[1] < crdc_rssi_thresh)) {
6415         ar9300_crdc_activate(ah, 0, 0);
6416     } else {
6417         if (ABS(avg_rssi_diff) >= crdc_diff_thresh) {
6418             ar9300_crdc_activate(ah, avg_rssi_diff, 1);
6419         } else {
6420             ar9300_crdc_activate(ah, 0, 1);
6421         }
6422     }
6423 }
6424 #endif
6425 
6426 #if ATH_ANT_DIV_COMB
6427 HAL_BOOL
6428 ar9300_ant_ctrl_set_lna_div_use_bt_ant(struct ath_hal *ah, HAL_BOOL enable, const struct ieee80211_channel *chan)
6429 {
6430     u_int32_t value;
6431     u_int32_t regval;
6432     struct ath_hal_9300 *ahp = AH9300(ah);
6433     HAL_CHANNEL_INTERNAL *ichan;
6434     struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
6435     HAL_CAPABILITIES *pcap = &ahpriv->ah_caps;
6436 
6437     HALDEBUG(ah, HAL_DEBUG_RESET | HAL_DEBUG_BT_COEX,
6438       "%s: called; enable=%d\n", __func__, enable);
6439 
6440     if (AR_SREV_POSEIDON(ah)) {
6441         // Make sure this scheme is only used for WB225(Astra)
6442         ahp->ah_lna_div_use_bt_ant_enable = enable;
6443 
6444         ichan = ar9300_check_chan(ah, chan);
6445         if ( ichan == AH_NULL ) {
6446             HALDEBUG(ah, HAL_DEBUG_CHANNEL, "%s: invalid channel %u/0x%x; no mapping\n",
6447                      __func__, chan->ic_freq, chan->ic_flags);
6448             return AH_FALSE;
6449         }
6450 
6451         if ( enable == TRUE ) {
6452             pcap->halAntDivCombSupport = TRUE;
6453         } else {
6454             pcap->halAntDivCombSupport = pcap->halAntDivCombSupportOrg;
6455         }
6456 
6457 #define AR_SWITCH_TABLE_COM2_ALL (0xffffff)
6458 #define AR_SWITCH_TABLE_COM2_ALL_S (0)
6459         value = ar9300_ant_ctrl_common2_get(ah, IS_CHAN_2GHZ(ichan));
6460         if ( enable == TRUE ) {
6461             value &= ~AR_SWITCH_TABLE_COM2_ALL;
6462             value |= ah->ah_config.ath_hal_ant_ctrl_comm2g_switch_enable;
6463         }
6464 	HALDEBUG(ah, HAL_DEBUG_RESET, "%s: com2=0x%08x\n", __func__, value);
6465         OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
6466 
6467         value = ar9300_eeprom_get(ahp, EEP_ANTDIV_control);
6468         /* main_lnaconf, alt_lnaconf, main_tb, alt_tb */
6469         regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
6470         regval &= (~ANT_DIV_CONTROL_ALL); /* clear bit 25~30 */
6471         regval |= (value & 0x3f) << ANT_DIV_CONTROL_ALL_S;
6472         /* enable_lnadiv */
6473         regval &= (~MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__MASK);
6474         regval |= ((value >> 6) & 0x1) <<
6475                   MULTICHAIN_GAIN_CTRL__ENABLE_ANT_DIV_LNADIV__SHIFT;
6476         if ( enable == TRUE ) {
6477             regval |= ANT_DIV_ENABLE;
6478         }
6479         OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
6480 
6481         /* enable fast_div */
6482         regval = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
6483         regval &= (~BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__MASK);
6484         regval |= ((value >> 7) & 0x1) <<
6485                   BBB_SIG_DETECT__ENABLE_ANT_FAST_DIV__SHIFT;
6486         if ( enable == TRUE ) {
6487             regval |= FAST_DIV_ENABLE;
6488         }
6489         OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
6490 
6491         if ( AR_SREV_POSEIDON_11_OR_LATER(ah) ) {
6492             if (pcap->halAntDivCombSupport) {
6493                 /* If support DivComb, set MAIN to LNA1 and ALT to LNA2 at the first beginning */
6494                 regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
6495                 /* clear bit 25~30 main_lnaconf, alt_lnaconf, main_tb, alt_tb */
6496                 regval &= (~(MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__MASK |
6497                              MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__MASK |
6498                              MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_GAINTB__MASK |
6499                              MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_GAINTB__MASK));
6500                 regval |= (HAL_ANT_DIV_COMB_LNA1 <<
6501                            MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT);
6502                 regval |= (HAL_ANT_DIV_COMB_LNA2 <<
6503                            MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT);
6504                 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
6505             }
6506         }
6507 
6508         return AH_TRUE;
6509     } else if (AR_SREV_APHRODITE(ah)) {
6510         ahp->ah_lna_div_use_bt_ant_enable = enable;
6511         if (enable) {
6512                 OS_REG_SET_BIT(ah, AR_PHY_MC_GAIN_CTRL, ANT_DIV_ENABLE);
6513                 OS_REG_SET_BIT(ah, AR_PHY_MC_GAIN_CTRL, (1 << MULTICHAIN_GAIN_CTRL__ENABLE_ANT_SW_RX_PROT__SHIFT));
6514                 OS_REG_SET_BIT(ah, AR_PHY_CCK_DETECT, AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
6515                 OS_REG_SET_BIT(ah, AR_PHY_RESTART, RESTART__ENABLE_ANT_FAST_DIV_M2FLAG__MASK);
6516                 OS_REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
6517         } else {
6518                 OS_REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL, ANT_DIV_ENABLE);
6519                 OS_REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL, (1 << MULTICHAIN_GAIN_CTRL__ENABLE_ANT_SW_RX_PROT__SHIFT));
6520                 OS_REG_CLR_BIT(ah, AR_PHY_CCK_DETECT, AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
6521                 OS_REG_CLR_BIT(ah, AR_PHY_RESTART, RESTART__ENABLE_ANT_FAST_DIV_M2FLAG__MASK);
6522                 OS_REG_CLR_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
6523 
6524                 regval = OS_REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
6525                 regval &= (~(MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__MASK |
6526                              MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__MASK |
6527                              MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_GAINTB__MASK |
6528                              MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_GAINTB__MASK));
6529                 regval |= (HAL_ANT_DIV_COMB_LNA1 <<
6530                            MULTICHAIN_GAIN_CTRL__ANT_DIV_MAIN_LNACONF__SHIFT);
6531                 regval |= (HAL_ANT_DIV_COMB_LNA2 <<
6532                            MULTICHAIN_GAIN_CTRL__ANT_DIV_ALT_LNACONF__SHIFT);
6533 
6534                 OS_REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
6535         }
6536         return AH_TRUE;
6537     }
6538     return AH_TRUE;
6539 }
6540 #endif /* ATH_ANT_DIV_COMB */
6541