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