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