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