Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c
48526 views
1
/*
2
* Copyright (c) 2013 Qualcomm Atheros, Inc.
3
*
4
* Permission to use, copy, modify, and/or distribute this software for any
5
* purpose with or without fee is hereby granted, provided that the above
6
* copyright notice and this permission notice appear in all copies.
7
*
8
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14
* PERFORMANCE OF THIS SOFTWARE.
15
*/
16
17
18
19
#include "opt_ah.h"
20
21
#include "ah.h"
22
#include "ah_internal.h"
23
#include "ah_devid.h"
24
#include "ah_desc.h"
25
26
#include "ar9300.h"
27
#include "ar9300reg.h"
28
#include "ar9300phy.h"
29
#include "ar9300desc.h"
30
31
#define FIX_NOISE_FLOOR 1
32
33
34
/* Additional Time delay to wait after activiting the Base band */
35
#define BASE_ACTIVATE_DELAY 100 /* usec */
36
#define RTC_PLL_SETTLE_DELAY 100 /* usec */
37
#define COEF_SCALE_S 24
38
#define HT40_CHANNEL_CENTER_SHIFT 10 /* MHz */
39
40
#define DELPT 32
41
42
/* XXX Duplicates! (in ar9300desc.h) */
43
#if 0
44
extern HAL_BOOL ar9300_reset_tx_queue(struct ath_hal *ah, u_int q);
45
extern u_int32_t ar9300_num_tx_pending(struct ath_hal *ah, u_int q);
46
#endif
47
48
49
#define MAX_MEASUREMENT 8
50
#define MAXIQCAL 3
51
struct coeff_t {
52
int32_t mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL];
53
int32_t phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MAXIQCAL];
54
int32_t iqc_coeff[2];
55
int last_nmeasurement;
56
HAL_BOOL last_cal;
57
};
58
59
static HAL_BOOL ar9300_tx_iq_cal_hw_run(struct ath_hal *ah);
60
static void ar9300_tx_iq_cal_post_proc(struct ath_hal *ah,HAL_CHANNEL_INTERNAL *ichan,
61
int iqcal_idx, int max_iqcal, HAL_BOOL is_cal_reusable, HAL_BOOL apply_last_corr);
62
static void ar9300_tx_iq_cal_outlier_detection(struct ath_hal *ah,HAL_CHANNEL_INTERNAL *ichan,
63
u_int32_t num_chains, struct coeff_t *coeff, HAL_BOOL is_cal_reusable);
64
#if ATH_SUPPORT_CAL_REUSE
65
static void ar9300_tx_iq_cal_apply(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan);
66
#endif
67
68
69
static inline void ar9300_prog_ini(struct ath_hal *ah, struct ar9300_ini_array *ini_arr, int column);
70
static inline void ar9300_set_rf_mode(struct ath_hal *ah, struct ieee80211_channel *chan);
71
static inline HAL_BOOL ar9300_init_cal(struct ath_hal *ah, struct ieee80211_channel *chan, HAL_BOOL skip_if_none, HAL_BOOL apply_last_corr);
72
static inline void ar9300_init_user_settings(struct ath_hal *ah);
73
74
#ifdef HOST_OFFLOAD
75
/*
76
* For usb offload solution, some USB registers must be tuned
77
* to gain better stability/performance but these registers
78
* might be changed while doing wlan reset so do this here
79
*/
80
#define WAR_USB_DISABLE_PLL_LOCK_DETECT(__ah) \
81
do { \
82
if (AR_SREV_HORNET(__ah) || AR_SREV_WASP(__ah)) { \
83
volatile u_int32_t *usb_ctrl_r1 = (u_int32_t *) 0xb8116c84; \
84
volatile u_int32_t *usb_ctrl_r2 = (u_int32_t *) 0xb8116c88; \
85
*usb_ctrl_r1 = (*usb_ctrl_r1 & 0xffefffff); \
86
*usb_ctrl_r2 = (*usb_ctrl_r2 & 0xfc1fffff) | (1 << 21) | (3 << 22); \
87
} \
88
} while (0)
89
#else
90
#define WAR_USB_DISABLE_PLL_LOCK_DETECT(__ah)
91
#endif
92
93
/*
94
* Note: the below is the version that ships with ath9k.
95
* The original HAL version is above.
96
*/
97
98
static void
99
ar9300_disable_pll_lock_detect(struct ath_hal *ah)
100
{
101
/*
102
* On AR9330 and AR9340 devices, some PHY registers must be
103
* tuned to gain better stability/performance. These registers
104
* might be changed while doing wlan reset so the registers must
105
* be reprogrammed after each reset.
106
*/
107
if (AR_SREV_HORNET(ah) || AR_SREV_WASP(ah)) {
108
HALDEBUG(ah, HAL_DEBUG_RESET, "%s: called\n", __func__);
109
OS_REG_CLR_BIT(ah, AR_PHY_USB_CTRL1, (1 << 20));
110
OS_REG_RMW(ah, AR_PHY_USB_CTRL2,
111
(1 << 21) | (0xf << 22),
112
(1 << 21) | (0x3 << 22));
113
}
114
}
115
116
static inline void
117
ar9300_attach_hw_platform(struct ath_hal *ah)
118
{
119
struct ath_hal_9300 *ahp = AH9300(ah);
120
121
ahp->ah_hwp = HAL_TRUE_CHIP;
122
return;
123
}
124
125
/* Adjust various register settings based on half/quarter rate clock setting.
126
* This includes: +USEC, TX/RX latency,
127
* + IFS params: slot, eifs, misc etc.
128
* SIFS stays the same.
129
*/
130
static void
131
ar9300_set_ifs_timing(struct ath_hal *ah, struct ieee80211_channel *chan)
132
{
133
u_int32_t tx_lat, rx_lat, usec, slot, regval, eifs;
134
135
regval = OS_REG_READ(ah, AR_USEC);
136
regval &= ~(AR_USEC_RX_LATENCY | AR_USEC_TX_LATENCY | AR_USEC_USEC);
137
if (IEEE80211_IS_CHAN_HALF(chan)) { /* half rates */
138
slot = ar9300_mac_to_clks(ah, AR_SLOT_HALF);
139
eifs = ar9300_mac_to_clks(ah, AR_EIFS_HALF);
140
if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { /* fast clock */
141
rx_lat = SM(AR_RX_LATENCY_HALF_FAST_CLOCK, AR_USEC_RX_LATENCY);
142
tx_lat = SM(AR_TX_LATENCY_HALF_FAST_CLOCK, AR_USEC_TX_LATENCY);
143
usec = SM(AR_USEC_HALF_FAST_CLOCK, AR_USEC_USEC);
144
} else {
145
rx_lat = SM(AR_RX_LATENCY_HALF, AR_USEC_RX_LATENCY);
146
tx_lat = SM(AR_TX_LATENCY_HALF, AR_USEC_TX_LATENCY);
147
usec = SM(AR_USEC_HALF, AR_USEC_USEC);
148
}
149
} else { /* quarter rate */
150
slot = ar9300_mac_to_clks(ah, AR_SLOT_QUARTER);
151
eifs = ar9300_mac_to_clks(ah, AR_EIFS_QUARTER);
152
if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) { /* fast clock */
153
rx_lat = SM(AR_RX_LATENCY_QUARTER_FAST_CLOCK, AR_USEC_RX_LATENCY);
154
tx_lat = SM(AR_TX_LATENCY_QUARTER_FAST_CLOCK, AR_USEC_TX_LATENCY);
155
usec = SM(AR_USEC_QUARTER_FAST_CLOCK, AR_USEC_USEC);
156
} else {
157
rx_lat = SM(AR_RX_LATENCY_QUARTER, AR_USEC_RX_LATENCY);
158
tx_lat = SM(AR_TX_LATENCY_QUARTER, AR_USEC_TX_LATENCY);
159
usec = SM(AR_USEC_QUARTER, AR_USEC_USEC);
160
}
161
}
162
163
OS_REG_WRITE(ah, AR_USEC, (usec | regval | tx_lat | rx_lat));
164
OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, slot);
165
OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS, eifs);
166
}
167
168
169
/*
170
* This inline function configures the chip either
171
* to encrypt/decrypt management frames or pass thru
172
*/
173
static inline void
174
ar9300_init_mfp(struct ath_hal * ah)
175
{
176
u_int32_t mfpcap, mfp_qos;
177
178
ath_hal_getcapability(ah, HAL_CAP_MFP, 0, &mfpcap);
179
180
if (mfpcap == HAL_MFP_QOSDATA) {
181
/* Treat like legacy hardware. Do not touch the MFP registers. */
182
HALDEBUG(ah, HAL_DEBUG_RESET, "%s forced to use QOSDATA\n", __func__);
183
return;
184
}
185
186
/* MFP support (Sowl 1.0 or greater) */
187
if (mfpcap == HAL_MFP_HW_CRYPTO) {
188
/* configure hardware MFP support */
189
HALDEBUG(ah, HAL_DEBUG_RESET, "%s using HW crypto\n", __func__);
190
OS_REG_RMW_FIELD(ah,
191
AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT, AR_AES_MUTE_MASK1_FC_MGMT_MFP);
192
OS_REG_RMW(ah,
193
AR_PCU_MISC_MODE2, AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE,
194
AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
195
/*
196
* Mask used to construct AAD for CCMP-AES
197
* Cisco spec defined bits 0-3 as mask
198
* IEEE802.11w defined as bit 4.
199
*/
200
if (ath_hal_get_mfp_qos(ah)) {
201
mfp_qos = AR_MFP_QOS_MASK_IEEE;
202
} else {
203
mfp_qos = AR_MFP_QOS_MASK_CISCO;
204
}
205
OS_REG_RMW_FIELD(ah,
206
AR_PCU_MISC_MODE2, AR_PCU_MISC_MODE2_MGMT_QOS, mfp_qos);
207
} else if (mfpcap == HAL_MFP_PASSTHRU) {
208
/* Disable en/decrypt by hardware */
209
HALDEBUG(ah, HAL_DEBUG_RESET, "%s using passthru\n", __func__);
210
OS_REG_RMW(ah,
211
AR_PCU_MISC_MODE2,
212
AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT,
213
AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
214
}
215
}
216
217
void
218
ar9300_get_channel_centers(struct ath_hal *ah, const struct ieee80211_channel *chan,
219
CHAN_CENTERS *centers)
220
{
221
int8_t extoff;
222
struct ath_hal_9300 *ahp = AH9300(ah);
223
HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
224
225
if (!IEEE80211_IS_CHAN_HT40(chan)) {
226
centers->ctl_center = centers->ext_center =
227
centers->synth_center = ichan->channel;
228
return;
229
}
230
231
HALASSERT(IEEE80211_IS_CHAN_HT40(chan));
232
233
/*
234
* In 20/40 phy mode, the center frequency is
235
* "between" the primary and extension channels.
236
*/
237
if (IEEE80211_IS_CHAN_HT40U(chan)) {
238
centers->synth_center = ichan->channel + HT40_CHANNEL_CENTER_SHIFT;
239
extoff = 1;
240
} else {
241
centers->synth_center = ichan->channel - HT40_CHANNEL_CENTER_SHIFT;
242
extoff = -1;
243
}
244
245
centers->ctl_center =
246
centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT);
247
centers->ext_center =
248
centers->synth_center +
249
(extoff * ((ahp->ah_ext_prot_spacing == HAL_HT_EXTPROTSPACING_20) ?
250
HT40_CHANNEL_CENTER_SHIFT : 15));
251
}
252
253
/*
254
* Read the noise-floor values from the HW.
255
* Specifically, read the minimum clear-channel assessment value for
256
* each chain, for both the control and extension channels.
257
* (The received power level during clear-channel periods is the
258
* noise floor.)
259
* These noise floor values computed by the HW will be stored in the
260
* NF history buffer.
261
* The HW sometimes produces bogus NF values. To avoid using these
262
* bogus values, the NF data is (a) range-limited, and (b) filtered.
263
* However, this data-processing is done when reading the NF values
264
* out of the history buffer. The history buffer stores the raw values.
265
* This allows the NF history buffer to be used to check for interference.
266
* A single high NF reading might be a bogus HW value, but if the NF
267
* readings are consistently high, it must be due to interference.
268
* This is the purpose of storing raw NF values in the history buffer,
269
* rather than processed values. By looking at a history of NF values
270
* that have not been range-limited, we can check if they are consistently
271
* high (due to interference).
272
*/
273
#define AH_NF_SIGN_EXTEND(nf) \
274
((nf) & 0x100) ? \
275
0 - (((nf) ^ 0x1ff) + 1) : \
276
(nf)
277
void
278
ar9300_upload_noise_floor(struct ath_hal *ah, int is_2g,
279
int16_t nfarray[HAL_NUM_NF_READINGS])
280
{
281
int16_t nf;
282
int chan, chain;
283
u_int32_t regs[HAL_NUM_NF_READINGS] = {
284
/* control channel */
285
AR_PHY_CCA_0, /* chain 0 */
286
AR_PHY_CCA_1, /* chain 1 */
287
AR_PHY_CCA_2, /* chain 2 */
288
/* extension channel */
289
AR_PHY_EXT_CCA, /* chain 0 */
290
AR_PHY_EXT_CCA_1, /* chain 1 */
291
AR_PHY_EXT_CCA_2, /* chain 2 */
292
};
293
u_int8_t chainmask;
294
295
/*
296
* Within a given channel (ctl vs. ext), the CH0, CH1, and CH2
297
* masks and shifts are the same, though they differ for the
298
* control vs. extension channels.
299
*/
300
u_int32_t masks[2] = {
301
AR_PHY_MINCCA_PWR, /* control channel */
302
AR_PHY_EXT_MINCCA_PWR, /* extention channel */
303
};
304
u_int8_t shifts[2] = {
305
AR_PHY_MINCCA_PWR_S, /* control channel */
306
AR_PHY_EXT_MINCCA_PWR_S, /* extention channel */
307
};
308
309
/*
310
* Force NF calibration for all chains.
311
*/
312
if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) {
313
chainmask = 0x01;
314
} else if (AR_SREV_WASP(ah) || AR_SREV_JUPITER(ah) || AR_SREV_HONEYBEE(ah)) {
315
chainmask = 0x03;
316
} else {
317
chainmask = 0x07;
318
}
319
320
for (chan = 0; chan < 2 /*ctl,ext*/; chan++) {
321
for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
322
int i;
323
324
if (!((chainmask >> chain) & 0x1)) {
325
continue;
326
}
327
i = chan * AR9300_MAX_CHAINS + chain;
328
nf = (OS_REG_READ(ah, regs[i]) & masks[chan]) >> shifts[chan];
329
nfarray[i] = AH_NF_SIGN_EXTEND(nf);
330
}
331
}
332
}
333
334
/* ar9300_get_min_cca_pwr -
335
* Used by the scan function for a quick read of the noise floor.
336
* This is used to detect presence of CW interference such as video bridge.
337
* The noise floor is assumed to have been already started during reset
338
* called during channel change. The function checks if the noise floor
339
* reading is done. In case it has been done, it reads the noise floor value.
340
* If the noise floor calibration has not been finished, it assumes this is
341
* due to presence of CW interference an returns a high value for noise floor,
342
* derived from the CW interference threshold + margin fudge factor.
343
*/
344
#define BAD_SCAN_NF_MARGIN (30)
345
int16_t ar9300_get_min_cca_pwr(struct ath_hal *ah)
346
{
347
int16_t nf;
348
// struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
349
350
351
if ((OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) == 0) {
352
nf = MS(OS_REG_READ(ah, AR_PHY_CCA_0), AR9280_PHY_MINCCA_PWR);
353
if (nf & 0x100) {
354
nf = 0 - ((nf ^ 0x1ff) + 1);
355
}
356
} else {
357
/* NF calibration is not done, assume CW interference */
358
nf = AH9300(ah)->nfp->nominal + AH9300(ah)->nf_cw_int_delta +
359
BAD_SCAN_NF_MARGIN;
360
}
361
return nf;
362
}
363
364
365
/*
366
* Noise Floor values for all chains.
367
* Most recently updated values from the NF history buffer are used.
368
*/
369
void ar9300_chain_noise_floor(struct ath_hal *ah, int16_t *nf_buf,
370
struct ieee80211_channel *chan, int is_scan)
371
{
372
struct ath_hal_9300 *ahp = AH9300(ah);
373
int i, nf_hist_len, recent_nf_index = 0;
374
HAL_NFCAL_HIST_FULL *h;
375
u_int8_t rx_chainmask = ahp->ah_rx_chainmask | (ahp->ah_rx_chainmask << 3);
376
HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
377
HALASSERT(ichan);
378
379
#ifdef ATH_NF_PER_CHAN
380
/* Fill 0 if valid internal channel is not found */
381
if (ichan == AH_NULL) {
382
OS_MEMZERO(nf_buf, sizeof(nf_buf[0])*HAL_NUM_NF_READINGS);
383
return;
384
}
385
h = &ichan->nf_cal_hist;
386
nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
387
#else
388
/*
389
* If a scan is not in progress, then the most recent value goes
390
* into ahpriv->nf_cal_hist. If a scan is in progress, then
391
* the most recent value goes into ichan->nf_cal_hist.
392
* Thus, return the value from ahpriv->nf_cal_hist if there's
393
* no scan, and if the specified channel is the current channel.
394
* Otherwise, return the noise floor from ichan->nf_cal_hist.
395
*/
396
if ((!is_scan) && chan == AH_PRIVATE(ah)->ah_curchan) {
397
h = &AH_PRIVATE(ah)->nf_cal_hist;
398
nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
399
} else {
400
/* Fill 0 if valid internal channel is not found */
401
if (ichan == AH_NULL) {
402
OS_MEMZERO(nf_buf, sizeof(nf_buf[0])*HAL_NUM_NF_READINGS);
403
return;
404
}
405
/*
406
* It is okay to treat a HAL_NFCAL_HIST_SMALL struct as if it were a
407
* HAL_NFCAL_HIST_FULL struct, as long as only the index 0 of the
408
* nf_cal_buffer is used (nf_cal_buffer[0][0:HAL_NUM_NF_READINGS-1])
409
*/
410
h = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist;
411
nf_hist_len = HAL_NF_CAL_HIST_LEN_SMALL;
412
}
413
#endif
414
/* Get most recently updated values from nf cal history buffer */
415
recent_nf_index =
416
(h->base.curr_index) ? h->base.curr_index - 1 : nf_hist_len - 1;
417
418
for (i = 0; i < HAL_NUM_NF_READINGS; i++) {
419
/* Fill 0 for unsupported chains */
420
if (!(rx_chainmask & (1 << i))) {
421
nf_buf[i] = 0;
422
continue;
423
}
424
nf_buf[i] = h->nf_cal_buffer[recent_nf_index][i];
425
}
426
}
427
428
/*
429
* Return the current NF value in register.
430
* If the current NF cal is not completed, return 0.
431
*/
432
int16_t ar9300_get_nf_from_reg(struct ath_hal *ah, struct ieee80211_channel *chan, int wait_time)
433
{
434
int16_t nfarray[HAL_NUM_NF_READINGS] = {0};
435
int is_2g = 0;
436
HAL_CHANNEL_INTERNAL *ichan = NULL;
437
438
ichan = ath_hal_checkchannel(ah, chan);
439
if (ichan == NULL)
440
return (0);
441
442
if (wait_time <= 0) {
443
return 0;
444
}
445
446
if (!ath_hal_waitfor(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF, 0, wait_time)) {
447
ath_hal_printf(ah, "%s: NF cal is not complete in %dus", __func__, wait_time);
448
return 0;
449
}
450
is_2g = !! (IS_CHAN_2GHZ(ichan));
451
ar9300_upload_noise_floor(ah, is_2g, nfarray);
452
453
return nfarray[0];
454
}
455
456
/*
457
* Pick up the medium one in the noise floor buffer and update the
458
* corresponding range for valid noise floor values
459
*/
460
static int16_t
461
ar9300_get_nf_hist_mid(struct ath_hal *ah, HAL_NFCAL_HIST_FULL *h, int reading,
462
int hist_len)
463
{
464
int16_t nfval;
465
int16_t sort[HAL_NF_CAL_HIST_LEN_FULL]; /* upper bound for hist_len */
466
int i, j;
467
468
469
for (i = 0; i < hist_len; i++) {
470
sort[i] = h->nf_cal_buffer[i][reading];
471
HALDEBUG(ah, HAL_DEBUG_NFCAL,
472
"nf_cal_buffer[%d][%d] = %d\n", i, reading, (int)sort[i]);
473
}
474
for (i = 0; i < hist_len - 1; i++) {
475
for (j = 1; j < hist_len - i; j++) {
476
if (sort[j] > sort[j - 1]) {
477
nfval = sort[j];
478
sort[j] = sort[j - 1];
479
sort[j - 1] = nfval;
480
}
481
}
482
}
483
nfval = sort[(hist_len - 1) >> 1];
484
485
return nfval;
486
}
487
488
static int16_t ar9300_limit_nf_range(struct ath_hal *ah, int16_t nf)
489
{
490
if (nf < AH9300(ah)->nfp->min) {
491
return AH9300(ah)->nfp->nominal;
492
} else if (nf > AH9300(ah)->nfp->max) {
493
return AH9300(ah)->nfp->max;
494
}
495
return nf;
496
}
497
498
#ifndef ATH_NF_PER_CHAN
499
inline static void
500
ar9300_reset_nf_hist_buff(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
501
{
502
HAL_CHAN_NFCAL_HIST *h = &ichan->nf_cal_hist;
503
HAL_NFCAL_HIST_FULL *home = &AH_PRIVATE(ah)->nf_cal_hist;
504
int i;
505
506
/*
507
* Copy the value for the channel in question into the home-channel
508
* NF history buffer. The channel NF is probably a value filled in by
509
* a prior background channel scan, but if no scan has been done then
510
* it is the nominal noise floor filled in by ath_hal_init_NF_buffer
511
* for this chip and the channel's band.
512
* Replicate this channel NF into all entries of the home-channel NF
513
* history buffer.
514
* If the channel NF was filled in by a channel scan, it has not had
515
* bounds limits applied to it yet - do so now. It is important to
516
* apply bounds limits to the priv_nf value that gets loaded into the
517
* WLAN chip's min_cca_pwr register field. It is also necessary to
518
* apply bounds limits to the nf_cal_buffer[] elements. Since we are
519
* replicating a single NF reading into all nf_cal_buffer elements,
520
* if the single reading were above the CW_INT threshold, the CW_INT
521
* check in ar9300_get_nf would immediately conclude that CW interference
522
* is present, even though we're not supposed to set CW_INT unless
523
* NF values are _consistently_ above the CW_INT threshold.
524
* Applying the bounds limits to the nf_cal_buffer contents fixes this
525
* problem.
526
*/
527
for (i = 0; i < HAL_NUM_NF_READINGS; i ++) {
528
int j;
529
int16_t nf;
530
/*
531
* No need to set curr_index, since it already has a value in
532
* the range [0..HAL_NF_CAL_HIST_LEN_FULL), and all nf_cal_buffer
533
* values will be the same.
534
*/
535
nf = ar9300_limit_nf_range(ah, h->nf_cal_buffer[0][i]);
536
for (j = 0; j < HAL_NF_CAL_HIST_LEN_FULL; j++) {
537
home->nf_cal_buffer[j][i] = nf;
538
}
539
AH_PRIVATE(ah)->nf_cal_hist.base.priv_nf[i] = nf;
540
}
541
}
542
#endif
543
544
/*
545
* Update the noise floor buffer as a ring buffer
546
*/
547
static int16_t
548
ar9300_update_nf_hist_buff(struct ath_hal *ah, HAL_NFCAL_HIST_FULL *h,
549
int16_t *nfarray, int hist_len)
550
{
551
int i, nr;
552
int16_t nf_no_lim_chain0;
553
554
nf_no_lim_chain0 = ar9300_get_nf_hist_mid(ah, h, 0, hist_len);
555
556
HALDEBUG(ah, HAL_DEBUG_NFCAL, "%s[%d] BEFORE\n", __func__, __LINE__);
557
for (nr = 0; nr < HAL_NF_CAL_HIST_LEN_FULL; nr++) {
558
for (i = 0; i < HAL_NUM_NF_READINGS; i++) {
559
HALDEBUG(ah, HAL_DEBUG_NFCAL,
560
"nf_cal_buffer[%d][%d] = %d\n",
561
nr, i, (int)h->nf_cal_buffer[nr][i]);
562
}
563
}
564
for (i = 0; i < HAL_NUM_NF_READINGS; i++) {
565
h->nf_cal_buffer[h->base.curr_index][i] = nfarray[i];
566
h->base.priv_nf[i] = ar9300_limit_nf_range(
567
ah, ar9300_get_nf_hist_mid(ah, h, i, hist_len));
568
}
569
HALDEBUG(ah, HAL_DEBUG_NFCAL, "%s[%d] AFTER\n", __func__, __LINE__);
570
for (nr = 0; nr < HAL_NF_CAL_HIST_LEN_FULL; nr++) {
571
for (i = 0; i < HAL_NUM_NF_READINGS; i++) {
572
HALDEBUG(ah, HAL_DEBUG_NFCAL,
573
"nf_cal_buffer[%d][%d] = %d\n",
574
nr, i, (int)h->nf_cal_buffer[nr][i]);
575
}
576
}
577
578
if (++h->base.curr_index >= hist_len) {
579
h->base.curr_index = 0;
580
}
581
582
return nf_no_lim_chain0;
583
}
584
585
#ifdef UNUSED
586
static HAL_BOOL
587
get_noise_floor_thresh(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *chan,
588
int16_t *nft)
589
{
590
struct ath_hal_9300 *ahp = AH9300(ah);
591
592
593
switch (chan->channel_flags & CHANNEL_ALL_NOTURBO) {
594
case CHANNEL_A:
595
case CHANNEL_A_HT20:
596
case CHANNEL_A_HT40PLUS:
597
case CHANNEL_A_HT40MINUS:
598
*nft = (int8_t)ar9300_eeprom_get(ahp, EEP_NFTHRESH_5);
599
break;
600
case CHANNEL_B:
601
case CHANNEL_G:
602
case CHANNEL_G_HT20:
603
case CHANNEL_G_HT40PLUS:
604
case CHANNEL_G_HT40MINUS:
605
*nft = (int8_t)ar9300_eeprom_get(ahp, EEP_NFTHRESH_2);
606
break;
607
default:
608
HALDEBUG(ah, HAL_DEBUG_CHANNEL, "%s: invalid channel flags 0x%x\n",
609
__func__, chan->channel_flags);
610
return AH_FALSE;
611
}
612
return AH_TRUE;
613
}
614
#endif
615
616
/*
617
* Read the NF and check it against the noise floor threshhold
618
*/
619
#define IS(_c, _f) (((_c)->channel_flags & _f) || 0)
620
static int
621
ar9300_store_new_nf(struct ath_hal *ah, struct ieee80211_channel *chan,
622
int is_scan)
623
{
624
// struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
625
int nf_hist_len;
626
int16_t nf_no_lim;
627
int16_t nfarray[HAL_NUM_NF_READINGS] = {0};
628
HAL_NFCAL_HIST_FULL *h;
629
int is_2g = 0;
630
HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
631
struct ath_hal_9300 *ahp = AH9300(ah);
632
633
if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
634
u_int32_t tsf32, nf_cal_dur_tsf;
635
/*
636
* The reason the NF calibration did not complete may just be that
637
* not enough time has passed since the NF calibration was started,
638
* because under certain conditions (when first moving to a new
639
* channel) the NF calibration may be checked very repeatedly.
640
* Or, there may be CW interference keeping the NF calibration
641
* from completing. Check the delta time between when the NF
642
* calibration was started and now to see whether the NF calibration
643
* should have already completed (but hasn't, probably due to CW
644
* interference), or hasn't had enough time to finish yet.
645
*/
646
/*
647
* AH_NF_CAL_DUR_MAX_TSF - A conservative maximum time that the
648
* HW should need to finish a NF calibration. If the HW
649
* does not complete a NF calibration within this time period,
650
* there must be a problem - probably CW interference.
651
* AH_NF_CAL_PERIOD_MAX_TSF - A conservative maximum time between
652
* check of the HW's NF calibration being finished.
653
* If the difference between the current TSF and the TSF
654
* recorded when the NF calibration started is larger than this
655
* value, the TSF must have been reset.
656
* In general, we expect the TSF to only be reset during
657
* regular operation for STAs, not for APs. However, an
658
* AP's TSF could be reset when joining an IBSS.
659
* There's an outside chance that this could result in the
660
* CW_INT flag being erroneously set, if the TSF adjustment
661
* is smaller than AH_NF_CAL_PERIOD_MAX_TSF but larger than
662
* AH_NF_CAL_DUR_TSF. However, even if this does happen,
663
* it shouldn't matter, as the IBSS case shouldn't be
664
* concerned about CW_INT.
665
*/
666
/* AH_NF_CAL_DUR_TSF - 90 sec in usec units */
667
#define AH_NF_CAL_DUR_TSF (90 * 1000 * 1000)
668
/* AH_NF_CAL_PERIOD_MAX_TSF - 180 sec in usec units */
669
#define AH_NF_CAL_PERIOD_MAX_TSF (180 * 1000 * 1000)
670
/* wraparound handled by using unsigned values */
671
tsf32 = ar9300_get_tsf32(ah);
672
nf_cal_dur_tsf = tsf32 - AH9300(ah)->nf_tsf32;
673
if (nf_cal_dur_tsf > AH_NF_CAL_PERIOD_MAX_TSF) {
674
/*
675
* The TSF must have gotten reset during the NF cal -
676
* just reset the NF TSF timestamp, so the next time
677
* this function is called, the timestamp comparison
678
* will be valid.
679
*/
680
AH9300(ah)->nf_tsf32 = tsf32;
681
} else if (nf_cal_dur_tsf > AH_NF_CAL_DUR_TSF) {
682
HALDEBUG(ah, HAL_DEBUG_CALIBRATE,
683
"%s: NF did not complete in calibration window\n", __func__);
684
/* the NF incompletion is probably due to CW interference */
685
chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
686
}
687
return 0; /* HW's NF measurement not finished */
688
}
689
HALDEBUG(ah, HAL_DEBUG_NFCAL,
690
"%s[%d] chan %d\n", __func__, __LINE__, ichan->channel);
691
is_2g = !! IS_CHAN_2GHZ(ichan);
692
ar9300_upload_noise_floor(ah, is_2g, nfarray);
693
694
/* Update the NF buffer for each chain masked by chainmask */
695
#ifdef ATH_NF_PER_CHAN
696
h = &ichan->nf_cal_hist;
697
nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
698
#else
699
if (is_scan) {
700
/*
701
* This channel's NF cal info is just a HAL_NFCAL_HIST_SMALL struct
702
* rather than a HAL_NFCAL_HIST_FULL struct.
703
* As long as we only use the first history element of nf_cal_buffer
704
* (nf_cal_buffer[0][0:HAL_NUM_NF_READINGS-1]), we can use
705
* HAL_NFCAL_HIST_SMALL and HAL_NFCAL_HIST_FULL interchangeably.
706
*/
707
h = (HAL_NFCAL_HIST_FULL *) &ichan->nf_cal_hist;
708
nf_hist_len = HAL_NF_CAL_HIST_LEN_SMALL;
709
} else {
710
h = &AH_PRIVATE(ah)->nf_cal_hist;
711
nf_hist_len = HAL_NF_CAL_HIST_LEN_FULL;
712
}
713
#endif
714
715
/*
716
* nf_no_lim = median value from NF history buffer without bounds limits,
717
* priv_nf = median value from NF history buffer with bounds limits.
718
*/
719
nf_no_lim = ar9300_update_nf_hist_buff(ah, h, nfarray, nf_hist_len);
720
ichan->rawNoiseFloor = h->base.priv_nf[0];
721
722
/* check if there is interference */
723
// ichan->channel_flags &= (~CHANNEL_CW_INT);
724
/*
725
* Use AR9300_EMULATION to check for emulation purpose as PCIE Device ID
726
* 0xABCD is recognized as valid Osprey as WAR in some EVs.
727
*/
728
if (nf_no_lim > ahp->nfp->nominal + ahp->nf_cw_int_delta) {
729
/*
730
* Since this CW interference check is being applied to the
731
* median element of the NF history buffer, this indicates that
732
* the CW interference is persistent. A single high NF reading
733
* will not show up in the median, and thus will not cause the
734
* CW_INT flag to be set.
735
*/
736
HALDEBUG(ah, HAL_DEBUG_NFCAL,
737
"%s: NF Cal: CW interferer detected through NF: %d\n",
738
__func__, nf_no_lim);
739
chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
740
}
741
return 1; /* HW's NF measurement finished */
742
}
743
#undef IS
744
745
static inline void
746
ar9300_get_delta_slope_values(struct ath_hal *ah, u_int32_t coef_scaled,
747
u_int32_t *coef_mantissa, u_int32_t *coef_exponent)
748
{
749
u_int32_t coef_exp, coef_man;
750
751
/*
752
* ALGO -> coef_exp = 14-floor(log2(coef));
753
* floor(log2(x)) is the highest set bit position
754
*/
755
for (coef_exp = 31; coef_exp > 0; coef_exp--) {
756
if ((coef_scaled >> coef_exp) & 0x1) {
757
break;
758
}
759
}
760
/* A coef_exp of 0 is a legal bit position but an unexpected coef_exp */
761
HALASSERT(coef_exp);
762
coef_exp = 14 - (coef_exp - COEF_SCALE_S);
763
764
765
/*
766
* ALGO -> coef_man = floor(coef* 2^coef_exp+0.5);
767
* The coefficient is already shifted up for scaling
768
*/
769
coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
770
771
*coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
772
*coef_exponent = coef_exp - 16;
773
}
774
775
#define MAX_ANALOG_START 319 /* XXX */
776
777
/*
778
* Delta slope coefficient computation.
779
* Required for OFDM operation.
780
*/
781
static void
782
ar9300_set_delta_slope(struct ath_hal *ah, struct ieee80211_channel *chan)
783
{
784
u_int32_t coef_scaled, ds_coef_exp, ds_coef_man;
785
u_int32_t fclk = COEFF; /* clock * 2.5 */
786
787
u_int32_t clock_mhz_scaled = 0x1000000 * fclk;
788
CHAN_CENTERS centers;
789
790
/*
791
* half and quarter rate can divide the scaled clock by 2 or 4
792
* scale for selected channel bandwidth
793
*/
794
if (IEEE80211_IS_CHAN_HALF(chan)) {
795
clock_mhz_scaled = clock_mhz_scaled >> 1;
796
} else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
797
clock_mhz_scaled = clock_mhz_scaled >> 2;
798
}
799
800
/*
801
* ALGO -> coef = 1e8/fcarrier*fclock/40;
802
* scaled coef to provide precision for this floating calculation
803
*/
804
ar9300_get_channel_centers(ah, chan, &centers);
805
coef_scaled = clock_mhz_scaled / centers.synth_center;
806
807
ar9300_get_delta_slope_values(ah, coef_scaled, &ds_coef_man, &ds_coef_exp);
808
809
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
810
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
811
812
/*
813
* For Short GI,
814
* scaled coeff is 9/10 that of normal coeff
815
*/
816
coef_scaled = (9 * coef_scaled) / 10;
817
818
ar9300_get_delta_slope_values(ah, coef_scaled, &ds_coef_man, &ds_coef_exp);
819
820
/* for short gi */
821
OS_REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA, AR_PHY_SGI_DSC_MAN, ds_coef_man);
822
OS_REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA, AR_PHY_SGI_DSC_EXP, ds_coef_exp);
823
}
824
825
#define IS(_c, _f) (IEEE80211_IS_ ## _f(_c))
826
827
/*
828
* XXX FreeBSD: This should be turned into something generic in ath_hal!
829
*/
830
HAL_CHANNEL_INTERNAL *
831
ar9300_check_chan(struct ath_hal *ah, const struct ieee80211_channel *chan)
832
{
833
834
if (chan == NULL) {
835
return AH_NULL;
836
}
837
838
if ((IS(chan, CHAN_2GHZ) ^ IS(chan, CHAN_5GHZ)) == 0) {
839
HALDEBUG(ah, HAL_DEBUG_CHANNEL,
840
"%s: invalid channel %u/0x%x; not marked as 2GHz or 5GHz\n",
841
__func__, chan->ic_freq , chan->ic_flags);
842
return AH_NULL;
843
}
844
845
/*
846
* FreeBSD sets multiple flags, so this will fail.
847
*/
848
#if 0
849
if ((IS(chan, CHAN_OFDM) ^ IS(chan, CHAN_CCK) ^ IS(chan, CHAN_DYN) ^
850
IS(chan, CHAN_HT20) ^ IS(chan, CHAN_HT40U) ^
851
IS(chan, CHAN_HT40D)) == 0)
852
{
853
HALDEBUG(ah, HAL_DEBUG_CHANNEL,
854
"%s: invalid channel %u/0x%x; not marked as "
855
"OFDM or CCK or DYN or HT20 or HT40PLUS or HT40MINUS\n",
856
__func__, chan->ic_freq , chan->ic_flags);
857
return AH_NULL;
858
}
859
#endif
860
861
return (ath_hal_checkchannel(ah, chan));
862
}
863
#undef IS
864
865
static void
866
ar9300_set_11n_regs(struct ath_hal *ah, struct ieee80211_channel *chan,
867
HAL_HT_MACMODE macmode)
868
{
869
u_int32_t phymode;
870
// struct ath_hal_9300 *ahp = AH9300(ah);
871
u_int32_t enable_dac_fifo;
872
873
/* XXX */
874
enable_dac_fifo =
875
OS_REG_READ(ah, AR_PHY_GEN_CTRL) & AR_PHY_GC_ENABLE_DAC_FIFO;
876
877
/* Enable 11n HT, 20 MHz */
878
phymode =
879
AR_PHY_GC_HT_EN | AR_PHY_GC_SINGLE_HT_LTF1 | AR_PHY_GC_SHORT_GI_40
880
| enable_dac_fifo;
881
/* Configure baseband for dynamic 20/40 operation */
882
if (IEEE80211_IS_CHAN_HT40(chan)) {
883
phymode |= AR_PHY_GC_DYN2040_EN;
884
/* Configure control (primary) channel at +-10MHz */
885
if (IEEE80211_IS_CHAN_HT40U(chan)) {
886
phymode |= AR_PHY_GC_DYN2040_PRI_CH;
887
}
888
889
#if 0
890
/* Configure 20/25 spacing */
891
if (ahp->ah_ext_prot_spacing == HAL_HT_EXTPROTSPACING_25) {
892
phymode |= AR_PHY_GC_DYN2040_EXT_CH;
893
}
894
#endif
895
}
896
897
/* make sure we preserve INI settings */
898
phymode |= OS_REG_READ(ah, AR_PHY_GEN_CTRL);
899
900
/* EV 62881/64991 - turn off Green Field detection for Maverick STA beta */
901
phymode &= ~AR_PHY_GC_GF_DETECT_EN;
902
903
OS_REG_WRITE(ah, AR_PHY_GEN_CTRL, phymode);
904
905
/* Set IFS timing for half/quarter rates */
906
if (IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan)) {
907
u_int32_t modeselect = OS_REG_READ(ah, AR_PHY_MODE);
908
909
if (IEEE80211_IS_CHAN_HALF(chan)) {
910
modeselect |= AR_PHY_MS_HALF_RATE;
911
} else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
912
modeselect |= AR_PHY_MS_QUARTER_RATE;
913
}
914
OS_REG_WRITE(ah, AR_PHY_MODE, modeselect);
915
916
ar9300_set_ifs_timing(ah, chan);
917
OS_REG_RMW_FIELD(
918
ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_CF_OVERLAP_WINDOW, 0x3);
919
}
920
921
/* Configure MAC for 20/40 operation */
922
ar9300_set_11n_mac2040(ah, macmode);
923
924
/* global transmit timeout (25 TUs default)*/
925
/* XXX - put this elsewhere??? */
926
OS_REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
927
928
/* carrier sense timeout */
929
OS_REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
930
}
931
932
/*
933
* Spur mitigation for MRC CCK
934
*/
935
static void
936
ar9300_spur_mitigate_mrc_cck(struct ath_hal *ah, struct ieee80211_channel *chan)
937
{
938
int i;
939
/* spur_freq_for_osprey - hardcoded by Systems team for now. */
940
u_int32_t spur_freq_for_osprey[4] = { 2420, 2440, 2464, 2480 };
941
u_int32_t spur_freq_for_jupiter[2] = { 2440, 2464};
942
int cur_bb_spur, negative = 0, cck_spur_freq;
943
u_int8_t* spur_fbin_ptr = NULL;
944
int synth_freq;
945
int range = 10;
946
int max_spurcounts = OSPREY_EEPROM_MODAL_SPURS;
947
HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
948
949
/*
950
* Need to verify range +/- 10 MHz in control channel, otherwise spur
951
* is out-of-band and can be ignored.
952
*/
953
if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) ||
954
AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
955
spur_fbin_ptr = ar9300_eeprom_get_spur_chans_ptr(ah, 1);
956
if (spur_fbin_ptr[0] == 0) {
957
return; /* No spur in the mode */
958
}
959
if (IEEE80211_IS_CHAN_HT40(chan)) {
960
range = 19;
961
if (OS_REG_READ_FIELD(ah, AR_PHY_GEN_CTRL, AR_PHY_GC_DYN2040_PRI_CH)
962
== 0x0)
963
{
964
synth_freq = ichan->channel + 10;
965
} else {
966
synth_freq = ichan->channel - 10;
967
}
968
} else {
969
range = 10;
970
synth_freq = ichan->channel;
971
}
972
} else if(AR_SREV_JUPITER(ah)) {
973
range = 5;
974
max_spurcounts = 2; /* Hardcoded by Jupiter Systems team for now. */
975
synth_freq = ichan->channel;
976
} else {
977
range = 10;
978
max_spurcounts = 4; /* Hardcoded by Osprey Systems team for now. */
979
synth_freq = ichan->channel;
980
}
981
982
for (i = 0; i < max_spurcounts; i++) {
983
negative = 0;
984
985
if (AR_SREV_HORNET(ah) || AR_SREV_POSEIDON(ah) ||
986
AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
987
cur_bb_spur =
988
FBIN2FREQ(spur_fbin_ptr[i], HAL_FREQ_BAND_2GHZ) - synth_freq;
989
} else if(AR_SREV_JUPITER(ah)) {
990
cur_bb_spur = spur_freq_for_jupiter[i] - synth_freq;
991
} else {
992
cur_bb_spur = spur_freq_for_osprey[i] - synth_freq;
993
}
994
995
if (cur_bb_spur < 0) {
996
negative = 1;
997
cur_bb_spur = -cur_bb_spur;
998
}
999
if (cur_bb_spur < range) {
1000
cck_spur_freq = (int)((cur_bb_spur << 19) / 11);
1001
if (negative == 1) {
1002
cck_spur_freq = -cck_spur_freq;
1003
}
1004
cck_spur_freq = cck_spur_freq & 0xfffff;
1005
/*OS_REG_WRITE_field(ah, BB_agc_control.ycok_max, 0x7);*/
1006
OS_REG_RMW_FIELD(ah,
1007
AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_YCOK_MAX, 0x7);
1008
/*OS_REG_WRITE_field(ah, BB_cck_spur_mit.spur_rssi_thr, 0x7f);*/
1009
OS_REG_RMW_FIELD(ah,
1010
AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR, 0x7f);
1011
/*OS_REG_WRITE(ah, BB_cck_spur_mit.spur_filter_type, 0x2);*/
1012
OS_REG_RMW_FIELD(ah,
1013
AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE, 0x2);
1014
/*OS_REG_WRITE(ah, BB_cck_spur_mit.use_cck_spur_mit, 0x1);*/
1015
OS_REG_RMW_FIELD(ah,
1016
AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT, 0x1);
1017
/*OS_REG_WRITE(ah, BB_cck_spur_mit.cck_spur_freq, cck_spur_freq);*/
1018
OS_REG_RMW_FIELD(ah,
1019
AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ,
1020
cck_spur_freq);
1021
return;
1022
}
1023
}
1024
1025
/*OS_REG_WRITE(ah, BB_agc_control.ycok_max, 0x5);*/
1026
OS_REG_RMW_FIELD(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_YCOK_MAX, 0x5);
1027
/*OS_REG_WRITE(ah, BB_cck_spur_mit.use_cck_spur_mit, 0x0);*/
1028
OS_REG_RMW_FIELD(ah,
1029
AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT, 0x0);
1030
/*OS_REG_WRITE(ah, BB_cck_spur_mit.cck_spur_freq, 0x0);*/
1031
OS_REG_RMW_FIELD(ah,
1032
AR_PHY_CCK_SPUR_MIT, AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ, 0x0);
1033
}
1034
1035
/* Spur mitigation for OFDM */
1036
static void
1037
ar9300_spur_mitigate_ofdm(struct ath_hal *ah, struct ieee80211_channel *chan)
1038
{
1039
int synth_freq;
1040
int range = 10;
1041
int freq_offset = 0;
1042
int spur_freq_sd = 0;
1043
int spur_subchannel_sd = 0;
1044
int spur_delta_phase = 0;
1045
int mask_index = 0;
1046
int i;
1047
int mode;
1048
u_int8_t* spur_chans_ptr;
1049
struct ath_hal_9300 *ahp;
1050
ahp = AH9300(ah);
1051
HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
1052
1053
if (IS_CHAN_5GHZ(ichan)) {
1054
spur_chans_ptr = ar9300_eeprom_get_spur_chans_ptr(ah, 0);
1055
mode = 0;
1056
} else {
1057
spur_chans_ptr = ar9300_eeprom_get_spur_chans_ptr(ah, 1);
1058
mode = 1;
1059
}
1060
1061
if (IEEE80211_IS_CHAN_HT40(chan)) {
1062
range = 19;
1063
if (OS_REG_READ_FIELD(ah, AR_PHY_GEN_CTRL, AR_PHY_GC_DYN2040_PRI_CH)
1064
== 0x0)
1065
{
1066
synth_freq = ichan->channel - 10;
1067
} else {
1068
synth_freq = ichan->channel + 10;
1069
}
1070
} else {
1071
range = 10;
1072
synth_freq = ichan->channel;
1073
}
1074
1075
/* Clean all spur register fields */
1076
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0);
1077
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING11, AR_PHY_TIMING11_SPUR_FREQ_SD, 0);
1078
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING11, AR_PHY_TIMING11_SPUR_DELTA_PHASE, 0);
1079
OS_REG_RMW_FIELD(ah,
1080
AR_PHY_SFCORR_EXT, AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, 0);
1081
OS_REG_RMW_FIELD(ah,
1082
AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0);
1083
OS_REG_RMW_FIELD(ah,
1084
AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0);
1085
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0);
1086
OS_REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 0);
1087
OS_REG_RMW_FIELD(ah,
1088
AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 0);
1089
OS_REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0);
1090
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0);
1091
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0);
1092
OS_REG_RMW_FIELD(ah,
1093
AR_PHY_PILOT_SPUR_MASK, AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, 0);
1094
OS_REG_RMW_FIELD(ah,
1095
AR_PHY_SPUR_MASK_A, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, 0);
1096
OS_REG_RMW_FIELD(ah,
1097
AR_PHY_CHAN_SPUR_MASK, AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, 0);
1098
OS_REG_RMW_FIELD(ah,
1099
AR_PHY_PILOT_SPUR_MASK, AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0);
1100
OS_REG_RMW_FIELD(ah,
1101
AR_PHY_CHAN_SPUR_MASK, AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0);
1102
OS_REG_RMW_FIELD(ah,
1103
AR_PHY_SPUR_MASK_A, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0);
1104
OS_REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0);
1105
1106
i = 0;
1107
while (spur_chans_ptr[i] && i < 5) {
1108
freq_offset = FBIN2FREQ(spur_chans_ptr[i], mode) - synth_freq;
1109
if (abs(freq_offset) < range) {
1110
/*
1111
printf(
1112
"Spur Mitigation for OFDM: Synth Frequency = %d, "
1113
"Spur Frequency = %d\n",
1114
synth_freq, FBIN2FREQ(spur_chans_ptr[i], mode));
1115
*/
1116
if (IEEE80211_IS_CHAN_HT40(chan)) {
1117
if (freq_offset < 0) {
1118
if (OS_REG_READ_FIELD(
1119
ah, AR_PHY_GEN_CTRL, AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
1120
{
1121
spur_subchannel_sd = 1;
1122
} else {
1123
spur_subchannel_sd = 0;
1124
}
1125
spur_freq_sd = ((freq_offset + 10) << 9) / 11;
1126
} else {
1127
if (OS_REG_READ_FIELD(ah,
1128
AR_PHY_GEN_CTRL, AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
1129
{
1130
spur_subchannel_sd = 0;
1131
} else {
1132
spur_subchannel_sd = 1;
1133
}
1134
spur_freq_sd = ((freq_offset - 10) << 9) / 11;
1135
}
1136
spur_delta_phase = (freq_offset << 17) / 5;
1137
} else {
1138
spur_subchannel_sd = 0;
1139
spur_freq_sd = (freq_offset << 9) / 11;
1140
spur_delta_phase = (freq_offset << 18) / 5;
1141
}
1142
spur_freq_sd = spur_freq_sd & 0x3ff;
1143
spur_delta_phase = spur_delta_phase & 0xfffff;
1144
/*
1145
printf(
1146
"spur_subchannel_sd = %d, spur_freq_sd = 0x%x, "
1147
"spur_delta_phase = 0x%x\n", spur_subchannel_sd,
1148
spur_freq_sd, spur_delta_phase);
1149
*/
1150
1151
/* OFDM Spur mitigation */
1152
OS_REG_RMW_FIELD(ah,
1153
AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0x1);
1154
OS_REG_RMW_FIELD(ah,
1155
AR_PHY_TIMING11, AR_PHY_TIMING11_SPUR_FREQ_SD, spur_freq_sd);
1156
OS_REG_RMW_FIELD(ah,
1157
AR_PHY_TIMING11, AR_PHY_TIMING11_SPUR_DELTA_PHASE,
1158
spur_delta_phase);
1159
OS_REG_RMW_FIELD(ah,
1160
AR_PHY_SFCORR_EXT, AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD,
1161
spur_subchannel_sd);
1162
OS_REG_RMW_FIELD(ah,
1163
AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0x1);
1164
OS_REG_RMW_FIELD(ah,
1165
AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR,
1166
0x1);
1167
OS_REG_RMW_FIELD(ah,
1168
AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0x1);
1169
OS_REG_RMW_FIELD(ah,
1170
AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH, 34);
1171
OS_REG_RMW_FIELD(ah,
1172
AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 1);
1173
1174
/*
1175
* Do not subtract spur power from noise floor for wasp.
1176
* This causes the maximum client test (on Veriwave) to fail
1177
* when run on spur channel (2464 MHz).
1178
* Refer to ev#82746 and ev#82744.
1179
*/
1180
if (!AR_SREV_WASP(ah) && (OS_REG_READ_FIELD(ah, AR_PHY_MODE,
1181
AR_PHY_MODE_DYNAMIC) == 0x1)) {
1182
OS_REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
1183
AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 1);
1184
}
1185
1186
mask_index = (freq_offset << 4) / 5;
1187
if (mask_index < 0) {
1188
mask_index = mask_index - 1;
1189
}
1190
mask_index = mask_index & 0x7f;
1191
/*printf("Bin 0x%x\n", mask_index);*/
1192
1193
OS_REG_RMW_FIELD(ah,
1194
AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0x1);
1195
OS_REG_RMW_FIELD(ah,
1196
AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0x1);
1197
OS_REG_RMW_FIELD(ah,
1198
AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0x1);
1199
OS_REG_RMW_FIELD(ah,
1200
AR_PHY_PILOT_SPUR_MASK,
1201
AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, mask_index);
1202
OS_REG_RMW_FIELD(ah,
1203
AR_PHY_SPUR_MASK_A, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A,
1204
mask_index);
1205
OS_REG_RMW_FIELD(ah,
1206
AR_PHY_CHAN_SPUR_MASK,
1207
AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, mask_index);
1208
OS_REG_RMW_FIELD(ah,
1209
AR_PHY_PILOT_SPUR_MASK, AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A,
1210
0xc);
1211
OS_REG_RMW_FIELD(ah,
1212
AR_PHY_CHAN_SPUR_MASK, AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A,
1213
0xc);
1214
OS_REG_RMW_FIELD(ah,
1215
AR_PHY_SPUR_MASK_A, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0xa0);
1216
OS_REG_RMW_FIELD(ah,
1217
AR_PHY_SPUR_REG, AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0xff);
1218
/*
1219
printf("BB_timing_control_4 = 0x%x\n",
1220
OS_REG_READ(ah, AR_PHY_TIMING4));
1221
printf("BB_timing_control_11 = 0x%x\n",
1222
OS_REG_READ(ah, AR_PHY_TIMING11));
1223
printf("BB_ext_chan_scorr_thr = 0x%x\n",
1224
OS_REG_READ(ah, AR_PHY_SFCORR_EXT));
1225
printf("BB_spur_mask_controls = 0x%x\n",
1226
OS_REG_READ(ah, AR_PHY_SPUR_REG));
1227
printf("BB_pilot_spur_mask = 0x%x\n",
1228
OS_REG_READ(ah, AR_PHY_PILOT_SPUR_MASK));
1229
printf("BB_chan_spur_mask = 0x%x\n",
1230
OS_REG_READ(ah, AR_PHY_CHAN_SPUR_MASK));
1231
printf("BB_vit_spur_mask_A = 0x%x\n",
1232
OS_REG_READ(ah, AR_PHY_SPUR_MASK_A));
1233
*/
1234
break;
1235
}
1236
i++;
1237
}
1238
}
1239
1240
1241
/*
1242
* Convert to baseband spur frequency given input channel frequency
1243
* and compute register settings below.
1244
*/
1245
static void
1246
ar9300_spur_mitigate(struct ath_hal *ah, struct ieee80211_channel *chan)
1247
{
1248
ar9300_spur_mitigate_ofdm(ah, chan);
1249
ar9300_spur_mitigate_mrc_cck(ah, chan);
1250
}
1251
1252
/**************************************************************
1253
* ar9300_channel_change
1254
* Assumes caller wants to change channel, and not reset.
1255
*/
1256
static inline HAL_BOOL
1257
ar9300_channel_change(struct ath_hal *ah, struct ieee80211_channel *chan,
1258
HAL_CHANNEL_INTERNAL *ichan, HAL_HT_MACMODE macmode)
1259
{
1260
1261
u_int32_t synth_delay, qnum;
1262
struct ath_hal_9300 *ahp = AH9300(ah);
1263
1264
/* TX must be stopped by now */
1265
for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
1266
if (ar9300_num_tx_pending(ah, qnum)) {
1267
HALDEBUG(ah, HAL_DEBUG_QUEUE,
1268
"%s: Transmit frames pending on queue %d\n", __func__, qnum);
1269
HALASSERT(0);
1270
return AH_FALSE;
1271
}
1272
}
1273
1274
1275
/*
1276
* Kill last Baseband Rx Frame - Request analog bus grant
1277
*/
1278
OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
1279
if (!ath_hal_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
1280
AR_PHY_RFBUS_GRANT_EN))
1281
{
1282
HALDEBUG(ah, HAL_DEBUG_PHYIO,
1283
"%s: Could not kill baseband RX\n", __func__);
1284
return AH_FALSE;
1285
}
1286
1287
1288
/* Setup 11n MAC/Phy mode registers */
1289
ar9300_set_11n_regs(ah, chan, macmode);
1290
1291
/*
1292
* Change the synth
1293
*/
1294
if (!ahp->ah_rf_hal.set_channel(ah, chan)) {
1295
HALDEBUG(ah, HAL_DEBUG_CHANNEL, "%s: failed to set channel\n", __func__);
1296
return AH_FALSE;
1297
}
1298
1299
/*
1300
* Some registers get reinitialized during ATH_INI_POST INI programming.
1301
*/
1302
ar9300_init_user_settings(ah);
1303
1304
/*
1305
* Setup the transmit power values.
1306
*
1307
* After the public to private hal channel mapping, ichan contains the
1308
* valid regulatory power value.
1309
* ath_hal_getctl and ath_hal_getantennaallowed look up ichan from chan.
1310
*/
1311
if (ar9300_eeprom_set_transmit_power(
1312
ah, &ahp->ah_eeprom, chan, ath_hal_getctl(ah, chan),
1313
ath_hal_getantennaallowed(ah, chan),
1314
ath_hal_get_twice_max_regpower(AH_PRIVATE(ah), ichan, chan),
1315
AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit)) != HAL_OK)
1316
{
1317
HALDEBUG(ah, HAL_DEBUG_EEPROM,
1318
"%s: error init'ing transmit power\n", __func__);
1319
return AH_FALSE;
1320
}
1321
1322
/*
1323
* Release the RFBus Grant.
1324
*/
1325
OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
1326
1327
/*
1328
* Write spur immunity and delta slope for OFDM enabled modes (A, G, Turbo)
1329
*/
1330
if (IEEE80211_IS_CHAN_OFDM(chan) || IEEE80211_IS_CHAN_HT(chan)) {
1331
ar9300_set_delta_slope(ah, chan);
1332
} else {
1333
/* Set to Ini default */
1334
OS_REG_WRITE(ah, AR_PHY_TIMING3, 0x9c0a9f6b);
1335
OS_REG_WRITE(ah, AR_PHY_SGI_DELTA, 0x00046384);
1336
}
1337
1338
ar9300_spur_mitigate(ah, chan);
1339
1340
1341
/*
1342
* Wait for the frequency synth to settle (synth goes on via PHY_ACTIVE_EN).
1343
* Read the phy active delay register. Value is in 100ns increments.
1344
*/
1345
synth_delay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
1346
if (IEEE80211_IS_CHAN_CCK(chan)) {
1347
synth_delay = (4 * synth_delay) / 22;
1348
} else {
1349
synth_delay /= 10;
1350
}
1351
1352
OS_DELAY(synth_delay + BASE_ACTIVATE_DELAY);
1353
1354
/*
1355
* Do calibration.
1356
*/
1357
1358
return AH_TRUE;
1359
}
1360
1361
void
1362
ar9300_set_operating_mode(struct ath_hal *ah, int opmode)
1363
{
1364
u_int32_t val;
1365
1366
val = OS_REG_READ(ah, AR_STA_ID1);
1367
val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
1368
switch (opmode) {
1369
case HAL_M_HOSTAP:
1370
OS_REG_WRITE(ah, AR_STA_ID1,
1371
val | AR_STA_ID1_STA_AP | AR_STA_ID1_KSRCH_MODE);
1372
OS_REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1373
break;
1374
case HAL_M_IBSS:
1375
OS_REG_WRITE(ah, AR_STA_ID1,
1376
val | AR_STA_ID1_ADHOC | AR_STA_ID1_KSRCH_MODE);
1377
OS_REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1378
break;
1379
case HAL_M_STA:
1380
case HAL_M_MONITOR:
1381
OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
1382
break;
1383
}
1384
}
1385
1386
/* XXX need the logic for Osprey */
1387
void
1388
ar9300_init_pll(struct ath_hal *ah, struct ieee80211_channel *chan)
1389
{
1390
u_int32_t pll;
1391
u_int8_t clk_25mhz = AH9300(ah)->clk_25mhz;
1392
HAL_CHANNEL_INTERNAL *ichan = NULL;
1393
1394
if (chan)
1395
ichan = ath_hal_checkchannel(ah, chan);
1396
1397
if (AR_SREV_HORNET(ah)) {
1398
if (clk_25mhz) {
1399
/* Hornet uses PLL_CONTROL_2. Xtal is 25MHz for Hornet.
1400
* REFDIV set to 0x1.
1401
* $xtal_freq = 25;
1402
* $PLL2_div = (704/$xtal_freq); # 176 * 4 = 704.
1403
* MAC and BB run at 176 MHz.
1404
* $PLL2_divint = int($PLL2_div);
1405
* $PLL2_divfrac = $PLL2_div - $PLL2_divint;
1406
* $PLL2_divfrac = int($PLL2_divfrac * 0x4000); # 2^14
1407
* $PLL2_Val = ($PLL2_divint & 0x3f) << 19 | (0x1) << 14 |
1408
* $PLL2_divfrac & 0x3fff;
1409
* Therefore, $PLL2_Val = 0xe04a3d
1410
*/
1411
#define DPLL2_KD_VAL 0x1D
1412
#define DPLL2_KI_VAL 0x06
1413
#define DPLL3_PHASE_SHIFT_VAL 0x1
1414
1415
/* Rewrite DDR PLL2 and PLL3 */
1416
/* program DDR PLL ki and kd value, ki=0x6, kd=0x1d */
1417
OS_REG_WRITE(ah, AR_HORNET_CH0_DDR_DPLL2, 0x18e82f01);
1418
1419
/* program DDR PLL phase_shift to 0x1 */
1420
OS_REG_RMW_FIELD(ah, AR_HORNET_CH0_DDR_DPLL3,
1421
AR_PHY_BB_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
1422
1423
OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
1424
OS_DELAY(1000);
1425
1426
/* program refdiv, nint, frac to RTC register */
1427
OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0xe04a3d);
1428
1429
/* program BB PLL ki and kd value, ki=0x6, kd=0x1d */
1430
OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1431
AR_PHY_BB_DPLL2_KD, DPLL2_KD_VAL);
1432
OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1433
AR_PHY_BB_DPLL2_KI, DPLL2_KI_VAL);
1434
1435
/* program BB PLL phase_shift to 0x1 */
1436
OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL3,
1437
AR_PHY_BB_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
1438
} else { /* 40MHz */
1439
#undef DPLL2_KD_VAL
1440
#undef DPLL2_KI_VAL
1441
#define DPLL2_KD_VAL 0x3D
1442
#define DPLL2_KI_VAL 0x06
1443
/* Rewrite DDR PLL2 and PLL3 */
1444
/* program DDR PLL ki and kd value, ki=0x6, kd=0x3d */
1445
OS_REG_WRITE(ah, AR_HORNET_CH0_DDR_DPLL2, 0x19e82f01);
1446
1447
/* program DDR PLL phase_shift to 0x1 */
1448
OS_REG_RMW_FIELD(ah, AR_HORNET_CH0_DDR_DPLL3,
1449
AR_PHY_BB_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
1450
1451
OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
1452
OS_DELAY(1000);
1453
1454
/* program refdiv, nint, frac to RTC register */
1455
OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666);
1456
1457
/* program BB PLL ki and kd value, ki=0x6, kd=0x3d */
1458
OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1459
AR_PHY_BB_DPLL2_KD, DPLL2_KD_VAL);
1460
OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1461
AR_PHY_BB_DPLL2_KI, DPLL2_KI_VAL);
1462
1463
/* program BB PLL phase_shift to 0x1 */
1464
OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL3,
1465
AR_PHY_BB_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
1466
}
1467
OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c);
1468
OS_DELAY(1000);
1469
} else if (AR_SREV_POSEIDON(ah) || AR_SREV_APHRODITE(ah)) {
1470
OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2, AR_PHY_BB_DPLL2_PLL_PWD, 0x1);
1471
1472
/* program BB PLL ki and kd value, ki=0x4, kd=0x40 */
1473
OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1474
AR_PHY_BB_DPLL2_KD, 0x40);
1475
OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1476
AR_PHY_BB_DPLL2_KI, 0x4);
1477
1478
OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL1,
1479
AR_PHY_BB_DPLL1_REFDIV, 0x5);
1480
OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL1,
1481
AR_PHY_BB_DPLL1_NINI, 0x58);
1482
OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL1,
1483
AR_PHY_BB_DPLL1_NFRAC, 0x0);
1484
1485
OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1486
AR_PHY_BB_DPLL2_OUTDIV, 0x1);
1487
OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1488
AR_PHY_BB_DPLL2_LOCAL_PLL, 0x1);
1489
OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1490
AR_PHY_BB_DPLL2_EN_NEGTRIG, 0x1);
1491
1492
/* program BB PLL phase_shift to 0x6 */
1493
OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL3,
1494
AR_PHY_BB_DPLL3_PHASE_SHIFT, 0x6);
1495
1496
OS_REG_RMW_FIELD(ah, AR_PHY_BB_DPLL2,
1497
AR_PHY_BB_DPLL2_PLL_PWD, 0x0);
1498
OS_DELAY(1000);
1499
1500
OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c);
1501
OS_DELAY(1000);
1502
} else if (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah) || AR_SREV_HONEYBEE(ah)) {
1503
#define SRIF_PLL 1
1504
u_int32_t regdata, pll2_divint, pll2_divfrac;
1505
1506
#ifndef SRIF_PLL
1507
u_int32_t pll2_clkmode;
1508
#endif
1509
1510
#ifdef SRIF_PLL
1511
u_int32_t refdiv;
1512
#endif
1513
if (clk_25mhz) {
1514
#ifndef SRIF_PLL
1515
pll2_divint = 0x1c;
1516
pll2_divfrac = 0xa3d7;
1517
#else
1518
if (AR_SREV_HONEYBEE(ah)) {
1519
pll2_divint = 0x1c;
1520
pll2_divfrac = 0xa3d2;
1521
refdiv = 1;
1522
} else {
1523
pll2_divint = 0x54;
1524
pll2_divfrac = 0x1eb85;
1525
refdiv = 3;
1526
}
1527
#endif
1528
} else {
1529
#ifndef SRIF_PLL
1530
pll2_divint = 0x11;
1531
pll2_divfrac = 0x26666;
1532
#else
1533
if (AR_SREV_WASP(ah)) {
1534
pll2_divint = 88;
1535
pll2_divfrac = 0;
1536
refdiv = 5;
1537
} else {
1538
pll2_divint = 0x11;
1539
pll2_divfrac = 0x26666;
1540
refdiv = 1;
1541
}
1542
#endif
1543
}
1544
#ifndef SRIF_PLL
1545
pll2_clkmode = 0x3d;
1546
#endif
1547
/* PLL programming through SRIF Local Mode */
1548
OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); /* Bypass mode */
1549
OS_DELAY(1000);
1550
do {
1551
regdata = OS_REG_READ(ah, AR_PHY_PLL_MODE);
1552
if (AR_SREV_HONEYBEE(ah)) {
1553
regdata = regdata | (0x1 << 22);
1554
} else {
1555
regdata = regdata | (0x1 << 16);
1556
}
1557
OS_REG_WRITE(ah, AR_PHY_PLL_MODE, regdata); /* PWD_PLL set to 1 */
1558
OS_DELAY(100);
1559
/* override int, frac, refdiv */
1560
#ifndef SRIF_PLL
1561
OS_REG_WRITE(ah, AR_PHY_PLL_CONTROL,
1562
((1 << 27) | (pll2_divint << 18) | pll2_divfrac));
1563
#else
1564
OS_REG_WRITE(ah, AR_PHY_PLL_CONTROL,
1565
((refdiv << 27) | (pll2_divint << 18) | pll2_divfrac));
1566
#endif
1567
OS_DELAY(100);
1568
regdata = OS_REG_READ(ah, AR_PHY_PLL_MODE);
1569
#ifndef SRIF_PLL
1570
regdata = (regdata & 0x80071fff) |
1571
(0x1 << 30) | (0x1 << 13) | (0x6 << 26) | (pll2_clkmode << 19);
1572
#else
1573
if (AR_SREV_WASP(ah)) {
1574
regdata = (regdata & 0x80071fff) |
1575
(0x1 << 30) | (0x1 << 13) | (0x4 << 26) | (0x18 << 19);
1576
} else if (AR_SREV_HONEYBEE(ah)) {
1577
/*
1578
* Kd=10, Ki=2, Outdiv=1, Local PLL=0, Phase Shift=4
1579
*/
1580
regdata = (regdata & 0x01c00fff) |
1581
(0x1 << 31) | (0x2 << 29) | (0xa << 25) | (0x1 << 19) | (0x6 << 12);
1582
} else {
1583
regdata = (regdata & 0x80071fff) |
1584
(0x3 << 30) | (0x1 << 13) | (0x4 << 26) | (0x60 << 19);
1585
}
1586
#endif
1587
/* Ki, Kd, Local PLL, Outdiv */
1588
OS_REG_WRITE(ah, AR_PHY_PLL_MODE, regdata);
1589
regdata = OS_REG_READ(ah, AR_PHY_PLL_MODE);
1590
if (AR_SREV_HONEYBEE(ah)) {
1591
regdata = (regdata & 0xffbfffff);
1592
} else {
1593
regdata = (regdata & 0xfffeffff);
1594
}
1595
OS_REG_WRITE(ah, AR_PHY_PLL_MODE, regdata); /* PWD_PLL set to 0 */
1596
OS_DELAY(1000);
1597
if (AR_SREV_WASP(ah)) {
1598
/* clear do measure */
1599
regdata = OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL3);
1600
regdata &= ~(1 << 30);
1601
OS_REG_WRITE(ah, AR_PHY_PLL_BB_DPLL3, regdata);
1602
OS_DELAY(100);
1603
1604
/* set do measure */
1605
regdata = OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL3);
1606
regdata |= (1 << 30);
1607
OS_REG_WRITE(ah, AR_PHY_PLL_BB_DPLL3, regdata);
1608
1609
/* wait for measure done */
1610
do {
1611
regdata = OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL4);
1612
} while ((regdata & (1 << 3)) == 0);
1613
1614
/* clear do measure */
1615
regdata = OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL3);
1616
regdata &= ~(1 << 30);
1617
OS_REG_WRITE(ah, AR_PHY_PLL_BB_DPLL3, regdata);
1618
1619
/* get measure sqsum dvc */
1620
regdata = (OS_REG_READ(ah, AR_PHY_PLL_BB_DPLL3) & 0x007FFFF8) >> 3;
1621
} else {
1622
break;
1623
}
1624
} while (regdata >= 0x40000);
1625
1626
/* Remove from Bypass mode */
1627
OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c);
1628
OS_DELAY(1000);
1629
} else {
1630
pll = SM(0x5, AR_RTC_PLL_REFDIV);
1631
1632
/* Supposedly not needed on Osprey */
1633
#if 0
1634
if (chan && IS_CHAN_HALF_RATE(chan)) {
1635
pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
1636
} else if (chan && IS_CHAN_QUARTER_RATE(chan)) {
1637
pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
1638
}
1639
#endif
1640
if (ichan && IS_CHAN_5GHZ(ichan)) {
1641
pll |= SM(0x28, AR_RTC_PLL_DIV);
1642
/*
1643
* When doing fast clock, set PLL to 0x142c
1644
*/
1645
if (IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
1646
pll = 0x142c;
1647
}
1648
} else {
1649
pll |= SM(0x2c, AR_RTC_PLL_DIV);
1650
}
1651
1652
OS_REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
1653
}
1654
1655
/* TODO:
1656
* For multi-band owl, switch between bands by reiniting the PLL.
1657
*/
1658
OS_DELAY(RTC_PLL_SETTLE_DELAY);
1659
1660
OS_REG_WRITE(ah, AR_RTC_SLEEP_CLK,
1661
AR_RTC_FORCE_DERIVED_CLK | AR_RTC_PCIE_RST_PWDN_EN);
1662
1663
/* XXX TODO: honeybee? */
1664
if (AR_SREV_WASP(ah) || AR_SREV_SCORPION(ah)) {
1665
if (clk_25mhz) {
1666
OS_REG_WRITE(ah,
1667
AR_RTC_DERIVED_RTC_CLK, (0x17c << 1)); /* 32KHz sleep clk */
1668
OS_REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
1669
OS_REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae);
1670
} else {
1671
OS_REG_WRITE(ah,
1672
AR_RTC_DERIVED_RTC_CLK, (0x261 << 1)); /* 32KHz sleep clk */
1673
OS_REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
1674
OS_REG_WRITE(ah, AR_SLP32_INC, 0x0001e800);
1675
}
1676
OS_DELAY(100);
1677
}
1678
}
1679
1680
static inline HAL_BOOL
1681
ar9300_set_reset(struct ath_hal *ah, int type)
1682
{
1683
u_int32_t rst_flags;
1684
u_int32_t tmp_reg;
1685
struct ath_hal_9300 *ahp = AH9300(ah);
1686
1687
HALASSERT(type == HAL_RESET_WARM || type == HAL_RESET_COLD);
1688
1689
/*
1690
* RTC Force wake should be done before resetting the MAC.
1691
* MDK/ART does it that way.
1692
*/
1693
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_WA), AH9300(ah)->ah_wa_reg_val);
1694
OS_DELAY(10); /* delay to allow AR_WA reg write to kick in */
1695
OS_REG_WRITE(ah,
1696
AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1697
1698
/* Reset AHB */
1699
/* Bug26871 */
1700
tmp_reg = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE));
1701
if (AR_SREV_WASP(ah)) {
1702
if (tmp_reg & (AR9340_INTR_SYNC_LOCAL_TIMEOUT)) {
1703
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), 0);
1704
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), AR_RC_HOSTIF);
1705
}
1706
} else {
1707
if (tmp_reg & (AR9300_INTR_SYNC_LOCAL_TIMEOUT | AR9300_INTR_SYNC_RADM_CPL_TIMEOUT)) {
1708
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), 0);
1709
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), AR_RC_HOSTIF);
1710
}
1711
else {
1712
/* NO AR_RC_AHB in Osprey */
1713
/*OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), AR_RC_AHB);*/
1714
}
1715
}
1716
1717
rst_flags = AR_RTC_RC_MAC_WARM;
1718
if (type == HAL_RESET_COLD) {
1719
rst_flags |= AR_RTC_RC_MAC_COLD;
1720
}
1721
1722
#ifdef AH_SUPPORT_HORNET
1723
/* Hornet WAR: trigger SoC to reset WMAC if ...
1724
* (1) doing cold reset. Ref: EV 69254
1725
* (2) beacon pending. Ref: EV 70983
1726
*/
1727
if (AR_SREV_HORNET(ah) &&
1728
(ar9300_num_tx_pending(
1729
ah, AH_PRIVATE(ah)->ah_caps.halTotalQueues - 1) != 0 ||
1730
type == HAL_RESET_COLD))
1731
{
1732
u_int32_t time_out;
1733
#define AR_SOC_RST_RESET 0xB806001C
1734
#define AR_SOC_BOOT_STRAP 0xB80600AC
1735
#define AR_SOC_WLAN_RST 0x00000800 /* WLAN reset */
1736
#define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val);
1737
#define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
1738
HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Hornet SoC reset WMAC.\n", __func__);
1739
1740
REG_WRITE(AR_SOC_RST_RESET,
1741
REG_READ(AR_SOC_RST_RESET) | AR_SOC_WLAN_RST);
1742
REG_WRITE(AR_SOC_RST_RESET,
1743
REG_READ(AR_SOC_RST_RESET) & (~AR_SOC_WLAN_RST));
1744
1745
time_out = 0;
1746
1747
while (1) {
1748
tmp_reg = REG_READ(AR_SOC_BOOT_STRAP);
1749
if ((tmp_reg & 0x10) == 0) {
1750
break;
1751
}
1752
if (time_out > 20) {
1753
break;
1754
}
1755
OS_DELAY(10000);
1756
time_out++;
1757
}
1758
1759
OS_REG_WRITE(ah, AR_RTC_RESET, 1);
1760
#undef REG_READ
1761
#undef REG_WRITE
1762
#undef AR_SOC_WLAN_RST
1763
#undef AR_SOC_RST_RESET
1764
#undef AR_SOC_BOOT_STRAP
1765
}
1766
#endif /* AH_SUPPORT_HORNET */
1767
1768
#ifdef AH_SUPPORT_SCORPION
1769
if (AR_SREV_SCORPION(ah)) {
1770
#define DDR_CTL_CONFIG_ADDRESS 0xb8000000
1771
#define DDR_CTL_CONFIG_OFFSET 0x0108
1772
#define DDR_CTL_CONFIG_CLIENT_ACTIVITY_MSB 29
1773
#define DDR_CTL_CONFIG_CLIENT_ACTIVITY_LSB 21
1774
#define DDR_CTL_CONFIG_CLIENT_ACTIVITY_MASK 0x3fe00000
1775
#define DDR_CTL_CONFIG_CLIENT_ACTIVITY_GET(x) (((x) & DDR_CTL_CONFIG_CLIENT_ACTIVITY_MASK) >> DDR_CTL_CONFIG_CLIENT_ACTIVITY_LSB)
1776
#define DDR_CTL_CONFIG_CLIENT_ACTIVITY_SET(x) (((x) << DDR_CTL_CONFIG_CLIENT_ACTIVITY_LSB) & DDR_CTL_CONFIG_CLIENT_ACTIVITY_MASK)
1777
#define MAC_DMA_CFG_ADDRESS 0xb8100000
1778
#define MAC_DMA_CFG_OFFSET 0x0014
1779
1780
#define MAC_DMA_CFG_HALT_REQ_MSB 11
1781
#define MAC_DMA_CFG_HALT_REQ_LSB 11
1782
#define MAC_DMA_CFG_HALT_REQ_MASK 0x00000800
1783
#define MAC_DMA_CFG_HALT_REQ_GET(x) (((x) & MAC_DMA_CFG_HALT_REQ_MASK) >> MAC_DMA_CFG_HALT_REQ_LSB)
1784
#define MAC_DMA_CFG_HALT_REQ_SET(x) (((x) << MAC_DMA_CFG_HALT_REQ_LSB) & MAC_DMA_CFG_HALT_REQ_MASK)
1785
#define MAC_DMA_CFG_HALT_ACK_MSB 12
1786
#define MAC_DMA_CFG_HALT_ACK_LSB 12
1787
#define MAC_DMA_CFG_HALT_ACK_MASK 0x00001000
1788
#define MAC_DMA_CFG_HALT_ACK_GET(x) (((x) & MAC_DMA_CFG_HALT_ACK_MASK) >> MAC_DMA_CFG_HALT_ACK_LSB)
1789
#define MAC_DMA_CFG_HALT_ACK_SET(x) (((x) << MAC_DMA_CFG_HALT_ACK_LSB) & MAC_DMA_CFG_HALT_ACK_MASK)
1790
1791
#define RST_RESET 0xB806001c
1792
#define RTC_RESET (1<<27)
1793
1794
#define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
1795
#define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val);
1796
1797
#define DDR_REG_READ(_ah, _reg) \
1798
*((volatile u_int32_t *)( DDR_CTL_CONFIG_ADDRESS + (_reg)))
1799
#define DDR_REG_WRITE(_ah, _reg, _val) \
1800
*((volatile u_int32_t *)(DDR_CTL_CONFIG_ADDRESS + (_reg))) = (_val)
1801
1802
OS_REG_WRITE(ah,MAC_DMA_CFG_OFFSET, (OS_REG_READ(ah,MAC_DMA_CFG_OFFSET) & ~MAC_DMA_CFG_HALT_REQ_MASK) |
1803
MAC_DMA_CFG_HALT_REQ_SET(1));
1804
1805
{
1806
int count;
1807
u_int32_t data;
1808
1809
count = 0;
1810
while (!MAC_DMA_CFG_HALT_ACK_GET(OS_REG_READ(ah, MAC_DMA_CFG_OFFSET) ))
1811
{
1812
count++;
1813
if (count > 10) {
1814
ath_hal_printf(ah, "Halt ACK timeout\n");
1815
break;
1816
}
1817
OS_DELAY(10);
1818
}
1819
1820
data = DDR_REG_READ(ah,DDR_CTL_CONFIG_OFFSET);
1821
HALDEBUG(ah, HAL_DEBUG_RESET, "check DDR Activity - HIGH\n");
1822
1823
count = 0;
1824
while (DDR_CTL_CONFIG_CLIENT_ACTIVITY_GET(data)) {
1825
// AVE_DEBUG(0,"DDR Activity - HIGH\n");
1826
HALDEBUG(ah, HAL_DEBUG_RESET, "DDR Activity - HIGH\n");
1827
count++;
1828
OS_DELAY(10);
1829
data = DDR_REG_READ(ah,DDR_CTL_CONFIG_OFFSET);
1830
if (count > 10) {
1831
ath_hal_printf(ah, "DDR Activity timeout\n");
1832
break;
1833
}
1834
}
1835
}
1836
1837
1838
{
1839
//Force RTC reset
1840
REG_WRITE(RST_RESET, (REG_READ(RST_RESET) | RTC_RESET));
1841
OS_DELAY(10);
1842
REG_WRITE(RST_RESET, (REG_READ(RST_RESET) & ~RTC_RESET));
1843
OS_DELAY(10);
1844
OS_REG_WRITE(ah, AR_RTC_RESET, 0);
1845
OS_DELAY(10);
1846
OS_REG_WRITE(ah, AR_RTC_RESET, 1);
1847
OS_DELAY(10);
1848
HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Scorpion SoC RTC reset done.\n", __func__);
1849
}
1850
#undef REG_READ
1851
#undef REG_WRITE
1852
}
1853
#endif /* AH_SUPPORT_SCORPION */
1854
1855
/*
1856
* Set Mac(BB,Phy) Warm Reset
1857
*/
1858
OS_REG_WRITE(ah, AR_RTC_RC, rst_flags);
1859
1860
OS_DELAY(50); /* XXX 50 usec */
1861
1862
/*
1863
* Clear resets and force wakeup
1864
*/
1865
OS_REG_WRITE(ah, AR_RTC_RC, 0);
1866
if (!ath_hal_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0)) {
1867
HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
1868
"%s: RTC stuck in MAC reset\n", __FUNCTION__);
1869
HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
1870
"%s: AR_RTC_RC = 0x%x\n", __func__, OS_REG_READ(ah, AR_RTC_RC));
1871
return AH_FALSE;
1872
}
1873
1874
/* Clear AHB reset */
1875
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), 0);
1876
ar9300_disable_pll_lock_detect(ah);
1877
1878
ar9300_attach_hw_platform(ah);
1879
1880
ahp->ah_chip_reset_done = 1;
1881
return AH_TRUE;
1882
}
1883
1884
static inline HAL_BOOL
1885
ar9300_set_reset_power_on(struct ath_hal *ah)
1886
{
1887
/* Force wake */
1888
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_WA), AH9300(ah)->ah_wa_reg_val);
1889
OS_DELAY(10); /* delay to allow AR_WA reg write to kick in */
1890
OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1891
AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1892
/*
1893
* RTC reset and clear. Some delay in between is needed
1894
* to give the chip time to settle.
1895
*/
1896
OS_REG_WRITE(ah, AR_RTC_RESET, 0);
1897
OS_DELAY(2);
1898
OS_REG_WRITE(ah, AR_RTC_RESET, 1);
1899
1900
/*
1901
* Poll till RTC is ON
1902
*/
1903
if (!ath_hal_wait(ah,
1904
AR_RTC_STATUS, AR_RTC_STATUS_M,
1905
AR_RTC_STATUS_ON))
1906
{
1907
HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
1908
"%s: RTC not waking up for %d\n", __FUNCTION__, 1000);
1909
return AH_FALSE;
1910
}
1911
1912
/*
1913
* Read Revisions from Chip right after RTC is on for the first time.
1914
* This helps us detect the chip type early and initialize it accordingly.
1915
*/
1916
ar9300_read_revisions(ah);
1917
1918
/*
1919
* Warm reset if we aren't really powering on,
1920
* just restarting the driver.
1921
*/
1922
return ar9300_set_reset(ah, HAL_RESET_WARM);
1923
}
1924
1925
/*
1926
* Write the given reset bit mask into the reset register
1927
*/
1928
HAL_BOOL
1929
ar9300_set_reset_reg(struct ath_hal *ah, u_int32_t type)
1930
{
1931
HAL_BOOL ret = AH_FALSE;
1932
1933
/*
1934
* Set force wake
1935
*/
1936
OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_WA), AH9300(ah)->ah_wa_reg_val);
1937
OS_DELAY(10); /* delay to allow AR_WA reg write to kick in */
1938
OS_REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1939
AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1940
1941
switch (type) {
1942
case HAL_RESET_POWER_ON:
1943
ret = ar9300_set_reset_power_on(ah);
1944
break;
1945
case HAL_RESET_WARM:
1946
case HAL_RESET_COLD:
1947
ret = ar9300_set_reset(ah, type);
1948
break;
1949
default:
1950
break;
1951
}
1952
1953
#if ATH_SUPPORT_MCI
1954
if (AH_PRIVATE(ah)->ah_caps.halMciSupport) {
1955
OS_REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2);
1956
}
1957
#endif
1958
1959
return ret;
1960
}
1961
1962
/*
1963
* Places the PHY and Radio chips into reset. A full reset
1964
* must be called to leave this state. The PCI/MAC/PCU are
1965
* not placed into reset as we must receive interrupt to
1966
* re-enable the hardware.
1967
*/
1968
HAL_BOOL
1969
ar9300_phy_disable(struct ath_hal *ah)
1970
{
1971
if (!ar9300_set_reset_reg(ah, HAL_RESET_WARM)) {
1972
return AH_FALSE;
1973
}
1974
1975
#ifdef ATH_SUPPORT_LED
1976
#define REG_READ(_reg) *((volatile u_int32_t *)(_reg))
1977
#define REG_WRITE(_reg, _val) *((volatile u_int32_t *)(_reg)) = (_val);
1978
#define ATH_GPIO_OE 0xB8040000
1979
#define ATH_GPIO_OUT 0xB8040008 /* GPIO Ouput Value reg.*/
1980
if (AR_SREV_WASP(ah)) {
1981
if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) {
1982
REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 13)));
1983
}
1984
else {
1985
REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 12)));
1986
}
1987
}
1988
else if (AR_SREV_SCORPION(ah)) {
1989
if (IS_CHAN_2GHZ((AH_PRIVATE(ah)->ah_curchan))) {
1990
REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 13)));
1991
}
1992
else {
1993
REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 12)));
1994
}
1995
/* Turn off JMPST led */
1996
REG_WRITE(ATH_GPIO_OUT, (REG_READ(ATH_GPIO_OUT) | (0x1 << 15)));
1997
}
1998
else if (AR_SREV_HONEYBEE(ah)) {
1999
REG_WRITE(ATH_GPIO_OE, (REG_READ(ATH_GPIO_OE) | (0x1 << 12)));
2000
}
2001
#undef REG_READ
2002
#undef REG_WRITE
2003
#endif
2004
2005
if ( AR_SREV_OSPREY(ah) ) {
2006
OS_REG_RMW(ah, AR_HOSTIF_REG(ah, AR_GPIO_OUTPUT_MUX1), 0x0, 0x1f);
2007
}
2008
2009
2010
ar9300_init_pll(ah, AH_NULL);
2011
ar9300_disable_pll_lock_detect(ah);
2012
2013
return AH_TRUE;
2014
}
2015
2016
/*
2017
* Places all of hardware into reset
2018
*/
2019
HAL_BOOL
2020
ar9300_disable(struct ath_hal *ah)
2021
{
2022
if (!ar9300_set_power_mode(ah, HAL_PM_AWAKE, AH_TRUE)) {
2023
return AH_FALSE;
2024
}
2025
if (!ar9300_set_reset_reg(ah, HAL_RESET_COLD)) {
2026
return AH_FALSE;
2027
}
2028
2029
ar9300_init_pll(ah, AH_NULL);
2030
2031
return AH_TRUE;
2032
}
2033
2034
/*
2035
* TODO: Only write the PLL if we're changing to or from CCK mode
2036
*
2037
* WARNING: The order of the PLL and mode registers must be correct.
2038
*/
2039
static inline void
2040
ar9300_set_rf_mode(struct ath_hal *ah, struct ieee80211_channel *chan)
2041
{
2042
u_int32_t rf_mode = 0;
2043
2044
if (chan == AH_NULL) {
2045
return;
2046
}
2047
switch (AH9300(ah)->ah_hwp) {
2048
case HAL_TRUE_CHIP:
2049
rf_mode |= (IEEE80211_IS_CHAN_B(chan) || IEEE80211_IS_CHAN_G(chan)) ?
2050
AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
2051
break;
2052
default:
2053
HALASSERT(0);
2054
break;
2055
}
2056
/* Phy mode bits for 5GHz channels requiring Fast Clock */
2057
if ( IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
2058
rf_mode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
2059
}
2060
OS_REG_WRITE(ah, AR_PHY_MODE, rf_mode);
2061
}
2062
2063
/*
2064
* Places the hardware into reset and then pulls it out of reset
2065
*/
2066
HAL_BOOL
2067
ar9300_chip_reset(struct ath_hal *ah, struct ieee80211_channel *chan, 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
*/
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
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
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
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
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
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
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
6562