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