Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/ath/ath_hal/ar5312/ar5312_reset.c
39566 views
1
/*-
2
* SPDX-License-Identifier: ISC
3
*
4
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
5
* Copyright (c) 2002-2008 Atheros Communications, Inc.
6
*
7
* Permission to use, copy, modify, and/or distribute this software for any
8
* purpose with or without fee is hereby granted, provided that the above
9
* copyright notice and this permission notice appear in all copies.
10
*
11
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
*/
19
#include "opt_ah.h"
20
21
#ifdef AH_SUPPORT_AR5312
22
23
#include "ah.h"
24
#include "ah_internal.h"
25
#include "ah_devid.h"
26
27
#include "ar5312/ar5312.h"
28
#include "ar5312/ar5312reg.h"
29
#include "ar5312/ar5312phy.h"
30
31
#include "ah_eeprom_v3.h"
32
33
/* Additional Time delay to wait after activiting the Base band */
34
#define BASE_ACTIVATE_DELAY 100 /* 100 usec */
35
#define PLL_SETTLE_DELAY 300 /* 300 usec */
36
37
extern int16_t ar5212GetNf(struct ath_hal *, const struct ieee80211_channel *);
38
extern void ar5212SetRateDurationTable(struct ath_hal *,
39
const struct ieee80211_channel *);
40
extern HAL_BOOL ar5212SetTransmitPower(struct ath_hal *ah,
41
const struct ieee80211_channel *chan, uint16_t *rfXpdGain);
42
extern void ar5212SetDeltaSlope(struct ath_hal *,
43
const struct ieee80211_channel *);
44
extern HAL_BOOL ar5212SetBoardValues(struct ath_hal *,
45
const struct ieee80211_channel *);
46
extern void ar5212SetIFSTiming(struct ath_hal *,
47
const struct ieee80211_channel *);
48
extern HAL_BOOL ar5212IsSpurChannel(struct ath_hal *,
49
const struct ieee80211_channel *);
50
extern HAL_BOOL ar5212ChannelChange(struct ath_hal *,
51
const struct ieee80211_channel *);
52
53
static HAL_BOOL ar5312SetResetReg(struct ath_hal *, uint32_t resetMask);
54
55
static int
56
write_common(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
57
HAL_BOOL bChannelChange, int writes)
58
{
59
#define IS_NO_RESET_TIMER_ADDR(x) \
60
( (((x) >= AR_BEACON) && ((x) <= AR_CFP_DUR)) || \
61
(((x) >= AR_SLEEP1) && ((x) <= AR_SLEEP3)))
62
#define V(r, c) (ia)->data[((r)*(ia)->cols) + (c)]
63
int i;
64
65
/* Write Common Array Parameters */
66
for (i = 0; i < ia->rows; i++) {
67
uint32_t reg = V(i, 0);
68
/* XXX timer/beacon setup registers? */
69
/* On channel change, don't reset the PCU registers */
70
if (!(bChannelChange && IS_NO_RESET_TIMER_ADDR(reg))) {
71
OS_REG_WRITE(ah, reg, V(i, 1));
72
DMA_YIELD(writes);
73
}
74
}
75
return writes;
76
#undef IS_NO_RESET_TIMER_ADDR
77
#undef V
78
}
79
80
/*
81
* Places the device in and out of reset and then places sane
82
* values in the registers based on EEPROM config, initialization
83
* vectors (as determined by the mode), and station configuration
84
*
85
* bChannelChange is used to preserve DMA/PCU registers across
86
* a HW Reset during channel change.
87
*/
88
HAL_BOOL
89
ar5312Reset(struct ath_hal *ah, HAL_OPMODE opmode,
90
struct ieee80211_channel *chan,
91
HAL_BOOL bChannelChange,
92
HAL_RESET_TYPE resetType,
93
HAL_STATUS *status)
94
{
95
#define N(a) (sizeof (a) / sizeof (a[0]))
96
#define FAIL(_code) do { ecode = _code; goto bad; } while (0)
97
struct ath_hal_5212 *ahp = AH5212(ah);
98
HAL_CHANNEL_INTERNAL *ichan;
99
const HAL_EEPROM *ee;
100
uint32_t saveFrameSeqCount, saveDefAntenna;
101
uint32_t macStaId1, synthDelay, txFrm2TxDStart;
102
uint16_t rfXpdGain[MAX_NUM_PDGAINS_PER_CHANNEL];
103
int16_t cckOfdmPwrDelta = 0;
104
u_int modesIndex, freqIndex;
105
HAL_STATUS ecode;
106
int i, regWrites = 0;
107
uint32_t testReg;
108
uint32_t saveLedState = 0;
109
110
HALASSERT(ah->ah_magic == AR5212_MAGIC);
111
ee = AH_PRIVATE(ah)->ah_eeprom;
112
113
OS_MARK(ah, AH_MARK_RESET, bChannelChange);
114
/*
115
* Map public channel to private.
116
*/
117
ichan = ath_hal_checkchannel(ah, chan);
118
if (ichan == AH_NULL) {
119
HALDEBUG(ah, HAL_DEBUG_ANY,
120
"%s: invalid channel %u/0x%x; no mapping\n",
121
__func__, chan->ic_freq, chan->ic_flags);
122
FAIL(HAL_EINVAL);
123
}
124
switch (opmode) {
125
case HAL_M_STA:
126
case HAL_M_IBSS:
127
case HAL_M_HOSTAP:
128
case HAL_M_MONITOR:
129
break;
130
default:
131
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid operating mode %u\n",
132
__func__, opmode);
133
FAIL(HAL_EINVAL);
134
break;
135
}
136
HALASSERT(ahp->ah_eeversion >= AR_EEPROM_VER3);
137
138
/* Preserve certain DMA hardware registers on a channel change */
139
if (bChannelChange) {
140
/*
141
* On Venice, the TSF is almost preserved across a reset;
142
* it requires the doubling writes to the RESET_TSF
143
* bit in the AR_BEACON register; it also has the quirk
144
* of the TSF going back in time on the station (station
145
* latches onto the last beacon's tsf during a reset 50%
146
* of the times); the latter is not a problem for adhoc
147
* stations since as long as the TSF is behind, it will
148
* get resynchronized on receiving the next beacon; the
149
* TSF going backwards in time could be a problem for the
150
* sleep operation (supported on infrastructure stations
151
* only) - the best and most general fix for this situation
152
* is to resynchronize the various sleep/beacon timers on
153
* the receipt of the next beacon i.e. when the TSF itself
154
* gets resynchronized to the AP's TSF - power save is
155
* needed to be temporarily disabled until that time
156
*
157
* Need to save the sequence number to restore it after
158
* the reset!
159
*/
160
saveFrameSeqCount = OS_REG_READ(ah, AR_D_SEQNUM);
161
} else
162
saveFrameSeqCount = 0; /* NB: silence compiler */
163
164
/* If the channel change is across the same mode - perform a fast channel change */
165
if ((IS_2413(ah) || IS_5413(ah))) {
166
/*
167
* Channel change can only be used when:
168
* -channel change requested - so it's not the initial reset.
169
* -it's not a change to the current channel - often called when switching modes
170
* on a channel
171
* -the modes of the previous and requested channel are the same - some ugly code for XR
172
*/
173
if (bChannelChange &&
174
AH_PRIVATE(ah)->ah_curchan != AH_NULL &&
175
(chan->ic_freq != AH_PRIVATE(ah)->ah_curchan->ic_freq) &&
176
((chan->ic_flags & IEEE80211_CHAN_ALLTURBO) ==
177
(AH_PRIVATE(ah)->ah_curchan->ic_flags & IEEE80211_CHAN_ALLTURBO))) {
178
if (ar5212ChannelChange(ah, chan))
179
/* If ChannelChange completed - skip the rest of reset */
180
return AH_TRUE;
181
}
182
}
183
184
/*
185
* Preserve the antenna on a channel change
186
*/
187
saveDefAntenna = OS_REG_READ(ah, AR_DEF_ANTENNA);
188
if (saveDefAntenna == 0) /* XXX magic constants */
189
saveDefAntenna = 1;
190
191
/* Save hardware flag before chip reset clears the register */
192
macStaId1 = OS_REG_READ(ah, AR_STA_ID1) &
193
(AR_STA_ID1_BASE_RATE_11B | AR_STA_ID1_USE_DEFANT);
194
195
/* Save led state from pci config register */
196
if (!IS_5315(ah))
197
saveLedState = OS_REG_READ(ah, AR5312_PCICFG) &
198
(AR_PCICFG_LEDCTL | AR_PCICFG_LEDMODE | AR_PCICFG_LEDBLINK |
199
AR_PCICFG_LEDSLOW);
200
201
ar5312RestoreClock(ah, opmode); /* move to refclk operation */
202
203
/*
204
* Adjust gain parameters before reset if
205
* there's an outstanding gain updated.
206
*/
207
(void) ar5212GetRfgain(ah);
208
209
if (!ar5312ChipReset(ah, chan)) {
210
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
211
FAIL(HAL_EIO);
212
}
213
214
/* Setup the indices for the next set of register array writes */
215
if (IEEE80211_IS_CHAN_2GHZ(chan)) {
216
freqIndex = 2;
217
modesIndex = IEEE80211_IS_CHAN_108G(chan) ? 5 :
218
IEEE80211_IS_CHAN_G(chan) ? 4 : 3;
219
} else {
220
freqIndex = 1;
221
modesIndex = IEEE80211_IS_CHAN_ST(chan) ? 2 : 1;
222
}
223
224
OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
225
226
/* Set correct Baseband to analog shift setting to access analog chips. */
227
OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
228
229
regWrites = ath_hal_ini_write(ah, &ahp->ah_ini_modes, modesIndex, 0);
230
regWrites = write_common(ah, &ahp->ah_ini_common, bChannelChange,
231
regWrites);
232
ahp->ah_rfHal->writeRegs(ah, modesIndex, freqIndex, regWrites);
233
234
OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
235
236
if (IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan))
237
ar5212SetIFSTiming(ah, chan);
238
239
/* Overwrite INI values for revised chipsets */
240
if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2) {
241
/* ADC_CTL */
242
OS_REG_WRITE(ah, AR_PHY_ADC_CTL,
243
SM(2, AR_PHY_ADC_CTL_OFF_INBUFGAIN) |
244
SM(2, AR_PHY_ADC_CTL_ON_INBUFGAIN) |
245
AR_PHY_ADC_CTL_OFF_PWDDAC |
246
AR_PHY_ADC_CTL_OFF_PWDADC);
247
248
/* TX_PWR_ADJ */
249
if (chan->channel == 2484) {
250
cckOfdmPwrDelta = SCALE_OC_DELTA(ee->ee_cckOfdmPwrDelta - ee->ee_scaledCh14FilterCckDelta);
251
} else {
252
cckOfdmPwrDelta = SCALE_OC_DELTA(ee->ee_cckOfdmPwrDelta);
253
}
254
255
if (IEEE80211_IS_CHAN_G(chan)) {
256
OS_REG_WRITE(ah, AR_PHY_TXPWRADJ,
257
SM((ee->ee_cckOfdmPwrDelta*-1), AR_PHY_TXPWRADJ_CCK_GAIN_DELTA) |
258
SM((cckOfdmPwrDelta*-1), AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX));
259
} else {
260
OS_REG_WRITE(ah, AR_PHY_TXPWRADJ, 0);
261
}
262
263
/* Add barker RSSI thresh enable as disabled */
264
OS_REG_CLR_BIT(ah, AR_PHY_DAG_CTRLCCK,
265
AR_PHY_DAG_CTRLCCK_EN_RSSI_THR);
266
OS_REG_RMW_FIELD(ah, AR_PHY_DAG_CTRLCCK,
267
AR_PHY_DAG_CTRLCCK_RSSI_THR, 2);
268
269
/* Set the mute mask to the correct default */
270
OS_REG_WRITE(ah, AR_SEQ_MASK, 0x0000000F);
271
}
272
273
if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_3) {
274
/* Clear reg to alllow RX_CLEAR line debug */
275
OS_REG_WRITE(ah, AR_PHY_BLUETOOTH, 0);
276
}
277
if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_4) {
278
#ifdef notyet
279
/* Enable burst prefetch for the data queues */
280
OS_REG_RMW_FIELD(ah, AR_D_FPCTL, ... );
281
/* Enable double-buffering */
282
OS_REG_CLR_BIT(ah, AR_TXCFG, AR_TXCFG_DBL_BUF_DIS);
283
#endif
284
}
285
286
if (IS_5312_2_X(ah)) {
287
/* ADC_CTRL */
288
OS_REG_WRITE(ah, AR_PHY_SIGMA_DELTA,
289
SM(2, AR_PHY_SIGMA_DELTA_ADC_SEL) |
290
SM(4, AR_PHY_SIGMA_DELTA_FILT2) |
291
SM(0x16, AR_PHY_SIGMA_DELTA_FILT1) |
292
SM(0, AR_PHY_SIGMA_DELTA_ADC_CLIP));
293
294
if (IEEE80211_IS_CHAN_2GHZ(chan))
295
OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN, AR_PHY_RXGAIN_TXRX_RF_MAX, 0x0F);
296
297
/* CCK Short parameter adjustment in 11B mode */
298
if (IEEE80211_IS_CHAN_B(chan))
299
OS_REG_RMW_FIELD(ah, AR_PHY_CCK_RXCTRL4, AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT, 12);
300
301
/* Set ADC/DAC select values */
302
OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x04);
303
304
/* Increase 11A AGC Settling */
305
if (IEEE80211_IS_CHAN_A(chan))
306
OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_AGC, 32);
307
} else {
308
/* Set ADC/DAC select values */
309
OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e);
310
}
311
312
/* Setup the transmit power values. */
313
if (!ar5212SetTransmitPower(ah, chan, rfXpdGain)) {
314
HALDEBUG(ah, HAL_DEBUG_ANY,
315
"%s: error init'ing transmit power\n", __func__);
316
FAIL(HAL_EIO);
317
}
318
319
/* Write the analog registers */
320
if (!ahp->ah_rfHal->setRfRegs(ah, chan, modesIndex, rfXpdGain)) {
321
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5212SetRfRegs failed\n",
322
__func__);
323
FAIL(HAL_EIO);
324
}
325
326
/* Write delta slope for OFDM enabled modes (A, G, Turbo) */
327
if (IEEE80211_IS_CHAN_OFDM(chan)) {
328
if (IS_5413(ah) ||
329
AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3)
330
ar5212SetSpurMitigation(ah, chan);
331
ar5212SetDeltaSlope(ah, chan);
332
}
333
334
/* Setup board specific options for EEPROM version 3 */
335
if (!ar5212SetBoardValues(ah, chan)) {
336
HALDEBUG(ah, HAL_DEBUG_ANY,
337
"%s: error setting board options\n", __func__);
338
FAIL(HAL_EIO);
339
}
340
341
/* Restore certain DMA hardware registers on a channel change */
342
if (bChannelChange)
343
OS_REG_WRITE(ah, AR_D_SEQNUM, saveFrameSeqCount);
344
345
OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
346
347
OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr));
348
OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4)
349
| macStaId1
350
| AR_STA_ID1_RTS_USE_DEF
351
| ahp->ah_staId1Defaults
352
);
353
ar5212SetOperatingMode(ah, opmode);
354
355
/* Set Venice BSSID mask according to current state */
356
OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask));
357
OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4));
358
359
/* Restore previous led state */
360
if (!IS_5315(ah))
361
OS_REG_WRITE(ah, AR5312_PCICFG, OS_REG_READ(ah, AR_PCICFG) | saveLedState);
362
363
/* Restore previous antenna */
364
OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
365
366
/* then our BSSID */
367
OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
368
OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4));
369
370
/* Restore bmiss rssi & count thresholds */
371
OS_REG_WRITE(ah, AR_RSSI_THR, ahp->ah_rssiThr);
372
373
OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */
374
375
if (!ar5212SetChannel(ah, chan))
376
FAIL(HAL_EIO);
377
378
OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
379
380
ar5212SetCoverageClass(ah, AH_PRIVATE(ah)->ah_coverageClass, 1);
381
382
ar5212SetRateDurationTable(ah, chan);
383
384
/* Set Tx frame start to tx data start delay */
385
if (IS_RAD5112_ANY(ah) &&
386
(IEEE80211_IS_CHAN_HALF(chan) || IEEE80211_IS_CHAN_QUARTER(chan))) {
387
txFrm2TxDStart =
388
IEEE80211_IS_CHAN_HALF(chan) ?
389
TX_FRAME_D_START_HALF_RATE:
390
TX_FRAME_D_START_QUARTER_RATE;
391
OS_REG_RMW_FIELD(ah, AR_PHY_TX_CTL,
392
AR_PHY_TX_FRAME_TO_TX_DATA_START, txFrm2TxDStart);
393
}
394
395
/*
396
* Setup fast diversity.
397
* Fast diversity can be enabled or disabled via regadd.txt.
398
* Default is enabled.
399
* For reference,
400
* Disable: reg val
401
* 0x00009860 0x00009d18 (if 11a / 11g, else no change)
402
* 0x00009970 0x192bb514
403
* 0x0000a208 0xd03e4648
404
*
405
* Enable: 0x00009860 0x00009d10 (if 11a / 11g, else no change)
406
* 0x00009970 0x192fb514
407
* 0x0000a208 0xd03e6788
408
*/
409
410
/* XXX Setup pre PHY ENABLE EAR additions */
411
412
/* flush SCAL reg */
413
if (IS_5312_2_X(ah)) {
414
(void) OS_REG_READ(ah, AR_PHY_SLEEP_SCAL);
415
}
416
417
/*
418
* Wait for the frequency synth to settle (synth goes on
419
* via AR_PHY_ACTIVE_EN). Read the phy active delay register.
420
* Value is in 100ns increments.
421
*/
422
synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
423
if (IEEE80211_IS_CHAN_B(chan)) {
424
synthDelay = (4 * synthDelay) / 22;
425
} else {
426
synthDelay /= 10;
427
}
428
429
/* Activate the PHY (includes baseband activate and synthesizer on) */
430
OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
431
432
/*
433
* There is an issue if the AP starts the calibration before
434
* the base band timeout completes. This could result in the
435
* rx_clear false triggering. As a workaround we add delay an
436
* extra BASE_ACTIVATE_DELAY usecs to ensure this condition
437
* does not happen.
438
*/
439
if (IEEE80211_IS_CHAN_HALF(chan)) {
440
OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY);
441
} else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
442
OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY);
443
} else {
444
OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);
445
}
446
447
/*
448
* The udelay method is not reliable with notebooks.
449
* Need to check to see if the baseband is ready
450
*/
451
testReg = OS_REG_READ(ah, AR_PHY_TESTCTRL);
452
/* Selects the Tx hold */
453
OS_REG_WRITE(ah, AR_PHY_TESTCTRL, AR_PHY_TESTCTRL_TXHOLD);
454
i = 0;
455
while ((i++ < 20) &&
456
(OS_REG_READ(ah, 0x9c24) & 0x10)) /* test if baseband not ready */ OS_DELAY(200);
457
OS_REG_WRITE(ah, AR_PHY_TESTCTRL, testReg);
458
459
/* Calibrate the AGC and start a NF calculation */
460
OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
461
OS_REG_READ(ah, AR_PHY_AGC_CONTROL)
462
| AR_PHY_AGC_CONTROL_CAL
463
| AR_PHY_AGC_CONTROL_NF);
464
465
if (!IEEE80211_IS_CHAN_B(chan) && ahp->ah_bIQCalibration != IQ_CAL_DONE) {
466
/* Start IQ calibration w/ 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples */
467
OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
468
AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
469
INIT_IQCAL_LOG_COUNT_MAX);
470
OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4,
471
AR_PHY_TIMING_CTRL4_DO_IQCAL);
472
ahp->ah_bIQCalibration = IQ_CAL_RUNNING;
473
} else
474
ahp->ah_bIQCalibration = IQ_CAL_INACTIVE;
475
476
/* Setup compression registers */
477
ar5212SetCompRegs(ah);
478
479
/* Set 1:1 QCU to DCU mapping for all queues */
480
for (i = 0; i < AR_NUM_DCU; i++)
481
OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
482
483
ahp->ah_intrTxqs = 0;
484
for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++)
485
ar5212ResetTxQueue(ah, i);
486
487
/*
488
* Setup interrupt handling. Note that ar5212ResetTxQueue
489
* manipulates the secondary IMR's as queues are enabled
490
* and disabled. This is done with RMW ops to insure the
491
* settings we make here are preserved.
492
*/
493
ahp->ah_maskReg = AR_IMR_TXOK | AR_IMR_TXERR | AR_IMR_TXURN
494
| AR_IMR_RXOK | AR_IMR_RXERR | AR_IMR_RXORN
495
| AR_IMR_HIUERR
496
;
497
if (opmode == HAL_M_HOSTAP)
498
ahp->ah_maskReg |= AR_IMR_MIB;
499
OS_REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
500
/* Enable bus errors that are OR'd to set the HIUERR bit */
501
OS_REG_WRITE(ah, AR_IMR_S2,
502
OS_REG_READ(ah, AR_IMR_S2)
503
| AR_IMR_S2_MCABT | AR_IMR_S2_SSERR | AR_IMR_S2_DPERR);
504
505
if (AH_PRIVATE(ah)->ah_rfkillEnabled)
506
ar5212EnableRfKill(ah);
507
508
if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
509
HALDEBUG(ah, HAL_DEBUG_ANY,
510
"%s: offset calibration failed to complete in 1ms;"
511
" noisy environment?\n", __func__);
512
}
513
514
/*
515
* Set clocks back to 32kHz if they had been using refClk, then
516
* use an external 32kHz crystal when sleeping, if one exists.
517
*/
518
ar5312SetupClock(ah, opmode);
519
520
/*
521
* Writing to AR_BEACON will start timers. Hence it should
522
* be the last register to be written. Do not reset tsf, do
523
* not enable beacons at this point, but preserve other values
524
* like beaconInterval.
525
*/
526
OS_REG_WRITE(ah, AR_BEACON,
527
(OS_REG_READ(ah, AR_BEACON) &~ (AR_BEACON_EN | AR_BEACON_RESET_TSF)));
528
529
/* XXX Setup post reset EAR additions */
530
531
/* QoS support */
532
if (AH_PRIVATE(ah)->ah_macVersion > AR_SREV_VERSION_VENICE ||
533
(AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_VENICE &&
534
AH_PRIVATE(ah)->ah_macRev >= AR_SREV_GRIFFIN_LITE)) {
535
OS_REG_WRITE(ah, AR_QOS_CONTROL, 0x100aa); /* XXX magic */
536
OS_REG_WRITE(ah, AR_QOS_SELECT, 0x3210); /* XXX magic */
537
}
538
539
/* Turn on NOACK Support for QoS packets */
540
OS_REG_WRITE(ah, AR_NOACK,
541
SM(2, AR_NOACK_2BIT_VALUE) |
542
SM(5, AR_NOACK_BIT_OFFSET) |
543
SM(0, AR_NOACK_BYTE_OFFSET));
544
545
/* Restore user-specified settings */
546
if (ahp->ah_miscMode != 0)
547
OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);
548
if (ahp->ah_slottime != (u_int) -1)
549
ar5212SetSlotTime(ah, ahp->ah_slottime);
550
if (ahp->ah_acktimeout != (u_int) -1)
551
ar5212SetAckTimeout(ah, ahp->ah_acktimeout);
552
if (ahp->ah_ctstimeout != (u_int) -1)
553
ar5212SetCTSTimeout(ah, ahp->ah_ctstimeout);
554
if (ahp->ah_sifstime != (u_int) -1)
555
ar5212SetSifsTime(ah, ahp->ah_sifstime);
556
if (AH_PRIVATE(ah)->ah_diagreg != 0)
557
OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);
558
559
AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */
560
561
if (bChannelChange && !IEEE80211_IS_CHAN_DFS(chan))
562
chan->ic_state &= ~IEEE80211_CHANSTATE_CWINT;
563
564
HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__);
565
566
OS_MARK(ah, AH_MARK_RESET_DONE, 0);
567
568
return AH_TRUE;
569
bad:
570
OS_MARK(ah, AH_MARK_RESET_DONE, ecode);
571
if (status != AH_NULL)
572
*status = ecode;
573
return AH_FALSE;
574
#undef FAIL
575
#undef N
576
}
577
578
/*
579
* Places the PHY and Radio chips into reset. A full reset
580
* must be called to leave this state. The PCI/MAC/PCU are
581
* not placed into reset as we must receive interrupt to
582
* re-enable the hardware.
583
*/
584
HAL_BOOL
585
ar5312PhyDisable(struct ath_hal *ah)
586
{
587
return ar5312SetResetReg(ah, AR_RC_BB);
588
}
589
590
/*
591
* Places all of hardware into reset
592
*/
593
HAL_BOOL
594
ar5312Disable(struct ath_hal *ah)
595
{
596
if (!ar5312SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
597
return AH_FALSE;
598
/*
599
* Reset the HW - PCI must be reset after the rest of the
600
* device has been reset.
601
*/
602
return ar5312SetResetReg(ah, AR_RC_MAC | AR_RC_BB);
603
}
604
605
/*
606
* Places the hardware into reset and then pulls it out of reset
607
*
608
* TODO: Only write the PLL if we're changing to or from CCK mode
609
*
610
* WARNING: The order of the PLL and mode registers must be correct.
611
*/
612
HAL_BOOL
613
ar5312ChipReset(struct ath_hal *ah, const struct ieee80211_channel *chan)
614
{
615
616
OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->ic_freq : 0);
617
618
/*
619
* Reset the HW
620
*/
621
if (!ar5312SetResetReg(ah, AR_RC_MAC | AR_RC_BB)) {
622
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5312SetResetReg failed\n",
623
__func__);
624
return AH_FALSE;
625
}
626
627
/* Bring out of sleep mode (AGAIN) */
628
if (!ar5312SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
629
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5312SetPowerMode failed\n",
630
__func__);
631
return AH_FALSE;
632
}
633
634
/* Clear warm reset register */
635
if (!ar5312SetResetReg(ah, 0)) {
636
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5312SetResetReg failed\n",
637
__func__);
638
return AH_FALSE;
639
}
640
641
/*
642
* Perform warm reset before the mode/PLL/turbo registers
643
* are changed in order to deactivate the radio. Mode changes
644
* with an active radio can result in corrupted shifts to the
645
* radio device.
646
*/
647
648
/*
649
* Set CCK and Turbo modes correctly.
650
*/
651
if (chan != AH_NULL) { /* NB: can be null during attach */
652
uint32_t rfMode, phyPLL = 0, curPhyPLL, turbo;
653
654
if (IS_RAD5112_ANY(ah)) {
655
rfMode = AR_PHY_MODE_AR5112;
656
if (!IS_5315(ah)) {
657
if (IEEE80211_IS_CHAN_CCK(chan)) {
658
phyPLL = AR_PHY_PLL_CTL_44_5312;
659
} else {
660
if (IEEE80211_IS_CHAN_HALF(chan)) {
661
phyPLL = AR_PHY_PLL_CTL_40_5312_HALF;
662
} else if (IEEE80211_IS_CHAN_QUARTER(chan)) {
663
phyPLL = AR_PHY_PLL_CTL_40_5312_QUARTER;
664
} else {
665
phyPLL = AR_PHY_PLL_CTL_40_5312;
666
}
667
}
668
} else {
669
if (IEEE80211_IS_CHAN_CCK(chan))
670
phyPLL = AR_PHY_PLL_CTL_44_5112;
671
else
672
phyPLL = AR_PHY_PLL_CTL_40_5112;
673
if (IEEE80211_IS_CHAN_HALF(chan))
674
phyPLL |= AR_PHY_PLL_CTL_HALF;
675
else if (IEEE80211_IS_CHAN_QUARTER(chan))
676
phyPLL |= AR_PHY_PLL_CTL_QUARTER;
677
}
678
} else {
679
rfMode = AR_PHY_MODE_AR5111;
680
if (IEEE80211_IS_CHAN_CCK(chan))
681
phyPLL = AR_PHY_PLL_CTL_44;
682
else
683
phyPLL = AR_PHY_PLL_CTL_40;
684
if (IEEE80211_IS_CHAN_HALF(chan))
685
phyPLL = AR_PHY_PLL_CTL_HALF;
686
else if (IEEE80211_IS_CHAN_QUARTER(chan))
687
phyPLL = AR_PHY_PLL_CTL_QUARTER;
688
}
689
if (IEEE80211_IS_CHAN_G(chan))
690
rfMode |= AR_PHY_MODE_DYNAMIC;
691
else if (IEEE80211_IS_CHAN_OFDM(chan))
692
rfMode |= AR_PHY_MODE_OFDM;
693
else
694
rfMode |= AR_PHY_MODE_CCK;
695
if (IEEE80211_IS_CHAN_5GHZ(chan))
696
rfMode |= AR_PHY_MODE_RF5GHZ;
697
else
698
rfMode |= AR_PHY_MODE_RF2GHZ;
699
turbo = IEEE80211_IS_CHAN_TURBO(chan) ?
700
(AR_PHY_FC_TURBO_MODE | AR_PHY_FC_TURBO_SHORT) : 0;
701
curPhyPLL = OS_REG_READ(ah, AR_PHY_PLL_CTL);
702
/*
703
* PLL, Mode, and Turbo values must be written in the correct
704
* order to ensure:
705
* - The PLL cannot be set to 44 unless the CCK or DYNAMIC
706
* mode bit is set
707
* - Turbo cannot be set at the same time as CCK or DYNAMIC
708
*/
709
if (IEEE80211_IS_CHAN_CCK(chan)) {
710
OS_REG_WRITE(ah, AR_PHY_TURBO, turbo);
711
OS_REG_WRITE(ah, AR_PHY_MODE, rfMode);
712
if (curPhyPLL != phyPLL) {
713
OS_REG_WRITE(ah, AR_PHY_PLL_CTL, phyPLL);
714
/* Wait for the PLL to settle */
715
OS_DELAY(PLL_SETTLE_DELAY);
716
}
717
} else {
718
if (curPhyPLL != phyPLL) {
719
OS_REG_WRITE(ah, AR_PHY_PLL_CTL, phyPLL);
720
/* Wait for the PLL to settle */
721
OS_DELAY(PLL_SETTLE_DELAY);
722
}
723
OS_REG_WRITE(ah, AR_PHY_TURBO, turbo);
724
OS_REG_WRITE(ah, AR_PHY_MODE, rfMode);
725
}
726
}
727
return AH_TRUE;
728
}
729
730
/*
731
* Write the given reset bit mask into the reset register
732
*/
733
static HAL_BOOL
734
ar5312SetResetReg(struct ath_hal *ah, uint32_t resetMask)
735
{
736
uint32_t mask = resetMask ? resetMask : ~0;
737
HAL_BOOL rt;
738
739
if ((rt = ar5312MacReset(ah, mask)) == AH_FALSE) {
740
return rt;
741
}
742
if ((resetMask & AR_RC_MAC) == 0) {
743
if (isBigEndian()) {
744
/*
745
* Set CFG, little-endian for descriptor accesses.
746
*/
747
#ifdef AH_NEED_DESC_SWAP
748
mask = INIT_CONFIG_STATUS | AR_CFG_SWRD;
749
#else
750
mask = INIT_CONFIG_STATUS |
751
AR_CFG_SWTD | AR_CFG_SWRD;
752
#endif
753
OS_REG_WRITE(ah, AR_CFG, mask);
754
} else
755
OS_REG_WRITE(ah, AR_CFG, INIT_CONFIG_STATUS);
756
}
757
return rt;
758
}
759
760
/*
761
* ar5312MacReset resets (and then un-resets) the specified
762
* wireless components.
763
* Note: The RCMask cannot be zero on entering from ar5312SetResetReg.
764
*/
765
766
HAL_BOOL
767
ar5312MacReset(struct ath_hal *ah, unsigned int RCMask)
768
{
769
int wlanNum = AR5312_UNIT(ah);
770
uint32_t resetBB, resetBits, regMask;
771
uint32_t reg;
772
773
if (RCMask == 0)
774
return(AH_FALSE);
775
#if ( AH_SUPPORT_2316 || AH_SUPPORT_2317 )
776
if (IS_5315(ah)) {
777
switch(wlanNum) {
778
case 0:
779
resetBB = AR5315_RC_BB0_CRES | AR5315_RC_WBB0_RES;
780
/* Warm and cold reset bits for wbb */
781
resetBits = AR5315_RC_WMAC0_RES;
782
break;
783
case 1:
784
resetBB = AR5315_RC_BB1_CRES | AR5315_RC_WBB1_RES;
785
/* Warm and cold reset bits for wbb */
786
resetBits = AR5315_RC_WMAC1_RES;
787
break;
788
default:
789
return(AH_FALSE);
790
}
791
regMask = ~(resetBB | resetBits);
792
793
/* read before */
794
reg = OS_REG_READ(ah,
795
(AR5315_RSTIMER_BASE - ((uint32_t) ah->ah_sh) + AR5315_RESET));
796
797
if (RCMask == AR_RC_BB) {
798
/* Put baseband in reset */
799
reg |= resetBB; /* Cold and warm reset the baseband bits */
800
} else {
801
/*
802
* Reset the MAC and baseband. This is a bit different than
803
* the PCI version, but holding in reset causes problems.
804
*/
805
reg &= regMask;
806
reg |= (resetBits | resetBB) ;
807
}
808
OS_REG_WRITE(ah,
809
(AR5315_RSTIMER_BASE - ((uint32_t) ah->ah_sh)+AR5315_RESET),
810
reg);
811
/* read after */
812
OS_REG_READ(ah,
813
(AR5315_RSTIMER_BASE - ((uint32_t) ah->ah_sh) +AR5315_RESET));
814
OS_DELAY(100);
815
816
/* Bring MAC and baseband out of reset */
817
reg &= regMask;
818
/* read before */
819
OS_REG_READ(ah,
820
(AR5315_RSTIMER_BASE- ((uint32_t) ah->ah_sh) +AR5315_RESET));
821
OS_REG_WRITE(ah,
822
(AR5315_RSTIMER_BASE - ((uint32_t) ah->ah_sh)+AR5315_RESET),
823
reg);
824
/* read after */
825
OS_REG_READ(ah,
826
(AR5315_RSTIMER_BASE- ((uint32_t) ah->ah_sh) +AR5315_RESET));
827
828
}
829
else
830
#endif
831
{
832
switch(wlanNum) {
833
case 0:
834
resetBB = AR5312_RC_BB0_CRES | AR5312_RC_WBB0_RES;
835
/* Warm and cold reset bits for wbb */
836
resetBits = AR5312_RC_WMAC0_RES;
837
break;
838
case 1:
839
resetBB = AR5312_RC_BB1_CRES | AR5312_RC_WBB1_RES;
840
/* Warm and cold reset bits for wbb */
841
resetBits = AR5312_RC_WMAC1_RES;
842
break;
843
default:
844
return(AH_FALSE);
845
}
846
regMask = ~(resetBB | resetBits);
847
848
/* read before */
849
reg = OS_REG_READ(ah,
850
(AR5312_RSTIMER_BASE - ((uint32_t) ah->ah_sh) + AR5312_RESET));
851
852
if (RCMask == AR_RC_BB) {
853
/* Put baseband in reset */
854
reg |= resetBB; /* Cold and warm reset the baseband bits */
855
} else {
856
/*
857
* Reset the MAC and baseband. This is a bit different than
858
* the PCI version, but holding in reset causes problems.
859
*/
860
reg &= regMask;
861
reg |= (resetBits | resetBB) ;
862
}
863
OS_REG_WRITE(ah,
864
(AR5312_RSTIMER_BASE - ((uint32_t) ah->ah_sh)+AR5312_RESET),
865
reg);
866
/* read after */
867
OS_REG_READ(ah,
868
(AR5312_RSTIMER_BASE - ((uint32_t) ah->ah_sh) +AR5312_RESET));
869
OS_DELAY(100);
870
871
/* Bring MAC and baseband out of reset */
872
reg &= regMask;
873
/* read before */
874
OS_REG_READ(ah,
875
(AR5312_RSTIMER_BASE- ((uint32_t) ah->ah_sh) +AR5312_RESET));
876
OS_REG_WRITE(ah,
877
(AR5312_RSTIMER_BASE - ((uint32_t) ah->ah_sh)+AR5312_RESET),
878
reg);
879
/* read after */
880
OS_REG_READ(ah,
881
(AR5312_RSTIMER_BASE- ((uint32_t) ah->ah_sh) +AR5312_RESET));
882
}
883
return(AH_TRUE);
884
}
885
886
#endif /* AH_SUPPORT_AR5312 */
887
888