Deleted Added
full compact
ar5212_reset.c (185380) ar5212_reset.c (185406)
1/*
2 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
3 * Copyright (c) 2002-2008 Atheros Communications, Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 *
17 * $Id: ar5212_reset.c,v 1.20 2008/11/27 22:30:00 sam Exp $
18 */
19#include "opt_ah.h"
20
1/*
2 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
3 * Copyright (c) 2002-2008 Atheros Communications, Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 *
17 * $Id: ar5212_reset.c,v 1.20 2008/11/27 22:30:00 sam Exp $
18 */
19#include "opt_ah.h"
20
21#ifdef AH_SUPPORT_AR5212
22
23#include "ah.h"
24#include "ah_internal.h"
25#include "ah_devid.h"
26
27#include "ar5212/ar5212.h"
28#include "ar5212/ar5212reg.h"
29#include "ar5212/ar5212phy.h"
21#include "ah.h"
22#include "ah_internal.h"
23#include "ah_devid.h"
24
25#include "ar5212/ar5212.h"
26#include "ar5212/ar5212reg.h"
27#include "ar5212/ar5212phy.h"
30#ifdef AH_SUPPORT_AR5311
31#include "ar5212/ar5311reg.h"
32#endif
33
34#include "ah_eeprom_v3.h"
35
36/* Additional Time delay to wait after activiting the Base band */
37#define BASE_ACTIVATE_DELAY 100 /* 100 usec */
38#define PLL_SETTLE_DELAY 300 /* 300 usec */
39
40static HAL_BOOL ar5212SetResetReg(struct ath_hal *, uint32_t resetMask);
41/* NB: public for 5312 use */
42HAL_BOOL ar5212IsSpurChannel(struct ath_hal *, HAL_CHANNEL *);
43HAL_BOOL ar5212ChannelChange(struct ath_hal *, HAL_CHANNEL *);
44int16_t ar5212GetNf(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
45HAL_BOOL ar5212SetBoardValues(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
46void ar5212SetDeltaSlope(struct ath_hal *, HAL_CHANNEL *);
47HAL_BOOL ar5212SetTransmitPower(struct ath_hal *ah,
48 HAL_CHANNEL_INTERNAL *chan, uint16_t *rfXpdGain);
49static HAL_BOOL ar5212SetRateTable(struct ath_hal *,
50 HAL_CHANNEL *, int16_t tpcScaleReduction, int16_t powerLimit,
51 HAL_BOOL commit, int16_t *minPower, int16_t *maxPower);
52static void ar5212CorrectGainDelta(struct ath_hal *, int twiceOfdmCckDelta);
53static void ar5212GetTargetPowers(struct ath_hal *, HAL_CHANNEL *,
54 const TRGT_POWER_INFO *pPowerInfo, uint16_t numChannels,
55 TRGT_POWER_INFO *pNewPower);
56static uint16_t ar5212GetMaxEdgePower(uint16_t channel,
57 const RD_EDGES_POWER *pRdEdgesPower);
58void ar5212SetRateDurationTable(struct ath_hal *, HAL_CHANNEL *);
59void ar5212SetIFSTiming(struct ath_hal *, HAL_CHANNEL *);
60
61/* NB: public for RF backend use */
62void ar5212GetLowerUpperValues(uint16_t value,
63 uint16_t *pList, uint16_t listSize,
64 uint16_t *pLowerValue, uint16_t *pUpperValue);
65void ar5212ModifyRfBuffer(uint32_t *rfBuf, uint32_t reg32,
66 uint32_t numBits, uint32_t firstBit, uint32_t column);
67
68static int
69write_common(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
70 HAL_BOOL bChannelChange, int writes)
71{
72#define IS_NO_RESET_TIMER_ADDR(x) \
73 ( (((x) >= AR_BEACON) && ((x) <= AR_CFP_DUR)) || \
74 (((x) >= AR_SLEEP1) && ((x) <= AR_SLEEP3)))
75#define V(r, c) (ia)->data[((r)*(ia)->cols) + (c)]
76 int r;
77
78 /* Write Common Array Parameters */
79 for (r = 0; r < ia->rows; r++) {
80 uint32_t reg = V(r, 0);
81 /* XXX timer/beacon setup registers? */
82 /* On channel change, don't reset the PCU registers */
83 if (!(bChannelChange && IS_NO_RESET_TIMER_ADDR(reg))) {
84 OS_REG_WRITE(ah, reg, V(r, 1));
85 DMA_YIELD(writes);
86 }
87 }
88 return writes;
89#undef IS_NO_RESET_TIMER_ADDR
90#undef V
91}
92
93#define IS_DISABLE_FAST_ADC_CHAN(x) (((x) == 2462) || ((x) == 2467))
94
95/*
96 * Places the device in and out of reset and then places sane
97 * values in the registers based on EEPROM config, initialization
98 * vectors (as determined by the mode), and station configuration
99 *
100 * bChannelChange is used to preserve DMA/PCU registers across
101 * a HW Reset during channel change.
102 */
103HAL_BOOL
104ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
105 HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status)
106{
107#define N(a) (sizeof (a) / sizeof (a[0]))
108#define FAIL(_code) do { ecode = _code; goto bad; } while (0)
109 struct ath_hal_5212 *ahp = AH5212(ah);
110 HAL_CHANNEL_INTERNAL *ichan = AH_NULL;
111 const HAL_EEPROM *ee;
112 uint32_t softLedCfg, softLedState;
113 uint32_t saveFrameSeqCount, saveDefAntenna, saveLedState;
114 uint32_t macStaId1, synthDelay, txFrm2TxDStart;
115 uint16_t rfXpdGain[MAX_NUM_PDGAINS_PER_CHANNEL];
116 int16_t cckOfdmPwrDelta = 0;
117 u_int modesIndex, freqIndex;
118 HAL_STATUS ecode;
119 int i, regWrites;
120 uint32_t testReg, powerVal;
121 int8_t twiceAntennaGain, twiceAntennaReduction;
122 uint32_t ackTpcPow, ctsTpcPow, chirpTpcPow;
123 HAL_BOOL isBmode = AH_FALSE;
124 HAL_BOOL ichan_isBmode = AH_FALSE;
125
126 HALASSERT(ah->ah_magic == AR5212_MAGIC);
127 ee = AH_PRIVATE(ah)->ah_eeprom;
128
129 OS_MARK(ah, AH_MARK_RESET, bChannelChange);
130#define IS(_c,_f) (((_c)->channelFlags & _f) || 0)
131 if ((IS(chan, CHANNEL_2GHZ) ^ IS(chan, CHANNEL_5GHZ)) == 0) {
132 HALDEBUG(ah, HAL_DEBUG_ANY,
133 "%s: invalid channel %u/0x%x; not marked as 2GHz or 5GHz\n",
134 __func__, chan->channel, chan->channelFlags);
135 FAIL(HAL_EINVAL);
136 }
137 if ((IS(chan, CHANNEL_OFDM) ^ IS(chan, CHANNEL_CCK)) == 0) {
138 HALDEBUG(ah, HAL_DEBUG_ANY,
139 "%s: invalid channel %u/0x%x; not marked as OFDM or CCK\n",
140 __func__, chan->channel, chan->channelFlags);
141 FAIL(HAL_EINVAL);
142 }
143#undef IS
144
145 /* Bring out of sleep mode */
146 if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
147 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip did not wakeup\n",
148 __func__);
149 FAIL(HAL_EIO);
150 }
151
152 /*
153 * Map public channel to private.
154 */
155 ichan = ath_hal_checkchannel(ah, chan);
156 if (ichan == AH_NULL) {
157 HALDEBUG(ah, HAL_DEBUG_ANY,
158 "%s: invalid channel %u/0x%x; no mapping\n",
159 __func__, chan->channel, chan->channelFlags);
160 FAIL(HAL_EINVAL);
161 }
162 switch (opmode) {
163 case HAL_M_STA:
164 case HAL_M_IBSS:
165 case HAL_M_HOSTAP:
166 case HAL_M_MONITOR:
167 break;
168 default:
169 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid operating mode %u\n",
170 __func__, opmode);
171 FAIL(HAL_EINVAL);
172 break;
173 }
174 HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER3);
175
176 SAVE_CCK(ah, ichan, ichan_isBmode);
177 SAVE_CCK(ah, chan, isBmode);
178
179 /* Preserve certain DMA hardware registers on a channel change */
180 if (bChannelChange) {
181 /*
182 * On Venice, the TSF is almost preserved across a reset;
183 * it requires doubling writes to the RESET_TSF
184 * bit in the AR_BEACON register; it also has the quirk
185 * of the TSF going back in time on the station (station
186 * latches onto the last beacon's tsf during a reset 50%
187 * of the times); the latter is not a problem for adhoc
188 * stations since as long as the TSF is behind, it will
189 * get resynchronized on receiving the next beacon; the
190 * TSF going backwards in time could be a problem for the
191 * sleep operation (supported on infrastructure stations
192 * only) - the best and most general fix for this situation
193 * is to resynchronize the various sleep/beacon timers on
194 * the receipt of the next beacon i.e. when the TSF itself
195 * gets resynchronized to the AP's TSF - power save is
196 * needed to be temporarily disabled until that time
197 *
198 * Need to save the sequence number to restore it after
199 * the reset!
200 */
201 saveFrameSeqCount = OS_REG_READ(ah, AR_D_SEQNUM);
202 } else
203 saveFrameSeqCount = 0; /* NB: silence compiler */
204#if 0
205 /*
206 * XXX disable for now; this appears to sometimes cause OFDM
207 * XXX timing error floods when ani is enabled and bg scanning
208 * XXX kicks in
209 */
210 /* If the channel change is across the same mode - perform a fast channel change */
211 if (IS_2413(ah) || IS_5413(ah)) {
212 /*
213 * Fast channel change can only be used when:
214 * -channel change requested - so it's not the initial reset.
215 * -it's not a change to the current channel -
216 * often called when switching modes on a channel
217 * -the modes of the previous and requested channel are the
218 * same
219 * XXX opmode shouldn't change either?
220 */
221 if (bChannelChange &&
222 (AH_PRIVATE(ah)->ah_curchan != AH_NULL) &&
223 (chan->channel != AH_PRIVATE(ah)->ah_curchan->channel) &&
224 ((chan->channelFlags & CHANNEL_ALL) ==
225 (AH_PRIVATE(ah)->ah_curchan->channelFlags & CHANNEL_ALL))) {
226 if (ar5212ChannelChange(ah, chan)) {
227 /* If ChannelChange completed - skip the rest of reset */
228 /* XXX ani? */
229 return AH_TRUE;
230 }
231 }
232 }
233#endif
234 /*
235 * Preserve the antenna on a channel change
236 */
237 saveDefAntenna = OS_REG_READ(ah, AR_DEF_ANTENNA);
238 if (saveDefAntenna == 0) /* XXX magic constants */
239 saveDefAntenna = 1;
240
241 /* Save hardware flag before chip reset clears the register */
242 macStaId1 = OS_REG_READ(ah, AR_STA_ID1) &
243 (AR_STA_ID1_BASE_RATE_11B | AR_STA_ID1_USE_DEFANT);
244
245 /* Save led state from pci config register */
246 saveLedState = OS_REG_READ(ah, AR_PCICFG) &
247 (AR_PCICFG_LEDCTL | AR_PCICFG_LEDMODE | AR_PCICFG_LEDBLINK |
248 AR_PCICFG_LEDSLOW);
249 softLedCfg = OS_REG_READ(ah, AR_GPIOCR);
250 softLedState = OS_REG_READ(ah, AR_GPIODO);
251
252 ar5212RestoreClock(ah, opmode); /* move to refclk operation */
253
254 /*
255 * Adjust gain parameters before reset if
256 * there's an outstanding gain updated.
257 */
258 (void) ar5212GetRfgain(ah);
259
260 if (!ar5212ChipReset(ah, chan)) {
261 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
262 FAIL(HAL_EIO);
263 }
264
265 /* Setup the indices for the next set of register array writes */
266 switch (chan->channelFlags & CHANNEL_ALL) {
267 case CHANNEL_A:
268 modesIndex = 1;
269 freqIndex = 1;
270 break;
271 case CHANNEL_T:
272 modesIndex = 2;
273 freqIndex = 1;
274 break;
275 case CHANNEL_B:
276 modesIndex = 3;
277 freqIndex = 2;
278 break;
279 case CHANNEL_PUREG:
280 modesIndex = 4;
281 freqIndex = 2;
282 break;
283 case CHANNEL_108G:
284 modesIndex = 5;
285 freqIndex = 2;
286 break;
287 default:
288 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
289 __func__, chan->channelFlags);
290 FAIL(HAL_EINVAL);
291 }
292
293 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
294
295 /* Set correct Baseband to analog shift setting to access analog chips. */
296 OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
297
298 regWrites = ath_hal_ini_write(ah, &ahp->ah_ini_modes, modesIndex, 0);
299 regWrites = write_common(ah, &ahp->ah_ini_common, bChannelChange,
300 regWrites);
301 ahp->ah_rfHal->writeRegs(ah, modesIndex, freqIndex, regWrites);
302
303 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
304
305 if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) {
306 ar5212SetIFSTiming(ah, chan);
307 if (IS_5413(ah)) {
308 /*
309 * Force window_length for 1/2 and 1/4 rate channels,
310 * the ini file sets this to zero otherwise.
311 */
312 OS_REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL,
313 AR_PHY_FRAME_CTL_WINLEN, 3);
314 }
315 }
316
317 /* Overwrite INI values for revised chipsets */
318 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2) {
319 /* ADC_CTL */
320 OS_REG_WRITE(ah, AR_PHY_ADC_CTL,
321 SM(2, AR_PHY_ADC_CTL_OFF_INBUFGAIN) |
322 SM(2, AR_PHY_ADC_CTL_ON_INBUFGAIN) |
323 AR_PHY_ADC_CTL_OFF_PWDDAC |
324 AR_PHY_ADC_CTL_OFF_PWDADC);
325
326 /* TX_PWR_ADJ */
327 if (chan->channel == 2484) {
328 cckOfdmPwrDelta = SCALE_OC_DELTA(
329 ee->ee_cckOfdmPwrDelta -
330 ee->ee_scaledCh14FilterCckDelta);
331 } else {
332 cckOfdmPwrDelta = SCALE_OC_DELTA(
333 ee->ee_cckOfdmPwrDelta);
334 }
335
336 if (IS_CHAN_G(chan)) {
337 OS_REG_WRITE(ah, AR_PHY_TXPWRADJ,
338 SM((ee->ee_cckOfdmPwrDelta*-1),
339 AR_PHY_TXPWRADJ_CCK_GAIN_DELTA) |
340 SM((cckOfdmPwrDelta*-1),
341 AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX));
342 } else {
343 OS_REG_WRITE(ah, AR_PHY_TXPWRADJ, 0);
344 }
345
346 /* Add barker RSSI thresh enable as disabled */
347 OS_REG_CLR_BIT(ah, AR_PHY_DAG_CTRLCCK,
348 AR_PHY_DAG_CTRLCCK_EN_RSSI_THR);
349 OS_REG_RMW_FIELD(ah, AR_PHY_DAG_CTRLCCK,
350 AR_PHY_DAG_CTRLCCK_RSSI_THR, 2);
351
352 /* Set the mute mask to the correct default */
353 OS_REG_WRITE(ah, AR_SEQ_MASK, 0x0000000F);
354 }
355
356 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_3) {
357 /* Clear reg to alllow RX_CLEAR line debug */
358 OS_REG_WRITE(ah, AR_PHY_BLUETOOTH, 0);
359 }
360 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_4) {
361#ifdef notyet
362 /* Enable burst prefetch for the data queues */
363 OS_REG_RMW_FIELD(ah, AR_D_FPCTL, ... );
364 /* Enable double-buffering */
365 OS_REG_CLR_BIT(ah, AR_TXCFG, AR_TXCFG_DBL_BUF_DIS);
366#endif
367 }
368
369 /* Set ADC/DAC select values */
370 OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e);
371
372 if (IS_5413(ah) || IS_2417(ah)) {
373 uint32_t newReg=1;
374 if (IS_DISABLE_FAST_ADC_CHAN(chan->channel))
375 newReg = 0;
376 /* As it's a clock changing register, only write when the value needs to be changed */
377 if (OS_REG_READ(ah, AR_PHY_FAST_ADC) != newReg)
378 OS_REG_WRITE(ah, AR_PHY_FAST_ADC, newReg);
379 }
380
381 /* Setup the transmit power values. */
382 if (!ar5212SetTransmitPower(ah, ichan, rfXpdGain)) {
383 HALDEBUG(ah, HAL_DEBUG_ANY,
384 "%s: error init'ing transmit power\n", __func__);
385 FAIL(HAL_EIO);
386 }
387
388 /* Write the analog registers */
389 if (!ahp->ah_rfHal->setRfRegs(ah, ichan, modesIndex, rfXpdGain)) {
390 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5212SetRfRegs failed\n",
391 __func__);
392 FAIL(HAL_EIO);
393 }
394
395 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */
396 if (IS_CHAN_OFDM(chan)) {
397 if ((IS_5413(ah) || (AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3)) &&
398 (!IS_CHAN_B(chan)))
399 ar5212SetSpurMitigation(ah, ichan);
400 ar5212SetDeltaSlope(ah, chan);
401 }
402
403 /* Setup board specific options for EEPROM version 3 */
404 if (!ar5212SetBoardValues(ah, ichan)) {
405 HALDEBUG(ah, HAL_DEBUG_ANY,
406 "%s: error setting board options\n", __func__);
407 FAIL(HAL_EIO);
408 }
409
410 /* Restore certain DMA hardware registers on a channel change */
411 if (bChannelChange)
412 OS_REG_WRITE(ah, AR_D_SEQNUM, saveFrameSeqCount);
413
414 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
415
416 OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr));
417 OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4)
418 | macStaId1
419 | AR_STA_ID1_RTS_USE_DEF
420 | ahp->ah_staId1Defaults
421 );
422 ar5212SetOperatingMode(ah, opmode);
423
424 /* Set Venice BSSID mask according to current state */
425 OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask));
426 OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4));
427
428 /* Restore previous led state */
429 OS_REG_WRITE(ah, AR_PCICFG, OS_REG_READ(ah, AR_PCICFG) | saveLedState);
430
431 /* Restore soft Led state to GPIO */
432 OS_REG_WRITE(ah, AR_GPIOCR, softLedCfg);
433 OS_REG_WRITE(ah, AR_GPIODO, softLedState);
434
435 /* Restore previous antenna */
436 OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
437
438 /* then our BSSID */
439 OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
440 OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4));
441
442 /* Restore bmiss rssi & count thresholds */
443 OS_REG_WRITE(ah, AR_RSSI_THR, ahp->ah_rssiThr);
444
445 OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */
446
447 if (!ar5212SetChannel(ah, ichan))
448 FAIL(HAL_EIO);
449
450 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
451
452 ar5212SetCoverageClass(ah, AH_PRIVATE(ah)->ah_coverageClass, 1);
453
454 ar5212SetRateDurationTable(ah, chan);
455
456 /* Set Tx frame start to tx data start delay */
457 if (IS_RAD5112_ANY(ah) &&
458 (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan) ||
459 IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan))) {
460 txFrm2TxDStart =
461 (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) ?
462 TX_FRAME_D_START_HALF_RATE:
463 TX_FRAME_D_START_QUARTER_RATE;
464 OS_REG_RMW_FIELD(ah, AR_PHY_TX_CTL,
465 AR_PHY_TX_FRAME_TO_TX_DATA_START, txFrm2TxDStart);
466 }
467
468 /*
469 * Setup fast diversity.
470 * Fast diversity can be enabled or disabled via regadd.txt.
471 * Default is enabled.
472 * For reference,
473 * Disable: reg val
474 * 0x00009860 0x00009d18 (if 11a / 11g, else no change)
475 * 0x00009970 0x192bb514
476 * 0x0000a208 0xd03e4648
477 *
478 * Enable: 0x00009860 0x00009d10 (if 11a / 11g, else no change)
479 * 0x00009970 0x192fb514
480 * 0x0000a208 0xd03e6788
481 */
482
483 /* XXX Setup pre PHY ENABLE EAR additions */
484 /*
485 * Wait for the frequency synth to settle (synth goes on
486 * via AR_PHY_ACTIVE_EN). Read the phy active delay register.
487 * Value is in 100ns increments.
488 */
489 synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
490 if (IS_CHAN_CCK(chan)) {
491 synthDelay = (4 * synthDelay) / 22;
492 } else {
493 synthDelay /= 10;
494 }
495
496 /* Activate the PHY (includes baseband activate and synthesizer on) */
497 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
498
499 /*
500 * There is an issue if the AP starts the calibration before
501 * the base band timeout completes. This could result in the
502 * rx_clear false triggering. As a workaround we add delay an
503 * extra BASE_ACTIVATE_DELAY usecs to ensure this condition
504 * does not happen.
505 */
506 if (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) {
507 OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY);
508 } else if (IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan)) {
509 OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY);
510 } else {
511 OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);
512 }
513
514 /*
515 * The udelay method is not reliable with notebooks.
516 * Need to check to see if the baseband is ready
517 */
518 testReg = OS_REG_READ(ah, AR_PHY_TESTCTRL);
519 /* Selects the Tx hold */
520 OS_REG_WRITE(ah, AR_PHY_TESTCTRL, AR_PHY_TESTCTRL_TXHOLD);
521 i = 0;
522 while ((i++ < 20) &&
523 (OS_REG_READ(ah, 0x9c24) & 0x10)) /* test if baseband not ready */ OS_DELAY(200);
524 OS_REG_WRITE(ah, AR_PHY_TESTCTRL, testReg);
525
526 /* Calibrate the AGC and start a NF calculation */
527 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
528 OS_REG_READ(ah, AR_PHY_AGC_CONTROL)
529 | AR_PHY_AGC_CONTROL_CAL
530 | AR_PHY_AGC_CONTROL_NF);
531
532 if (!IS_CHAN_B(chan) && ahp->ah_bIQCalibration != IQ_CAL_DONE) {
533 /* Start IQ calibration w/ 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples */
534 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
535 AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
536 INIT_IQCAL_LOG_COUNT_MAX);
537 OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4,
538 AR_PHY_TIMING_CTRL4_DO_IQCAL);
539 ahp->ah_bIQCalibration = IQ_CAL_RUNNING;
540 } else
541 ahp->ah_bIQCalibration = IQ_CAL_INACTIVE;
542
543 /* Setup compression registers */
544 ar5212SetCompRegs(ah);
545
546 /* Set 1:1 QCU to DCU mapping for all queues */
547 for (i = 0; i < AR_NUM_DCU; i++)
548 OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
549
550 ahp->ah_intrTxqs = 0;
551 for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++)
552 ar5212ResetTxQueue(ah, i);
553
554 /*
555 * Setup interrupt handling. Note that ar5212ResetTxQueue
556 * manipulates the secondary IMR's as queues are enabled
557 * and disabled. This is done with RMW ops to insure the
558 * settings we make here are preserved.
559 */
560 ahp->ah_maskReg = AR_IMR_TXOK | AR_IMR_TXERR | AR_IMR_TXURN
561 | AR_IMR_RXOK | AR_IMR_RXERR | AR_IMR_RXORN
562 | AR_IMR_HIUERR
563 ;
564 if (opmode == HAL_M_HOSTAP)
565 ahp->ah_maskReg |= AR_IMR_MIB;
566 OS_REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
567 /* Enable bus errors that are OR'd to set the HIUERR bit */
568 OS_REG_WRITE(ah, AR_IMR_S2,
569 OS_REG_READ(ah, AR_IMR_S2)
570 | AR_IMR_S2_MCABT | AR_IMR_S2_SSERR | AR_IMR_S2_DPERR);
571
572 if (AH_PRIVATE(ah)->ah_rfkillEnabled)
573 ar5212EnableRfKill(ah);
574
575 if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
576 HALDEBUG(ah, HAL_DEBUG_ANY,
577 "%s: offset calibration failed to complete in 1ms;"
578 " noisy environment?\n", __func__);
579 }
580
581 /*
582 * Set clocks back to 32kHz if they had been using refClk, then
583 * use an external 32kHz crystal when sleeping, if one exists.
584 */
585 ar5212SetupClock(ah, opmode);
586
587 /*
588 * Writing to AR_BEACON will start timers. Hence it should
589 * be the last register to be written. Do not reset tsf, do
590 * not enable beacons at this point, but preserve other values
591 * like beaconInterval.
592 */
593 OS_REG_WRITE(ah, AR_BEACON,
594 (OS_REG_READ(ah, AR_BEACON) &~ (AR_BEACON_EN | AR_BEACON_RESET_TSF)));
595
596 /* XXX Setup post reset EAR additions */
597
598 /* QoS support */
599 if (AH_PRIVATE(ah)->ah_macVersion > AR_SREV_VERSION_VENICE ||
600 (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_VENICE &&
601 AH_PRIVATE(ah)->ah_macRev >= AR_SREV_GRIFFIN_LITE)) {
602 OS_REG_WRITE(ah, AR_QOS_CONTROL, 0x100aa); /* XXX magic */
603 OS_REG_WRITE(ah, AR_QOS_SELECT, 0x3210); /* XXX magic */
604 }
605
606 /* Turn on NOACK Support for QoS packets */
607 OS_REG_WRITE(ah, AR_NOACK,
608 SM(2, AR_NOACK_2BIT_VALUE) |
609 SM(5, AR_NOACK_BIT_OFFSET) |
610 SM(0, AR_NOACK_BYTE_OFFSET));
611
612 /* Get Antenna Gain reduction */
613 if (IS_CHAN_5GHZ(chan)) {
614 ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_5, &twiceAntennaGain);
615 } else {
616 ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_2, &twiceAntennaGain);
617 }
618 twiceAntennaReduction =
619 ath_hal_getantennareduction(ah, chan, twiceAntennaGain);
620
621 /* TPC for self-generated frames */
622
623 ackTpcPow = MS(ahp->ah_macTPC, AR_TPC_ACK);
624 if ((ackTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower)
625 ackTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset;
626
627 if (ackTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction))
628 ackTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction)
629 + ahp->ah_txPowerIndexOffset;
630
631 ctsTpcPow = MS(ahp->ah_macTPC, AR_TPC_CTS);
632 if ((ctsTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower)
633 ctsTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset;
634
635 if (ctsTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction))
636 ctsTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction)
637 + ahp->ah_txPowerIndexOffset;
638
639 chirpTpcPow = MS(ahp->ah_macTPC, AR_TPC_CHIRP);
640 if ((chirpTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower)
641 chirpTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset;
642
643 if (chirpTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction))
644 chirpTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction)
645 + ahp->ah_txPowerIndexOffset;
646
647 if (ackTpcPow > 63)
648 ackTpcPow = 63;
649 if (ctsTpcPow > 63)
650 ctsTpcPow = 63;
651 if (chirpTpcPow > 63)
652 chirpTpcPow = 63;
653
654 powerVal = SM(ackTpcPow, AR_TPC_ACK) |
655 SM(ctsTpcPow, AR_TPC_CTS) |
656 SM(chirpTpcPow, AR_TPC_CHIRP);
657
658 OS_REG_WRITE(ah, AR_TPC, powerVal);
659
660 /* Restore user-specified settings */
661 if (ahp->ah_miscMode != 0)
662 OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);
663 if (ahp->ah_sifstime != (u_int) -1)
664 ar5212SetSifsTime(ah, ahp->ah_sifstime);
665 if (ahp->ah_slottime != (u_int) -1)
666 ar5212SetSlotTime(ah, ahp->ah_slottime);
667 if (ahp->ah_acktimeout != (u_int) -1)
668 ar5212SetAckTimeout(ah, ahp->ah_acktimeout);
669 if (ahp->ah_ctstimeout != (u_int) -1)
670 ar5212SetCTSTimeout(ah, ahp->ah_ctstimeout);
671 if (AH_PRIVATE(ah)->ah_diagreg != 0)
672 OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);
673
674 AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */
675
676 if (bChannelChange) {
677 if (!(ichan->privFlags & CHANNEL_DFS))
678 ichan->privFlags &= ~CHANNEL_INTERFERENCE;
679 chan->channelFlags = ichan->channelFlags;
680 chan->privFlags = ichan->privFlags;
681 chan->maxRegTxPower = ichan->maxRegTxPower;
682 chan->maxTxPower = ichan->maxTxPower;
683 chan->minTxPower = ichan->minTxPower;
684 }
685
686 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__);
687
688 RESTORE_CCK(ah, ichan, ichan_isBmode);
689 RESTORE_CCK(ah, chan, isBmode);
690
691 OS_MARK(ah, AH_MARK_RESET_DONE, 0);
692
693 return AH_TRUE;
694bad:
695 if (ichan != AH_NULL)
696 RESTORE_CCK(ah, ichan, ichan_isBmode);
697 RESTORE_CCK(ah, chan, isBmode);
698
699 OS_MARK(ah, AH_MARK_RESET_DONE, ecode);
700 if (*status)
701 *status = ecode;
702 return AH_FALSE;
703#undef FAIL
704#undef N
705}
706
707/*
708 * Call the rf backend to change the channel.
709 */
710HAL_BOOL
711ar5212SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
712{
713 struct ath_hal_5212 *ahp = AH5212(ah);
714
715 /* Change the synth */
716 if (!ahp->ah_rfHal->setChannel(ah, chan))
717 return AH_FALSE;
718 return AH_TRUE;
719}
720
721/*
722 * This channel change evaluates whether the selected hardware can
723 * perform a synthesizer-only channel change (no reset). If the
724 * TX is not stopped, or the RFBus cannot be granted in the given
725 * time, the function returns false as a reset is necessary
726 */
727HAL_BOOL
728ar5212ChannelChange(struct ath_hal *ah, HAL_CHANNEL *chan)
729{
730 uint32_t ulCount;
731 uint32_t data, synthDelay, qnum;
732 uint16_t rfXpdGain[MAX_NUM_PDGAINS_PER_CHANNEL];
733 HAL_BOOL txStopped = AH_TRUE;
734 HAL_CHANNEL_INTERNAL *ichan;
735
736 /*
737 * Map public channel to private.
738 */
739 ichan = ath_hal_checkchannel(ah, chan);
740
741 /* TX must be stopped or RF Bus grant will not work */
742 for (qnum = 0; qnum < AH_PRIVATE(ah)->ah_caps.halTotalQueues; qnum++) {
743 if (ar5212NumTxPending(ah, qnum)) {
744 txStopped = AH_FALSE;
745 break;
746 }
747 }
748 if (!txStopped)
749 return AH_FALSE;
750
751 /* Kill last Baseband Rx Frame */
752 OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_REQUEST); /* Request analog bus grant */
753 for (ulCount = 0; ulCount < 100; ulCount++) {
754 if (OS_REG_READ(ah, AR_PHY_RFBUS_GNT))
755 break;
756 OS_DELAY(5);
757 }
758 if (ulCount >= 100)
759 return AH_FALSE;
760
761 /* Change the synth */
762 if (!ar5212SetChannel(ah, ichan))
763 return AH_FALSE;
764
765 /*
766 * Wait for the frequency synth to settle (synth goes on via PHY_ACTIVE_EN).
767 * Read the phy active delay register. Value is in 100ns increments.
768 */
769 data = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
770 if (IS_CHAN_CCK(ichan)) {
771 synthDelay = (4 * data) / 22;
772 } else {
773 synthDelay = data / 10;
774 }
775 OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);
776
777 /* Setup the transmit power values. */
778 if (!ar5212SetTransmitPower(ah, ichan, rfXpdGain)) {
779 HALDEBUG(ah, HAL_DEBUG_ANY,
780 "%s: error init'ing transmit power\n", __func__);
781 return AH_FALSE;
782 }
783
784 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */
785 if (IS_CHAN_OFDM(ichan)) {
786 if ((IS_5413(ah) || (AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3)) &&
787 (!IS_CHAN_B(chan)))
788 ar5212SetSpurMitigation(ah, ichan);
789 ar5212SetDeltaSlope(ah, chan);
790 }
791
792 /* Release the RFBus Grant */
793 OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
794
795 /* Start Noise Floor Cal */
796 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
797
798 if (!(ichan->privFlags & CHANNEL_DFS))
799 ichan->privFlags &= ~CHANNEL_INTERFERENCE;
800 chan->channelFlags = ichan->channelFlags;
801 chan->privFlags = ichan->privFlags;
802 chan->maxRegTxPower = ichan->maxRegTxPower;
803 chan->maxTxPower = ichan->maxTxPower;
804 chan->minTxPower = ichan->minTxPower;
805 return AH_TRUE;
806}
807
808void
809ar5212SetOperatingMode(struct ath_hal *ah, int opmode)
810{
811 uint32_t val;
812
813 val = OS_REG_READ(ah, AR_STA_ID1);
814 val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
815 switch (opmode) {
816 case HAL_M_HOSTAP:
817 OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP
818 | AR_STA_ID1_KSRCH_MODE);
819 OS_REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
820 break;
821 case HAL_M_IBSS:
822 OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
823 | AR_STA_ID1_KSRCH_MODE);
824 OS_REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
825 break;
826 case HAL_M_STA:
827 case HAL_M_MONITOR:
828 OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
829 break;
830 }
831}
832
833/*
834 * Places the PHY and Radio chips into reset. A full reset
835 * must be called to leave this state. The PCI/MAC/PCU are
836 * not placed into reset as we must receive interrupt to
837 * re-enable the hardware.
838 */
839HAL_BOOL
840ar5212PhyDisable(struct ath_hal *ah)
841{
842 return ar5212SetResetReg(ah, AR_RC_BB);
843}
844
845/*
846 * Places all of hardware into reset
847 */
848HAL_BOOL
849ar5212Disable(struct ath_hal *ah)
850{
851 if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
852 return AH_FALSE;
853 /*
854 * Reset the HW - PCI must be reset after the rest of the
855 * device has been reset.
856 */
857 return ar5212SetResetReg(ah, AR_RC_MAC | AR_RC_BB | AR_RC_PCI);
858}
859
860/*
861 * Places the hardware into reset and then pulls it out of reset
862 *
863 * TODO: Only write the PLL if we're changing to or from CCK mode
864 *
865 * WARNING: The order of the PLL and mode registers must be correct.
866 */
867HAL_BOOL
868ar5212ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
869{
870
871 OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->channel : 0);
872
873 /*
874 * Reset the HW - PCI must be reset after the rest of the
875 * device has been reset
876 */
877 if (!ar5212SetResetReg(ah, AR_RC_MAC | AR_RC_BB | AR_RC_PCI))
878 return AH_FALSE;
879
880 /* Bring out of sleep mode (AGAIN) */
881 if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
882 return AH_FALSE;
883
884 /* Clear warm reset register */
885 if (!ar5212SetResetReg(ah, 0))
886 return AH_FALSE;
887
888 /*
889 * Perform warm reset before the mode/PLL/turbo registers
890 * are changed in order to deactivate the radio. Mode changes
891 * with an active radio can result in corrupted shifts to the
892 * radio device.
893 */
894
895 /*
896 * Set CCK and Turbo modes correctly.
897 */
898 if (chan != AH_NULL) { /* NB: can be null during attach */
899 uint32_t rfMode, phyPLL = 0, curPhyPLL, turbo;
900
901 if (IS_5413(ah)) { /* NB: =>'s 5424 also */
902 rfMode = AR_PHY_MODE_AR5112;
903 if (IS_CHAN_HALF_RATE(chan))
904 rfMode |= AR_PHY_MODE_HALF;
905 else if (IS_CHAN_QUARTER_RATE(chan))
906 rfMode |= AR_PHY_MODE_QUARTER;
907
908 if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))
909 phyPLL = AR_PHY_PLL_CTL_44_5112;
910 else
911 phyPLL = AR_PHY_PLL_CTL_40_5413;
912 } else if (IS_RAD5111(ah)) {
913 rfMode = AR_PHY_MODE_AR5111;
914 if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))
915 phyPLL = AR_PHY_PLL_CTL_44;
916 else
917 phyPLL = AR_PHY_PLL_CTL_40;
918 if (IS_CHAN_HALF_RATE(chan))
919 phyPLL = AR_PHY_PLL_CTL_HALF;
920 else if (IS_CHAN_QUARTER_RATE(chan))
921 phyPLL = AR_PHY_PLL_CTL_QUARTER;
922 } else { /* 5112, 2413, 2316, 2317 */
923 rfMode = AR_PHY_MODE_AR5112;
924 if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))
925 phyPLL = AR_PHY_PLL_CTL_44_5112;
926 else
927 phyPLL = AR_PHY_PLL_CTL_40_5112;
928 if (IS_CHAN_HALF_RATE(chan))
929 phyPLL |= AR_PHY_PLL_CTL_HALF;
930 else if (IS_CHAN_QUARTER_RATE(chan))
931 phyPLL |= AR_PHY_PLL_CTL_QUARTER;
932 }
933 if (IS_CHAN_OFDM(chan) && (IS_CHAN_CCK(chan) ||
934 IS_CHAN_G(chan)))
935 rfMode |= AR_PHY_MODE_DYNAMIC;
936 else if (IS_CHAN_OFDM(chan))
937 rfMode |= AR_PHY_MODE_OFDM;
938 else
939 rfMode |= AR_PHY_MODE_CCK;
940 if (IS_CHAN_5GHZ(chan))
941 rfMode |= AR_PHY_MODE_RF5GHZ;
942 else
943 rfMode |= AR_PHY_MODE_RF2GHZ;
944 turbo = IS_CHAN_TURBO(chan) ?
945 (AR_PHY_FC_TURBO_MODE | AR_PHY_FC_TURBO_SHORT) : 0;
946 curPhyPLL = OS_REG_READ(ah, AR_PHY_PLL_CTL);
947 /*
948 * PLL, Mode, and Turbo values must be written in the correct
949 * order to ensure:
950 * - The PLL cannot be set to 44 unless the CCK or DYNAMIC
951 * mode bit is set
952 * - Turbo cannot be set at the same time as CCK or DYNAMIC
953 */
954 if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) {
955 OS_REG_WRITE(ah, AR_PHY_TURBO, turbo);
956 OS_REG_WRITE(ah, AR_PHY_MODE, rfMode);
957 if (curPhyPLL != phyPLL) {
958 OS_REG_WRITE(ah, AR_PHY_PLL_CTL, phyPLL);
959 /* Wait for the PLL to settle */
960 OS_DELAY(PLL_SETTLE_DELAY);
961 }
962 } else {
963 if (curPhyPLL != phyPLL) {
964 OS_REG_WRITE(ah, AR_PHY_PLL_CTL, phyPLL);
965 /* Wait for the PLL to settle */
966 OS_DELAY(PLL_SETTLE_DELAY);
967 }
968 OS_REG_WRITE(ah, AR_PHY_TURBO, turbo);
969 OS_REG_WRITE(ah, AR_PHY_MODE, rfMode);
970 }
971 }
972 return AH_TRUE;
973}
974
975/*
976 * Recalibrate the lower PHY chips to account for temperature/environment
977 * changes.
978 */
979HAL_BOOL
980ar5212PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
981 HAL_BOOL longCal, HAL_BOOL *isCalDone)
982{
983#define IQ_CAL_TRIES 10
984 struct ath_hal_5212 *ahp = AH5212(ah);
985 HAL_CHANNEL_INTERNAL *ichan;
986 int32_t qCoff, qCoffDenom;
987 int32_t iqCorrMeas, iCoff, iCoffDenom;
988 uint32_t powerMeasQ, powerMeasI;
989 HAL_BOOL ichan_isBmode = AH_FALSE;
990 HAL_BOOL isBmode = AH_FALSE;
991
992 OS_MARK(ah, AH_MARK_PERCAL, chan->channel);
993 *isCalDone = AH_FALSE;
994 ichan = ath_hal_checkchannel(ah, chan);
995 if (ichan == AH_NULL) {
996 HALDEBUG(ah, HAL_DEBUG_ANY,
997 "%s: invalid channel %u/0x%x; no mapping\n",
998 __func__, chan->channel, chan->channelFlags);
999 return AH_FALSE;
1000 }
1001 SAVE_CCK(ah, ichan, ichan_isBmode);
1002 SAVE_CCK(ah, chan, isBmode);
1003
1004 if (ahp->ah_bIQCalibration == IQ_CAL_DONE ||
1005 ahp->ah_bIQCalibration == IQ_CAL_INACTIVE)
1006 *isCalDone = AH_TRUE;
1007
1008 /* IQ calibration in progress. Check to see if it has finished. */
1009 if (ahp->ah_bIQCalibration == IQ_CAL_RUNNING &&
1010 !(OS_REG_READ(ah, AR_PHY_TIMING_CTRL4) & AR_PHY_TIMING_CTRL4_DO_IQCAL)) {
1011 int i;
1012
1013 /* IQ Calibration has finished. */
1014 ahp->ah_bIQCalibration = IQ_CAL_INACTIVE;
1015 *isCalDone = AH_TRUE;
1016
1017 /* workaround for misgated IQ Cal results */
1018 i = 0;
1019 do {
1020 /* Read calibration results. */
1021 powerMeasI = OS_REG_READ(ah, AR_PHY_IQCAL_RES_PWR_MEAS_I);
1022 powerMeasQ = OS_REG_READ(ah, AR_PHY_IQCAL_RES_PWR_MEAS_Q);
1023 iqCorrMeas = OS_REG_READ(ah, AR_PHY_IQCAL_RES_IQ_CORR_MEAS);
1024 if (powerMeasI && powerMeasQ)
1025 break;
1026 /* Do we really need this??? */
1027 OS_REG_WRITE (ah, AR_PHY_TIMING_CTRL4,
1028 OS_REG_READ(ah, AR_PHY_TIMING_CTRL4) |
1029 AR_PHY_TIMING_CTRL4_DO_IQCAL);
1030 } while (++i < IQ_CAL_TRIES);
1031
1032 /*
1033 * Prescale these values to remove 64-bit operation
1034 * requirement at the loss of a little precision.
1035 */
1036 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
1037 qCoffDenom = powerMeasQ / 128;
1038
1039 /* Protect against divide-by-0 and loss of sign bits. */
1040 if (iCoffDenom != 0 && qCoffDenom >= 2) {
1041 iCoff = (int8_t)(-iqCorrMeas) / iCoffDenom;
1042 /* IQCORR_Q_I_COFF is a signed 6 bit number */
1043 if (iCoff < -32) {
1044 iCoff = -32;
1045 } else if (iCoff > 31) {
1046 iCoff = 31;
1047 }
1048
1049 /* IQCORR_Q_Q_COFF is a signed 5 bit number */
1050 qCoff = (powerMeasI / qCoffDenom) - 128;
1051 if (qCoff < -16) {
1052 qCoff = -16;
1053 } else if (qCoff > 15) {
1054 qCoff = 15;
1055 }
1056
1057 HALDEBUG(ah, HAL_DEBUG_PERCAL,
1058 "****************** MISGATED IQ CAL! *******************\n");
1059 HALDEBUG(ah, HAL_DEBUG_PERCAL,
1060 "time = %d, i = %d, \n", OS_GETUPTIME(ah), i);
1061 HALDEBUG(ah, HAL_DEBUG_PERCAL,
1062 "powerMeasI = 0x%08x\n", powerMeasI);
1063 HALDEBUG(ah, HAL_DEBUG_PERCAL,
1064 "powerMeasQ = 0x%08x\n", powerMeasQ);
1065 HALDEBUG(ah, HAL_DEBUG_PERCAL,
1066 "iqCorrMeas = 0x%08x\n", iqCorrMeas);
1067 HALDEBUG(ah, HAL_DEBUG_PERCAL,
1068 "iCoff = %d\n", iCoff);
1069 HALDEBUG(ah, HAL_DEBUG_PERCAL,
1070 "qCoff = %d\n", qCoff);
1071
1072 /* Write values and enable correction */
1073 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
1074 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, iCoff);
1075 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
1076 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, qCoff);
1077 OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4,
1078 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
1079
1080 ahp->ah_bIQCalibration = IQ_CAL_DONE;
1081 ichan->iqCalValid = AH_TRUE;
1082 ichan->iCoff = iCoff;
1083 ichan->qCoff = qCoff;
1084 }
1085 } else if (!IS_CHAN_B(chan) && ahp->ah_bIQCalibration == IQ_CAL_DONE &&
1086 !ichan->iqCalValid) {
1087 /*
1088 * Start IQ calibration if configured channel has changed.
1089 * Use a magic number of 15 based on default value.
1090 */
1091 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
1092 AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
1093 INIT_IQCAL_LOG_COUNT_MAX);
1094 OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4,
1095 AR_PHY_TIMING_CTRL4_DO_IQCAL);
1096 ahp->ah_bIQCalibration = IQ_CAL_RUNNING;
1097 }
1098 /* XXX EAR */
1099
1100 if (longCal) {
1101 /* Check noise floor results */
1102 ar5212GetNf(ah, ichan);
1103
1104 if ((ichan->channelFlags & CHANNEL_CW_INT) == 0) {
1105 /* Perform cal for 5Ghz channels and any OFDM on 5112 */
1106 if (IS_CHAN_5GHZ(chan) ||
1107 (IS_RAD5112(ah) && IS_CHAN_OFDM(chan)))
1108 ar5212RequestRfgain(ah);
1109 } else {
1110 /* report up and clear internal state */
1111 chan->channelFlags |= CHANNEL_CW_INT;
1112 ichan->channelFlags &= ~CHANNEL_CW_INT;
1113 }
1114 }
1115 RESTORE_CCK(ah, ichan, ichan_isBmode);
1116 RESTORE_CCK(ah, chan, isBmode);
1117
1118 return AH_TRUE;
1119#undef IQ_CAL_TRIES
1120}
1121
1122HAL_BOOL
1123ar5212PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
1124{
1125 return ar5212PerCalibrationN(ah, chan, 0x1, AH_TRUE, isIQdone);
1126}
1127
1128HAL_BOOL
1129ar5212ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan)
1130{
1131 /* XXX */
1132 return AH_TRUE;
1133}
1134
1135/*
1136 * Write the given reset bit mask into the reset register
1137 */
1138static HAL_BOOL
1139ar5212SetResetReg(struct ath_hal *ah, uint32_t resetMask)
1140{
1141 uint32_t mask = resetMask ? resetMask : ~0;
1142 HAL_BOOL rt;
1143
1144 /* XXX ar5212MacStop & co. */
1145
1146 if (IS_PCIE(ah)) {
1147 resetMask &= ~AR_RC_PCI;
1148 }
1149
1150 (void) OS_REG_READ(ah, AR_RXDP);/* flush any pending MMR writes */
1151 OS_REG_WRITE(ah, AR_RC, resetMask);
1152 OS_DELAY(15); /* need to wait at least 128 clocks
1153 when reseting PCI before read */
1154 mask &= (AR_RC_MAC | AR_RC_BB);
1155 resetMask &= (AR_RC_MAC | AR_RC_BB);
1156 rt = ath_hal_wait(ah, AR_RC, mask, resetMask);
1157 if ((resetMask & AR_RC_MAC) == 0) {
1158 if (isBigEndian()) {
1159 /*
1160 * Set CFG, little-endian for register
1161 * and descriptor accesses.
1162 */
1163 mask = INIT_CONFIG_STATUS | AR_CFG_SWRD | AR_CFG_SWRG;
1164#ifndef AH_NEED_DESC_SWAP
1165 mask |= AR_CFG_SWTD;
1166#endif
1167 OS_REG_WRITE(ah, AR_CFG, LE_READ_4(&mask));
1168 } else
1169 OS_REG_WRITE(ah, AR_CFG, INIT_CONFIG_STATUS);
1170 if (ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
1171 (void) OS_REG_READ(ah, AR_ISR_RAC);
1172 }
1173
1174 /* track PHY power state so we don't try to r/w BB registers */
1175 AH5212(ah)->ah_phyPowerOn = ((resetMask & AR_RC_BB) == 0);
1176 return rt;
1177}
1178
1179int16_t
1180ar5212GetNoiseFloor(struct ath_hal *ah)
1181{
1182 int16_t nf = (OS_REG_READ(ah, AR_PHY(25)) >> 19) & 0x1ff;
1183 if (nf & 0x100)
1184 nf = 0 - ((nf ^ 0x1ff) + 1);
1185 return nf;
1186}
1187
1188static HAL_BOOL
1189getNoiseFloorThresh(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *chan,
1190 int16_t *nft)
1191{
1192 const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1193
1194 HALASSERT(ah->ah_magic == AR5212_MAGIC);
1195
1196 switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {
1197 case CHANNEL_A:
1198 *nft = ee->ee_noiseFloorThresh[headerInfo11A];
1199 break;
1200 case CHANNEL_B:
1201 *nft = ee->ee_noiseFloorThresh[headerInfo11B];
1202 break;
1203 case CHANNEL_PUREG:
1204 *nft = ee->ee_noiseFloorThresh[headerInfo11G];
1205 break;
1206 default:
1207 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
1208 __func__, chan->channelFlags);
1209 return AH_FALSE;
1210 }
1211 return AH_TRUE;
1212}
1213
1214/*
1215 * Setup the noise floor cal history buffer.
1216 */
1217void
1218ar5212InitNfCalHistBuffer(struct ath_hal *ah)
1219{
1220 struct ath_hal_5212 *ahp = AH5212(ah);
1221 int i;
1222
1223 ahp->ah_nfCalHist.first_run = 1;
1224 ahp->ah_nfCalHist.currIndex = 0;
1225 ahp->ah_nfCalHist.privNF = AR5212_CCA_MAX_GOOD_VALUE;
1226 ahp->ah_nfCalHist.invalidNFcount = AR512_NF_CAL_HIST_MAX;
1227 for (i = 0; i < AR512_NF_CAL_HIST_MAX; i ++)
1228 ahp->ah_nfCalHist.nfCalBuffer[i] = AR5212_CCA_MAX_GOOD_VALUE;
1229}
1230
1231/*
1232 * Add a noise floor value to the ring buffer.
1233 */
1234static __inline void
1235updateNFHistBuff(struct ar5212NfCalHist *h, int16_t nf)
1236{
1237 h->nfCalBuffer[h->currIndex] = nf;
1238 if (++h->currIndex >= AR512_NF_CAL_HIST_MAX)
1239 h->currIndex = 0;
1240}
1241
1242/*
1243 * Return the median noise floor value in the ring buffer.
1244 */
1245int16_t
1246ar5212GetNfHistMid(const int16_t calData[AR512_NF_CAL_HIST_MAX])
1247{
1248 int16_t sort[AR512_NF_CAL_HIST_MAX];
1249 int i, j;
1250
1251 OS_MEMCPY(sort, calData, AR512_NF_CAL_HIST_MAX*sizeof(int16_t));
1252 for (i = 0; i < AR512_NF_CAL_HIST_MAX-1; i ++) {
1253 for (j = 1; j < AR512_NF_CAL_HIST_MAX-i; j ++) {
1254 if (sort[j] > sort[j-1]) {
1255 int16_t nf = sort[j];
1256 sort[j] = sort[j-1];
1257 sort[j-1] = nf;
1258 }
1259 }
1260 }
1261 return sort[(AR512_NF_CAL_HIST_MAX-1)>>1];
1262}
1263
1264/*
1265 * Read the NF and check it against the noise floor threshhold
1266 */
1267int16_t
1268ar5212GetNf(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
1269{
1270 struct ath_hal_5212 *ahp = AH5212(ah);
1271 struct ar5212NfCalHist *h = &ahp->ah_nfCalHist;
1272 int16_t nf, nfThresh;
1273 int32_t val;
1274
1275 if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
1276 HALDEBUG(ah, HAL_DEBUG_ANY,
1277 "%s: NF did not complete in calibration window\n", __func__);
1278 chan->rawNoiseFloor = h->privNF; /* most recent value */
1279 return chan->rawNoiseFloor;
1280 }
1281
1282 /*
1283 * Finished NF cal, check against threshold.
1284 */
1285 nf = ar5212GetNoiseFloor(ah);
1286 if (getNoiseFloorThresh(ah, chan, &nfThresh)) {
1287 if (nf > nfThresh) {
1288 HALDEBUG(ah, HAL_DEBUG_ANY,
1289 "%s: noise floor failed detected; detected %u, "
1290 "threshold %u\n", __func__, nf, nfThresh);
1291 /*
1292 * NB: Don't discriminate 2.4 vs 5Ghz, if this
1293 * happens it indicates a problem regardless
1294 * of the band.
1295 */
1296 chan->channelFlags |= CHANNEL_CW_INT;
1297 nf = 0;
1298 }
1299 } else
1300 nf = 0;
1301
1302 /*
1303 * Pass through histogram and write median value as
1304 * calculated from the accrued window. We require a
1305 * full window of in-range values to be seen before we
1306 * start using the history.
1307 */
1308 updateNFHistBuff(h, nf);
1309 if (h->first_run) {
1310 if (nf < AR5212_CCA_MIN_BAD_VALUE ||
1311 nf > AR5212_CCA_MAX_HIGH_VALUE) {
1312 nf = AR5212_CCA_MAX_GOOD_VALUE;
1313 h->invalidNFcount = AR512_NF_CAL_HIST_MAX;
1314 } else if (--(h->invalidNFcount) == 0) {
1315 h->first_run = 0;
1316 h->privNF = nf = ar5212GetNfHistMid(h->nfCalBuffer);
1317 } else {
1318 nf = AR5212_CCA_MAX_GOOD_VALUE;
1319 }
1320 } else {
1321 h->privNF = nf = ar5212GetNfHistMid(h->nfCalBuffer);
1322 }
1323
1324 val = OS_REG_READ(ah, AR_PHY(25));
1325 val &= 0xFFFFFE00;
1326 val |= (((uint32_t)nf << 1) & 0x1FF);
1327 OS_REG_WRITE(ah, AR_PHY(25), val);
1328 OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
1329 OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1330 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1331
1332 if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF, 0)) {
1333#ifdef AH_DEBUG
1334 ath_hal_printf(ah, "%s: AGC not ready AGC_CONTROL 0x%x\n",
1335 __func__, OS_REG_READ(ah, AR_PHY_AGC_CONTROL));
1336#endif
1337 }
1338
1339 /*
1340 * Now load a high maxCCAPower value again so that we're
1341 * not capped by the median we just loaded
1342 */
1343 val &= 0xFFFFFE00;
1344 val |= (((uint32_t)(-50) << 1) & 0x1FF);
1345 OS_REG_WRITE(ah, AR_PHY(25), val);
1346 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
1347 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1348 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1349
1350 return (chan->rawNoiseFloor = nf);
1351}
1352
1353/*
1354 * Set up compression configuration registers
1355 */
1356void
1357ar5212SetCompRegs(struct ath_hal *ah)
1358{
1359 struct ath_hal_5212 *ahp = AH5212(ah);
1360 int i;
1361
1362 /* Check if h/w supports compression */
1363 if (!AH_PRIVATE(ah)->ah_caps.halCompressSupport)
1364 return;
1365
1366 OS_REG_WRITE(ah, AR_DCCFG, 1);
1367
1368 OS_REG_WRITE(ah, AR_CCFG,
1369 (AR_COMPRESSION_WINDOW_SIZE >> 8) & AR_CCFG_WIN_M);
1370
1371 OS_REG_WRITE(ah, AR_CCFG,
1372 OS_REG_READ(ah, AR_CCFG) | AR_CCFG_MIB_INT_EN);
1373 OS_REG_WRITE(ah, AR_CCUCFG,
1374 AR_CCUCFG_RESET_VAL | AR_CCUCFG_CATCHUP_EN);
1375
1376 OS_REG_WRITE(ah, AR_CPCOVF, 0);
1377
1378 /* reset decompression mask */
1379 for (i = 0; i < HAL_DECOMP_MASK_SIZE; i++) {
1380 OS_REG_WRITE(ah, AR_DCM_A, i);
1381 OS_REG_WRITE(ah, AR_DCM_D, ahp->ah_decompMask[i]);
1382 }
1383}
1384
1385HAL_BOOL
1386ar5212SetAntennaSwitchInternal(struct ath_hal *ah, HAL_ANT_SETTING settings,
1387 const HAL_CHANNEL_INTERNAL *chan)
1388{
1389#define ANT_SWITCH_TABLE1 AR_PHY(88)
1390#define ANT_SWITCH_TABLE2 AR_PHY(89)
1391 struct ath_hal_5212 *ahp = AH5212(ah);
1392 const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1393 uint32_t antSwitchA, antSwitchB;
1394 int ix;
1395 HAL_BOOL isBmode = AH_FALSE;
1396 /* NB: need local copy for SAVE/RESTORE 'cuz chan is const */
1397 HAL_CHANNEL_INTERNAL ichan = *chan;
1398
1399 HALASSERT(ah->ah_magic == AR5212_MAGIC);
1400 HALASSERT(ahp->ah_phyPowerOn);
1401
1402 SAVE_CCK(ah, &ichan, isBmode);
1403 switch (ichan.channelFlags & CHANNEL_ALL_NOTURBO) {
1404 case CHANNEL_A: ix = 0; break;
1405 case CHANNEL_B: ix = 1; break;
1406 case CHANNEL_PUREG: ix = 2; break;
1407 default:
1408 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
1409 __func__, ichan.channelFlags);
1410 RESTORE_CCK(ah, &ichan, isBmode);
1411 return AH_FALSE;
1412 }
1413 RESTORE_CCK(ah, &ichan, isBmode);
1414
1415 antSwitchA = ee->ee_antennaControl[1][ix]
1416 | (ee->ee_antennaControl[2][ix] << 6)
1417 | (ee->ee_antennaControl[3][ix] << 12)
1418 | (ee->ee_antennaControl[4][ix] << 18)
1419 | (ee->ee_antennaControl[5][ix] << 24)
1420 ;
1421 antSwitchB = ee->ee_antennaControl[6][ix]
1422 | (ee->ee_antennaControl[7][ix] << 6)
1423 | (ee->ee_antennaControl[8][ix] << 12)
1424 | (ee->ee_antennaControl[9][ix] << 18)
1425 | (ee->ee_antennaControl[10][ix] << 24)
1426 ;
1427 /*
1428 * For fixed antenna, give the same setting for both switch banks
1429 */
1430 switch (settings) {
1431 case HAL_ANT_FIXED_A:
1432 antSwitchB = antSwitchA;
1433 break;
1434 case HAL_ANT_FIXED_B:
1435 antSwitchA = antSwitchB;
1436 break;
1437 case HAL_ANT_VARIABLE:
1438 break;
1439 default:
1440 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad antenna setting %u\n",
1441 __func__, settings);
1442 return AH_FALSE;
1443 }
1444 if (antSwitchB == antSwitchA) {
1445 HALDEBUG(ah, HAL_DEBUG_RFPARAM,
1446 "%s: Setting fast diversity off.\n", __func__);
1447 OS_REG_CLR_BIT(ah,AR_PHY_CCK_DETECT,
1448 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
1449 ahp->ah_diversity = AH_FALSE;
1450 } else {
1451 HALDEBUG(ah, HAL_DEBUG_RFPARAM,
1452 "%s: Setting fast diversity on.\n", __func__);
1453 OS_REG_SET_BIT(ah,AR_PHY_CCK_DETECT,
1454 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
1455 ahp->ah_diversity = AH_TRUE;
1456 }
1457 ahp->ah_antControl = settings;
1458
1459 OS_REG_WRITE(ah, ANT_SWITCH_TABLE1, antSwitchA);
1460 OS_REG_WRITE(ah, ANT_SWITCH_TABLE2, antSwitchB);
1461
1462 return AH_TRUE;
1463#undef ANT_SWITCH_TABLE2
1464#undef ANT_SWITCH_TABLE1
1465}
1466
1467HAL_BOOL
1468ar5212IsSpurChannel(struct ath_hal *ah, HAL_CHANNEL *chan)
1469{
1470 uint32_t clockFreq =
1471 ((IS_5413(ah) || IS_RAD5112_ANY(ah) || IS_2417(ah)) ? 40 : 32);
1472 return ( ((chan->channel % clockFreq) != 0)
1473 && (((chan->channel % clockFreq) < 10)
1474 || (((chan->channel) % clockFreq) > 22)) );
1475}
1476
1477/*
1478 * Read EEPROM header info and program the device for correct operation
1479 * given the channel value.
1480 */
1481HAL_BOOL
1482ar5212SetBoardValues(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
1483{
1484#define NO_FALSE_DETECT_BACKOFF 2
1485#define CB22_FALSE_DETECT_BACKOFF 6
1486#define AR_PHY_BIS(_ah, _reg, _mask, _val) \
1487 OS_REG_WRITE(_ah, AR_PHY(_reg), \
1488 (OS_REG_READ(_ah, AR_PHY(_reg)) & _mask) | (_val));
1489 struct ath_hal_5212 *ahp = AH5212(ah);
1490 const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1491 int arrayMode, falseDectectBackoff;
1492 int is2GHz = IS_CHAN_2GHZ(chan);
1493 int8_t adcDesiredSize, pgaDesiredSize;
1494 uint16_t switchSettling, txrxAtten, rxtxMargin;
1495 int iCoff, qCoff;
1496
1497 HALASSERT(ah->ah_magic == AR5212_MAGIC);
1498
1499 switch (chan->channelFlags & CHANNEL_ALL) {
1500 case CHANNEL_A:
1501 case CHANNEL_T:
1502 arrayMode = headerInfo11A;
1503 if (!IS_RAD5112_ANY(ah) && !IS_2413(ah) && !IS_5413(ah))
1504 OS_REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL,
1505 AR_PHY_FRAME_CTL_TX_CLIP,
1506 ahp->ah_gainValues.currStep->paramVal[GP_TXCLIP]);
1507 break;
1508 case CHANNEL_B:
1509 arrayMode = headerInfo11B;
1510 break;
1511 case CHANNEL_G:
1512 case CHANNEL_108G:
1513 arrayMode = headerInfo11G;
1514 break;
1515 default:
1516 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
1517 __func__, chan->channelFlags);
1518 return AH_FALSE;
1519 }
1520
1521 /* Set the antenna register(s) correctly for the chip revision */
1522 AR_PHY_BIS(ah, 68, 0xFFFFFC06,
1523 (ee->ee_antennaControl[0][arrayMode] << 4) | 0x1);
1524
1525 ar5212SetAntennaSwitchInternal(ah, ahp->ah_antControl, chan);
1526
1527 /* Set the Noise Floor Thresh on ar5211 devices */
1528 OS_REG_WRITE(ah, AR_PHY(90),
1529 (ee->ee_noiseFloorThresh[arrayMode] & 0x1FF)
1530 | (1 << 9));
1531
1532 if (ee->ee_version >= AR_EEPROM_VER5_0 && IS_CHAN_TURBO(chan)) {
1533 switchSettling = ee->ee_switchSettlingTurbo[is2GHz];
1534 adcDesiredSize = ee->ee_adcDesiredSizeTurbo[is2GHz];
1535 pgaDesiredSize = ee->ee_pgaDesiredSizeTurbo[is2GHz];
1536 txrxAtten = ee->ee_txrxAttenTurbo[is2GHz];
1537 rxtxMargin = ee->ee_rxtxMarginTurbo[is2GHz];
1538 } else {
1539 switchSettling = ee->ee_switchSettling[arrayMode];
1540 adcDesiredSize = ee->ee_adcDesiredSize[arrayMode];
1541 pgaDesiredSize = ee->ee_pgaDesiredSize[is2GHz];
1542 txrxAtten = ee->ee_txrxAtten[is2GHz];
1543 rxtxMargin = ee->ee_rxtxMargin[is2GHz];
1544 }
1545
1546 OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING,
1547 AR_PHY_SETTLING_SWITCH, switchSettling);
1548 OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
1549 AR_PHY_DESIRED_SZ_ADC, adcDesiredSize);
1550 OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
1551 AR_PHY_DESIRED_SZ_PGA, pgaDesiredSize);
1552 OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN,
1553 AR_PHY_RXGAIN_TXRX_ATTEN, txrxAtten);
1554 OS_REG_WRITE(ah, AR_PHY(13),
1555 (ee->ee_txEndToXPAOff[arrayMode] << 24)
1556 | (ee->ee_txEndToXPAOff[arrayMode] << 16)
1557 | (ee->ee_txFrameToXPAOn[arrayMode] << 8)
1558 | ee->ee_txFrameToXPAOn[arrayMode]);
1559 AR_PHY_BIS(ah, 10, 0xFFFF00FF,
1560 ee->ee_txEndToXLNAOn[arrayMode] << 8);
1561 AR_PHY_BIS(ah, 25, 0xFFF80FFF,
1562 (ee->ee_thresh62[arrayMode] << 12) & 0x7F000);
1563
1564 /*
1565 * False detect backoff - suspected 32 MHz spur causes false
1566 * detects in OFDM, causing Tx Hangs. Decrease weak signal
1567 * sensitivity for this card.
1568 */
1569 falseDectectBackoff = NO_FALSE_DETECT_BACKOFF;
1570 if (ee->ee_version < AR_EEPROM_VER3_3) {
1571 /* XXX magic number */
1572 if (AH_PRIVATE(ah)->ah_subvendorid == 0x1022 &&
1573 IS_CHAN_OFDM(chan))
1574 falseDectectBackoff += CB22_FALSE_DETECT_BACKOFF;
1575 } else {
1576 if (ar5212IsSpurChannel(ah, (HAL_CHANNEL *)chan)) {
1577 falseDectectBackoff += ee->ee_falseDetectBackoff[arrayMode];
1578 }
1579 }
1580 AR_PHY_BIS(ah, 73, 0xFFFFFF01, (falseDectectBackoff << 1) & 0xFE);
1581
1582 if (chan->iqCalValid) {
1583 iCoff = chan->iCoff;
1584 qCoff = chan->qCoff;
1585 } else {
1586 iCoff = ee->ee_iqCalI[is2GHz];
1587 qCoff = ee->ee_iqCalQ[is2GHz];
1588 }
1589
1590 /* write previous IQ results */
1591 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
1592 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, iCoff);
1593 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
1594 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, qCoff);
1595 OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4,
1596 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
1597
1598 if (ee->ee_version >= AR_EEPROM_VER4_1) {
1599 if (!IS_CHAN_108G(chan) || ee->ee_version >= AR_EEPROM_VER5_0)
1600 OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
1601 AR_PHY_GAIN_2GHZ_RXTX_MARGIN, rxtxMargin);
1602 }
1603 if (ee->ee_version >= AR_EEPROM_VER5_1) {
1604 /* for now always disabled */
1605 OS_REG_WRITE(ah, AR_PHY_HEAVY_CLIP_ENABLE, 0);
1606 }
1607
1608 return AH_TRUE;
1609#undef AR_PHY_BIS
1610#undef NO_FALSE_DETECT_BACKOFF
1611#undef CB22_FALSE_DETECT_BACKOFF
1612}
1613
1614/*
1615 * Apply Spur Immunity to Boards that require it.
1616 * Applies only to OFDM RX operation.
1617 */
1618
1619void
1620ar5212SetSpurMitigation(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
1621{
1622 uint32_t pilotMask[2] = {0, 0}, binMagMask[4] = {0, 0, 0 , 0};
1623 uint16_t i, finalSpur, curChanAsSpur, binWidth = 0, spurDetectWidth, spurChan;
1624 int32_t spurDeltaPhase = 0, spurFreqSd = 0, spurOffset, binOffsetNumT16, curBinOffset;
1625 int16_t numBinOffsets;
1626 static const uint16_t magMapFor4[4] = {1, 2, 2, 1};
1627 static const uint16_t magMapFor3[3] = {1, 2, 1};
1628 const uint16_t *pMagMap;
1629 HAL_BOOL is2GHz = IS_CHAN_2GHZ(ichan);
1630 uint32_t val;
1631
1632#define CHAN_TO_SPUR(_f, _freq) ( ((_freq) - ((_f) ? 2300 : 4900)) * 10 )
1633 if (IS_2417(ah)) {
1634 HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: no spur mitigation\n",
1635 __func__);
1636 return;
1637 }
1638
1639 curChanAsSpur = CHAN_TO_SPUR(is2GHz, ichan->channel);
1640
1641 if (ichan->mainSpur) {
1642 /* Pull out the saved spur value */
1643 finalSpur = ichan->mainSpur;
1644 } else {
1645 /*
1646 * Check if spur immunity should be performed for this channel
1647 * Should only be performed once per channel and then saved
1648 */
1649 finalSpur = AR_NO_SPUR;
1650 spurDetectWidth = HAL_SPUR_CHAN_WIDTH;
1651 if (IS_CHAN_TURBO(ichan))
1652 spurDetectWidth *= 2;
1653
1654 /* Decide if any spur affects the current channel */
1655 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
1656 spurChan = ath_hal_getSpurChan(ah, i, is2GHz);
1657 if (spurChan == AR_NO_SPUR) {
1658 break;
1659 }
1660 if ((curChanAsSpur - spurDetectWidth <= (spurChan & HAL_SPUR_VAL_MASK)) &&
1661 (curChanAsSpur + spurDetectWidth >= (spurChan & HAL_SPUR_VAL_MASK))) {
1662 finalSpur = spurChan & HAL_SPUR_VAL_MASK;
1663 break;
1664 }
1665 }
1666 /* Save detected spur (or no spur) for this channel */
1667 ichan->mainSpur = finalSpur;
1668 }
1669
1670 /* Write spur immunity data */
1671 if (finalSpur == AR_NO_SPUR) {
1672 /* Disable Spur Immunity Regs if they appear set */
1673 if (OS_REG_READ(ah, AR_PHY_TIMING_CTRL4) & AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER) {
1674 /* Clear Spur Delta Phase, Spur Freq, and enable bits */
1675 OS_REG_RMW_FIELD(ah, AR_PHY_MASK_CTL, AR_PHY_MASK_CTL_RATE, 0);
1676 val = OS_REG_READ(ah, AR_PHY_TIMING_CTRL4);
1677 val &= ~(AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
1678 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
1679 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
1680 OS_REG_WRITE(ah, AR_PHY_MASK_CTL, val);
1681 OS_REG_WRITE(ah, AR_PHY_TIMING11, 0);
1682
1683 /* Clear pilot masks */
1684 OS_REG_WRITE(ah, AR_PHY_TIMING7, 0);
1685 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING8, AR_PHY_TIMING8_PILOT_MASK_2, 0);
1686 OS_REG_WRITE(ah, AR_PHY_TIMING9, 0);
1687 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING10, AR_PHY_TIMING10_PILOT_MASK_2, 0);
1688
1689 /* Clear magnitude masks */
1690 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_1, 0);
1691 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_2, 0);
1692 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_3, 0);
1693 OS_REG_RMW_FIELD(ah, AR_PHY_MASK_CTL, AR_PHY_MASK_CTL_MASK_4, 0);
1694 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_1, 0);
1695 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_2, 0);
1696 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_3, 0);
1697 OS_REG_RMW_FIELD(ah, AR_PHY_BIN_MASK2_4, AR_PHY_BIN_MASK2_4_MASK_4, 0);
1698 }
1699 } else {
1700 spurOffset = finalSpur - curChanAsSpur;
1701 /*
1702 * Spur calculations:
1703 * spurDeltaPhase is (spurOffsetIn100KHz / chipFrequencyIn100KHz) << 21
1704 * spurFreqSd is (spurOffsetIn100KHz / sampleFrequencyIn100KHz) << 11
1705 */
1706 switch (ichan->channelFlags & CHANNEL_ALL) {
1707 case CHANNEL_A: /* Chip Frequency & sampleFrequency are 40 MHz */
1708 spurDeltaPhase = (spurOffset << 17) / 25;
1709 spurFreqSd = spurDeltaPhase >> 10;
1710 binWidth = HAL_BIN_WIDTH_BASE_100HZ;
1711 break;
1712 case CHANNEL_G: /* Chip Frequency is 44MHz, sampleFrequency is 40 MHz */
1713 spurFreqSd = (spurOffset << 8) / 55;
1714 spurDeltaPhase = (spurOffset << 17) / 25;
1715 binWidth = HAL_BIN_WIDTH_BASE_100HZ;
1716 break;
1717 case CHANNEL_T: /* Chip Frequency & sampleFrequency are 80 MHz */
1718 case CHANNEL_108G:
1719 spurDeltaPhase = (spurOffset << 16) / 25;
1720 spurFreqSd = spurDeltaPhase >> 10;
1721 binWidth = HAL_BIN_WIDTH_TURBO_100HZ;
1722 break;
1723 }
1724
1725 /* Compute Pilot Mask */
1726 binOffsetNumT16 = ((spurOffset * 1000) << 4) / binWidth;
1727 /* The spur is on a bin if it's remainder at times 16 is 0 */
1728 if (binOffsetNumT16 & 0xF) {
1729 numBinOffsets = 4;
1730 pMagMap = magMapFor4;
1731 } else {
1732 numBinOffsets = 3;
1733 pMagMap = magMapFor3;
1734 }
1735 for (i = 0; i < numBinOffsets; i++) {
1736 if ((binOffsetNumT16 >> 4) > HAL_MAX_BINS_ALLOWED) {
1737 HALDEBUG(ah, HAL_DEBUG_ANY,
1738 "Too man bins in spur mitigation\n");
1739 return;
1740 }
1741
1742 /* Get Pilot Mask values */
1743 curBinOffset = (binOffsetNumT16 >> 4) + i + 25;
1744 if ((curBinOffset >= 0) && (curBinOffset <= 32)) {
1745 if (curBinOffset <= 25)
1746 pilotMask[0] |= 1 << curBinOffset;
1747 else if (curBinOffset >= 27)
1748 pilotMask[0] |= 1 << (curBinOffset - 1);
1749 } else if ((curBinOffset >= 33) && (curBinOffset <= 52))
1750 pilotMask[1] |= 1 << (curBinOffset - 33);
1751
1752 /* Get viterbi values */
1753 if ((curBinOffset >= -1) && (curBinOffset <= 14))
1754 binMagMask[0] |= pMagMap[i] << (curBinOffset + 1) * 2;
1755 else if ((curBinOffset >= 15) && (curBinOffset <= 30))
1756 binMagMask[1] |= pMagMap[i] << (curBinOffset - 15) * 2;
1757 else if ((curBinOffset >= 31) && (curBinOffset <= 46))
1758 binMagMask[2] |= pMagMap[i] << (curBinOffset -31) * 2;
1759 else if((curBinOffset >= 47) && (curBinOffset <= 53))
1760 binMagMask[3] |= pMagMap[i] << (curBinOffset -47) * 2;
1761 }
1762
1763 /* Write Spur Delta Phase, Spur Freq, and enable bits */
1764 OS_REG_RMW_FIELD(ah, AR_PHY_MASK_CTL, AR_PHY_MASK_CTL_RATE, 0xFF);
1765 val = OS_REG_READ(ah, AR_PHY_TIMING_CTRL4);
1766 val |= (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
1767 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
1768 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
1769 OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4, val);
1770 OS_REG_WRITE(ah, AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_IN_AGC |
1771 SM(spurFreqSd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
1772 SM(spurDeltaPhase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
1773
1774 /* Write pilot masks */
1775 OS_REG_WRITE(ah, AR_PHY_TIMING7, pilotMask[0]);
1776 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING8, AR_PHY_TIMING8_PILOT_MASK_2, pilotMask[1]);
1777 OS_REG_WRITE(ah, AR_PHY_TIMING9, pilotMask[0]);
1778 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING10, AR_PHY_TIMING10_PILOT_MASK_2, pilotMask[1]);
1779
1780 /* Write magnitude masks */
1781 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_1, binMagMask[0]);
1782 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_2, binMagMask[1]);
1783 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_3, binMagMask[2]);
1784 OS_REG_RMW_FIELD(ah, AR_PHY_MASK_CTL, AR_PHY_MASK_CTL_MASK_4, binMagMask[3]);
1785 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_1, binMagMask[0]);
1786 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_2, binMagMask[1]);
1787 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_3, binMagMask[2]);
1788 OS_REG_RMW_FIELD(ah, AR_PHY_BIN_MASK2_4, AR_PHY_BIN_MASK2_4_MASK_4, binMagMask[3]);
1789 }
1790#undef CHAN_TO_SPUR
1791}
1792
1793
1794/*
1795 * Delta slope coefficient computation.
1796 * Required for OFDM operation.
1797 */
1798void
1799ar5212SetDeltaSlope(struct ath_hal *ah, HAL_CHANNEL *chan)
1800{
1801#define COEF_SCALE_S 24
1802#define INIT_CLOCKMHZSCALED 0x64000000
1803 unsigned long coef_scaled, coef_exp, coef_man, ds_coef_exp, ds_coef_man;
1804 unsigned long clockMhzScaled = INIT_CLOCKMHZSCALED;
1805
1806 if (IS_CHAN_TURBO(chan))
1807 clockMhzScaled *= 2;
1808 /* half and quarter rate can divide the scaled clock by 2 or 4 respectively */
1809 /* scale for selected channel bandwidth */
1810 if (IS_CHAN_HALF_RATE(chan)) {
1811 clockMhzScaled = clockMhzScaled >> 1;
1812 } else if (IS_CHAN_QUARTER_RATE(chan)) {
1813 clockMhzScaled = clockMhzScaled >> 2;
1814 }
1815
1816 /*
1817 * ALGO -> coef = 1e8/fcarrier*fclock/40;
1818 * scaled coef to provide precision for this floating calculation
1819 */
1820 coef_scaled = clockMhzScaled / chan->channel;
1821
1822 /*
1823 * ALGO -> coef_exp = 14-floor(log2(coef));
1824 * floor(log2(x)) is the highest set bit position
1825 */
1826 for (coef_exp = 31; coef_exp > 0; coef_exp--)
1827 if ((coef_scaled >> coef_exp) & 0x1)
1828 break;
1829 /* A coef_exp of 0 is a legal bit position but an unexpected coef_exp */
1830 HALASSERT(coef_exp);
1831 coef_exp = 14 - (coef_exp - COEF_SCALE_S);
1832
1833 /*
1834 * ALGO -> coef_man = floor(coef* 2^coef_exp+0.5);
1835 * The coefficient is already shifted up for scaling
1836 */
1837 coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
1838 ds_coef_man = coef_man >> (COEF_SCALE_S - coef_exp);
1839 ds_coef_exp = coef_exp - 16;
1840
1841 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3,
1842 AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
1843 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3,
1844 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
1845#undef INIT_CLOCKMHZSCALED
1846#undef COEF_SCALE_S
1847}
1848
1849/*
1850 * Set a limit on the overall output power. Used for dynamic
1851 * transmit power control and the like.
1852 *
1853 * NB: limit is in units of 0.5 dbM.
1854 */
1855HAL_BOOL
1856ar5212SetTxPowerLimit(struct ath_hal *ah, uint32_t limit)
1857{
1858 uint16_t dummyXpdGains[2];
1859 HAL_BOOL ret, isBmode = AH_FALSE;
1860
1861 SAVE_CCK(ah, AH_PRIVATE(ah)->ah_curchan, isBmode);
1862 AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER);
1863 ret = ar5212SetTransmitPower(ah, AH_PRIVATE(ah)->ah_curchan,
1864 dummyXpdGains);
1865 RESTORE_CCK(ah, AH_PRIVATE(ah)->ah_curchan, isBmode);
1866 return ret;
1867}
1868
1869/*
1870 * Set the transmit power in the baseband for the given
1871 * operating channel and mode.
1872 */
1873HAL_BOOL
1874ar5212SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
1875 uint16_t *rfXpdGain)
1876{
1877#define POW_OFDM(_r, _s) (((0 & 1)<< ((_s)+6)) | (((_r) & 0x3f) << (_s)))
1878#define POW_CCK(_r, _s) (((_r) & 0x3f) << (_s))
1879#define N(a) (sizeof (a) / sizeof (a[0]))
1880 static const uint16_t tpcScaleReductionTable[5] =
1881 { 0, 3, 6, 9, MAX_RATE_POWER };
1882 struct ath_hal_5212 *ahp = AH5212(ah);
1883 const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1884 int16_t minPower, maxPower, tpcInDb, powerLimit;
1885 int i;
1886
1887 HALASSERT(ah->ah_magic == AR5212_MAGIC);
1888
1889 OS_MEMZERO(ahp->ah_pcdacTable, ahp->ah_pcdacTableSize);
1890 OS_MEMZERO(ahp->ah_ratesArray, sizeof(ahp->ah_ratesArray));
1891
1892 powerLimit = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit);
1893 if (powerLimit >= MAX_RATE_POWER || powerLimit == 0)
1894 tpcInDb = tpcScaleReductionTable[AH_PRIVATE(ah)->ah_tpScale];
1895 else
1896 tpcInDb = 0;
1897 if (!ar5212SetRateTable(ah, (HAL_CHANNEL *) chan, tpcInDb, powerLimit,
1898 AH_TRUE, &minPower, &maxPower)) {
1899 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set rate table\n",
1900 __func__);
1901 return AH_FALSE;
1902 }
1903 if (!ahp->ah_rfHal->setPowerTable(ah,
1904 &minPower, &maxPower, chan, rfXpdGain)) {
1905 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set power table\n",
1906 __func__);
1907 return AH_FALSE;
1908 }
1909
1910 /*
1911 * Adjust XR power/rate up by 2 dB to account for greater peak
1912 * to avg ratio - except in newer avg power designs
1913 */
1914 if (!IS_2413(ah) && !IS_5413(ah))
1915 ahp->ah_ratesArray[15] += 4;
1916 /*
1917 * txPowerIndexOffset is set by the SetPowerTable() call -
1918 * adjust the rate table
1919 */
1920 for (i = 0; i < N(ahp->ah_ratesArray); i++) {
1921 ahp->ah_ratesArray[i] += ahp->ah_txPowerIndexOffset;
1922 if (ahp->ah_ratesArray[i] > 63)
1923 ahp->ah_ratesArray[i] = 63;
1924 }
1925
1926 if (ee->ee_eepMap < 2) {
1927 /*
1928 * Correct gain deltas for 5212 G operation -
1929 * Removed with revised chipset
1930 */
1931 if (AH_PRIVATE(ah)->ah_phyRev < AR_PHY_CHIP_ID_REV_2 &&
1932 IS_CHAN_G(chan)) {
1933 uint16_t cckOfdmPwrDelta;
1934
1935 if (chan->channel == 2484)
1936 cckOfdmPwrDelta = SCALE_OC_DELTA(
1937 ee->ee_cckOfdmPwrDelta -
1938 ee->ee_scaledCh14FilterCckDelta);
1939 else
1940 cckOfdmPwrDelta = SCALE_OC_DELTA(
1941 ee->ee_cckOfdmPwrDelta);
1942 ar5212CorrectGainDelta(ah, cckOfdmPwrDelta);
1943 }
1944 /*
1945 * Finally, write the power values into the
1946 * baseband power table
1947 */
1948 for (i = 0; i < (PWR_TABLE_SIZE/2); i++) {
1949 OS_REG_WRITE(ah, AR_PHY_PCDAC_TX_POWER(i),
1950 ((((ahp->ah_pcdacTable[2*i + 1] << 8) | 0xff) & 0xffff) << 16)
1951 | (((ahp->ah_pcdacTable[2*i] << 8) | 0xff) & 0xffff)
1952 );
1953 }
1954 }
1955
1956 /* Write the OFDM power per rate set */
1957 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
1958 POW_OFDM(ahp->ah_ratesArray[3], 24)
1959 | POW_OFDM(ahp->ah_ratesArray[2], 16)
1960 | POW_OFDM(ahp->ah_ratesArray[1], 8)
1961 | POW_OFDM(ahp->ah_ratesArray[0], 0)
1962 );
1963 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
1964 POW_OFDM(ahp->ah_ratesArray[7], 24)
1965 | POW_OFDM(ahp->ah_ratesArray[6], 16)
1966 | POW_OFDM(ahp->ah_ratesArray[5], 8)
1967 | POW_OFDM(ahp->ah_ratesArray[4], 0)
1968 );
1969
1970 /* Write the CCK power per rate set */
1971 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
1972 POW_CCK(ahp->ah_ratesArray[10], 24)
1973 | POW_CCK(ahp->ah_ratesArray[9], 16)
1974 | POW_CCK(ahp->ah_ratesArray[15], 8) /* XR target power */
1975 | POW_CCK(ahp->ah_ratesArray[8], 0)
1976 );
1977 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
1978 POW_CCK(ahp->ah_ratesArray[14], 24)
1979 | POW_CCK(ahp->ah_ratesArray[13], 16)
1980 | POW_CCK(ahp->ah_ratesArray[12], 8)
1981 | POW_CCK(ahp->ah_ratesArray[11], 0)
1982 );
1983
1984 /*
1985 * Set max power to 30 dBm and, optionally,
1986 * enable TPC in tx descriptors.
1987 */
1988 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX, MAX_RATE_POWER |
1989 (ahp->ah_tpcEnabled ? AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE : 0));
1990
1991 return AH_TRUE;
1992#undef N
1993#undef POW_CCK
1994#undef POW_OFDM
1995}
1996
1997/*
1998 * Sets the transmit power in the baseband for the given
1999 * operating channel and mode.
2000 */
2001static HAL_BOOL
2002ar5212SetRateTable(struct ath_hal *ah, HAL_CHANNEL *chan,
2003 int16_t tpcScaleReduction, int16_t powerLimit, HAL_BOOL commit,
2004 int16_t *pMinPower, int16_t *pMaxPower)
2005{
2006 struct ath_hal_5212 *ahp = AH5212(ah);
2007 const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
2008 uint16_t *rpow = ahp->ah_ratesArray;
2009 uint16_t twiceMaxEdgePower = MAX_RATE_POWER;
2010 uint16_t twiceMaxEdgePowerCck = MAX_RATE_POWER;
2011 uint16_t twiceMaxRDPower = MAX_RATE_POWER;
2012 int i;
2013 uint8_t cfgCtl;
2014 int8_t twiceAntennaGain, twiceAntennaReduction;
2015 const RD_EDGES_POWER *rep;
2016 TRGT_POWER_INFO targetPowerOfdm, targetPowerCck;
2017 int16_t scaledPower, maxAvailPower = 0;
2018 int16_t r13, r9, r7, r0;
2019
2020 HALASSERT(ah->ah_magic == AR5212_MAGIC);
2021
2022 twiceMaxRDPower = chan->maxRegTxPower * 2;
2023 *pMaxPower = -MAX_RATE_POWER;
2024 *pMinPower = MAX_RATE_POWER;
2025
2026 /* Get conformance test limit maximum for this channel */
2027 cfgCtl = ath_hal_getctl(ah, chan);
2028 for (i = 0; i < ee->ee_numCtls; i++) {
2029 uint16_t twiceMinEdgePower;
2030
2031 if (ee->ee_ctl[i] == 0)
2032 continue;
2033 if (ee->ee_ctl[i] == cfgCtl ||
2034 cfgCtl == ((ee->ee_ctl[i] & CTL_MODE_M) | SD_NO_CTL)) {
2035 rep = &ee->ee_rdEdgesPower[i * NUM_EDGES];
2036 twiceMinEdgePower = ar5212GetMaxEdgePower(chan->channel, rep);
2037 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
2038 /* Find the minimum of all CTL edge powers that apply to this channel */
2039 twiceMaxEdgePower = AH_MIN(twiceMaxEdgePower, twiceMinEdgePower);
2040 } else {
2041 twiceMaxEdgePower = twiceMinEdgePower;
2042 break;
2043 }
2044 }
2045 }
2046
2047 if (IS_CHAN_G(chan)) {
2048 /* Check for a CCK CTL for 11G CCK powers */
2049 cfgCtl = (cfgCtl & ~CTL_MODE_M) | CTL_11B;
2050 for (i = 0; i < ee->ee_numCtls; i++) {
2051 uint16_t twiceMinEdgePowerCck;
2052
2053 if (ee->ee_ctl[i] == 0)
2054 continue;
2055 if (ee->ee_ctl[i] == cfgCtl ||
2056 cfgCtl == ((ee->ee_ctl[i] & CTL_MODE_M) | SD_NO_CTL)) {
2057 rep = &ee->ee_rdEdgesPower[i * NUM_EDGES];
2058 twiceMinEdgePowerCck = ar5212GetMaxEdgePower(chan->channel, rep);
2059 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
2060 /* Find the minimum of all CTL edge powers that apply to this channel */
2061 twiceMaxEdgePowerCck = AH_MIN(twiceMaxEdgePowerCck, twiceMinEdgePowerCck);
2062 } else {
2063 twiceMaxEdgePowerCck = twiceMinEdgePowerCck;
2064 break;
2065 }
2066 }
2067 }
2068 } else {
2069 /* Set the 11B cck edge power to the one found before */
2070 twiceMaxEdgePowerCck = twiceMaxEdgePower;
2071 }
2072
2073 /* Get Antenna Gain reduction */
2074 if (IS_CHAN_5GHZ(chan)) {
2075 ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_5, &twiceAntennaGain);
2076 } else {
2077 ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_2, &twiceAntennaGain);
2078 }
2079 twiceAntennaReduction =
2080 ath_hal_getantennareduction(ah, chan, twiceAntennaGain);
2081
2082 if (IS_CHAN_OFDM(chan)) {
2083 /* Get final OFDM target powers */
2084 if (IS_CHAN_2GHZ(chan)) {
2085 ar5212GetTargetPowers(ah, chan, ee->ee_trgtPwr_11g,
2086 ee->ee_numTargetPwr_11g, &targetPowerOfdm);
2087 } else {
2088 ar5212GetTargetPowers(ah, chan, ee->ee_trgtPwr_11a,
2089 ee->ee_numTargetPwr_11a, &targetPowerOfdm);
2090 }
2091
2092 /* Get Maximum OFDM power */
2093 /* Minimum of target and edge powers */
2094 scaledPower = AH_MIN(twiceMaxEdgePower,
2095 twiceMaxRDPower - twiceAntennaReduction);
2096
2097 /*
2098 * If turbo is set, reduce power to keep power
2099 * consumption under 2 Watts. Note that we always do
2100 * this unless specially configured. Then we limit
2101 * power only for non-AP operation.
2102 */
2103 if (IS_CHAN_TURBO(chan)
2104#ifdef AH_ENABLE_AP_SUPPORT
2105 && AH_PRIVATE(ah)->ah_opmode != HAL_M_HOSTAP
2106#endif
2107 ) {
2108 /*
2109 * If turbo is set, reduce power to keep power
2110 * consumption under 2 Watts
2111 */
2112 if (ee->ee_version >= AR_EEPROM_VER3_1)
2113 scaledPower = AH_MIN(scaledPower,
2114 ee->ee_turbo2WMaxPower5);
2115 /*
2116 * EEPROM version 4.0 added an additional
2117 * constraint on 2.4GHz channels.
2118 */
2119 if (ee->ee_version >= AR_EEPROM_VER4_0 &&
2120 IS_CHAN_2GHZ(chan))
2121 scaledPower = AH_MIN(scaledPower,
2122 ee->ee_turbo2WMaxPower2);
2123 }
2124
2125 maxAvailPower = AH_MIN(scaledPower,
2126 targetPowerOfdm.twicePwr6_24);
2127
2128 /* Reduce power by max regulatory domain allowed restrictions */
2129 scaledPower = maxAvailPower - (tpcScaleReduction * 2);
2130 scaledPower = (scaledPower < 0) ? 0 : scaledPower;
2131 scaledPower = AH_MIN(scaledPower, powerLimit);
2132
2133 if (commit) {
2134 /* Set OFDM rates 9, 12, 18, 24 */
2135 r0 = rpow[0] = rpow[1] = rpow[2] = rpow[3] = rpow[4] = scaledPower;
2136
2137 /* Set OFDM rates 36, 48, 54, XR */
2138 rpow[5] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr36);
2139 rpow[6] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr48);
2140 r7 = rpow[7] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr54);
2141
2142 if (ee->ee_version >= AR_EEPROM_VER4_0) {
2143 /* Setup XR target power from EEPROM */
2144 rpow[15] = AH_MIN(scaledPower, IS_CHAN_2GHZ(chan) ?
2145 ee->ee_xrTargetPower2 : ee->ee_xrTargetPower5);
2146 } else {
2147 /* XR uses 6mb power */
2148 rpow[15] = rpow[0];
2149 }
2150 ahp->ah_ofdmTxPower = *pMaxPower;
2151
2152 } else {
2153 r0 = scaledPower;
2154 r7 = AH_MIN(r0, targetPowerOfdm.twicePwr54);
2155 }
2156 *pMinPower = r7;
2157 *pMaxPower = r0;
2158
2159 HALDEBUG(ah, HAL_DEBUG_RFPARAM,
2160 "%s: MaxRD: %d TurboMax: %d MaxCTL: %d "
2161 "TPC_Reduction %d chan=%d (0x%x) maxAvailPower=%d pwr6_24=%d, maxPower=%d\n",
2162 __func__, twiceMaxRDPower, ee->ee_turbo2WMaxPower5,
2163 twiceMaxEdgePower, tpcScaleReduction * 2,
2164 chan->channel, chan->channelFlags,
2165 maxAvailPower, targetPowerOfdm.twicePwr6_24, *pMaxPower);
2166 }
2167
2168 if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) {
2169 /* Get final CCK target powers */
2170 ar5212GetTargetPowers(ah, chan, ee->ee_trgtPwr_11b,
2171 ee->ee_numTargetPwr_11b, &targetPowerCck);
2172
2173 /* Reduce power by max regulatory domain allowed restrictions */
2174 scaledPower = AH_MIN(twiceMaxEdgePowerCck,
2175 twiceMaxRDPower - twiceAntennaReduction);
2176 if (maxAvailPower < AH_MIN(scaledPower, targetPowerCck.twicePwr6_24))
2177 maxAvailPower = AH_MIN(scaledPower, targetPowerCck.twicePwr6_24);
2178
2179 /* Reduce power by user selection */
2180 scaledPower = AH_MIN(scaledPower, targetPowerCck.twicePwr6_24) - (tpcScaleReduction * 2);
2181 scaledPower = (scaledPower < 0) ? 0 : scaledPower;
2182 scaledPower = AH_MIN(scaledPower, powerLimit);
2183
2184 if (commit) {
2185 /* Set CCK rates 2L, 2S, 5.5L, 5.5S, 11L, 11S */
2186 rpow[8] = AH_MIN(scaledPower, targetPowerCck.twicePwr6_24);
2187 r9 = rpow[9] = AH_MIN(scaledPower, targetPowerCck.twicePwr36);
2188 rpow[10] = rpow[9];
2189 rpow[11] = AH_MIN(scaledPower, targetPowerCck.twicePwr48);
2190 rpow[12] = rpow[11];
2191 r13 = rpow[13] = AH_MIN(scaledPower, targetPowerCck.twicePwr54);
2192 rpow[14] = rpow[13];
2193 } else {
2194 r9 = AH_MIN(scaledPower, targetPowerCck.twicePwr36);
2195 r13 = AH_MIN(scaledPower, targetPowerCck.twicePwr54);
2196 }
2197
2198 /* Set min/max power based off OFDM values or initialization */
2199 if (r13 < *pMinPower)
2200 *pMinPower = r13;
2201 if (r9 > *pMaxPower)
2202 *pMaxPower = r9;
2203
2204 HALDEBUG(ah, HAL_DEBUG_RFPARAM,
2205 "%s: cck: MaxRD: %d MaxCTL: %d "
2206 "TPC_Reduction %d chan=%d (0x%x) maxAvailPower=%d pwr6_24=%d, maxPower=%d\n",
2207 __func__, twiceMaxRDPower, twiceMaxEdgePowerCck,
2208 tpcScaleReduction * 2, chan->channel, chan->channelFlags,
2209 maxAvailPower, targetPowerCck.twicePwr6_24, *pMaxPower);
2210 }
2211 if (commit) {
2212 ahp->ah_tx6PowerInHalfDbm = *pMaxPower;
2213 AH_PRIVATE(ah)->ah_maxPowerLevel = ahp->ah_tx6PowerInHalfDbm;
2214 }
2215 return AH_TRUE;
2216}
2217
2218HAL_BOOL
2219ar5212GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, uint32_t nchans)
2220{
2221 struct ath_hal_5212 *ahp = AH5212(ah);
2222 static const uint16_t tpcScaleReductionTable[5] =
2223 { 0, 3, 6, 9, MAX_RATE_POWER };
2224 int16_t minPower, maxPower, tpcInDb, powerLimit;
2225 HAL_CHANNEL *chan;
2226 int i;
2227
2228 /*
2229 * Get Pier table max and min powers.
2230 */
2231 for (i = 0; i < nchans; i++) {
2232 chan = &chans[i];
2233 if (ahp->ah_rfHal->getChannelMaxMinPower(ah, chan, &maxPower, &minPower)) {
2234 /* NB: rf code returns 1/4 dBm units, convert */
2235 chan->maxTxPower = maxPower / 2;
2236 chan->minTxPower = minPower / 2;
2237 } else {
2238 HALDEBUG(ah, HAL_DEBUG_ANY,
2239 "%s: no min/max power for %u/0x%x\n",
2240 __func__, chan->channel, chan->channelFlags);
2241 chan->maxTxPower = MAX_RATE_POWER;
2242 chan->minTxPower = 0;
2243 }
2244 }
2245 /*
2246 * Now adjust to reflect any global scale and/or CTL's.
2247 * (XXX is that correct?)
2248 */
2249 powerLimit = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit);
2250 if (powerLimit >= MAX_RATE_POWER || powerLimit == 0)
2251 tpcInDb = tpcScaleReductionTable[AH_PRIVATE(ah)->ah_tpScale];
2252 else
2253 tpcInDb = 0;
2254 for (i=0; i<nchans; i++) {
2255 chan = &chans[i];
2256 if (!ar5212SetRateTable(ah, (HAL_CHANNEL *) chan, tpcInDb, powerLimit,
2257 AH_FALSE, &minPower, &maxPower)) {
2258 HALDEBUG(ah, HAL_DEBUG_ANY,
2259 "%s: unable to find max/min power\n",__func__);
2260 return AH_FALSE;
2261 }
2262 if (maxPower < chan->maxTxPower)
2263 chan->maxTxPower = maxPower;
2264 if (minPower < chan->minTxPower)
2265 chan->minTxPower = minPower;
2266 }
2267#ifdef AH_DEBUG
2268 for (i=0; i<nchans; i++) {
2269 HALDEBUG(ah, HAL_DEBUG_RESET,
2270 "Chan %d: MaxPow = %d MinPow = %d\n",
2271 chans[i].channel,chans[i].maxTxPower, chans[i].minTxPower);
2272 }
2273#endif
2274 return AH_TRUE;
2275}
2276
2277/*
2278 * Correct for the gain-delta between ofdm and cck mode target
2279 * powers. Write the results to the rate table and the power table.
2280 *
2281 * Conventions :
2282 * 1. rpow[ii] is the integer value of 2*(desired power
2283 * for the rate ii in dBm) to provide 0.5dB resolution. rate
2284 * mapping is as following :
2285 * [0..7] --> ofdm 6, 9, .. 48, 54
2286 * [8..14] --> cck 1L, 2L, 2S, .. 11L, 11S
2287 * [15] --> XR (all rates get the same power)
2288 * 2. powv[ii] is the pcdac corresponding to ii/2 dBm.
2289 */
2290static void
2291ar5212CorrectGainDelta(struct ath_hal *ah, int twiceOfdmCckDelta)
2292{
2293#define N(_a) (sizeof(_a) / sizeof(_a[0]))
2294 struct ath_hal_5212 *ahp = AH5212(ah);
2295 const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
2296 int16_t ratesIndex[N(ahp->ah_ratesArray)];
2297 uint16_t ii, jj, iter;
2298 int32_t cckIndex;
2299 int16_t gainDeltaAdjust;
2300
2301 HALASSERT(ah->ah_magic == AR5212_MAGIC);
2302
2303 gainDeltaAdjust = ee->ee_cckOfdmGainDelta;
2304
2305 /* make a local copy of desired powers as initial indices */
2306 OS_MEMCPY(ratesIndex, ahp->ah_ratesArray, sizeof(ratesIndex));
2307
2308 /* fix only the CCK indices */
2309 for (ii = 8; ii < 15; ii++) {
2310 /* apply a gain_delta correction of -15 for CCK */
2311 ratesIndex[ii] -= gainDeltaAdjust;
2312
2313 /* Now check for contention with all ofdm target powers */
2314 jj = 0;
2315 iter = 0;
2316 /* indicates not all ofdm rates checked forcontention yet */
2317 while (jj < 16) {
2318 if (ratesIndex[ii] < 0)
2319 ratesIndex[ii] = 0;
2320 if (jj == 8) { /* skip CCK rates */
2321 jj = 15;
2322 continue;
2323 }
2324 if (ratesIndex[ii] == ahp->ah_ratesArray[jj]) {
2325 if (ahp->ah_ratesArray[jj] == 0)
2326 ratesIndex[ii]++;
2327 else if (iter > 50) {
2328 /*
2329 * To avoid pathological case of of
2330 * dm target powers 0 and 0.5dBm
2331 */
2332 ratesIndex[ii]++;
2333 } else
2334 ratesIndex[ii]--;
2335 /* check with all rates again */
2336 jj = 0;
2337 iter++;
2338 } else
2339 jj++;
2340 }
2341 if (ratesIndex[ii] >= PWR_TABLE_SIZE)
2342 ratesIndex[ii] = PWR_TABLE_SIZE -1;
2343 cckIndex = ahp->ah_ratesArray[ii] - twiceOfdmCckDelta;
2344 if (cckIndex < 0)
2345 cckIndex = 0;
2346
2347 /*
2348 * Validate that the indexes for the powv are not
2349 * out of bounds.
2350 */
2351 HALASSERT(cckIndex < PWR_TABLE_SIZE);
2352 HALASSERT(ratesIndex[ii] < PWR_TABLE_SIZE);
2353 ahp->ah_pcdacTable[ratesIndex[ii]] =
2354 ahp->ah_pcdacTable[cckIndex];
2355 }
2356 /* Override rate per power table with new values */
2357 for (ii = 8; ii < 15; ii++)
2358 ahp->ah_ratesArray[ii] = ratesIndex[ii];
2359#undef N
2360}
2361
2362/*
2363 * Find the maximum conformance test limit for the given channel and CTL info
2364 */
2365static uint16_t
2366ar5212GetMaxEdgePower(uint16_t channel, const RD_EDGES_POWER *pRdEdgesPower)
2367{
2368 /* temp array for holding edge channels */
2369 uint16_t tempChannelList[NUM_EDGES];
2370 uint16_t clo, chi, twiceMaxEdgePower;
2371 int i, numEdges;
2372
2373 /* Get the edge power */
2374 for (i = 0; i < NUM_EDGES; i++) {
2375 if (pRdEdgesPower[i].rdEdge == 0)
2376 break;
2377 tempChannelList[i] = pRdEdgesPower[i].rdEdge;
2378 }
2379 numEdges = i;
2380
2381 ar5212GetLowerUpperValues(channel, tempChannelList,
2382 numEdges, &clo, &chi);
2383 /* Get the index for the lower channel */
2384 for (i = 0; i < numEdges && clo != tempChannelList[i]; i++)
2385 ;
2386 /* Is lower channel ever outside the rdEdge? */
2387 HALASSERT(i != numEdges);
2388
2389 if ((clo == chi && clo == channel) || (pRdEdgesPower[i].flag)) {
2390 /*
2391 * If there's an exact channel match or an inband flag set
2392 * on the lower channel use the given rdEdgePower
2393 */
2394 twiceMaxEdgePower = pRdEdgesPower[i].twice_rdEdgePower;
2395 HALASSERT(twiceMaxEdgePower > 0);
2396 } else
2397 twiceMaxEdgePower = MAX_RATE_POWER;
2398 return twiceMaxEdgePower;
2399}
2400
2401/*
2402 * Returns interpolated or the scaled up interpolated value
2403 */
2404static uint16_t
2405interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight,
2406 uint16_t targetLeft, uint16_t targetRight)
2407{
2408 uint16_t rv;
2409 int16_t lRatio;
2410
2411 /* to get an accurate ratio, always scale, if want to scale, then don't scale back down */
2412 if ((targetLeft * targetRight) == 0)
2413 return 0;
2414
2415 if (srcRight != srcLeft) {
2416 /*
2417 * Note the ratio always need to be scaled,
2418 * since it will be a fraction.
2419 */
2420 lRatio = (target - srcLeft) * EEP_SCALE / (srcRight - srcLeft);
2421 if (lRatio < 0) {
2422 /* Return as Left target if value would be negative */
2423 rv = targetLeft;
2424 } else if (lRatio > EEP_SCALE) {
2425 /* Return as Right target if Ratio is greater than 100% (SCALE) */
2426 rv = targetRight;
2427 } else {
2428 rv = (lRatio * targetRight + (EEP_SCALE - lRatio) *
2429 targetLeft) / EEP_SCALE;
2430 }
2431 } else {
2432 rv = targetLeft;
2433 }
2434 return rv;
2435}
2436
2437/*
2438 * Return the four rates of target power for the given target power table
2439 * channel, and number of channels
2440 */
2441static void
2442ar5212GetTargetPowers(struct ath_hal *ah, HAL_CHANNEL *chan,
2443 const TRGT_POWER_INFO *powInfo,
2444 uint16_t numChannels, TRGT_POWER_INFO *pNewPower)
2445{
2446 /* temp array for holding target power channels */
2447 uint16_t tempChannelList[NUM_TEST_FREQUENCIES];
2448 uint16_t clo, chi, ixlo, ixhi;
2449 int i;
2450
2451 /* Copy the target powers into the temp channel list */
2452 for (i = 0; i < numChannels; i++)
2453 tempChannelList[i] = powInfo[i].testChannel;
2454
2455 ar5212GetLowerUpperValues(chan->channel, tempChannelList,
2456 numChannels, &clo, &chi);
2457
2458 /* Get the indices for the channel */
2459 ixlo = ixhi = 0;
2460 for (i = 0; i < numChannels; i++) {
2461 if (clo == tempChannelList[i]) {
2462 ixlo = i;
2463 }
2464 if (chi == tempChannelList[i]) {
2465 ixhi = i;
2466 break;
2467 }
2468 }
2469
2470 /*
2471 * Get the lower and upper channels, target powers,
2472 * and interpolate between them.
2473 */
2474 pNewPower->twicePwr6_24 = interpolate(chan->channel, clo, chi,
2475 powInfo[ixlo].twicePwr6_24, powInfo[ixhi].twicePwr6_24);
2476 pNewPower->twicePwr36 = interpolate(chan->channel, clo, chi,
2477 powInfo[ixlo].twicePwr36, powInfo[ixhi].twicePwr36);
2478 pNewPower->twicePwr48 = interpolate(chan->channel, clo, chi,
2479 powInfo[ixlo].twicePwr48, powInfo[ixhi].twicePwr48);
2480 pNewPower->twicePwr54 = interpolate(chan->channel, clo, chi,
2481 powInfo[ixlo].twicePwr54, powInfo[ixhi].twicePwr54);
2482}
2483
2484/*
2485 * Search a list for a specified value v that is within
2486 * EEP_DELTA of the search values. Return the closest
2487 * values in the list above and below the desired value.
2488 * EEP_DELTA is a factional value; everything is scaled
2489 * so only integer arithmetic is used.
2490 *
2491 * NB: the input list is assumed to be sorted in ascending order
2492 */
2493void
2494ar5212GetLowerUpperValues(uint16_t v, uint16_t *lp, uint16_t listSize,
2495 uint16_t *vlo, uint16_t *vhi)
2496{
2497 uint32_t target = v * EEP_SCALE;
2498 uint16_t *ep = lp+listSize;
2499
2500 /*
2501 * Check first and last elements for out-of-bounds conditions.
2502 */
2503 if (target < (uint32_t)(lp[0] * EEP_SCALE - EEP_DELTA)) {
2504 *vlo = *vhi = lp[0];
2505 return;
2506 }
2507 if (target > (uint32_t)(ep[-1] * EEP_SCALE + EEP_DELTA)) {
2508 *vlo = *vhi = ep[-1];
2509 return;
2510 }
2511
2512 /* look for value being near or between 2 values in list */
2513 for (; lp < ep; lp++) {
2514 /*
2515 * If value is close to the current value of the list
2516 * then target is not between values, it is one of the values
2517 */
2518 if (abs(lp[0] * EEP_SCALE - target) < EEP_DELTA) {
2519 *vlo = *vhi = lp[0];
2520 return;
2521 }
2522 /*
2523 * Look for value being between current value and next value
2524 * if so return these 2 values
2525 */
2526 if (target < (uint32_t)(lp[1] * EEP_SCALE - EEP_DELTA)) {
2527 *vlo = lp[0];
2528 *vhi = lp[1];
2529 return;
2530 }
2531 }
2532 HALASSERT(AH_FALSE); /* should not reach here */
2533}
2534
2535/*
2536 * Perform analog "swizzling" of parameters into their location
2537 *
2538 * NB: used by RF backends
2539 */
2540void
2541ar5212ModifyRfBuffer(uint32_t *rfBuf, uint32_t reg32, uint32_t numBits,
2542 uint32_t firstBit, uint32_t column)
2543{
2544#define MAX_ANALOG_START 319 /* XXX */
2545 uint32_t tmp32, mask, arrayEntry, lastBit;
2546 int32_t bitPosition, bitsLeft;
2547
2548 HALASSERT(column <= 3);
2549 HALASSERT(numBits <= 32);
2550 HALASSERT(firstBit + numBits <= MAX_ANALOG_START);
2551
2552 tmp32 = ath_hal_reverseBits(reg32, numBits);
2553 arrayEntry = (firstBit - 1) / 8;
2554 bitPosition = (firstBit - 1) % 8;
2555 bitsLeft = numBits;
2556 while (bitsLeft > 0) {
2557 lastBit = (bitPosition + bitsLeft > 8) ?
2558 8 : bitPosition + bitsLeft;
2559 mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<
2560 (column * 8);
2561 rfBuf[arrayEntry] &= ~mask;
2562 rfBuf[arrayEntry] |= ((tmp32 << bitPosition) <<
2563 (column * 8)) & mask;
2564 bitsLeft -= 8 - bitPosition;
2565 tmp32 = tmp32 >> (8 - bitPosition);
2566 bitPosition = 0;
2567 arrayEntry++;
2568 }
2569#undef MAX_ANALOG_START
2570}
2571
2572/*
2573 * Sets the rate to duration values in MAC - used for multi-
2574 * rate retry.
2575 * The rate duration table needs to cover all valid rate codes;
2576 * the 11g table covers all ofdm rates, while the 11b table
2577 * covers all cck rates => all valid rates get covered between
2578 * these two mode's ratetables!
2579 * But if we're turbo, the ofdm phy is replaced by the turbo phy
2580 * and cck is not valid with turbo => all rates get covered
2581 * by the turbo ratetable only
2582 */
2583void
2584ar5212SetRateDurationTable(struct ath_hal *ah, HAL_CHANNEL *chan)
2585{
2586 const HAL_RATE_TABLE *rt;
2587 int i;
2588
2589 /* NB: band doesn't matter for 1/2 and 1/4 rate */
2590 if (IS_CHAN_HALF_RATE(chan)) {
2591 rt = ar5212GetRateTable(ah, HAL_MODE_11A_HALF_RATE);
2592 } else if (IS_CHAN_QUARTER_RATE(chan)) {
2593 rt = ar5212GetRateTable(ah, HAL_MODE_11A_QUARTER_RATE);
2594 } else {
2595 rt = ar5212GetRateTable(ah,
2596 IS_CHAN_TURBO(chan) ? HAL_MODE_TURBO : HAL_MODE_11G);
2597 }
2598
2599 for (i = 0; i < rt->rateCount; ++i)
2600 OS_REG_WRITE(ah,
2601 AR_RATE_DURATION(rt->info[i].rateCode),
2602 ath_hal_computetxtime(ah, rt,
2603 WLAN_CTRL_FRAME_SIZE,
2604 rt->info[i].controlRate, AH_FALSE));
2605 if (!IS_CHAN_TURBO(chan)) {
2606 /* 11g Table is used to cover the CCK rates. */
2607 rt = ar5212GetRateTable(ah, HAL_MODE_11G);
2608 for (i = 0; i < rt->rateCount; ++i) {
2609 uint32_t reg = AR_RATE_DURATION(rt->info[i].rateCode);
2610
2611 if (rt->info[i].phy != IEEE80211_T_CCK)
2612 continue;
2613
2614 OS_REG_WRITE(ah, reg,
2615 ath_hal_computetxtime(ah, rt,
2616 WLAN_CTRL_FRAME_SIZE,
2617 rt->info[i].controlRate, AH_FALSE));
2618 /* cck rates have short preamble option also */
2619 if (rt->info[i].shortPreamble) {
2620 reg += rt->info[i].shortPreamble << 2;
2621 OS_REG_WRITE(ah, reg,
2622 ath_hal_computetxtime(ah, rt,
2623 WLAN_CTRL_FRAME_SIZE,
2624 rt->info[i].controlRate,
2625 AH_TRUE));
2626 }
2627 }
2628 }
2629}
2630
2631/* Adjust various register settings based on half/quarter rate clock setting.
2632 * This includes: +USEC, TX/RX latency,
2633 * + IFS params: slot, eifs, misc etc.
2634 */
2635void
2636ar5212SetIFSTiming(struct ath_hal *ah, HAL_CHANNEL *chan)
2637{
2638 uint32_t txLat, rxLat, usec, slot, refClock, eifs, init_usec;
2639
2640 HALASSERT(IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan));
2641
2642 refClock = OS_REG_READ(ah, AR_USEC) & AR_USEC_USEC32;
2643 if (IS_CHAN_HALF_RATE(chan)) {
2644 slot = IFS_SLOT_HALF_RATE;
2645 rxLat = RX_NON_FULL_RATE_LATENCY << AR5212_USEC_RX_LAT_S;
2646 txLat = TX_HALF_RATE_LATENCY << AR5212_USEC_TX_LAT_S;
2647 usec = HALF_RATE_USEC;
2648 eifs = IFS_EIFS_HALF_RATE;
2649 init_usec = INIT_USEC >> 1;
2650 } else { /* quarter rate */
2651 slot = IFS_SLOT_QUARTER_RATE;
2652 rxLat = RX_NON_FULL_RATE_LATENCY << AR5212_USEC_RX_LAT_S;
2653 txLat = TX_QUARTER_RATE_LATENCY << AR5212_USEC_TX_LAT_S;
2654 usec = QUARTER_RATE_USEC;
2655 eifs = IFS_EIFS_QUARTER_RATE;
2656 init_usec = INIT_USEC >> 2;
2657 }
2658
2659 OS_REG_WRITE(ah, AR_USEC, (usec | refClock | txLat | rxLat));
2660 OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, slot);
2661 OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS, eifs);
2662 OS_REG_RMW_FIELD(ah, AR_D_GBL_IFS_MISC,
2663 AR_D_GBL_IFS_MISC_USEC_DURATION, init_usec);
2664}
28
29#include "ah_eeprom_v3.h"
30
31/* Additional Time delay to wait after activiting the Base band */
32#define BASE_ACTIVATE_DELAY 100 /* 100 usec */
33#define PLL_SETTLE_DELAY 300 /* 300 usec */
34
35static HAL_BOOL ar5212SetResetReg(struct ath_hal *, uint32_t resetMask);
36/* NB: public for 5312 use */
37HAL_BOOL ar5212IsSpurChannel(struct ath_hal *, HAL_CHANNEL *);
38HAL_BOOL ar5212ChannelChange(struct ath_hal *, HAL_CHANNEL *);
39int16_t ar5212GetNf(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
40HAL_BOOL ar5212SetBoardValues(struct ath_hal *, HAL_CHANNEL_INTERNAL *);
41void ar5212SetDeltaSlope(struct ath_hal *, HAL_CHANNEL *);
42HAL_BOOL ar5212SetTransmitPower(struct ath_hal *ah,
43 HAL_CHANNEL_INTERNAL *chan, uint16_t *rfXpdGain);
44static HAL_BOOL ar5212SetRateTable(struct ath_hal *,
45 HAL_CHANNEL *, int16_t tpcScaleReduction, int16_t powerLimit,
46 HAL_BOOL commit, int16_t *minPower, int16_t *maxPower);
47static void ar5212CorrectGainDelta(struct ath_hal *, int twiceOfdmCckDelta);
48static void ar5212GetTargetPowers(struct ath_hal *, HAL_CHANNEL *,
49 const TRGT_POWER_INFO *pPowerInfo, uint16_t numChannels,
50 TRGT_POWER_INFO *pNewPower);
51static uint16_t ar5212GetMaxEdgePower(uint16_t channel,
52 const RD_EDGES_POWER *pRdEdgesPower);
53void ar5212SetRateDurationTable(struct ath_hal *, HAL_CHANNEL *);
54void ar5212SetIFSTiming(struct ath_hal *, HAL_CHANNEL *);
55
56/* NB: public for RF backend use */
57void ar5212GetLowerUpperValues(uint16_t value,
58 uint16_t *pList, uint16_t listSize,
59 uint16_t *pLowerValue, uint16_t *pUpperValue);
60void ar5212ModifyRfBuffer(uint32_t *rfBuf, uint32_t reg32,
61 uint32_t numBits, uint32_t firstBit, uint32_t column);
62
63static int
64write_common(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
65 HAL_BOOL bChannelChange, int writes)
66{
67#define IS_NO_RESET_TIMER_ADDR(x) \
68 ( (((x) >= AR_BEACON) && ((x) <= AR_CFP_DUR)) || \
69 (((x) >= AR_SLEEP1) && ((x) <= AR_SLEEP3)))
70#define V(r, c) (ia)->data[((r)*(ia)->cols) + (c)]
71 int r;
72
73 /* Write Common Array Parameters */
74 for (r = 0; r < ia->rows; r++) {
75 uint32_t reg = V(r, 0);
76 /* XXX timer/beacon setup registers? */
77 /* On channel change, don't reset the PCU registers */
78 if (!(bChannelChange && IS_NO_RESET_TIMER_ADDR(reg))) {
79 OS_REG_WRITE(ah, reg, V(r, 1));
80 DMA_YIELD(writes);
81 }
82 }
83 return writes;
84#undef IS_NO_RESET_TIMER_ADDR
85#undef V
86}
87
88#define IS_DISABLE_FAST_ADC_CHAN(x) (((x) == 2462) || ((x) == 2467))
89
90/*
91 * Places the device in and out of reset and then places sane
92 * values in the registers based on EEPROM config, initialization
93 * vectors (as determined by the mode), and station configuration
94 *
95 * bChannelChange is used to preserve DMA/PCU registers across
96 * a HW Reset during channel change.
97 */
98HAL_BOOL
99ar5212Reset(struct ath_hal *ah, HAL_OPMODE opmode,
100 HAL_CHANNEL *chan, HAL_BOOL bChannelChange, HAL_STATUS *status)
101{
102#define N(a) (sizeof (a) / sizeof (a[0]))
103#define FAIL(_code) do { ecode = _code; goto bad; } while (0)
104 struct ath_hal_5212 *ahp = AH5212(ah);
105 HAL_CHANNEL_INTERNAL *ichan = AH_NULL;
106 const HAL_EEPROM *ee;
107 uint32_t softLedCfg, softLedState;
108 uint32_t saveFrameSeqCount, saveDefAntenna, saveLedState;
109 uint32_t macStaId1, synthDelay, txFrm2TxDStart;
110 uint16_t rfXpdGain[MAX_NUM_PDGAINS_PER_CHANNEL];
111 int16_t cckOfdmPwrDelta = 0;
112 u_int modesIndex, freqIndex;
113 HAL_STATUS ecode;
114 int i, regWrites;
115 uint32_t testReg, powerVal;
116 int8_t twiceAntennaGain, twiceAntennaReduction;
117 uint32_t ackTpcPow, ctsTpcPow, chirpTpcPow;
118 HAL_BOOL isBmode = AH_FALSE;
119 HAL_BOOL ichan_isBmode = AH_FALSE;
120
121 HALASSERT(ah->ah_magic == AR5212_MAGIC);
122 ee = AH_PRIVATE(ah)->ah_eeprom;
123
124 OS_MARK(ah, AH_MARK_RESET, bChannelChange);
125#define IS(_c,_f) (((_c)->channelFlags & _f) || 0)
126 if ((IS(chan, CHANNEL_2GHZ) ^ IS(chan, CHANNEL_5GHZ)) == 0) {
127 HALDEBUG(ah, HAL_DEBUG_ANY,
128 "%s: invalid channel %u/0x%x; not marked as 2GHz or 5GHz\n",
129 __func__, chan->channel, chan->channelFlags);
130 FAIL(HAL_EINVAL);
131 }
132 if ((IS(chan, CHANNEL_OFDM) ^ IS(chan, CHANNEL_CCK)) == 0) {
133 HALDEBUG(ah, HAL_DEBUG_ANY,
134 "%s: invalid channel %u/0x%x; not marked as OFDM or CCK\n",
135 __func__, chan->channel, chan->channelFlags);
136 FAIL(HAL_EINVAL);
137 }
138#undef IS
139
140 /* Bring out of sleep mode */
141 if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
142 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip did not wakeup\n",
143 __func__);
144 FAIL(HAL_EIO);
145 }
146
147 /*
148 * Map public channel to private.
149 */
150 ichan = ath_hal_checkchannel(ah, chan);
151 if (ichan == AH_NULL) {
152 HALDEBUG(ah, HAL_DEBUG_ANY,
153 "%s: invalid channel %u/0x%x; no mapping\n",
154 __func__, chan->channel, chan->channelFlags);
155 FAIL(HAL_EINVAL);
156 }
157 switch (opmode) {
158 case HAL_M_STA:
159 case HAL_M_IBSS:
160 case HAL_M_HOSTAP:
161 case HAL_M_MONITOR:
162 break;
163 default:
164 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid operating mode %u\n",
165 __func__, opmode);
166 FAIL(HAL_EINVAL);
167 break;
168 }
169 HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER3);
170
171 SAVE_CCK(ah, ichan, ichan_isBmode);
172 SAVE_CCK(ah, chan, isBmode);
173
174 /* Preserve certain DMA hardware registers on a channel change */
175 if (bChannelChange) {
176 /*
177 * On Venice, the TSF is almost preserved across a reset;
178 * it requires doubling writes to the RESET_TSF
179 * bit in the AR_BEACON register; it also has the quirk
180 * of the TSF going back in time on the station (station
181 * latches onto the last beacon's tsf during a reset 50%
182 * of the times); the latter is not a problem for adhoc
183 * stations since as long as the TSF is behind, it will
184 * get resynchronized on receiving the next beacon; the
185 * TSF going backwards in time could be a problem for the
186 * sleep operation (supported on infrastructure stations
187 * only) - the best and most general fix for this situation
188 * is to resynchronize the various sleep/beacon timers on
189 * the receipt of the next beacon i.e. when the TSF itself
190 * gets resynchronized to the AP's TSF - power save is
191 * needed to be temporarily disabled until that time
192 *
193 * Need to save the sequence number to restore it after
194 * the reset!
195 */
196 saveFrameSeqCount = OS_REG_READ(ah, AR_D_SEQNUM);
197 } else
198 saveFrameSeqCount = 0; /* NB: silence compiler */
199#if 0
200 /*
201 * XXX disable for now; this appears to sometimes cause OFDM
202 * XXX timing error floods when ani is enabled and bg scanning
203 * XXX kicks in
204 */
205 /* If the channel change is across the same mode - perform a fast channel change */
206 if (IS_2413(ah) || IS_5413(ah)) {
207 /*
208 * Fast channel change can only be used when:
209 * -channel change requested - so it's not the initial reset.
210 * -it's not a change to the current channel -
211 * often called when switching modes on a channel
212 * -the modes of the previous and requested channel are the
213 * same
214 * XXX opmode shouldn't change either?
215 */
216 if (bChannelChange &&
217 (AH_PRIVATE(ah)->ah_curchan != AH_NULL) &&
218 (chan->channel != AH_PRIVATE(ah)->ah_curchan->channel) &&
219 ((chan->channelFlags & CHANNEL_ALL) ==
220 (AH_PRIVATE(ah)->ah_curchan->channelFlags & CHANNEL_ALL))) {
221 if (ar5212ChannelChange(ah, chan)) {
222 /* If ChannelChange completed - skip the rest of reset */
223 /* XXX ani? */
224 return AH_TRUE;
225 }
226 }
227 }
228#endif
229 /*
230 * Preserve the antenna on a channel change
231 */
232 saveDefAntenna = OS_REG_READ(ah, AR_DEF_ANTENNA);
233 if (saveDefAntenna == 0) /* XXX magic constants */
234 saveDefAntenna = 1;
235
236 /* Save hardware flag before chip reset clears the register */
237 macStaId1 = OS_REG_READ(ah, AR_STA_ID1) &
238 (AR_STA_ID1_BASE_RATE_11B | AR_STA_ID1_USE_DEFANT);
239
240 /* Save led state from pci config register */
241 saveLedState = OS_REG_READ(ah, AR_PCICFG) &
242 (AR_PCICFG_LEDCTL | AR_PCICFG_LEDMODE | AR_PCICFG_LEDBLINK |
243 AR_PCICFG_LEDSLOW);
244 softLedCfg = OS_REG_READ(ah, AR_GPIOCR);
245 softLedState = OS_REG_READ(ah, AR_GPIODO);
246
247 ar5212RestoreClock(ah, opmode); /* move to refclk operation */
248
249 /*
250 * Adjust gain parameters before reset if
251 * there's an outstanding gain updated.
252 */
253 (void) ar5212GetRfgain(ah);
254
255 if (!ar5212ChipReset(ah, chan)) {
256 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
257 FAIL(HAL_EIO);
258 }
259
260 /* Setup the indices for the next set of register array writes */
261 switch (chan->channelFlags & CHANNEL_ALL) {
262 case CHANNEL_A:
263 modesIndex = 1;
264 freqIndex = 1;
265 break;
266 case CHANNEL_T:
267 modesIndex = 2;
268 freqIndex = 1;
269 break;
270 case CHANNEL_B:
271 modesIndex = 3;
272 freqIndex = 2;
273 break;
274 case CHANNEL_PUREG:
275 modesIndex = 4;
276 freqIndex = 2;
277 break;
278 case CHANNEL_108G:
279 modesIndex = 5;
280 freqIndex = 2;
281 break;
282 default:
283 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
284 __func__, chan->channelFlags);
285 FAIL(HAL_EINVAL);
286 }
287
288 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
289
290 /* Set correct Baseband to analog shift setting to access analog chips. */
291 OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
292
293 regWrites = ath_hal_ini_write(ah, &ahp->ah_ini_modes, modesIndex, 0);
294 regWrites = write_common(ah, &ahp->ah_ini_common, bChannelChange,
295 regWrites);
296 ahp->ah_rfHal->writeRegs(ah, modesIndex, freqIndex, regWrites);
297
298 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
299
300 if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) {
301 ar5212SetIFSTiming(ah, chan);
302 if (IS_5413(ah)) {
303 /*
304 * Force window_length for 1/2 and 1/4 rate channels,
305 * the ini file sets this to zero otherwise.
306 */
307 OS_REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL,
308 AR_PHY_FRAME_CTL_WINLEN, 3);
309 }
310 }
311
312 /* Overwrite INI values for revised chipsets */
313 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2) {
314 /* ADC_CTL */
315 OS_REG_WRITE(ah, AR_PHY_ADC_CTL,
316 SM(2, AR_PHY_ADC_CTL_OFF_INBUFGAIN) |
317 SM(2, AR_PHY_ADC_CTL_ON_INBUFGAIN) |
318 AR_PHY_ADC_CTL_OFF_PWDDAC |
319 AR_PHY_ADC_CTL_OFF_PWDADC);
320
321 /* TX_PWR_ADJ */
322 if (chan->channel == 2484) {
323 cckOfdmPwrDelta = SCALE_OC_DELTA(
324 ee->ee_cckOfdmPwrDelta -
325 ee->ee_scaledCh14FilterCckDelta);
326 } else {
327 cckOfdmPwrDelta = SCALE_OC_DELTA(
328 ee->ee_cckOfdmPwrDelta);
329 }
330
331 if (IS_CHAN_G(chan)) {
332 OS_REG_WRITE(ah, AR_PHY_TXPWRADJ,
333 SM((ee->ee_cckOfdmPwrDelta*-1),
334 AR_PHY_TXPWRADJ_CCK_GAIN_DELTA) |
335 SM((cckOfdmPwrDelta*-1),
336 AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX));
337 } else {
338 OS_REG_WRITE(ah, AR_PHY_TXPWRADJ, 0);
339 }
340
341 /* Add barker RSSI thresh enable as disabled */
342 OS_REG_CLR_BIT(ah, AR_PHY_DAG_CTRLCCK,
343 AR_PHY_DAG_CTRLCCK_EN_RSSI_THR);
344 OS_REG_RMW_FIELD(ah, AR_PHY_DAG_CTRLCCK,
345 AR_PHY_DAG_CTRLCCK_RSSI_THR, 2);
346
347 /* Set the mute mask to the correct default */
348 OS_REG_WRITE(ah, AR_SEQ_MASK, 0x0000000F);
349 }
350
351 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_3) {
352 /* Clear reg to alllow RX_CLEAR line debug */
353 OS_REG_WRITE(ah, AR_PHY_BLUETOOTH, 0);
354 }
355 if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_4) {
356#ifdef notyet
357 /* Enable burst prefetch for the data queues */
358 OS_REG_RMW_FIELD(ah, AR_D_FPCTL, ... );
359 /* Enable double-buffering */
360 OS_REG_CLR_BIT(ah, AR_TXCFG, AR_TXCFG_DBL_BUF_DIS);
361#endif
362 }
363
364 /* Set ADC/DAC select values */
365 OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e);
366
367 if (IS_5413(ah) || IS_2417(ah)) {
368 uint32_t newReg=1;
369 if (IS_DISABLE_FAST_ADC_CHAN(chan->channel))
370 newReg = 0;
371 /* As it's a clock changing register, only write when the value needs to be changed */
372 if (OS_REG_READ(ah, AR_PHY_FAST_ADC) != newReg)
373 OS_REG_WRITE(ah, AR_PHY_FAST_ADC, newReg);
374 }
375
376 /* Setup the transmit power values. */
377 if (!ar5212SetTransmitPower(ah, ichan, rfXpdGain)) {
378 HALDEBUG(ah, HAL_DEBUG_ANY,
379 "%s: error init'ing transmit power\n", __func__);
380 FAIL(HAL_EIO);
381 }
382
383 /* Write the analog registers */
384 if (!ahp->ah_rfHal->setRfRegs(ah, ichan, modesIndex, rfXpdGain)) {
385 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: ar5212SetRfRegs failed\n",
386 __func__);
387 FAIL(HAL_EIO);
388 }
389
390 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */
391 if (IS_CHAN_OFDM(chan)) {
392 if ((IS_5413(ah) || (AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3)) &&
393 (!IS_CHAN_B(chan)))
394 ar5212SetSpurMitigation(ah, ichan);
395 ar5212SetDeltaSlope(ah, chan);
396 }
397
398 /* Setup board specific options for EEPROM version 3 */
399 if (!ar5212SetBoardValues(ah, ichan)) {
400 HALDEBUG(ah, HAL_DEBUG_ANY,
401 "%s: error setting board options\n", __func__);
402 FAIL(HAL_EIO);
403 }
404
405 /* Restore certain DMA hardware registers on a channel change */
406 if (bChannelChange)
407 OS_REG_WRITE(ah, AR_D_SEQNUM, saveFrameSeqCount);
408
409 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
410
411 OS_REG_WRITE(ah, AR_STA_ID0, LE_READ_4(ahp->ah_macaddr));
412 OS_REG_WRITE(ah, AR_STA_ID1, LE_READ_2(ahp->ah_macaddr + 4)
413 | macStaId1
414 | AR_STA_ID1_RTS_USE_DEF
415 | ahp->ah_staId1Defaults
416 );
417 ar5212SetOperatingMode(ah, opmode);
418
419 /* Set Venice BSSID mask according to current state */
420 OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask));
421 OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4));
422
423 /* Restore previous led state */
424 OS_REG_WRITE(ah, AR_PCICFG, OS_REG_READ(ah, AR_PCICFG) | saveLedState);
425
426 /* Restore soft Led state to GPIO */
427 OS_REG_WRITE(ah, AR_GPIOCR, softLedCfg);
428 OS_REG_WRITE(ah, AR_GPIODO, softLedState);
429
430 /* Restore previous antenna */
431 OS_REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
432
433 /* then our BSSID */
434 OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
435 OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid + 4));
436
437 /* Restore bmiss rssi & count thresholds */
438 OS_REG_WRITE(ah, AR_RSSI_THR, ahp->ah_rssiThr);
439
440 OS_REG_WRITE(ah, AR_ISR, ~0); /* cleared on write */
441
442 if (!ar5212SetChannel(ah, ichan))
443 FAIL(HAL_EIO);
444
445 OS_MARK(ah, AH_MARK_RESET_LINE, __LINE__);
446
447 ar5212SetCoverageClass(ah, AH_PRIVATE(ah)->ah_coverageClass, 1);
448
449 ar5212SetRateDurationTable(ah, chan);
450
451 /* Set Tx frame start to tx data start delay */
452 if (IS_RAD5112_ANY(ah) &&
453 (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan) ||
454 IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan))) {
455 txFrm2TxDStart =
456 (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) ?
457 TX_FRAME_D_START_HALF_RATE:
458 TX_FRAME_D_START_QUARTER_RATE;
459 OS_REG_RMW_FIELD(ah, AR_PHY_TX_CTL,
460 AR_PHY_TX_FRAME_TO_TX_DATA_START, txFrm2TxDStart);
461 }
462
463 /*
464 * Setup fast diversity.
465 * Fast diversity can be enabled or disabled via regadd.txt.
466 * Default is enabled.
467 * For reference,
468 * Disable: reg val
469 * 0x00009860 0x00009d18 (if 11a / 11g, else no change)
470 * 0x00009970 0x192bb514
471 * 0x0000a208 0xd03e4648
472 *
473 * Enable: 0x00009860 0x00009d10 (if 11a / 11g, else no change)
474 * 0x00009970 0x192fb514
475 * 0x0000a208 0xd03e6788
476 */
477
478 /* XXX Setup pre PHY ENABLE EAR additions */
479 /*
480 * Wait for the frequency synth to settle (synth goes on
481 * via AR_PHY_ACTIVE_EN). Read the phy active delay register.
482 * Value is in 100ns increments.
483 */
484 synthDelay = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
485 if (IS_CHAN_CCK(chan)) {
486 synthDelay = (4 * synthDelay) / 22;
487 } else {
488 synthDelay /= 10;
489 }
490
491 /* Activate the PHY (includes baseband activate and synthesizer on) */
492 OS_REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
493
494 /*
495 * There is an issue if the AP starts the calibration before
496 * the base band timeout completes. This could result in the
497 * rx_clear false triggering. As a workaround we add delay an
498 * extra BASE_ACTIVATE_DELAY usecs to ensure this condition
499 * does not happen.
500 */
501 if (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) {
502 OS_DELAY((synthDelay << 1) + BASE_ACTIVATE_DELAY);
503 } else if (IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan)) {
504 OS_DELAY((synthDelay << 2) + BASE_ACTIVATE_DELAY);
505 } else {
506 OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);
507 }
508
509 /*
510 * The udelay method is not reliable with notebooks.
511 * Need to check to see if the baseband is ready
512 */
513 testReg = OS_REG_READ(ah, AR_PHY_TESTCTRL);
514 /* Selects the Tx hold */
515 OS_REG_WRITE(ah, AR_PHY_TESTCTRL, AR_PHY_TESTCTRL_TXHOLD);
516 i = 0;
517 while ((i++ < 20) &&
518 (OS_REG_READ(ah, 0x9c24) & 0x10)) /* test if baseband not ready */ OS_DELAY(200);
519 OS_REG_WRITE(ah, AR_PHY_TESTCTRL, testReg);
520
521 /* Calibrate the AGC and start a NF calculation */
522 OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
523 OS_REG_READ(ah, AR_PHY_AGC_CONTROL)
524 | AR_PHY_AGC_CONTROL_CAL
525 | AR_PHY_AGC_CONTROL_NF);
526
527 if (!IS_CHAN_B(chan) && ahp->ah_bIQCalibration != IQ_CAL_DONE) {
528 /* Start IQ calibration w/ 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples */
529 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
530 AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
531 INIT_IQCAL_LOG_COUNT_MAX);
532 OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4,
533 AR_PHY_TIMING_CTRL4_DO_IQCAL);
534 ahp->ah_bIQCalibration = IQ_CAL_RUNNING;
535 } else
536 ahp->ah_bIQCalibration = IQ_CAL_INACTIVE;
537
538 /* Setup compression registers */
539 ar5212SetCompRegs(ah);
540
541 /* Set 1:1 QCU to DCU mapping for all queues */
542 for (i = 0; i < AR_NUM_DCU; i++)
543 OS_REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
544
545 ahp->ah_intrTxqs = 0;
546 for (i = 0; i < AH_PRIVATE(ah)->ah_caps.halTotalQueues; i++)
547 ar5212ResetTxQueue(ah, i);
548
549 /*
550 * Setup interrupt handling. Note that ar5212ResetTxQueue
551 * manipulates the secondary IMR's as queues are enabled
552 * and disabled. This is done with RMW ops to insure the
553 * settings we make here are preserved.
554 */
555 ahp->ah_maskReg = AR_IMR_TXOK | AR_IMR_TXERR | AR_IMR_TXURN
556 | AR_IMR_RXOK | AR_IMR_RXERR | AR_IMR_RXORN
557 | AR_IMR_HIUERR
558 ;
559 if (opmode == HAL_M_HOSTAP)
560 ahp->ah_maskReg |= AR_IMR_MIB;
561 OS_REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
562 /* Enable bus errors that are OR'd to set the HIUERR bit */
563 OS_REG_WRITE(ah, AR_IMR_S2,
564 OS_REG_READ(ah, AR_IMR_S2)
565 | AR_IMR_S2_MCABT | AR_IMR_S2_SSERR | AR_IMR_S2_DPERR);
566
567 if (AH_PRIVATE(ah)->ah_rfkillEnabled)
568 ar5212EnableRfKill(ah);
569
570 if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
571 HALDEBUG(ah, HAL_DEBUG_ANY,
572 "%s: offset calibration failed to complete in 1ms;"
573 " noisy environment?\n", __func__);
574 }
575
576 /*
577 * Set clocks back to 32kHz if they had been using refClk, then
578 * use an external 32kHz crystal when sleeping, if one exists.
579 */
580 ar5212SetupClock(ah, opmode);
581
582 /*
583 * Writing to AR_BEACON will start timers. Hence it should
584 * be the last register to be written. Do not reset tsf, do
585 * not enable beacons at this point, but preserve other values
586 * like beaconInterval.
587 */
588 OS_REG_WRITE(ah, AR_BEACON,
589 (OS_REG_READ(ah, AR_BEACON) &~ (AR_BEACON_EN | AR_BEACON_RESET_TSF)));
590
591 /* XXX Setup post reset EAR additions */
592
593 /* QoS support */
594 if (AH_PRIVATE(ah)->ah_macVersion > AR_SREV_VERSION_VENICE ||
595 (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_VENICE &&
596 AH_PRIVATE(ah)->ah_macRev >= AR_SREV_GRIFFIN_LITE)) {
597 OS_REG_WRITE(ah, AR_QOS_CONTROL, 0x100aa); /* XXX magic */
598 OS_REG_WRITE(ah, AR_QOS_SELECT, 0x3210); /* XXX magic */
599 }
600
601 /* Turn on NOACK Support for QoS packets */
602 OS_REG_WRITE(ah, AR_NOACK,
603 SM(2, AR_NOACK_2BIT_VALUE) |
604 SM(5, AR_NOACK_BIT_OFFSET) |
605 SM(0, AR_NOACK_BYTE_OFFSET));
606
607 /* Get Antenna Gain reduction */
608 if (IS_CHAN_5GHZ(chan)) {
609 ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_5, &twiceAntennaGain);
610 } else {
611 ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_2, &twiceAntennaGain);
612 }
613 twiceAntennaReduction =
614 ath_hal_getantennareduction(ah, chan, twiceAntennaGain);
615
616 /* TPC for self-generated frames */
617
618 ackTpcPow = MS(ahp->ah_macTPC, AR_TPC_ACK);
619 if ((ackTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower)
620 ackTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset;
621
622 if (ackTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction))
623 ackTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction)
624 + ahp->ah_txPowerIndexOffset;
625
626 ctsTpcPow = MS(ahp->ah_macTPC, AR_TPC_CTS);
627 if ((ctsTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower)
628 ctsTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset;
629
630 if (ctsTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction))
631 ctsTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction)
632 + ahp->ah_txPowerIndexOffset;
633
634 chirpTpcPow = MS(ahp->ah_macTPC, AR_TPC_CHIRP);
635 if ((chirpTpcPow-ahp->ah_txPowerIndexOffset) > ichan->maxTxPower)
636 chirpTpcPow = ichan->maxTxPower+ahp->ah_txPowerIndexOffset;
637
638 if (chirpTpcPow > (2*ichan->maxRegTxPower - twiceAntennaReduction))
639 chirpTpcPow = (2*ichan->maxRegTxPower - twiceAntennaReduction)
640 + ahp->ah_txPowerIndexOffset;
641
642 if (ackTpcPow > 63)
643 ackTpcPow = 63;
644 if (ctsTpcPow > 63)
645 ctsTpcPow = 63;
646 if (chirpTpcPow > 63)
647 chirpTpcPow = 63;
648
649 powerVal = SM(ackTpcPow, AR_TPC_ACK) |
650 SM(ctsTpcPow, AR_TPC_CTS) |
651 SM(chirpTpcPow, AR_TPC_CHIRP);
652
653 OS_REG_WRITE(ah, AR_TPC, powerVal);
654
655 /* Restore user-specified settings */
656 if (ahp->ah_miscMode != 0)
657 OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);
658 if (ahp->ah_sifstime != (u_int) -1)
659 ar5212SetSifsTime(ah, ahp->ah_sifstime);
660 if (ahp->ah_slottime != (u_int) -1)
661 ar5212SetSlotTime(ah, ahp->ah_slottime);
662 if (ahp->ah_acktimeout != (u_int) -1)
663 ar5212SetAckTimeout(ah, ahp->ah_acktimeout);
664 if (ahp->ah_ctstimeout != (u_int) -1)
665 ar5212SetCTSTimeout(ah, ahp->ah_ctstimeout);
666 if (AH_PRIVATE(ah)->ah_diagreg != 0)
667 OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);
668
669 AH_PRIVATE(ah)->ah_opmode = opmode; /* record operating mode */
670
671 if (bChannelChange) {
672 if (!(ichan->privFlags & CHANNEL_DFS))
673 ichan->privFlags &= ~CHANNEL_INTERFERENCE;
674 chan->channelFlags = ichan->channelFlags;
675 chan->privFlags = ichan->privFlags;
676 chan->maxRegTxPower = ichan->maxRegTxPower;
677 chan->maxTxPower = ichan->maxTxPower;
678 chan->minTxPower = ichan->minTxPower;
679 }
680
681 HALDEBUG(ah, HAL_DEBUG_RESET, "%s: done\n", __func__);
682
683 RESTORE_CCK(ah, ichan, ichan_isBmode);
684 RESTORE_CCK(ah, chan, isBmode);
685
686 OS_MARK(ah, AH_MARK_RESET_DONE, 0);
687
688 return AH_TRUE;
689bad:
690 if (ichan != AH_NULL)
691 RESTORE_CCK(ah, ichan, ichan_isBmode);
692 RESTORE_CCK(ah, chan, isBmode);
693
694 OS_MARK(ah, AH_MARK_RESET_DONE, ecode);
695 if (*status)
696 *status = ecode;
697 return AH_FALSE;
698#undef FAIL
699#undef N
700}
701
702/*
703 * Call the rf backend to change the channel.
704 */
705HAL_BOOL
706ar5212SetChannel(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
707{
708 struct ath_hal_5212 *ahp = AH5212(ah);
709
710 /* Change the synth */
711 if (!ahp->ah_rfHal->setChannel(ah, chan))
712 return AH_FALSE;
713 return AH_TRUE;
714}
715
716/*
717 * This channel change evaluates whether the selected hardware can
718 * perform a synthesizer-only channel change (no reset). If the
719 * TX is not stopped, or the RFBus cannot be granted in the given
720 * time, the function returns false as a reset is necessary
721 */
722HAL_BOOL
723ar5212ChannelChange(struct ath_hal *ah, HAL_CHANNEL *chan)
724{
725 uint32_t ulCount;
726 uint32_t data, synthDelay, qnum;
727 uint16_t rfXpdGain[MAX_NUM_PDGAINS_PER_CHANNEL];
728 HAL_BOOL txStopped = AH_TRUE;
729 HAL_CHANNEL_INTERNAL *ichan;
730
731 /*
732 * Map public channel to private.
733 */
734 ichan = ath_hal_checkchannel(ah, chan);
735
736 /* TX must be stopped or RF Bus grant will not work */
737 for (qnum = 0; qnum < AH_PRIVATE(ah)->ah_caps.halTotalQueues; qnum++) {
738 if (ar5212NumTxPending(ah, qnum)) {
739 txStopped = AH_FALSE;
740 break;
741 }
742 }
743 if (!txStopped)
744 return AH_FALSE;
745
746 /* Kill last Baseband Rx Frame */
747 OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_REQUEST); /* Request analog bus grant */
748 for (ulCount = 0; ulCount < 100; ulCount++) {
749 if (OS_REG_READ(ah, AR_PHY_RFBUS_GNT))
750 break;
751 OS_DELAY(5);
752 }
753 if (ulCount >= 100)
754 return AH_FALSE;
755
756 /* Change the synth */
757 if (!ar5212SetChannel(ah, ichan))
758 return AH_FALSE;
759
760 /*
761 * Wait for the frequency synth to settle (synth goes on via PHY_ACTIVE_EN).
762 * Read the phy active delay register. Value is in 100ns increments.
763 */
764 data = OS_REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
765 if (IS_CHAN_CCK(ichan)) {
766 synthDelay = (4 * data) / 22;
767 } else {
768 synthDelay = data / 10;
769 }
770 OS_DELAY(synthDelay + BASE_ACTIVATE_DELAY);
771
772 /* Setup the transmit power values. */
773 if (!ar5212SetTransmitPower(ah, ichan, rfXpdGain)) {
774 HALDEBUG(ah, HAL_DEBUG_ANY,
775 "%s: error init'ing transmit power\n", __func__);
776 return AH_FALSE;
777 }
778
779 /* Write delta slope for OFDM enabled modes (A, G, Turbo) */
780 if (IS_CHAN_OFDM(ichan)) {
781 if ((IS_5413(ah) || (AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER5_3)) &&
782 (!IS_CHAN_B(chan)))
783 ar5212SetSpurMitigation(ah, ichan);
784 ar5212SetDeltaSlope(ah, chan);
785 }
786
787 /* Release the RFBus Grant */
788 OS_REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
789
790 /* Start Noise Floor Cal */
791 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
792
793 if (!(ichan->privFlags & CHANNEL_DFS))
794 ichan->privFlags &= ~CHANNEL_INTERFERENCE;
795 chan->channelFlags = ichan->channelFlags;
796 chan->privFlags = ichan->privFlags;
797 chan->maxRegTxPower = ichan->maxRegTxPower;
798 chan->maxTxPower = ichan->maxTxPower;
799 chan->minTxPower = ichan->minTxPower;
800 return AH_TRUE;
801}
802
803void
804ar5212SetOperatingMode(struct ath_hal *ah, int opmode)
805{
806 uint32_t val;
807
808 val = OS_REG_READ(ah, AR_STA_ID1);
809 val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
810 switch (opmode) {
811 case HAL_M_HOSTAP:
812 OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP
813 | AR_STA_ID1_KSRCH_MODE);
814 OS_REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
815 break;
816 case HAL_M_IBSS:
817 OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
818 | AR_STA_ID1_KSRCH_MODE);
819 OS_REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
820 break;
821 case HAL_M_STA:
822 case HAL_M_MONITOR:
823 OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
824 break;
825 }
826}
827
828/*
829 * Places the PHY and Radio chips into reset. A full reset
830 * must be called to leave this state. The PCI/MAC/PCU are
831 * not placed into reset as we must receive interrupt to
832 * re-enable the hardware.
833 */
834HAL_BOOL
835ar5212PhyDisable(struct ath_hal *ah)
836{
837 return ar5212SetResetReg(ah, AR_RC_BB);
838}
839
840/*
841 * Places all of hardware into reset
842 */
843HAL_BOOL
844ar5212Disable(struct ath_hal *ah)
845{
846 if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
847 return AH_FALSE;
848 /*
849 * Reset the HW - PCI must be reset after the rest of the
850 * device has been reset.
851 */
852 return ar5212SetResetReg(ah, AR_RC_MAC | AR_RC_BB | AR_RC_PCI);
853}
854
855/*
856 * Places the hardware into reset and then pulls it out of reset
857 *
858 * TODO: Only write the PLL if we're changing to or from CCK mode
859 *
860 * WARNING: The order of the PLL and mode registers must be correct.
861 */
862HAL_BOOL
863ar5212ChipReset(struct ath_hal *ah, HAL_CHANNEL *chan)
864{
865
866 OS_MARK(ah, AH_MARK_CHIPRESET, chan ? chan->channel : 0);
867
868 /*
869 * Reset the HW - PCI must be reset after the rest of the
870 * device has been reset
871 */
872 if (!ar5212SetResetReg(ah, AR_RC_MAC | AR_RC_BB | AR_RC_PCI))
873 return AH_FALSE;
874
875 /* Bring out of sleep mode (AGAIN) */
876 if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
877 return AH_FALSE;
878
879 /* Clear warm reset register */
880 if (!ar5212SetResetReg(ah, 0))
881 return AH_FALSE;
882
883 /*
884 * Perform warm reset before the mode/PLL/turbo registers
885 * are changed in order to deactivate the radio. Mode changes
886 * with an active radio can result in corrupted shifts to the
887 * radio device.
888 */
889
890 /*
891 * Set CCK and Turbo modes correctly.
892 */
893 if (chan != AH_NULL) { /* NB: can be null during attach */
894 uint32_t rfMode, phyPLL = 0, curPhyPLL, turbo;
895
896 if (IS_5413(ah)) { /* NB: =>'s 5424 also */
897 rfMode = AR_PHY_MODE_AR5112;
898 if (IS_CHAN_HALF_RATE(chan))
899 rfMode |= AR_PHY_MODE_HALF;
900 else if (IS_CHAN_QUARTER_RATE(chan))
901 rfMode |= AR_PHY_MODE_QUARTER;
902
903 if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))
904 phyPLL = AR_PHY_PLL_CTL_44_5112;
905 else
906 phyPLL = AR_PHY_PLL_CTL_40_5413;
907 } else if (IS_RAD5111(ah)) {
908 rfMode = AR_PHY_MODE_AR5111;
909 if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))
910 phyPLL = AR_PHY_PLL_CTL_44;
911 else
912 phyPLL = AR_PHY_PLL_CTL_40;
913 if (IS_CHAN_HALF_RATE(chan))
914 phyPLL = AR_PHY_PLL_CTL_HALF;
915 else if (IS_CHAN_QUARTER_RATE(chan))
916 phyPLL = AR_PHY_PLL_CTL_QUARTER;
917 } else { /* 5112, 2413, 2316, 2317 */
918 rfMode = AR_PHY_MODE_AR5112;
919 if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan))
920 phyPLL = AR_PHY_PLL_CTL_44_5112;
921 else
922 phyPLL = AR_PHY_PLL_CTL_40_5112;
923 if (IS_CHAN_HALF_RATE(chan))
924 phyPLL |= AR_PHY_PLL_CTL_HALF;
925 else if (IS_CHAN_QUARTER_RATE(chan))
926 phyPLL |= AR_PHY_PLL_CTL_QUARTER;
927 }
928 if (IS_CHAN_OFDM(chan) && (IS_CHAN_CCK(chan) ||
929 IS_CHAN_G(chan)))
930 rfMode |= AR_PHY_MODE_DYNAMIC;
931 else if (IS_CHAN_OFDM(chan))
932 rfMode |= AR_PHY_MODE_OFDM;
933 else
934 rfMode |= AR_PHY_MODE_CCK;
935 if (IS_CHAN_5GHZ(chan))
936 rfMode |= AR_PHY_MODE_RF5GHZ;
937 else
938 rfMode |= AR_PHY_MODE_RF2GHZ;
939 turbo = IS_CHAN_TURBO(chan) ?
940 (AR_PHY_FC_TURBO_MODE | AR_PHY_FC_TURBO_SHORT) : 0;
941 curPhyPLL = OS_REG_READ(ah, AR_PHY_PLL_CTL);
942 /*
943 * PLL, Mode, and Turbo values must be written in the correct
944 * order to ensure:
945 * - The PLL cannot be set to 44 unless the CCK or DYNAMIC
946 * mode bit is set
947 * - Turbo cannot be set at the same time as CCK or DYNAMIC
948 */
949 if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) {
950 OS_REG_WRITE(ah, AR_PHY_TURBO, turbo);
951 OS_REG_WRITE(ah, AR_PHY_MODE, rfMode);
952 if (curPhyPLL != phyPLL) {
953 OS_REG_WRITE(ah, AR_PHY_PLL_CTL, phyPLL);
954 /* Wait for the PLL to settle */
955 OS_DELAY(PLL_SETTLE_DELAY);
956 }
957 } else {
958 if (curPhyPLL != phyPLL) {
959 OS_REG_WRITE(ah, AR_PHY_PLL_CTL, phyPLL);
960 /* Wait for the PLL to settle */
961 OS_DELAY(PLL_SETTLE_DELAY);
962 }
963 OS_REG_WRITE(ah, AR_PHY_TURBO, turbo);
964 OS_REG_WRITE(ah, AR_PHY_MODE, rfMode);
965 }
966 }
967 return AH_TRUE;
968}
969
970/*
971 * Recalibrate the lower PHY chips to account for temperature/environment
972 * changes.
973 */
974HAL_BOOL
975ar5212PerCalibrationN(struct ath_hal *ah, HAL_CHANNEL *chan, u_int chainMask,
976 HAL_BOOL longCal, HAL_BOOL *isCalDone)
977{
978#define IQ_CAL_TRIES 10
979 struct ath_hal_5212 *ahp = AH5212(ah);
980 HAL_CHANNEL_INTERNAL *ichan;
981 int32_t qCoff, qCoffDenom;
982 int32_t iqCorrMeas, iCoff, iCoffDenom;
983 uint32_t powerMeasQ, powerMeasI;
984 HAL_BOOL ichan_isBmode = AH_FALSE;
985 HAL_BOOL isBmode = AH_FALSE;
986
987 OS_MARK(ah, AH_MARK_PERCAL, chan->channel);
988 *isCalDone = AH_FALSE;
989 ichan = ath_hal_checkchannel(ah, chan);
990 if (ichan == AH_NULL) {
991 HALDEBUG(ah, HAL_DEBUG_ANY,
992 "%s: invalid channel %u/0x%x; no mapping\n",
993 __func__, chan->channel, chan->channelFlags);
994 return AH_FALSE;
995 }
996 SAVE_CCK(ah, ichan, ichan_isBmode);
997 SAVE_CCK(ah, chan, isBmode);
998
999 if (ahp->ah_bIQCalibration == IQ_CAL_DONE ||
1000 ahp->ah_bIQCalibration == IQ_CAL_INACTIVE)
1001 *isCalDone = AH_TRUE;
1002
1003 /* IQ calibration in progress. Check to see if it has finished. */
1004 if (ahp->ah_bIQCalibration == IQ_CAL_RUNNING &&
1005 !(OS_REG_READ(ah, AR_PHY_TIMING_CTRL4) & AR_PHY_TIMING_CTRL4_DO_IQCAL)) {
1006 int i;
1007
1008 /* IQ Calibration has finished. */
1009 ahp->ah_bIQCalibration = IQ_CAL_INACTIVE;
1010 *isCalDone = AH_TRUE;
1011
1012 /* workaround for misgated IQ Cal results */
1013 i = 0;
1014 do {
1015 /* Read calibration results. */
1016 powerMeasI = OS_REG_READ(ah, AR_PHY_IQCAL_RES_PWR_MEAS_I);
1017 powerMeasQ = OS_REG_READ(ah, AR_PHY_IQCAL_RES_PWR_MEAS_Q);
1018 iqCorrMeas = OS_REG_READ(ah, AR_PHY_IQCAL_RES_IQ_CORR_MEAS);
1019 if (powerMeasI && powerMeasQ)
1020 break;
1021 /* Do we really need this??? */
1022 OS_REG_WRITE (ah, AR_PHY_TIMING_CTRL4,
1023 OS_REG_READ(ah, AR_PHY_TIMING_CTRL4) |
1024 AR_PHY_TIMING_CTRL4_DO_IQCAL);
1025 } while (++i < IQ_CAL_TRIES);
1026
1027 /*
1028 * Prescale these values to remove 64-bit operation
1029 * requirement at the loss of a little precision.
1030 */
1031 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
1032 qCoffDenom = powerMeasQ / 128;
1033
1034 /* Protect against divide-by-0 and loss of sign bits. */
1035 if (iCoffDenom != 0 && qCoffDenom >= 2) {
1036 iCoff = (int8_t)(-iqCorrMeas) / iCoffDenom;
1037 /* IQCORR_Q_I_COFF is a signed 6 bit number */
1038 if (iCoff < -32) {
1039 iCoff = -32;
1040 } else if (iCoff > 31) {
1041 iCoff = 31;
1042 }
1043
1044 /* IQCORR_Q_Q_COFF is a signed 5 bit number */
1045 qCoff = (powerMeasI / qCoffDenom) - 128;
1046 if (qCoff < -16) {
1047 qCoff = -16;
1048 } else if (qCoff > 15) {
1049 qCoff = 15;
1050 }
1051
1052 HALDEBUG(ah, HAL_DEBUG_PERCAL,
1053 "****************** MISGATED IQ CAL! *******************\n");
1054 HALDEBUG(ah, HAL_DEBUG_PERCAL,
1055 "time = %d, i = %d, \n", OS_GETUPTIME(ah), i);
1056 HALDEBUG(ah, HAL_DEBUG_PERCAL,
1057 "powerMeasI = 0x%08x\n", powerMeasI);
1058 HALDEBUG(ah, HAL_DEBUG_PERCAL,
1059 "powerMeasQ = 0x%08x\n", powerMeasQ);
1060 HALDEBUG(ah, HAL_DEBUG_PERCAL,
1061 "iqCorrMeas = 0x%08x\n", iqCorrMeas);
1062 HALDEBUG(ah, HAL_DEBUG_PERCAL,
1063 "iCoff = %d\n", iCoff);
1064 HALDEBUG(ah, HAL_DEBUG_PERCAL,
1065 "qCoff = %d\n", qCoff);
1066
1067 /* Write values and enable correction */
1068 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
1069 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, iCoff);
1070 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
1071 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, qCoff);
1072 OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4,
1073 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
1074
1075 ahp->ah_bIQCalibration = IQ_CAL_DONE;
1076 ichan->iqCalValid = AH_TRUE;
1077 ichan->iCoff = iCoff;
1078 ichan->qCoff = qCoff;
1079 }
1080 } else if (!IS_CHAN_B(chan) && ahp->ah_bIQCalibration == IQ_CAL_DONE &&
1081 !ichan->iqCalValid) {
1082 /*
1083 * Start IQ calibration if configured channel has changed.
1084 * Use a magic number of 15 based on default value.
1085 */
1086 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
1087 AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
1088 INIT_IQCAL_LOG_COUNT_MAX);
1089 OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4,
1090 AR_PHY_TIMING_CTRL4_DO_IQCAL);
1091 ahp->ah_bIQCalibration = IQ_CAL_RUNNING;
1092 }
1093 /* XXX EAR */
1094
1095 if (longCal) {
1096 /* Check noise floor results */
1097 ar5212GetNf(ah, ichan);
1098
1099 if ((ichan->channelFlags & CHANNEL_CW_INT) == 0) {
1100 /* Perform cal for 5Ghz channels and any OFDM on 5112 */
1101 if (IS_CHAN_5GHZ(chan) ||
1102 (IS_RAD5112(ah) && IS_CHAN_OFDM(chan)))
1103 ar5212RequestRfgain(ah);
1104 } else {
1105 /* report up and clear internal state */
1106 chan->channelFlags |= CHANNEL_CW_INT;
1107 ichan->channelFlags &= ~CHANNEL_CW_INT;
1108 }
1109 }
1110 RESTORE_CCK(ah, ichan, ichan_isBmode);
1111 RESTORE_CCK(ah, chan, isBmode);
1112
1113 return AH_TRUE;
1114#undef IQ_CAL_TRIES
1115}
1116
1117HAL_BOOL
1118ar5212PerCalibration(struct ath_hal *ah, HAL_CHANNEL *chan, HAL_BOOL *isIQdone)
1119{
1120 return ar5212PerCalibrationN(ah, chan, 0x1, AH_TRUE, isIQdone);
1121}
1122
1123HAL_BOOL
1124ar5212ResetCalValid(struct ath_hal *ah, HAL_CHANNEL *chan)
1125{
1126 /* XXX */
1127 return AH_TRUE;
1128}
1129
1130/*
1131 * Write the given reset bit mask into the reset register
1132 */
1133static HAL_BOOL
1134ar5212SetResetReg(struct ath_hal *ah, uint32_t resetMask)
1135{
1136 uint32_t mask = resetMask ? resetMask : ~0;
1137 HAL_BOOL rt;
1138
1139 /* XXX ar5212MacStop & co. */
1140
1141 if (IS_PCIE(ah)) {
1142 resetMask &= ~AR_RC_PCI;
1143 }
1144
1145 (void) OS_REG_READ(ah, AR_RXDP);/* flush any pending MMR writes */
1146 OS_REG_WRITE(ah, AR_RC, resetMask);
1147 OS_DELAY(15); /* need to wait at least 128 clocks
1148 when reseting PCI before read */
1149 mask &= (AR_RC_MAC | AR_RC_BB);
1150 resetMask &= (AR_RC_MAC | AR_RC_BB);
1151 rt = ath_hal_wait(ah, AR_RC, mask, resetMask);
1152 if ((resetMask & AR_RC_MAC) == 0) {
1153 if (isBigEndian()) {
1154 /*
1155 * Set CFG, little-endian for register
1156 * and descriptor accesses.
1157 */
1158 mask = INIT_CONFIG_STATUS | AR_CFG_SWRD | AR_CFG_SWRG;
1159#ifndef AH_NEED_DESC_SWAP
1160 mask |= AR_CFG_SWTD;
1161#endif
1162 OS_REG_WRITE(ah, AR_CFG, LE_READ_4(&mask));
1163 } else
1164 OS_REG_WRITE(ah, AR_CFG, INIT_CONFIG_STATUS);
1165 if (ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE))
1166 (void) OS_REG_READ(ah, AR_ISR_RAC);
1167 }
1168
1169 /* track PHY power state so we don't try to r/w BB registers */
1170 AH5212(ah)->ah_phyPowerOn = ((resetMask & AR_RC_BB) == 0);
1171 return rt;
1172}
1173
1174int16_t
1175ar5212GetNoiseFloor(struct ath_hal *ah)
1176{
1177 int16_t nf = (OS_REG_READ(ah, AR_PHY(25)) >> 19) & 0x1ff;
1178 if (nf & 0x100)
1179 nf = 0 - ((nf ^ 0x1ff) + 1);
1180 return nf;
1181}
1182
1183static HAL_BOOL
1184getNoiseFloorThresh(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *chan,
1185 int16_t *nft)
1186{
1187 const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1188
1189 HALASSERT(ah->ah_magic == AR5212_MAGIC);
1190
1191 switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) {
1192 case CHANNEL_A:
1193 *nft = ee->ee_noiseFloorThresh[headerInfo11A];
1194 break;
1195 case CHANNEL_B:
1196 *nft = ee->ee_noiseFloorThresh[headerInfo11B];
1197 break;
1198 case CHANNEL_PUREG:
1199 *nft = ee->ee_noiseFloorThresh[headerInfo11G];
1200 break;
1201 default:
1202 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
1203 __func__, chan->channelFlags);
1204 return AH_FALSE;
1205 }
1206 return AH_TRUE;
1207}
1208
1209/*
1210 * Setup the noise floor cal history buffer.
1211 */
1212void
1213ar5212InitNfCalHistBuffer(struct ath_hal *ah)
1214{
1215 struct ath_hal_5212 *ahp = AH5212(ah);
1216 int i;
1217
1218 ahp->ah_nfCalHist.first_run = 1;
1219 ahp->ah_nfCalHist.currIndex = 0;
1220 ahp->ah_nfCalHist.privNF = AR5212_CCA_MAX_GOOD_VALUE;
1221 ahp->ah_nfCalHist.invalidNFcount = AR512_NF_CAL_HIST_MAX;
1222 for (i = 0; i < AR512_NF_CAL_HIST_MAX; i ++)
1223 ahp->ah_nfCalHist.nfCalBuffer[i] = AR5212_CCA_MAX_GOOD_VALUE;
1224}
1225
1226/*
1227 * Add a noise floor value to the ring buffer.
1228 */
1229static __inline void
1230updateNFHistBuff(struct ar5212NfCalHist *h, int16_t nf)
1231{
1232 h->nfCalBuffer[h->currIndex] = nf;
1233 if (++h->currIndex >= AR512_NF_CAL_HIST_MAX)
1234 h->currIndex = 0;
1235}
1236
1237/*
1238 * Return the median noise floor value in the ring buffer.
1239 */
1240int16_t
1241ar5212GetNfHistMid(const int16_t calData[AR512_NF_CAL_HIST_MAX])
1242{
1243 int16_t sort[AR512_NF_CAL_HIST_MAX];
1244 int i, j;
1245
1246 OS_MEMCPY(sort, calData, AR512_NF_CAL_HIST_MAX*sizeof(int16_t));
1247 for (i = 0; i < AR512_NF_CAL_HIST_MAX-1; i ++) {
1248 for (j = 1; j < AR512_NF_CAL_HIST_MAX-i; j ++) {
1249 if (sort[j] > sort[j-1]) {
1250 int16_t nf = sort[j];
1251 sort[j] = sort[j-1];
1252 sort[j-1] = nf;
1253 }
1254 }
1255 }
1256 return sort[(AR512_NF_CAL_HIST_MAX-1)>>1];
1257}
1258
1259/*
1260 * Read the NF and check it against the noise floor threshhold
1261 */
1262int16_t
1263ar5212GetNf(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
1264{
1265 struct ath_hal_5212 *ahp = AH5212(ah);
1266 struct ar5212NfCalHist *h = &ahp->ah_nfCalHist;
1267 int16_t nf, nfThresh;
1268 int32_t val;
1269
1270 if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
1271 HALDEBUG(ah, HAL_DEBUG_ANY,
1272 "%s: NF did not complete in calibration window\n", __func__);
1273 chan->rawNoiseFloor = h->privNF; /* most recent value */
1274 return chan->rawNoiseFloor;
1275 }
1276
1277 /*
1278 * Finished NF cal, check against threshold.
1279 */
1280 nf = ar5212GetNoiseFloor(ah);
1281 if (getNoiseFloorThresh(ah, chan, &nfThresh)) {
1282 if (nf > nfThresh) {
1283 HALDEBUG(ah, HAL_DEBUG_ANY,
1284 "%s: noise floor failed detected; detected %u, "
1285 "threshold %u\n", __func__, nf, nfThresh);
1286 /*
1287 * NB: Don't discriminate 2.4 vs 5Ghz, if this
1288 * happens it indicates a problem regardless
1289 * of the band.
1290 */
1291 chan->channelFlags |= CHANNEL_CW_INT;
1292 nf = 0;
1293 }
1294 } else
1295 nf = 0;
1296
1297 /*
1298 * Pass through histogram and write median value as
1299 * calculated from the accrued window. We require a
1300 * full window of in-range values to be seen before we
1301 * start using the history.
1302 */
1303 updateNFHistBuff(h, nf);
1304 if (h->first_run) {
1305 if (nf < AR5212_CCA_MIN_BAD_VALUE ||
1306 nf > AR5212_CCA_MAX_HIGH_VALUE) {
1307 nf = AR5212_CCA_MAX_GOOD_VALUE;
1308 h->invalidNFcount = AR512_NF_CAL_HIST_MAX;
1309 } else if (--(h->invalidNFcount) == 0) {
1310 h->first_run = 0;
1311 h->privNF = nf = ar5212GetNfHistMid(h->nfCalBuffer);
1312 } else {
1313 nf = AR5212_CCA_MAX_GOOD_VALUE;
1314 }
1315 } else {
1316 h->privNF = nf = ar5212GetNfHistMid(h->nfCalBuffer);
1317 }
1318
1319 val = OS_REG_READ(ah, AR_PHY(25));
1320 val &= 0xFFFFFE00;
1321 val |= (((uint32_t)nf << 1) & 0x1FF);
1322 OS_REG_WRITE(ah, AR_PHY(25), val);
1323 OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
1324 OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1325 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1326
1327 if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF, 0)) {
1328#ifdef AH_DEBUG
1329 ath_hal_printf(ah, "%s: AGC not ready AGC_CONTROL 0x%x\n",
1330 __func__, OS_REG_READ(ah, AR_PHY_AGC_CONTROL));
1331#endif
1332 }
1333
1334 /*
1335 * Now load a high maxCCAPower value again so that we're
1336 * not capped by the median we just loaded
1337 */
1338 val &= 0xFFFFFE00;
1339 val |= (((uint32_t)(-50) << 1) & 0x1FF);
1340 OS_REG_WRITE(ah, AR_PHY(25), val);
1341 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF);
1342 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1343 OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1344
1345 return (chan->rawNoiseFloor = nf);
1346}
1347
1348/*
1349 * Set up compression configuration registers
1350 */
1351void
1352ar5212SetCompRegs(struct ath_hal *ah)
1353{
1354 struct ath_hal_5212 *ahp = AH5212(ah);
1355 int i;
1356
1357 /* Check if h/w supports compression */
1358 if (!AH_PRIVATE(ah)->ah_caps.halCompressSupport)
1359 return;
1360
1361 OS_REG_WRITE(ah, AR_DCCFG, 1);
1362
1363 OS_REG_WRITE(ah, AR_CCFG,
1364 (AR_COMPRESSION_WINDOW_SIZE >> 8) & AR_CCFG_WIN_M);
1365
1366 OS_REG_WRITE(ah, AR_CCFG,
1367 OS_REG_READ(ah, AR_CCFG) | AR_CCFG_MIB_INT_EN);
1368 OS_REG_WRITE(ah, AR_CCUCFG,
1369 AR_CCUCFG_RESET_VAL | AR_CCUCFG_CATCHUP_EN);
1370
1371 OS_REG_WRITE(ah, AR_CPCOVF, 0);
1372
1373 /* reset decompression mask */
1374 for (i = 0; i < HAL_DECOMP_MASK_SIZE; i++) {
1375 OS_REG_WRITE(ah, AR_DCM_A, i);
1376 OS_REG_WRITE(ah, AR_DCM_D, ahp->ah_decompMask[i]);
1377 }
1378}
1379
1380HAL_BOOL
1381ar5212SetAntennaSwitchInternal(struct ath_hal *ah, HAL_ANT_SETTING settings,
1382 const HAL_CHANNEL_INTERNAL *chan)
1383{
1384#define ANT_SWITCH_TABLE1 AR_PHY(88)
1385#define ANT_SWITCH_TABLE2 AR_PHY(89)
1386 struct ath_hal_5212 *ahp = AH5212(ah);
1387 const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1388 uint32_t antSwitchA, antSwitchB;
1389 int ix;
1390 HAL_BOOL isBmode = AH_FALSE;
1391 /* NB: need local copy for SAVE/RESTORE 'cuz chan is const */
1392 HAL_CHANNEL_INTERNAL ichan = *chan;
1393
1394 HALASSERT(ah->ah_magic == AR5212_MAGIC);
1395 HALASSERT(ahp->ah_phyPowerOn);
1396
1397 SAVE_CCK(ah, &ichan, isBmode);
1398 switch (ichan.channelFlags & CHANNEL_ALL_NOTURBO) {
1399 case CHANNEL_A: ix = 0; break;
1400 case CHANNEL_B: ix = 1; break;
1401 case CHANNEL_PUREG: ix = 2; break;
1402 default:
1403 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
1404 __func__, ichan.channelFlags);
1405 RESTORE_CCK(ah, &ichan, isBmode);
1406 return AH_FALSE;
1407 }
1408 RESTORE_CCK(ah, &ichan, isBmode);
1409
1410 antSwitchA = ee->ee_antennaControl[1][ix]
1411 | (ee->ee_antennaControl[2][ix] << 6)
1412 | (ee->ee_antennaControl[3][ix] << 12)
1413 | (ee->ee_antennaControl[4][ix] << 18)
1414 | (ee->ee_antennaControl[5][ix] << 24)
1415 ;
1416 antSwitchB = ee->ee_antennaControl[6][ix]
1417 | (ee->ee_antennaControl[7][ix] << 6)
1418 | (ee->ee_antennaControl[8][ix] << 12)
1419 | (ee->ee_antennaControl[9][ix] << 18)
1420 | (ee->ee_antennaControl[10][ix] << 24)
1421 ;
1422 /*
1423 * For fixed antenna, give the same setting for both switch banks
1424 */
1425 switch (settings) {
1426 case HAL_ANT_FIXED_A:
1427 antSwitchB = antSwitchA;
1428 break;
1429 case HAL_ANT_FIXED_B:
1430 antSwitchA = antSwitchB;
1431 break;
1432 case HAL_ANT_VARIABLE:
1433 break;
1434 default:
1435 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad antenna setting %u\n",
1436 __func__, settings);
1437 return AH_FALSE;
1438 }
1439 if (antSwitchB == antSwitchA) {
1440 HALDEBUG(ah, HAL_DEBUG_RFPARAM,
1441 "%s: Setting fast diversity off.\n", __func__);
1442 OS_REG_CLR_BIT(ah,AR_PHY_CCK_DETECT,
1443 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
1444 ahp->ah_diversity = AH_FALSE;
1445 } else {
1446 HALDEBUG(ah, HAL_DEBUG_RFPARAM,
1447 "%s: Setting fast diversity on.\n", __func__);
1448 OS_REG_SET_BIT(ah,AR_PHY_CCK_DETECT,
1449 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
1450 ahp->ah_diversity = AH_TRUE;
1451 }
1452 ahp->ah_antControl = settings;
1453
1454 OS_REG_WRITE(ah, ANT_SWITCH_TABLE1, antSwitchA);
1455 OS_REG_WRITE(ah, ANT_SWITCH_TABLE2, antSwitchB);
1456
1457 return AH_TRUE;
1458#undef ANT_SWITCH_TABLE2
1459#undef ANT_SWITCH_TABLE1
1460}
1461
1462HAL_BOOL
1463ar5212IsSpurChannel(struct ath_hal *ah, HAL_CHANNEL *chan)
1464{
1465 uint32_t clockFreq =
1466 ((IS_5413(ah) || IS_RAD5112_ANY(ah) || IS_2417(ah)) ? 40 : 32);
1467 return ( ((chan->channel % clockFreq) != 0)
1468 && (((chan->channel % clockFreq) < 10)
1469 || (((chan->channel) % clockFreq) > 22)) );
1470}
1471
1472/*
1473 * Read EEPROM header info and program the device for correct operation
1474 * given the channel value.
1475 */
1476HAL_BOOL
1477ar5212SetBoardValues(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan)
1478{
1479#define NO_FALSE_DETECT_BACKOFF 2
1480#define CB22_FALSE_DETECT_BACKOFF 6
1481#define AR_PHY_BIS(_ah, _reg, _mask, _val) \
1482 OS_REG_WRITE(_ah, AR_PHY(_reg), \
1483 (OS_REG_READ(_ah, AR_PHY(_reg)) & _mask) | (_val));
1484 struct ath_hal_5212 *ahp = AH5212(ah);
1485 const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1486 int arrayMode, falseDectectBackoff;
1487 int is2GHz = IS_CHAN_2GHZ(chan);
1488 int8_t adcDesiredSize, pgaDesiredSize;
1489 uint16_t switchSettling, txrxAtten, rxtxMargin;
1490 int iCoff, qCoff;
1491
1492 HALASSERT(ah->ah_magic == AR5212_MAGIC);
1493
1494 switch (chan->channelFlags & CHANNEL_ALL) {
1495 case CHANNEL_A:
1496 case CHANNEL_T:
1497 arrayMode = headerInfo11A;
1498 if (!IS_RAD5112_ANY(ah) && !IS_2413(ah) && !IS_5413(ah))
1499 OS_REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL,
1500 AR_PHY_FRAME_CTL_TX_CLIP,
1501 ahp->ah_gainValues.currStep->paramVal[GP_TXCLIP]);
1502 break;
1503 case CHANNEL_B:
1504 arrayMode = headerInfo11B;
1505 break;
1506 case CHANNEL_G:
1507 case CHANNEL_108G:
1508 arrayMode = headerInfo11G;
1509 break;
1510 default:
1511 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel flags 0x%x\n",
1512 __func__, chan->channelFlags);
1513 return AH_FALSE;
1514 }
1515
1516 /* Set the antenna register(s) correctly for the chip revision */
1517 AR_PHY_BIS(ah, 68, 0xFFFFFC06,
1518 (ee->ee_antennaControl[0][arrayMode] << 4) | 0x1);
1519
1520 ar5212SetAntennaSwitchInternal(ah, ahp->ah_antControl, chan);
1521
1522 /* Set the Noise Floor Thresh on ar5211 devices */
1523 OS_REG_WRITE(ah, AR_PHY(90),
1524 (ee->ee_noiseFloorThresh[arrayMode] & 0x1FF)
1525 | (1 << 9));
1526
1527 if (ee->ee_version >= AR_EEPROM_VER5_0 && IS_CHAN_TURBO(chan)) {
1528 switchSettling = ee->ee_switchSettlingTurbo[is2GHz];
1529 adcDesiredSize = ee->ee_adcDesiredSizeTurbo[is2GHz];
1530 pgaDesiredSize = ee->ee_pgaDesiredSizeTurbo[is2GHz];
1531 txrxAtten = ee->ee_txrxAttenTurbo[is2GHz];
1532 rxtxMargin = ee->ee_rxtxMarginTurbo[is2GHz];
1533 } else {
1534 switchSettling = ee->ee_switchSettling[arrayMode];
1535 adcDesiredSize = ee->ee_adcDesiredSize[arrayMode];
1536 pgaDesiredSize = ee->ee_pgaDesiredSize[is2GHz];
1537 txrxAtten = ee->ee_txrxAtten[is2GHz];
1538 rxtxMargin = ee->ee_rxtxMargin[is2GHz];
1539 }
1540
1541 OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING,
1542 AR_PHY_SETTLING_SWITCH, switchSettling);
1543 OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
1544 AR_PHY_DESIRED_SZ_ADC, adcDesiredSize);
1545 OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
1546 AR_PHY_DESIRED_SZ_PGA, pgaDesiredSize);
1547 OS_REG_RMW_FIELD(ah, AR_PHY_RXGAIN,
1548 AR_PHY_RXGAIN_TXRX_ATTEN, txrxAtten);
1549 OS_REG_WRITE(ah, AR_PHY(13),
1550 (ee->ee_txEndToXPAOff[arrayMode] << 24)
1551 | (ee->ee_txEndToXPAOff[arrayMode] << 16)
1552 | (ee->ee_txFrameToXPAOn[arrayMode] << 8)
1553 | ee->ee_txFrameToXPAOn[arrayMode]);
1554 AR_PHY_BIS(ah, 10, 0xFFFF00FF,
1555 ee->ee_txEndToXLNAOn[arrayMode] << 8);
1556 AR_PHY_BIS(ah, 25, 0xFFF80FFF,
1557 (ee->ee_thresh62[arrayMode] << 12) & 0x7F000);
1558
1559 /*
1560 * False detect backoff - suspected 32 MHz spur causes false
1561 * detects in OFDM, causing Tx Hangs. Decrease weak signal
1562 * sensitivity for this card.
1563 */
1564 falseDectectBackoff = NO_FALSE_DETECT_BACKOFF;
1565 if (ee->ee_version < AR_EEPROM_VER3_3) {
1566 /* XXX magic number */
1567 if (AH_PRIVATE(ah)->ah_subvendorid == 0x1022 &&
1568 IS_CHAN_OFDM(chan))
1569 falseDectectBackoff += CB22_FALSE_DETECT_BACKOFF;
1570 } else {
1571 if (ar5212IsSpurChannel(ah, (HAL_CHANNEL *)chan)) {
1572 falseDectectBackoff += ee->ee_falseDetectBackoff[arrayMode];
1573 }
1574 }
1575 AR_PHY_BIS(ah, 73, 0xFFFFFF01, (falseDectectBackoff << 1) & 0xFE);
1576
1577 if (chan->iqCalValid) {
1578 iCoff = chan->iCoff;
1579 qCoff = chan->qCoff;
1580 } else {
1581 iCoff = ee->ee_iqCalI[is2GHz];
1582 qCoff = ee->ee_iqCalQ[is2GHz];
1583 }
1584
1585 /* write previous IQ results */
1586 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
1587 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, iCoff);
1588 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4,
1589 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, qCoff);
1590 OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4,
1591 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
1592
1593 if (ee->ee_version >= AR_EEPROM_VER4_1) {
1594 if (!IS_CHAN_108G(chan) || ee->ee_version >= AR_EEPROM_VER5_0)
1595 OS_REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
1596 AR_PHY_GAIN_2GHZ_RXTX_MARGIN, rxtxMargin);
1597 }
1598 if (ee->ee_version >= AR_EEPROM_VER5_1) {
1599 /* for now always disabled */
1600 OS_REG_WRITE(ah, AR_PHY_HEAVY_CLIP_ENABLE, 0);
1601 }
1602
1603 return AH_TRUE;
1604#undef AR_PHY_BIS
1605#undef NO_FALSE_DETECT_BACKOFF
1606#undef CB22_FALSE_DETECT_BACKOFF
1607}
1608
1609/*
1610 * Apply Spur Immunity to Boards that require it.
1611 * Applies only to OFDM RX operation.
1612 */
1613
1614void
1615ar5212SetSpurMitigation(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan)
1616{
1617 uint32_t pilotMask[2] = {0, 0}, binMagMask[4] = {0, 0, 0 , 0};
1618 uint16_t i, finalSpur, curChanAsSpur, binWidth = 0, spurDetectWidth, spurChan;
1619 int32_t spurDeltaPhase = 0, spurFreqSd = 0, spurOffset, binOffsetNumT16, curBinOffset;
1620 int16_t numBinOffsets;
1621 static const uint16_t magMapFor4[4] = {1, 2, 2, 1};
1622 static const uint16_t magMapFor3[3] = {1, 2, 1};
1623 const uint16_t *pMagMap;
1624 HAL_BOOL is2GHz = IS_CHAN_2GHZ(ichan);
1625 uint32_t val;
1626
1627#define CHAN_TO_SPUR(_f, _freq) ( ((_freq) - ((_f) ? 2300 : 4900)) * 10 )
1628 if (IS_2417(ah)) {
1629 HALDEBUG(ah, HAL_DEBUG_RFPARAM, "%s: no spur mitigation\n",
1630 __func__);
1631 return;
1632 }
1633
1634 curChanAsSpur = CHAN_TO_SPUR(is2GHz, ichan->channel);
1635
1636 if (ichan->mainSpur) {
1637 /* Pull out the saved spur value */
1638 finalSpur = ichan->mainSpur;
1639 } else {
1640 /*
1641 * Check if spur immunity should be performed for this channel
1642 * Should only be performed once per channel and then saved
1643 */
1644 finalSpur = AR_NO_SPUR;
1645 spurDetectWidth = HAL_SPUR_CHAN_WIDTH;
1646 if (IS_CHAN_TURBO(ichan))
1647 spurDetectWidth *= 2;
1648
1649 /* Decide if any spur affects the current channel */
1650 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
1651 spurChan = ath_hal_getSpurChan(ah, i, is2GHz);
1652 if (spurChan == AR_NO_SPUR) {
1653 break;
1654 }
1655 if ((curChanAsSpur - spurDetectWidth <= (spurChan & HAL_SPUR_VAL_MASK)) &&
1656 (curChanAsSpur + spurDetectWidth >= (spurChan & HAL_SPUR_VAL_MASK))) {
1657 finalSpur = spurChan & HAL_SPUR_VAL_MASK;
1658 break;
1659 }
1660 }
1661 /* Save detected spur (or no spur) for this channel */
1662 ichan->mainSpur = finalSpur;
1663 }
1664
1665 /* Write spur immunity data */
1666 if (finalSpur == AR_NO_SPUR) {
1667 /* Disable Spur Immunity Regs if they appear set */
1668 if (OS_REG_READ(ah, AR_PHY_TIMING_CTRL4) & AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER) {
1669 /* Clear Spur Delta Phase, Spur Freq, and enable bits */
1670 OS_REG_RMW_FIELD(ah, AR_PHY_MASK_CTL, AR_PHY_MASK_CTL_RATE, 0);
1671 val = OS_REG_READ(ah, AR_PHY_TIMING_CTRL4);
1672 val &= ~(AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
1673 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
1674 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
1675 OS_REG_WRITE(ah, AR_PHY_MASK_CTL, val);
1676 OS_REG_WRITE(ah, AR_PHY_TIMING11, 0);
1677
1678 /* Clear pilot masks */
1679 OS_REG_WRITE(ah, AR_PHY_TIMING7, 0);
1680 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING8, AR_PHY_TIMING8_PILOT_MASK_2, 0);
1681 OS_REG_WRITE(ah, AR_PHY_TIMING9, 0);
1682 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING10, AR_PHY_TIMING10_PILOT_MASK_2, 0);
1683
1684 /* Clear magnitude masks */
1685 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_1, 0);
1686 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_2, 0);
1687 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_3, 0);
1688 OS_REG_RMW_FIELD(ah, AR_PHY_MASK_CTL, AR_PHY_MASK_CTL_MASK_4, 0);
1689 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_1, 0);
1690 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_2, 0);
1691 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_3, 0);
1692 OS_REG_RMW_FIELD(ah, AR_PHY_BIN_MASK2_4, AR_PHY_BIN_MASK2_4_MASK_4, 0);
1693 }
1694 } else {
1695 spurOffset = finalSpur - curChanAsSpur;
1696 /*
1697 * Spur calculations:
1698 * spurDeltaPhase is (spurOffsetIn100KHz / chipFrequencyIn100KHz) << 21
1699 * spurFreqSd is (spurOffsetIn100KHz / sampleFrequencyIn100KHz) << 11
1700 */
1701 switch (ichan->channelFlags & CHANNEL_ALL) {
1702 case CHANNEL_A: /* Chip Frequency & sampleFrequency are 40 MHz */
1703 spurDeltaPhase = (spurOffset << 17) / 25;
1704 spurFreqSd = spurDeltaPhase >> 10;
1705 binWidth = HAL_BIN_WIDTH_BASE_100HZ;
1706 break;
1707 case CHANNEL_G: /* Chip Frequency is 44MHz, sampleFrequency is 40 MHz */
1708 spurFreqSd = (spurOffset << 8) / 55;
1709 spurDeltaPhase = (spurOffset << 17) / 25;
1710 binWidth = HAL_BIN_WIDTH_BASE_100HZ;
1711 break;
1712 case CHANNEL_T: /* Chip Frequency & sampleFrequency are 80 MHz */
1713 case CHANNEL_108G:
1714 spurDeltaPhase = (spurOffset << 16) / 25;
1715 spurFreqSd = spurDeltaPhase >> 10;
1716 binWidth = HAL_BIN_WIDTH_TURBO_100HZ;
1717 break;
1718 }
1719
1720 /* Compute Pilot Mask */
1721 binOffsetNumT16 = ((spurOffset * 1000) << 4) / binWidth;
1722 /* The spur is on a bin if it's remainder at times 16 is 0 */
1723 if (binOffsetNumT16 & 0xF) {
1724 numBinOffsets = 4;
1725 pMagMap = magMapFor4;
1726 } else {
1727 numBinOffsets = 3;
1728 pMagMap = magMapFor3;
1729 }
1730 for (i = 0; i < numBinOffsets; i++) {
1731 if ((binOffsetNumT16 >> 4) > HAL_MAX_BINS_ALLOWED) {
1732 HALDEBUG(ah, HAL_DEBUG_ANY,
1733 "Too man bins in spur mitigation\n");
1734 return;
1735 }
1736
1737 /* Get Pilot Mask values */
1738 curBinOffset = (binOffsetNumT16 >> 4) + i + 25;
1739 if ((curBinOffset >= 0) && (curBinOffset <= 32)) {
1740 if (curBinOffset <= 25)
1741 pilotMask[0] |= 1 << curBinOffset;
1742 else if (curBinOffset >= 27)
1743 pilotMask[0] |= 1 << (curBinOffset - 1);
1744 } else if ((curBinOffset >= 33) && (curBinOffset <= 52))
1745 pilotMask[1] |= 1 << (curBinOffset - 33);
1746
1747 /* Get viterbi values */
1748 if ((curBinOffset >= -1) && (curBinOffset <= 14))
1749 binMagMask[0] |= pMagMap[i] << (curBinOffset + 1) * 2;
1750 else if ((curBinOffset >= 15) && (curBinOffset <= 30))
1751 binMagMask[1] |= pMagMap[i] << (curBinOffset - 15) * 2;
1752 else if ((curBinOffset >= 31) && (curBinOffset <= 46))
1753 binMagMask[2] |= pMagMap[i] << (curBinOffset -31) * 2;
1754 else if((curBinOffset >= 47) && (curBinOffset <= 53))
1755 binMagMask[3] |= pMagMap[i] << (curBinOffset -47) * 2;
1756 }
1757
1758 /* Write Spur Delta Phase, Spur Freq, and enable bits */
1759 OS_REG_RMW_FIELD(ah, AR_PHY_MASK_CTL, AR_PHY_MASK_CTL_RATE, 0xFF);
1760 val = OS_REG_READ(ah, AR_PHY_TIMING_CTRL4);
1761 val |= (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
1762 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
1763 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
1764 OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4, val);
1765 OS_REG_WRITE(ah, AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_IN_AGC |
1766 SM(spurFreqSd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
1767 SM(spurDeltaPhase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
1768
1769 /* Write pilot masks */
1770 OS_REG_WRITE(ah, AR_PHY_TIMING7, pilotMask[0]);
1771 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING8, AR_PHY_TIMING8_PILOT_MASK_2, pilotMask[1]);
1772 OS_REG_WRITE(ah, AR_PHY_TIMING9, pilotMask[0]);
1773 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING10, AR_PHY_TIMING10_PILOT_MASK_2, pilotMask[1]);
1774
1775 /* Write magnitude masks */
1776 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_1, binMagMask[0]);
1777 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_2, binMagMask[1]);
1778 OS_REG_WRITE(ah, AR_PHY_BIN_MASK_3, binMagMask[2]);
1779 OS_REG_RMW_FIELD(ah, AR_PHY_MASK_CTL, AR_PHY_MASK_CTL_MASK_4, binMagMask[3]);
1780 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_1, binMagMask[0]);
1781 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_2, binMagMask[1]);
1782 OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_3, binMagMask[2]);
1783 OS_REG_RMW_FIELD(ah, AR_PHY_BIN_MASK2_4, AR_PHY_BIN_MASK2_4_MASK_4, binMagMask[3]);
1784 }
1785#undef CHAN_TO_SPUR
1786}
1787
1788
1789/*
1790 * Delta slope coefficient computation.
1791 * Required for OFDM operation.
1792 */
1793void
1794ar5212SetDeltaSlope(struct ath_hal *ah, HAL_CHANNEL *chan)
1795{
1796#define COEF_SCALE_S 24
1797#define INIT_CLOCKMHZSCALED 0x64000000
1798 unsigned long coef_scaled, coef_exp, coef_man, ds_coef_exp, ds_coef_man;
1799 unsigned long clockMhzScaled = INIT_CLOCKMHZSCALED;
1800
1801 if (IS_CHAN_TURBO(chan))
1802 clockMhzScaled *= 2;
1803 /* half and quarter rate can divide the scaled clock by 2 or 4 respectively */
1804 /* scale for selected channel bandwidth */
1805 if (IS_CHAN_HALF_RATE(chan)) {
1806 clockMhzScaled = clockMhzScaled >> 1;
1807 } else if (IS_CHAN_QUARTER_RATE(chan)) {
1808 clockMhzScaled = clockMhzScaled >> 2;
1809 }
1810
1811 /*
1812 * ALGO -> coef = 1e8/fcarrier*fclock/40;
1813 * scaled coef to provide precision for this floating calculation
1814 */
1815 coef_scaled = clockMhzScaled / chan->channel;
1816
1817 /*
1818 * ALGO -> coef_exp = 14-floor(log2(coef));
1819 * floor(log2(x)) is the highest set bit position
1820 */
1821 for (coef_exp = 31; coef_exp > 0; coef_exp--)
1822 if ((coef_scaled >> coef_exp) & 0x1)
1823 break;
1824 /* A coef_exp of 0 is a legal bit position but an unexpected coef_exp */
1825 HALASSERT(coef_exp);
1826 coef_exp = 14 - (coef_exp - COEF_SCALE_S);
1827
1828 /*
1829 * ALGO -> coef_man = floor(coef* 2^coef_exp+0.5);
1830 * The coefficient is already shifted up for scaling
1831 */
1832 coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
1833 ds_coef_man = coef_man >> (COEF_SCALE_S - coef_exp);
1834 ds_coef_exp = coef_exp - 16;
1835
1836 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3,
1837 AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
1838 OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3,
1839 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
1840#undef INIT_CLOCKMHZSCALED
1841#undef COEF_SCALE_S
1842}
1843
1844/*
1845 * Set a limit on the overall output power. Used for dynamic
1846 * transmit power control and the like.
1847 *
1848 * NB: limit is in units of 0.5 dbM.
1849 */
1850HAL_BOOL
1851ar5212SetTxPowerLimit(struct ath_hal *ah, uint32_t limit)
1852{
1853 uint16_t dummyXpdGains[2];
1854 HAL_BOOL ret, isBmode = AH_FALSE;
1855
1856 SAVE_CCK(ah, AH_PRIVATE(ah)->ah_curchan, isBmode);
1857 AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER);
1858 ret = ar5212SetTransmitPower(ah, AH_PRIVATE(ah)->ah_curchan,
1859 dummyXpdGains);
1860 RESTORE_CCK(ah, AH_PRIVATE(ah)->ah_curchan, isBmode);
1861 return ret;
1862}
1863
1864/*
1865 * Set the transmit power in the baseband for the given
1866 * operating channel and mode.
1867 */
1868HAL_BOOL
1869ar5212SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan,
1870 uint16_t *rfXpdGain)
1871{
1872#define POW_OFDM(_r, _s) (((0 & 1)<< ((_s)+6)) | (((_r) & 0x3f) << (_s)))
1873#define POW_CCK(_r, _s) (((_r) & 0x3f) << (_s))
1874#define N(a) (sizeof (a) / sizeof (a[0]))
1875 static const uint16_t tpcScaleReductionTable[5] =
1876 { 0, 3, 6, 9, MAX_RATE_POWER };
1877 struct ath_hal_5212 *ahp = AH5212(ah);
1878 const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
1879 int16_t minPower, maxPower, tpcInDb, powerLimit;
1880 int i;
1881
1882 HALASSERT(ah->ah_magic == AR5212_MAGIC);
1883
1884 OS_MEMZERO(ahp->ah_pcdacTable, ahp->ah_pcdacTableSize);
1885 OS_MEMZERO(ahp->ah_ratesArray, sizeof(ahp->ah_ratesArray));
1886
1887 powerLimit = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit);
1888 if (powerLimit >= MAX_RATE_POWER || powerLimit == 0)
1889 tpcInDb = tpcScaleReductionTable[AH_PRIVATE(ah)->ah_tpScale];
1890 else
1891 tpcInDb = 0;
1892 if (!ar5212SetRateTable(ah, (HAL_CHANNEL *) chan, tpcInDb, powerLimit,
1893 AH_TRUE, &minPower, &maxPower)) {
1894 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set rate table\n",
1895 __func__);
1896 return AH_FALSE;
1897 }
1898 if (!ahp->ah_rfHal->setPowerTable(ah,
1899 &minPower, &maxPower, chan, rfXpdGain)) {
1900 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set power table\n",
1901 __func__);
1902 return AH_FALSE;
1903 }
1904
1905 /*
1906 * Adjust XR power/rate up by 2 dB to account for greater peak
1907 * to avg ratio - except in newer avg power designs
1908 */
1909 if (!IS_2413(ah) && !IS_5413(ah))
1910 ahp->ah_ratesArray[15] += 4;
1911 /*
1912 * txPowerIndexOffset is set by the SetPowerTable() call -
1913 * adjust the rate table
1914 */
1915 for (i = 0; i < N(ahp->ah_ratesArray); i++) {
1916 ahp->ah_ratesArray[i] += ahp->ah_txPowerIndexOffset;
1917 if (ahp->ah_ratesArray[i] > 63)
1918 ahp->ah_ratesArray[i] = 63;
1919 }
1920
1921 if (ee->ee_eepMap < 2) {
1922 /*
1923 * Correct gain deltas for 5212 G operation -
1924 * Removed with revised chipset
1925 */
1926 if (AH_PRIVATE(ah)->ah_phyRev < AR_PHY_CHIP_ID_REV_2 &&
1927 IS_CHAN_G(chan)) {
1928 uint16_t cckOfdmPwrDelta;
1929
1930 if (chan->channel == 2484)
1931 cckOfdmPwrDelta = SCALE_OC_DELTA(
1932 ee->ee_cckOfdmPwrDelta -
1933 ee->ee_scaledCh14FilterCckDelta);
1934 else
1935 cckOfdmPwrDelta = SCALE_OC_DELTA(
1936 ee->ee_cckOfdmPwrDelta);
1937 ar5212CorrectGainDelta(ah, cckOfdmPwrDelta);
1938 }
1939 /*
1940 * Finally, write the power values into the
1941 * baseband power table
1942 */
1943 for (i = 0; i < (PWR_TABLE_SIZE/2); i++) {
1944 OS_REG_WRITE(ah, AR_PHY_PCDAC_TX_POWER(i),
1945 ((((ahp->ah_pcdacTable[2*i + 1] << 8) | 0xff) & 0xffff) << 16)
1946 | (((ahp->ah_pcdacTable[2*i] << 8) | 0xff) & 0xffff)
1947 );
1948 }
1949 }
1950
1951 /* Write the OFDM power per rate set */
1952 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
1953 POW_OFDM(ahp->ah_ratesArray[3], 24)
1954 | POW_OFDM(ahp->ah_ratesArray[2], 16)
1955 | POW_OFDM(ahp->ah_ratesArray[1], 8)
1956 | POW_OFDM(ahp->ah_ratesArray[0], 0)
1957 );
1958 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
1959 POW_OFDM(ahp->ah_ratesArray[7], 24)
1960 | POW_OFDM(ahp->ah_ratesArray[6], 16)
1961 | POW_OFDM(ahp->ah_ratesArray[5], 8)
1962 | POW_OFDM(ahp->ah_ratesArray[4], 0)
1963 );
1964
1965 /* Write the CCK power per rate set */
1966 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
1967 POW_CCK(ahp->ah_ratesArray[10], 24)
1968 | POW_CCK(ahp->ah_ratesArray[9], 16)
1969 | POW_CCK(ahp->ah_ratesArray[15], 8) /* XR target power */
1970 | POW_CCK(ahp->ah_ratesArray[8], 0)
1971 );
1972 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
1973 POW_CCK(ahp->ah_ratesArray[14], 24)
1974 | POW_CCK(ahp->ah_ratesArray[13], 16)
1975 | POW_CCK(ahp->ah_ratesArray[12], 8)
1976 | POW_CCK(ahp->ah_ratesArray[11], 0)
1977 );
1978
1979 /*
1980 * Set max power to 30 dBm and, optionally,
1981 * enable TPC in tx descriptors.
1982 */
1983 OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX, MAX_RATE_POWER |
1984 (ahp->ah_tpcEnabled ? AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE : 0));
1985
1986 return AH_TRUE;
1987#undef N
1988#undef POW_CCK
1989#undef POW_OFDM
1990}
1991
1992/*
1993 * Sets the transmit power in the baseband for the given
1994 * operating channel and mode.
1995 */
1996static HAL_BOOL
1997ar5212SetRateTable(struct ath_hal *ah, HAL_CHANNEL *chan,
1998 int16_t tpcScaleReduction, int16_t powerLimit, HAL_BOOL commit,
1999 int16_t *pMinPower, int16_t *pMaxPower)
2000{
2001 struct ath_hal_5212 *ahp = AH5212(ah);
2002 const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
2003 uint16_t *rpow = ahp->ah_ratesArray;
2004 uint16_t twiceMaxEdgePower = MAX_RATE_POWER;
2005 uint16_t twiceMaxEdgePowerCck = MAX_RATE_POWER;
2006 uint16_t twiceMaxRDPower = MAX_RATE_POWER;
2007 int i;
2008 uint8_t cfgCtl;
2009 int8_t twiceAntennaGain, twiceAntennaReduction;
2010 const RD_EDGES_POWER *rep;
2011 TRGT_POWER_INFO targetPowerOfdm, targetPowerCck;
2012 int16_t scaledPower, maxAvailPower = 0;
2013 int16_t r13, r9, r7, r0;
2014
2015 HALASSERT(ah->ah_magic == AR5212_MAGIC);
2016
2017 twiceMaxRDPower = chan->maxRegTxPower * 2;
2018 *pMaxPower = -MAX_RATE_POWER;
2019 *pMinPower = MAX_RATE_POWER;
2020
2021 /* Get conformance test limit maximum for this channel */
2022 cfgCtl = ath_hal_getctl(ah, chan);
2023 for (i = 0; i < ee->ee_numCtls; i++) {
2024 uint16_t twiceMinEdgePower;
2025
2026 if (ee->ee_ctl[i] == 0)
2027 continue;
2028 if (ee->ee_ctl[i] == cfgCtl ||
2029 cfgCtl == ((ee->ee_ctl[i] & CTL_MODE_M) | SD_NO_CTL)) {
2030 rep = &ee->ee_rdEdgesPower[i * NUM_EDGES];
2031 twiceMinEdgePower = ar5212GetMaxEdgePower(chan->channel, rep);
2032 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
2033 /* Find the minimum of all CTL edge powers that apply to this channel */
2034 twiceMaxEdgePower = AH_MIN(twiceMaxEdgePower, twiceMinEdgePower);
2035 } else {
2036 twiceMaxEdgePower = twiceMinEdgePower;
2037 break;
2038 }
2039 }
2040 }
2041
2042 if (IS_CHAN_G(chan)) {
2043 /* Check for a CCK CTL for 11G CCK powers */
2044 cfgCtl = (cfgCtl & ~CTL_MODE_M) | CTL_11B;
2045 for (i = 0; i < ee->ee_numCtls; i++) {
2046 uint16_t twiceMinEdgePowerCck;
2047
2048 if (ee->ee_ctl[i] == 0)
2049 continue;
2050 if (ee->ee_ctl[i] == cfgCtl ||
2051 cfgCtl == ((ee->ee_ctl[i] & CTL_MODE_M) | SD_NO_CTL)) {
2052 rep = &ee->ee_rdEdgesPower[i * NUM_EDGES];
2053 twiceMinEdgePowerCck = ar5212GetMaxEdgePower(chan->channel, rep);
2054 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
2055 /* Find the minimum of all CTL edge powers that apply to this channel */
2056 twiceMaxEdgePowerCck = AH_MIN(twiceMaxEdgePowerCck, twiceMinEdgePowerCck);
2057 } else {
2058 twiceMaxEdgePowerCck = twiceMinEdgePowerCck;
2059 break;
2060 }
2061 }
2062 }
2063 } else {
2064 /* Set the 11B cck edge power to the one found before */
2065 twiceMaxEdgePowerCck = twiceMaxEdgePower;
2066 }
2067
2068 /* Get Antenna Gain reduction */
2069 if (IS_CHAN_5GHZ(chan)) {
2070 ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_5, &twiceAntennaGain);
2071 } else {
2072 ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_2, &twiceAntennaGain);
2073 }
2074 twiceAntennaReduction =
2075 ath_hal_getantennareduction(ah, chan, twiceAntennaGain);
2076
2077 if (IS_CHAN_OFDM(chan)) {
2078 /* Get final OFDM target powers */
2079 if (IS_CHAN_2GHZ(chan)) {
2080 ar5212GetTargetPowers(ah, chan, ee->ee_trgtPwr_11g,
2081 ee->ee_numTargetPwr_11g, &targetPowerOfdm);
2082 } else {
2083 ar5212GetTargetPowers(ah, chan, ee->ee_trgtPwr_11a,
2084 ee->ee_numTargetPwr_11a, &targetPowerOfdm);
2085 }
2086
2087 /* Get Maximum OFDM power */
2088 /* Minimum of target and edge powers */
2089 scaledPower = AH_MIN(twiceMaxEdgePower,
2090 twiceMaxRDPower - twiceAntennaReduction);
2091
2092 /*
2093 * If turbo is set, reduce power to keep power
2094 * consumption under 2 Watts. Note that we always do
2095 * this unless specially configured. Then we limit
2096 * power only for non-AP operation.
2097 */
2098 if (IS_CHAN_TURBO(chan)
2099#ifdef AH_ENABLE_AP_SUPPORT
2100 && AH_PRIVATE(ah)->ah_opmode != HAL_M_HOSTAP
2101#endif
2102 ) {
2103 /*
2104 * If turbo is set, reduce power to keep power
2105 * consumption under 2 Watts
2106 */
2107 if (ee->ee_version >= AR_EEPROM_VER3_1)
2108 scaledPower = AH_MIN(scaledPower,
2109 ee->ee_turbo2WMaxPower5);
2110 /*
2111 * EEPROM version 4.0 added an additional
2112 * constraint on 2.4GHz channels.
2113 */
2114 if (ee->ee_version >= AR_EEPROM_VER4_0 &&
2115 IS_CHAN_2GHZ(chan))
2116 scaledPower = AH_MIN(scaledPower,
2117 ee->ee_turbo2WMaxPower2);
2118 }
2119
2120 maxAvailPower = AH_MIN(scaledPower,
2121 targetPowerOfdm.twicePwr6_24);
2122
2123 /* Reduce power by max regulatory domain allowed restrictions */
2124 scaledPower = maxAvailPower - (tpcScaleReduction * 2);
2125 scaledPower = (scaledPower < 0) ? 0 : scaledPower;
2126 scaledPower = AH_MIN(scaledPower, powerLimit);
2127
2128 if (commit) {
2129 /* Set OFDM rates 9, 12, 18, 24 */
2130 r0 = rpow[0] = rpow[1] = rpow[2] = rpow[3] = rpow[4] = scaledPower;
2131
2132 /* Set OFDM rates 36, 48, 54, XR */
2133 rpow[5] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr36);
2134 rpow[6] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr48);
2135 r7 = rpow[7] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr54);
2136
2137 if (ee->ee_version >= AR_EEPROM_VER4_0) {
2138 /* Setup XR target power from EEPROM */
2139 rpow[15] = AH_MIN(scaledPower, IS_CHAN_2GHZ(chan) ?
2140 ee->ee_xrTargetPower2 : ee->ee_xrTargetPower5);
2141 } else {
2142 /* XR uses 6mb power */
2143 rpow[15] = rpow[0];
2144 }
2145 ahp->ah_ofdmTxPower = *pMaxPower;
2146
2147 } else {
2148 r0 = scaledPower;
2149 r7 = AH_MIN(r0, targetPowerOfdm.twicePwr54);
2150 }
2151 *pMinPower = r7;
2152 *pMaxPower = r0;
2153
2154 HALDEBUG(ah, HAL_DEBUG_RFPARAM,
2155 "%s: MaxRD: %d TurboMax: %d MaxCTL: %d "
2156 "TPC_Reduction %d chan=%d (0x%x) maxAvailPower=%d pwr6_24=%d, maxPower=%d\n",
2157 __func__, twiceMaxRDPower, ee->ee_turbo2WMaxPower5,
2158 twiceMaxEdgePower, tpcScaleReduction * 2,
2159 chan->channel, chan->channelFlags,
2160 maxAvailPower, targetPowerOfdm.twicePwr6_24, *pMaxPower);
2161 }
2162
2163 if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) {
2164 /* Get final CCK target powers */
2165 ar5212GetTargetPowers(ah, chan, ee->ee_trgtPwr_11b,
2166 ee->ee_numTargetPwr_11b, &targetPowerCck);
2167
2168 /* Reduce power by max regulatory domain allowed restrictions */
2169 scaledPower = AH_MIN(twiceMaxEdgePowerCck,
2170 twiceMaxRDPower - twiceAntennaReduction);
2171 if (maxAvailPower < AH_MIN(scaledPower, targetPowerCck.twicePwr6_24))
2172 maxAvailPower = AH_MIN(scaledPower, targetPowerCck.twicePwr6_24);
2173
2174 /* Reduce power by user selection */
2175 scaledPower = AH_MIN(scaledPower, targetPowerCck.twicePwr6_24) - (tpcScaleReduction * 2);
2176 scaledPower = (scaledPower < 0) ? 0 : scaledPower;
2177 scaledPower = AH_MIN(scaledPower, powerLimit);
2178
2179 if (commit) {
2180 /* Set CCK rates 2L, 2S, 5.5L, 5.5S, 11L, 11S */
2181 rpow[8] = AH_MIN(scaledPower, targetPowerCck.twicePwr6_24);
2182 r9 = rpow[9] = AH_MIN(scaledPower, targetPowerCck.twicePwr36);
2183 rpow[10] = rpow[9];
2184 rpow[11] = AH_MIN(scaledPower, targetPowerCck.twicePwr48);
2185 rpow[12] = rpow[11];
2186 r13 = rpow[13] = AH_MIN(scaledPower, targetPowerCck.twicePwr54);
2187 rpow[14] = rpow[13];
2188 } else {
2189 r9 = AH_MIN(scaledPower, targetPowerCck.twicePwr36);
2190 r13 = AH_MIN(scaledPower, targetPowerCck.twicePwr54);
2191 }
2192
2193 /* Set min/max power based off OFDM values or initialization */
2194 if (r13 < *pMinPower)
2195 *pMinPower = r13;
2196 if (r9 > *pMaxPower)
2197 *pMaxPower = r9;
2198
2199 HALDEBUG(ah, HAL_DEBUG_RFPARAM,
2200 "%s: cck: MaxRD: %d MaxCTL: %d "
2201 "TPC_Reduction %d chan=%d (0x%x) maxAvailPower=%d pwr6_24=%d, maxPower=%d\n",
2202 __func__, twiceMaxRDPower, twiceMaxEdgePowerCck,
2203 tpcScaleReduction * 2, chan->channel, chan->channelFlags,
2204 maxAvailPower, targetPowerCck.twicePwr6_24, *pMaxPower);
2205 }
2206 if (commit) {
2207 ahp->ah_tx6PowerInHalfDbm = *pMaxPower;
2208 AH_PRIVATE(ah)->ah_maxPowerLevel = ahp->ah_tx6PowerInHalfDbm;
2209 }
2210 return AH_TRUE;
2211}
2212
2213HAL_BOOL
2214ar5212GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, uint32_t nchans)
2215{
2216 struct ath_hal_5212 *ahp = AH5212(ah);
2217 static const uint16_t tpcScaleReductionTable[5] =
2218 { 0, 3, 6, 9, MAX_RATE_POWER };
2219 int16_t minPower, maxPower, tpcInDb, powerLimit;
2220 HAL_CHANNEL *chan;
2221 int i;
2222
2223 /*
2224 * Get Pier table max and min powers.
2225 */
2226 for (i = 0; i < nchans; i++) {
2227 chan = &chans[i];
2228 if (ahp->ah_rfHal->getChannelMaxMinPower(ah, chan, &maxPower, &minPower)) {
2229 /* NB: rf code returns 1/4 dBm units, convert */
2230 chan->maxTxPower = maxPower / 2;
2231 chan->minTxPower = minPower / 2;
2232 } else {
2233 HALDEBUG(ah, HAL_DEBUG_ANY,
2234 "%s: no min/max power for %u/0x%x\n",
2235 __func__, chan->channel, chan->channelFlags);
2236 chan->maxTxPower = MAX_RATE_POWER;
2237 chan->minTxPower = 0;
2238 }
2239 }
2240 /*
2241 * Now adjust to reflect any global scale and/or CTL's.
2242 * (XXX is that correct?)
2243 */
2244 powerLimit = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit);
2245 if (powerLimit >= MAX_RATE_POWER || powerLimit == 0)
2246 tpcInDb = tpcScaleReductionTable[AH_PRIVATE(ah)->ah_tpScale];
2247 else
2248 tpcInDb = 0;
2249 for (i=0; i<nchans; i++) {
2250 chan = &chans[i];
2251 if (!ar5212SetRateTable(ah, (HAL_CHANNEL *) chan, tpcInDb, powerLimit,
2252 AH_FALSE, &minPower, &maxPower)) {
2253 HALDEBUG(ah, HAL_DEBUG_ANY,
2254 "%s: unable to find max/min power\n",__func__);
2255 return AH_FALSE;
2256 }
2257 if (maxPower < chan->maxTxPower)
2258 chan->maxTxPower = maxPower;
2259 if (minPower < chan->minTxPower)
2260 chan->minTxPower = minPower;
2261 }
2262#ifdef AH_DEBUG
2263 for (i=0; i<nchans; i++) {
2264 HALDEBUG(ah, HAL_DEBUG_RESET,
2265 "Chan %d: MaxPow = %d MinPow = %d\n",
2266 chans[i].channel,chans[i].maxTxPower, chans[i].minTxPower);
2267 }
2268#endif
2269 return AH_TRUE;
2270}
2271
2272/*
2273 * Correct for the gain-delta between ofdm and cck mode target
2274 * powers. Write the results to the rate table and the power table.
2275 *
2276 * Conventions :
2277 * 1. rpow[ii] is the integer value of 2*(desired power
2278 * for the rate ii in dBm) to provide 0.5dB resolution. rate
2279 * mapping is as following :
2280 * [0..7] --> ofdm 6, 9, .. 48, 54
2281 * [8..14] --> cck 1L, 2L, 2S, .. 11L, 11S
2282 * [15] --> XR (all rates get the same power)
2283 * 2. powv[ii] is the pcdac corresponding to ii/2 dBm.
2284 */
2285static void
2286ar5212CorrectGainDelta(struct ath_hal *ah, int twiceOfdmCckDelta)
2287{
2288#define N(_a) (sizeof(_a) / sizeof(_a[0]))
2289 struct ath_hal_5212 *ahp = AH5212(ah);
2290 const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;
2291 int16_t ratesIndex[N(ahp->ah_ratesArray)];
2292 uint16_t ii, jj, iter;
2293 int32_t cckIndex;
2294 int16_t gainDeltaAdjust;
2295
2296 HALASSERT(ah->ah_magic == AR5212_MAGIC);
2297
2298 gainDeltaAdjust = ee->ee_cckOfdmGainDelta;
2299
2300 /* make a local copy of desired powers as initial indices */
2301 OS_MEMCPY(ratesIndex, ahp->ah_ratesArray, sizeof(ratesIndex));
2302
2303 /* fix only the CCK indices */
2304 for (ii = 8; ii < 15; ii++) {
2305 /* apply a gain_delta correction of -15 for CCK */
2306 ratesIndex[ii] -= gainDeltaAdjust;
2307
2308 /* Now check for contention with all ofdm target powers */
2309 jj = 0;
2310 iter = 0;
2311 /* indicates not all ofdm rates checked forcontention yet */
2312 while (jj < 16) {
2313 if (ratesIndex[ii] < 0)
2314 ratesIndex[ii] = 0;
2315 if (jj == 8) { /* skip CCK rates */
2316 jj = 15;
2317 continue;
2318 }
2319 if (ratesIndex[ii] == ahp->ah_ratesArray[jj]) {
2320 if (ahp->ah_ratesArray[jj] == 0)
2321 ratesIndex[ii]++;
2322 else if (iter > 50) {
2323 /*
2324 * To avoid pathological case of of
2325 * dm target powers 0 and 0.5dBm
2326 */
2327 ratesIndex[ii]++;
2328 } else
2329 ratesIndex[ii]--;
2330 /* check with all rates again */
2331 jj = 0;
2332 iter++;
2333 } else
2334 jj++;
2335 }
2336 if (ratesIndex[ii] >= PWR_TABLE_SIZE)
2337 ratesIndex[ii] = PWR_TABLE_SIZE -1;
2338 cckIndex = ahp->ah_ratesArray[ii] - twiceOfdmCckDelta;
2339 if (cckIndex < 0)
2340 cckIndex = 0;
2341
2342 /*
2343 * Validate that the indexes for the powv are not
2344 * out of bounds.
2345 */
2346 HALASSERT(cckIndex < PWR_TABLE_SIZE);
2347 HALASSERT(ratesIndex[ii] < PWR_TABLE_SIZE);
2348 ahp->ah_pcdacTable[ratesIndex[ii]] =
2349 ahp->ah_pcdacTable[cckIndex];
2350 }
2351 /* Override rate per power table with new values */
2352 for (ii = 8; ii < 15; ii++)
2353 ahp->ah_ratesArray[ii] = ratesIndex[ii];
2354#undef N
2355}
2356
2357/*
2358 * Find the maximum conformance test limit for the given channel and CTL info
2359 */
2360static uint16_t
2361ar5212GetMaxEdgePower(uint16_t channel, const RD_EDGES_POWER *pRdEdgesPower)
2362{
2363 /* temp array for holding edge channels */
2364 uint16_t tempChannelList[NUM_EDGES];
2365 uint16_t clo, chi, twiceMaxEdgePower;
2366 int i, numEdges;
2367
2368 /* Get the edge power */
2369 for (i = 0; i < NUM_EDGES; i++) {
2370 if (pRdEdgesPower[i].rdEdge == 0)
2371 break;
2372 tempChannelList[i] = pRdEdgesPower[i].rdEdge;
2373 }
2374 numEdges = i;
2375
2376 ar5212GetLowerUpperValues(channel, tempChannelList,
2377 numEdges, &clo, &chi);
2378 /* Get the index for the lower channel */
2379 for (i = 0; i < numEdges && clo != tempChannelList[i]; i++)
2380 ;
2381 /* Is lower channel ever outside the rdEdge? */
2382 HALASSERT(i != numEdges);
2383
2384 if ((clo == chi && clo == channel) || (pRdEdgesPower[i].flag)) {
2385 /*
2386 * If there's an exact channel match or an inband flag set
2387 * on the lower channel use the given rdEdgePower
2388 */
2389 twiceMaxEdgePower = pRdEdgesPower[i].twice_rdEdgePower;
2390 HALASSERT(twiceMaxEdgePower > 0);
2391 } else
2392 twiceMaxEdgePower = MAX_RATE_POWER;
2393 return twiceMaxEdgePower;
2394}
2395
2396/*
2397 * Returns interpolated or the scaled up interpolated value
2398 */
2399static uint16_t
2400interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight,
2401 uint16_t targetLeft, uint16_t targetRight)
2402{
2403 uint16_t rv;
2404 int16_t lRatio;
2405
2406 /* to get an accurate ratio, always scale, if want to scale, then don't scale back down */
2407 if ((targetLeft * targetRight) == 0)
2408 return 0;
2409
2410 if (srcRight != srcLeft) {
2411 /*
2412 * Note the ratio always need to be scaled,
2413 * since it will be a fraction.
2414 */
2415 lRatio = (target - srcLeft) * EEP_SCALE / (srcRight - srcLeft);
2416 if (lRatio < 0) {
2417 /* Return as Left target if value would be negative */
2418 rv = targetLeft;
2419 } else if (lRatio > EEP_SCALE) {
2420 /* Return as Right target if Ratio is greater than 100% (SCALE) */
2421 rv = targetRight;
2422 } else {
2423 rv = (lRatio * targetRight + (EEP_SCALE - lRatio) *
2424 targetLeft) / EEP_SCALE;
2425 }
2426 } else {
2427 rv = targetLeft;
2428 }
2429 return rv;
2430}
2431
2432/*
2433 * Return the four rates of target power for the given target power table
2434 * channel, and number of channels
2435 */
2436static void
2437ar5212GetTargetPowers(struct ath_hal *ah, HAL_CHANNEL *chan,
2438 const TRGT_POWER_INFO *powInfo,
2439 uint16_t numChannels, TRGT_POWER_INFO *pNewPower)
2440{
2441 /* temp array for holding target power channels */
2442 uint16_t tempChannelList[NUM_TEST_FREQUENCIES];
2443 uint16_t clo, chi, ixlo, ixhi;
2444 int i;
2445
2446 /* Copy the target powers into the temp channel list */
2447 for (i = 0; i < numChannels; i++)
2448 tempChannelList[i] = powInfo[i].testChannel;
2449
2450 ar5212GetLowerUpperValues(chan->channel, tempChannelList,
2451 numChannels, &clo, &chi);
2452
2453 /* Get the indices for the channel */
2454 ixlo = ixhi = 0;
2455 for (i = 0; i < numChannels; i++) {
2456 if (clo == tempChannelList[i]) {
2457 ixlo = i;
2458 }
2459 if (chi == tempChannelList[i]) {
2460 ixhi = i;
2461 break;
2462 }
2463 }
2464
2465 /*
2466 * Get the lower and upper channels, target powers,
2467 * and interpolate between them.
2468 */
2469 pNewPower->twicePwr6_24 = interpolate(chan->channel, clo, chi,
2470 powInfo[ixlo].twicePwr6_24, powInfo[ixhi].twicePwr6_24);
2471 pNewPower->twicePwr36 = interpolate(chan->channel, clo, chi,
2472 powInfo[ixlo].twicePwr36, powInfo[ixhi].twicePwr36);
2473 pNewPower->twicePwr48 = interpolate(chan->channel, clo, chi,
2474 powInfo[ixlo].twicePwr48, powInfo[ixhi].twicePwr48);
2475 pNewPower->twicePwr54 = interpolate(chan->channel, clo, chi,
2476 powInfo[ixlo].twicePwr54, powInfo[ixhi].twicePwr54);
2477}
2478
2479/*
2480 * Search a list for a specified value v that is within
2481 * EEP_DELTA of the search values. Return the closest
2482 * values in the list above and below the desired value.
2483 * EEP_DELTA is a factional value; everything is scaled
2484 * so only integer arithmetic is used.
2485 *
2486 * NB: the input list is assumed to be sorted in ascending order
2487 */
2488void
2489ar5212GetLowerUpperValues(uint16_t v, uint16_t *lp, uint16_t listSize,
2490 uint16_t *vlo, uint16_t *vhi)
2491{
2492 uint32_t target = v * EEP_SCALE;
2493 uint16_t *ep = lp+listSize;
2494
2495 /*
2496 * Check first and last elements for out-of-bounds conditions.
2497 */
2498 if (target < (uint32_t)(lp[0] * EEP_SCALE - EEP_DELTA)) {
2499 *vlo = *vhi = lp[0];
2500 return;
2501 }
2502 if (target > (uint32_t)(ep[-1] * EEP_SCALE + EEP_DELTA)) {
2503 *vlo = *vhi = ep[-1];
2504 return;
2505 }
2506
2507 /* look for value being near or between 2 values in list */
2508 for (; lp < ep; lp++) {
2509 /*
2510 * If value is close to the current value of the list
2511 * then target is not between values, it is one of the values
2512 */
2513 if (abs(lp[0] * EEP_SCALE - target) < EEP_DELTA) {
2514 *vlo = *vhi = lp[0];
2515 return;
2516 }
2517 /*
2518 * Look for value being between current value and next value
2519 * if so return these 2 values
2520 */
2521 if (target < (uint32_t)(lp[1] * EEP_SCALE - EEP_DELTA)) {
2522 *vlo = lp[0];
2523 *vhi = lp[1];
2524 return;
2525 }
2526 }
2527 HALASSERT(AH_FALSE); /* should not reach here */
2528}
2529
2530/*
2531 * Perform analog "swizzling" of parameters into their location
2532 *
2533 * NB: used by RF backends
2534 */
2535void
2536ar5212ModifyRfBuffer(uint32_t *rfBuf, uint32_t reg32, uint32_t numBits,
2537 uint32_t firstBit, uint32_t column)
2538{
2539#define MAX_ANALOG_START 319 /* XXX */
2540 uint32_t tmp32, mask, arrayEntry, lastBit;
2541 int32_t bitPosition, bitsLeft;
2542
2543 HALASSERT(column <= 3);
2544 HALASSERT(numBits <= 32);
2545 HALASSERT(firstBit + numBits <= MAX_ANALOG_START);
2546
2547 tmp32 = ath_hal_reverseBits(reg32, numBits);
2548 arrayEntry = (firstBit - 1) / 8;
2549 bitPosition = (firstBit - 1) % 8;
2550 bitsLeft = numBits;
2551 while (bitsLeft > 0) {
2552 lastBit = (bitPosition + bitsLeft > 8) ?
2553 8 : bitPosition + bitsLeft;
2554 mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<
2555 (column * 8);
2556 rfBuf[arrayEntry] &= ~mask;
2557 rfBuf[arrayEntry] |= ((tmp32 << bitPosition) <<
2558 (column * 8)) & mask;
2559 bitsLeft -= 8 - bitPosition;
2560 tmp32 = tmp32 >> (8 - bitPosition);
2561 bitPosition = 0;
2562 arrayEntry++;
2563 }
2564#undef MAX_ANALOG_START
2565}
2566
2567/*
2568 * Sets the rate to duration values in MAC - used for multi-
2569 * rate retry.
2570 * The rate duration table needs to cover all valid rate codes;
2571 * the 11g table covers all ofdm rates, while the 11b table
2572 * covers all cck rates => all valid rates get covered between
2573 * these two mode's ratetables!
2574 * But if we're turbo, the ofdm phy is replaced by the turbo phy
2575 * and cck is not valid with turbo => all rates get covered
2576 * by the turbo ratetable only
2577 */
2578void
2579ar5212SetRateDurationTable(struct ath_hal *ah, HAL_CHANNEL *chan)
2580{
2581 const HAL_RATE_TABLE *rt;
2582 int i;
2583
2584 /* NB: band doesn't matter for 1/2 and 1/4 rate */
2585 if (IS_CHAN_HALF_RATE(chan)) {
2586 rt = ar5212GetRateTable(ah, HAL_MODE_11A_HALF_RATE);
2587 } else if (IS_CHAN_QUARTER_RATE(chan)) {
2588 rt = ar5212GetRateTable(ah, HAL_MODE_11A_QUARTER_RATE);
2589 } else {
2590 rt = ar5212GetRateTable(ah,
2591 IS_CHAN_TURBO(chan) ? HAL_MODE_TURBO : HAL_MODE_11G);
2592 }
2593
2594 for (i = 0; i < rt->rateCount; ++i)
2595 OS_REG_WRITE(ah,
2596 AR_RATE_DURATION(rt->info[i].rateCode),
2597 ath_hal_computetxtime(ah, rt,
2598 WLAN_CTRL_FRAME_SIZE,
2599 rt->info[i].controlRate, AH_FALSE));
2600 if (!IS_CHAN_TURBO(chan)) {
2601 /* 11g Table is used to cover the CCK rates. */
2602 rt = ar5212GetRateTable(ah, HAL_MODE_11G);
2603 for (i = 0; i < rt->rateCount; ++i) {
2604 uint32_t reg = AR_RATE_DURATION(rt->info[i].rateCode);
2605
2606 if (rt->info[i].phy != IEEE80211_T_CCK)
2607 continue;
2608
2609 OS_REG_WRITE(ah, reg,
2610 ath_hal_computetxtime(ah, rt,
2611 WLAN_CTRL_FRAME_SIZE,
2612 rt->info[i].controlRate, AH_FALSE));
2613 /* cck rates have short preamble option also */
2614 if (rt->info[i].shortPreamble) {
2615 reg += rt->info[i].shortPreamble << 2;
2616 OS_REG_WRITE(ah, reg,
2617 ath_hal_computetxtime(ah, rt,
2618 WLAN_CTRL_FRAME_SIZE,
2619 rt->info[i].controlRate,
2620 AH_TRUE));
2621 }
2622 }
2623 }
2624}
2625
2626/* Adjust various register settings based on half/quarter rate clock setting.
2627 * This includes: +USEC, TX/RX latency,
2628 * + IFS params: slot, eifs, misc etc.
2629 */
2630void
2631ar5212SetIFSTiming(struct ath_hal *ah, HAL_CHANNEL *chan)
2632{
2633 uint32_t txLat, rxLat, usec, slot, refClock, eifs, init_usec;
2634
2635 HALASSERT(IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan));
2636
2637 refClock = OS_REG_READ(ah, AR_USEC) & AR_USEC_USEC32;
2638 if (IS_CHAN_HALF_RATE(chan)) {
2639 slot = IFS_SLOT_HALF_RATE;
2640 rxLat = RX_NON_FULL_RATE_LATENCY << AR5212_USEC_RX_LAT_S;
2641 txLat = TX_HALF_RATE_LATENCY << AR5212_USEC_TX_LAT_S;
2642 usec = HALF_RATE_USEC;
2643 eifs = IFS_EIFS_HALF_RATE;
2644 init_usec = INIT_USEC >> 1;
2645 } else { /* quarter rate */
2646 slot = IFS_SLOT_QUARTER_RATE;
2647 rxLat = RX_NON_FULL_RATE_LATENCY << AR5212_USEC_RX_LAT_S;
2648 txLat = TX_QUARTER_RATE_LATENCY << AR5212_USEC_TX_LAT_S;
2649 usec = QUARTER_RATE_USEC;
2650 eifs = IFS_EIFS_QUARTER_RATE;
2651 init_usec = INIT_USEC >> 2;
2652 }
2653
2654 OS_REG_WRITE(ah, AR_USEC, (usec | refClock | txLat | rxLat));
2655 OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, slot);
2656 OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS, eifs);
2657 OS_REG_RMW_FIELD(ah, AR_D_GBL_IFS_MISC,
2658 AR_D_GBL_IFS_MISC_USEC_DURATION, init_usec);
2659}
2665#endif /* AH_SUPPORT_AR5212 */