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_attach.c,v 1.4 2011/03/07 11:25:43 cegger Exp $
18 */
19 #include "opt_ah.h"
20
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"
28
29 #define AH_5212_COMMON
30 #include "ar5212/ar5212.ini"
31
32 static void ar5212ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore);
33 static void ar5212DisablePCIE(struct ath_hal *ah);
34
35 static const struct ath_hal_private ar5212hal = {{
36 .ah_magic = AR5212_MAGIC,
37 .ah_abi = HAL_ABI_VERSION,
38 .ah_countryCode = CTRY_DEFAULT,
39
40 .ah_getRateTable = ar5212GetRateTable,
41 .ah_detach = ar5212Detach,
42
43 /* Reset Functions */
44 .ah_reset = ar5212Reset,
45 .ah_phyDisable = ar5212PhyDisable,
46 .ah_disable = ar5212Disable,
47 .ah_configPCIE = ar5212ConfigPCIE,
48 .ah_disablePCIE = ar5212DisablePCIE,
49 .ah_setPCUConfig = ar5212SetPCUConfig,
50 .ah_perCalibration = ar5212PerCalibration,
51 .ah_perCalibrationN = ar5212PerCalibrationN,
52 .ah_resetCalValid = ar5212ResetCalValid,
53 .ah_setTxPowerLimit = ar5212SetTxPowerLimit,
54 .ah_getChanNoise = ath_hal_getChanNoise,
55
56 /* Transmit functions */
57 .ah_updateTxTrigLevel = ar5212UpdateTxTrigLevel,
58 .ah_setupTxQueue = ar5212SetupTxQueue,
59 .ah_setTxQueueProps = ar5212SetTxQueueProps,
60 .ah_getTxQueueProps = ar5212GetTxQueueProps,
61 .ah_releaseTxQueue = ar5212ReleaseTxQueue,
62 .ah_resetTxQueue = ar5212ResetTxQueue,
63 .ah_getTxDP = ar5212GetTxDP,
64 .ah_setTxDP = ar5212SetTxDP,
65 .ah_numTxPending = ar5212NumTxPending,
66 .ah_startTxDma = ar5212StartTxDma,
67 .ah_stopTxDma = ar5212StopTxDma,
68 .ah_setupTxDesc = ar5212SetupTxDesc,
69 .ah_setupXTxDesc = ar5212SetupXTxDesc,
70 .ah_fillTxDesc = ar5212FillTxDesc,
71 .ah_procTxDesc = ar5212ProcTxDesc,
72 .ah_getTxIntrQueue = ar5212GetTxIntrQueue,
73 .ah_reqTxIntrDesc = ar5212IntrReqTxDesc,
74
75 /* RX Functions */
76 .ah_getRxDP = ar5212GetRxDP,
77 .ah_setRxDP = ar5212SetRxDP,
78 .ah_enableReceive = ar5212EnableReceive,
79 .ah_stopDmaReceive = ar5212StopDmaReceive,
80 .ah_startPcuReceive = ar5212StartPcuReceive,
81 .ah_stopPcuReceive = ar5212StopPcuReceive,
82 .ah_setMulticastFilter = ar5212SetMulticastFilter,
83 .ah_setMulticastFilterIndex = ar5212SetMulticastFilterIndex,
84 .ah_clrMulticastFilterIndex = ar5212ClrMulticastFilterIndex,
85 .ah_getRxFilter = ar5212GetRxFilter,
86 .ah_setRxFilter = ar5212SetRxFilter,
87 .ah_setupRxDesc = ar5212SetupRxDesc,
88 .ah_procRxDesc = ar5212ProcRxDesc,
89 .ah_rxMonitor = ar5212AniPoll,
90 .ah_procMibEvent = ar5212ProcessMibIntr,
91
92 /* Misc Functions */
93 .ah_getCapability = ar5212GetCapability,
94 .ah_setCapability = ar5212SetCapability,
95 .ah_getDiagState = ar5212GetDiagState,
96 .ah_getMacAddress = ar5212GetMacAddress,
97 .ah_setMacAddress = ar5212SetMacAddress,
98 .ah_getBssIdMask = ar5212GetBssIdMask,
99 .ah_setBssIdMask = ar5212SetBssIdMask,
100 .ah_setRegulatoryDomain = ar5212SetRegulatoryDomain,
101 .ah_setLedState = ar5212SetLedState,
102 .ah_writeAssocid = ar5212WriteAssocid,
103 .ah_gpioCfgInput = ar5212GpioCfgInput,
104 .ah_gpioCfgOutput = ar5212GpioCfgOutput,
105 .ah_gpioGet = ar5212GpioGet,
106 .ah_gpioSet = ar5212GpioSet,
107 .ah_gpioSetIntr = ar5212GpioSetIntr,
108 .ah_getTsf32 = ar5212GetTsf32,
109 .ah_getTsf64 = ar5212GetTsf64,
110 .ah_resetTsf = ar5212ResetTsf,
111 .ah_detectCardPresent = ar5212DetectCardPresent,
112 .ah_updateMibCounters = ar5212UpdateMibCounters,
113 .ah_getRfGain = ar5212GetRfgain,
114 .ah_getDefAntenna = ar5212GetDefAntenna,
115 .ah_setDefAntenna = ar5212SetDefAntenna,
116 .ah_getAntennaSwitch = ar5212GetAntennaSwitch,
117 .ah_setAntennaSwitch = ar5212SetAntennaSwitch,
118 .ah_setSifsTime = ar5212SetSifsTime,
119 .ah_getSifsTime = ar5212GetSifsTime,
120 .ah_setSlotTime = ar5212SetSlotTime,
121 .ah_getSlotTime = ar5212GetSlotTime,
122 .ah_setAckTimeout = ar5212SetAckTimeout,
123 .ah_getAckTimeout = ar5212GetAckTimeout,
124 .ah_setAckCTSRate = ar5212SetAckCTSRate,
125 .ah_getAckCTSRate = ar5212GetAckCTSRate,
126 .ah_setCTSTimeout = ar5212SetCTSTimeout,
127 .ah_getCTSTimeout = ar5212GetCTSTimeout,
128 .ah_setDecompMask = ar5212SetDecompMask,
129 .ah_setCoverageClass = ar5212SetCoverageClass,
130
131 /* Key Cache Functions */
132 .ah_getKeyCacheSize = ar5212GetKeyCacheSize,
133 .ah_resetKeyCacheEntry = ar5212ResetKeyCacheEntry,
134 .ah_isKeyCacheEntryValid = ar5212IsKeyCacheEntryValid,
135 .ah_setKeyCacheEntry = ar5212SetKeyCacheEntry,
136 .ah_setKeyCacheEntryMac = ar5212SetKeyCacheEntryMac,
137
138 /* Power Management Functions */
139 .ah_setPowerMode = ar5212SetPowerMode,
140 .ah_getPowerMode = ar5212GetPowerMode,
141
142 /* Beacon Functions */
143 .ah_setBeaconTimers = ar5212SetBeaconTimers,
144 .ah_beaconInit = ar5212BeaconInit,
145 .ah_setStationBeaconTimers = ar5212SetStaBeaconTimers,
146 .ah_resetStationBeaconTimers = ar5212ResetStaBeaconTimers,
147
148 /* Interrupt Functions */
149 .ah_isInterruptPending = ar5212IsInterruptPending,
150 .ah_getPendingInterrupts = ar5212GetPendingInterrupts,
151 .ah_getInterrupts = ar5212GetInterrupts,
152 .ah_setInterrupts = ar5212SetInterrupts },
153
154 .ah_getChannelEdges = ar5212GetChannelEdges,
155 .ah_getWirelessModes = ar5212GetWirelessModes,
156 .ah_eepromRead = ar5212EepromRead,
157 #ifdef AH_SUPPORT_WRITE_EEPROM
158 .ah_eepromWrite = ar5212EepromWrite,
159 #endif
160 .ah_gpioCfgOutput = ar5212GpioCfgOutput,
161 .ah_gpioCfgInput = ar5212GpioCfgInput,
162 .ah_gpioGet = ar5212GpioGet,
163 .ah_gpioSet = ar5212GpioSet,
164 .ah_gpioSetIntr = ar5212GpioSetIntr,
165 .ah_getChipPowerLimits = ar5212GetChipPowerLimits,
166 };
167
168 uint32_t
ar5212GetRadioRev(struct ath_hal * ah)169 ar5212GetRadioRev(struct ath_hal *ah)
170 {
171 uint32_t val;
172 int i;
173
174 /* Read Radio Chip Rev Extract */
175 OS_REG_WRITE(ah, AR_PHY(0x34), 0x00001c16);
176 for (i = 0; i < 8; i++)
177 OS_REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
178 val = (OS_REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
179 val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
180 return ath_hal_reverseBits(val, 8);
181 }
182
183 static void
ar5212AniSetup(struct ath_hal * ah)184 ar5212AniSetup(struct ath_hal *ah)
185 {
186 static const struct ar5212AniParams aniparams = {
187 .maxNoiseImmunityLevel = 4, /* levels 0..4 */
188 .totalSizeDesired = { -55, -55, -55, -55, -62 },
189 .coarseHigh = { -14, -14, -14, -14, -12 },
190 .coarseLow = { -64, -64, -64, -64, -70 },
191 .firpwr = { -78, -78, -78, -78, -80 },
192 .maxSpurImmunityLevel = 2, /* NB: depends on chip rev */
193 .cycPwrThr1 = { 2, 4, 6, 8, 10, 12, 14, 16 },
194 .maxFirstepLevel = 2, /* levels 0..2 */
195 .firstep = { 0, 4, 8 },
196 .ofdmTrigHigh = 500,
197 .ofdmTrigLow = 200,
198 .cckTrigHigh = 200,
199 .cckTrigLow = 100,
200 .rssiThrHigh = 40,
201 .rssiThrLow = 7,
202 .period = 100,
203 };
204 if (AH_PRIVATE(ah)->ah_macVersion < AR_SREV_VERSION_GRIFFIN) {
205 struct ar5212AniParams tmp;
206 OS_MEMCPY(&tmp, &aniparams, sizeof(struct ar5212AniParams));
207 tmp.maxSpurImmunityLevel = 7; /* Venice and earlier */
208 ar5212AniAttach(ah, &tmp, &tmp, AH_TRUE);
209 } else
210 ar5212AniAttach(ah, &aniparams, &aniparams, AH_TRUE);
211 }
212
213 /*
214 * Attach for an AR5212 part.
215 */
216 void
ar5212InitState(struct ath_hal_5212 * ahp,uint16_t devid,HAL_SOFTC sc,HAL_BUS_TAG st,HAL_BUS_HANDLE sh,HAL_STATUS * status)217 ar5212InitState(struct ath_hal_5212 *ahp, uint16_t devid, HAL_SOFTC sc,
218 HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status)
219 {
220 #define N(a) (sizeof(a)/sizeof(a[0]))
221 static const uint8_t defbssidmask[IEEE80211_ADDR_LEN] =
222 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
223 struct ath_hal *ah;
224
225 ah = &ahp->ah_priv.h;
226 /* set initial values */
227 OS_MEMCPY(&ahp->ah_priv, &ar5212hal, sizeof(struct ath_hal_private));
228 ah->ah_sc = sc;
229 ah->ah_st = st;
230 ah->ah_sh = sh;
231
232 ah->ah_devid = devid; /* NB: for alq */
233 AH_PRIVATE(ah)->ah_devid = devid;
234 AH_PRIVATE(ah)->ah_subvendorid = 0; /* XXX */
235
236 AH_PRIVATE(ah)->ah_powerLimit = MAX_RATE_POWER;
237 AH_PRIVATE(ah)->ah_tpScale = HAL_TP_SCALE_MAX; /* no scaling */
238
239 ahp->ah_antControl = HAL_ANT_VARIABLE;
240 ahp->ah_diversity = AH_TRUE;
241 ahp->ah_bIQCalibration = AH_FALSE;
242 /*
243 * Enable MIC handling.
244 */
245 ahp->ah_staId1Defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
246 ahp->ah_rssiThr = INIT_RSSI_THR;
247 ahp->ah_tpcEnabled = AH_FALSE; /* disabled by default */
248 ahp->ah_phyPowerOn = AH_FALSE;
249 ahp->ah_macTPC = SM(MAX_RATE_POWER, AR_TPC_ACK)
250 | SM(MAX_RATE_POWER, AR_TPC_CTS)
251 | SM(MAX_RATE_POWER, AR_TPC_CHIRP);
252 ahp->ah_beaconInterval = 100; /* XXX [20..1000] */
253 ahp->ah_enable32kHzClock = DONT_USE_32KHZ;/* XXX */
254 ahp->ah_slottime = (u_int) -1;
255 ahp->ah_acktimeout = (u_int) -1;
256 ahp->ah_ctstimeout = (u_int) -1;
257 ahp->ah_sifstime = (u_int) -1;
258 ahp->ah_txTrigLev = INIT_TX_FIFO_THRESHOLD;
259 ahp->ah_maxTxTrigLev = MAX_TX_FIFO_THRESHOLD;
260
261 OS_MEMCPY(&ahp->ah_bssidmask, defbssidmask, IEEE80211_ADDR_LEN);
262 #undef N
263 }
264
265 /*
266 * Validate MAC version and revision.
267 */
268 static HAL_BOOL
ar5212IsMacSupported(uint8_t macVersion,uint8_t macRev)269 ar5212IsMacSupported(uint8_t macVersion, uint8_t macRev)
270 {
271 #define N(a) (sizeof(a)/sizeof(a[0]))
272 static const struct {
273 uint8_t version;
274 uint8_t revMin, revMax;
275 } macs[] = {
276 { AR_SREV_VERSION_VENICE,
277 AR_SREV_D2PLUS, AR_SREV_REVISION_MAX },
278 { AR_SREV_VERSION_GRIFFIN,
279 AR_SREV_D2PLUS, AR_SREV_REVISION_MAX },
280 { AR_SREV_5413,
281 AR_SREV_REVISION_MIN, AR_SREV_REVISION_MAX },
282 { AR_SREV_5424,
283 AR_SREV_REVISION_MIN, AR_SREV_REVISION_MAX },
284 { AR_SREV_2425,
285 AR_SREV_REVISION_MIN, AR_SREV_REVISION_MAX },
286 { AR_SREV_2417,
287 AR_SREV_REVISION_MIN, AR_SREV_REVISION_MAX },
288 };
289 int i;
290
291 for (i = 0; i < N(macs); i++)
292 if (macs[i].version == macVersion &&
293 macs[i].revMin <= macRev && macRev <= macs[i].revMax)
294 return AH_TRUE;
295 return AH_FALSE;
296 #undef N
297 }
298
299 /*
300 * Attach for an AR5212 part.
301 */
302 static struct ath_hal *
ar5212Attach(uint16_t devid,HAL_SOFTC sc,HAL_BUS_TAG st,HAL_BUS_HANDLE sh,HAL_STATUS * status)303 ar5212Attach(uint16_t devid, HAL_SOFTC sc,
304 HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status)
305 {
306 #define AH_EEPROM_PROTECT(ah) \
307 (AH_PRIVATE(ah)->ah_ispcie)? AR_EEPROM_PROTECT_PCIE : AR_EEPROM_PROTECT)
308 struct ath_hal_5212 *ahp;
309 struct ath_hal *ah;
310 struct ath_hal_rf *rf;
311 uint32_t val;
312 uint16_t eeval;
313 HAL_STATUS ecode;
314
315 HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",
316 __func__, sc, (void*) st, (void*) sh);
317
318 /* NB: memory is returned zero'd */
319 ahp = ath_hal_malloc(sizeof (struct ath_hal_5212));
320 if (ahp == AH_NULL) {
321 HALDEBUG(AH_NULL, HAL_DEBUG_ANY,
322 "%s: cannot allocate memory for state block\n", __func__);
323 *status = HAL_ENOMEM;
324 return AH_NULL;
325 }
326 ar5212InitState(ahp, devid, sc, st, sh, status);
327 ah = &ahp->ah_priv.h;
328
329 if (!ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
330 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n",
331 __func__);
332 ecode = HAL_EIO;
333 goto bad;
334 }
335 /* Read Revisions from Chips before taking out of reset */
336 val = OS_REG_READ(ah, AR_SREV) & AR_SREV_ID;
337 AH_PRIVATE(ah)->ah_macVersion = val >> AR_SREV_ID_S;
338 AH_PRIVATE(ah)->ah_macRev = val & AR_SREV_REVISION;
339 AH_PRIVATE(ah)->ah_ispcie = IS_5424(ah) || IS_2425(ah);
340
341 if (!ar5212IsMacSupported(AH_PRIVATE(ah)->ah_macVersion, AH_PRIVATE(ah)->ah_macRev)) {
342 HALDEBUG(ah, HAL_DEBUG_ANY,
343 "%s: Mac Chip Rev 0x%02x.%x not supported\n" ,
344 __func__, AH_PRIVATE(ah)->ah_macVersion,
345 AH_PRIVATE(ah)->ah_macRev);
346 ecode = HAL_ENOTSUPP;
347 goto bad;
348 }
349
350 /* setup common ini data; rf backends handle remainder */
351 HAL_INI_INIT(&ahp->ah_ini_modes, ar5212Modes, 6);
352 HAL_INI_INIT(&ahp->ah_ini_common, ar5212Common, 2);
353
354 if (!ar5212ChipReset(ah, AH_NULL)) { /* reset chip */
355 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
356 ecode = HAL_EIO;
357 goto bad;
358 }
359
360 AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID);
361
362 if (AH_PRIVATE(ah)->ah_ispcie) {
363 /* XXX: build flag to disable this? */
364 ath_hal_configPCIE(ah, AH_FALSE);
365 }
366
367 if (!ar5212ChipTest(ah)) {
368 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n",
369 __func__);
370 ecode = HAL_ESELFTEST;
371 goto bad;
372 }
373
374 /* Enable PCI core retry fix in software for Hainan and up */
375 if (AH_PRIVATE(ah)->ah_macVersion >= AR_SREV_VERSION_VENICE)
376 OS_REG_SET_BIT(ah, AR_PCICFG, AR_PCICFG_RETRYFIXEN);
377
378 /*
379 * Set correct Baseband to analog shift
380 * setting to access analog chips.
381 */
382 OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
383
384 /* Read Radio Chip Rev Extract */
385 AH_PRIVATE(ah)->ah_analog5GhzRev = ar5212GetRadioRev(ah);
386
387 rf = ath_hal_rfprobe(ah, &ecode);
388 if (rf == AH_NULL)
389 goto bad;
390
391 /* NB: silently accept anything in release code per Atheros */
392 switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) {
393 case AR_RAD5111_SREV_MAJOR:
394 case AR_RAD5112_SREV_MAJOR:
395 case AR_RAD2112_SREV_MAJOR:
396 case AR_RAD2111_SREV_MAJOR:
397 case AR_RAD2413_SREV_MAJOR:
398 case AR_RAD5413_SREV_MAJOR:
399 case AR_RAD5424_SREV_MAJOR:
400 break;
401 default:
402 if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) {
403 /*
404 * When RF_Silent is used, the
405 * analog chip is reset. So when the system boots
406 * up with the radio switch off we cannot determine
407 * the RF chip rev. To workaround this check the
408 * mac+phy revs and if Hainan, set the radio rev
409 * to Derby.
410 */
411 if (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_VENICE &&
412 AH_PRIVATE(ah)->ah_macRev == AR_SREV_HAINAN &&
413 AH_PRIVATE(ah)->ah_phyRev == AR_PHYREV_HAINAN) {
414 AH_PRIVATE(ah)->ah_analog5GhzRev = AR_ANALOG5REV_HAINAN;
415 break;
416 }
417 if (IS_2413(ah)) { /* Griffin */
418 AH_PRIVATE(ah)->ah_analog5GhzRev =
419 AR_RAD2413_SREV_MAJOR | 0x1;
420 break;
421 }
422 if (IS_5413(ah)) { /* Eagle */
423 AH_PRIVATE(ah)->ah_analog5GhzRev =
424 AR_RAD5413_SREV_MAJOR | 0x2;
425 break;
426 }
427 if (IS_2425(ah) || IS_2417(ah)) {/* Swan or Nala */
428 AH_PRIVATE(ah)->ah_analog5GhzRev =
429 AR_RAD5424_SREV_MAJOR | 0x2;
430 break;
431 }
432 }
433 #ifdef AH_DEBUG
434 HALDEBUG(ah, HAL_DEBUG_ANY,
435 "%s: 5G Radio Chip Rev 0x%02X is not supported by "
436 "this driver\n",
437 __func__, AH_PRIVATE(ah)->ah_analog5GhzRev);
438 ecode = HAL_ENOTSUPP;
439 goto bad;
440 #endif
441 }
442 if (IS_RAD5112_REV1(ah)) {
443 HALDEBUG(ah, HAL_DEBUG_ANY,
444 "%s: 5112 Rev 1 is not supported by this "
445 "driver (analog5GhzRev 0x%x)\n", __func__,
446 AH_PRIVATE(ah)->ah_analog5GhzRev);
447 ecode = HAL_ENOTSUPP;
448 goto bad;
449 }
450
451 val = OS_REG_READ(ah, AR_PCICFG);
452 val = MS(val, AR_PCICFG_EEPROM_SIZE);
453 if (val == 0) {
454 if (!AH_PRIVATE(ah)->ah_ispcie) {
455 HALDEBUG(ah, HAL_DEBUG_ANY,
456 "%s: unsupported EEPROM size %u (0x%x) found\n",
457 __func__, val, val);
458 ecode = HAL_EESIZE;
459 goto bad;
460 }
461 /* XXX AH_PRIVATE(ah)->ah_isPciExpress = AH_TRUE; */
462 } else if (val != AR_PCICFG_EEPROM_SIZE_16K) {
463 if (AR_PCICFG_EEPROM_SIZE_FAILED == val) {
464 HALDEBUG(ah, HAL_DEBUG_ANY,
465 "%s: unsupported EEPROM size %u (0x%x) found\n",
466 __func__, val, val);
467 ecode = HAL_EESIZE;
468 goto bad;
469 }
470 HALDEBUG(ah, HAL_DEBUG_ANY,
471 "%s: EEPROM size = %d. Must be %d (16k).\n",
472 __func__, val, AR_PCICFG_EEPROM_SIZE_16K);
473 ecode = HAL_EESIZE;
474 goto bad;
475 }
476 ecode = ath_hal_legacyEepromAttach(ah);
477 if (ecode != HAL_OK) {
478 goto bad;
479 }
480 ahp->ah_isHb63 = IS_2425(ah) && ath_hal_eepromGetFlag(ah, AR_EEP_ISTALON);
481
482 /*
483 * If Bmode and AR5212, verify 2.4 analog exists
484 */
485 if (ath_hal_eepromGetFlag(ah, AR_EEP_BMODE) &&
486 (AH_PRIVATE(ah)->ah_analog5GhzRev & 0xF0) == AR_RAD5111_SREV_MAJOR) {
487 /*
488 * Set correct Baseband to analog shift
489 * setting to access analog chips.
490 */
491 OS_REG_WRITE(ah, AR_PHY(0), 0x00004007);
492 OS_DELAY(2000);
493 AH_PRIVATE(ah)->ah_analog2GhzRev = ar5212GetRadioRev(ah);
494
495 /* Set baseband for 5GHz chip */
496 OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
497 OS_DELAY(2000);
498 if ((AH_PRIVATE(ah)->ah_analog2GhzRev & 0xF0) != AR_RAD2111_SREV_MAJOR) {
499 HALDEBUG(ah, HAL_DEBUG_ANY,
500 "%s: 2G Radio Chip Rev 0x%02X is not "
501 "supported by this driver\n", __func__,
502 AH_PRIVATE(ah)->ah_analog2GhzRev);
503 ecode = HAL_ENOTSUPP;
504 goto bad;
505 }
506 }
507
508 ecode = ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, &eeval);
509 if (ecode != HAL_OK) {
510 HALDEBUG(ah, HAL_DEBUG_ANY,
511 "%s: cannot read regulatory domain from EEPROM\n",
512 __func__);
513 goto bad;
514 }
515 AH_PRIVATE(ah)->ah_currentRD = eeval;
516 /* XXX record serial number */
517
518 /*
519 * Got everything we need now to setup the capabilities.
520 */
521 if (!ar5212FillCapabilityInfo(ah)) {
522 HALDEBUG(ah, HAL_DEBUG_ANY,
523 "%s: failed ar5212FillCapabilityInfo\n", __func__);
524 ecode = HAL_EEREAD;
525 goto bad;
526 }
527
528 if (!rf->attach(ah, &ecode)) {
529 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n",
530 __func__, ecode);
531 goto bad;
532 }
533 /*
534 * Set noise floor adjust method; we arrange a
535 * direct call instead of thunking.
536 */
537 AH_PRIVATE(ah)->ah_getNfAdjust = ahp->ah_rfHal->getNfAdjust;
538
539 /* Initialize gain ladder thermal calibration structure */
540 ar5212InitializeGainValues(ah);
541
542 ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr);
543 if (ecode != HAL_OK) {
544 HALDEBUG(ah, HAL_DEBUG_ANY,
545 "%s: error getting mac address from EEPROM\n", __func__);
546 goto bad;
547 }
548
549 ar5212AniSetup(ah);
550 /* Setup of Radar/AR structures happens in ath_hal_initchannels*/
551 ar5212InitNfCalHistBuffer(ah);
552
553 /* XXX EAR stuff goes here */
554
555 HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);
556
557 return ah;
558
559 bad:
560 if (ahp)
561 ar5212Detach((struct ath_hal *) ahp);
562 if (status)
563 *status = ecode;
564 return AH_NULL;
565 #undef AH_EEPROM_PROTECT
566 }
567
568 void
ar5212Detach(struct ath_hal * ah)569 ar5212Detach(struct ath_hal *ah)
570 {
571 HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s:\n", __func__);
572
573 HALASSERT(ah != AH_NULL);
574 HALASSERT(ah->ah_magic == AR5212_MAGIC);
575
576 ar5212AniDetach(ah);
577 ar5212RfDetach(ah);
578 ar5212Disable(ah);
579 ar5212SetPowerMode(ah, HAL_PM_FULL_SLEEP, AH_TRUE);
580
581 ath_hal_eepromDetach(ah);
582 ath_hal_free(ah);
583 }
584
585 HAL_BOOL
ar5212ChipTest(struct ath_hal * ah)586 ar5212ChipTest(struct ath_hal *ah)
587 {
588 uint32_t regAddr[2] = { AR_STA_ID0, AR_PHY_BASE+(8 << 2) };
589 uint32_t regHold[2];
590 uint32_t patternData[4] =
591 { 0x55555555, 0xaaaaaaaa, 0x66666666, 0x99999999 };
592 int i, j;
593
594 /* Test PHY & MAC registers */
595 for (i = 0; i < 2; i++) {
596 uint32_t addr = regAddr[i];
597 uint32_t wrData, rdData;
598
599 regHold[i] = OS_REG_READ(ah, addr);
600 for (j = 0; j < 0x100; j++) {
601 wrData = (j << 16) | j;
602 OS_REG_WRITE(ah, addr, wrData);
603 rdData = OS_REG_READ(ah, addr);
604 if (rdData != wrData) {
605 HALDEBUG(ah, HAL_DEBUG_ANY,
606 "%s: address test failed addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
607 __func__, addr, wrData, rdData);
608 return AH_FALSE;
609 }
610 }
611 for (j = 0; j < 4; j++) {
612 wrData = patternData[j];
613 OS_REG_WRITE(ah, addr, wrData);
614 rdData = OS_REG_READ(ah, addr);
615 if (wrData != rdData) {
616 HALDEBUG(ah, HAL_DEBUG_ANY,
617 "%s: address test failed addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
618 __func__, addr, wrData, rdData);
619 return AH_FALSE;
620 }
621 }
622 OS_REG_WRITE(ah, regAddr[i], regHold[i]);
623 }
624 OS_DELAY(100);
625 return AH_TRUE;
626 }
627
628 /*
629 * Store the channel edges for the requested operational mode
630 */
631 HAL_BOOL
ar5212GetChannelEdges(struct ath_hal * ah,uint16_t flags,uint16_t * low,uint16_t * high)632 ar5212GetChannelEdges(struct ath_hal *ah,
633 uint16_t flags, uint16_t *low, uint16_t *high)
634 {
635 if (flags & CHANNEL_5GHZ) {
636 *low = 4915;
637 *high = 6100;
638 return AH_TRUE;
639 }
640 if ((flags & CHANNEL_2GHZ) &&
641 (ath_hal_eepromGetFlag(ah, AR_EEP_BMODE) ||
642 ath_hal_eepromGetFlag(ah, AR_EEP_GMODE))) {
643 *low = 2312;
644 *high = 2732;
645 return AH_TRUE;
646 }
647 return AH_FALSE;
648 }
649
650 /*
651 * Disable PLL when in L0s as well as receiver clock when in L1.
652 * This power saving option must be enabled through the Serdes.
653 *
654 * Programming the Serdes must go through the same 288 bit serial shift
655 * register as the other analog registers. Hence the 9 writes.
656 *
657 * XXX Clean up the magic numbers.
658 */
659 static void
ar5212ConfigPCIE(struct ath_hal * ah,HAL_BOOL restore)660 ar5212ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore)
661 {
662 OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
663 OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
664
665 /* RX shut off when elecidle is asserted */
666 OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
667 OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
668 OS_REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
669
670 /* Shut off PLL and CLKREQ active in L1 */
671 OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
672 OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
673 OS_REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
674 OS_REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
675
676 /* Load the new settings */
677 OS_REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
678 }
679
680 static void
ar5212DisablePCIE(struct ath_hal * ah)681 ar5212DisablePCIE(struct ath_hal *ah)
682 {
683 /* NB: fill in for 9100 */
684 }
685
686 /*
687 * Fill all software cached or static hardware state information.
688 * Return failure if capabilities are to come from EEPROM and
689 * cannot be read.
690 */
691 HAL_BOOL
ar5212FillCapabilityInfo(struct ath_hal * ah)692 ar5212FillCapabilityInfo(struct ath_hal *ah)
693 {
694 #define AR_KEYTABLE_SIZE 128
695 #define IS_GRIFFIN_LITE(ah) \
696 (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_GRIFFIN && \
697 AH_PRIVATE(ah)->ah_macRev == AR_SREV_GRIFFIN_LITE)
698 #define IS_COBRA(ah) \
699 (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_COBRA)
700 #define IS_2112(ah) \
701 ((AH_PRIVATE(ah)->ah_analog5GhzRev & 0xF0) == AR_RAD2112_SREV_MAJOR)
702
703 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
704 HAL_CAPABILITIES *pCap = &ahpriv->ah_caps;
705 uint16_t capField, val;
706
707 /* Read the capability EEPROM location */
708 if (ath_hal_eepromGet(ah, AR_EEP_OPCAP, &capField) != HAL_OK) {
709 HALDEBUG(ah, HAL_DEBUG_ANY,
710 "%s: unable to read caps from eeprom\n", __func__);
711 return AH_FALSE;
712 }
713 if (IS_2112(ah))
714 ath_hal_eepromSet(ah, AR_EEP_AMODE, AH_FALSE);
715 if (capField == 0 && IS_GRIFFIN_LITE(ah)) {
716 /*
717 * For griffin-lite cards with unprogrammed capabilities.
718 */
719 ath_hal_eepromSet(ah, AR_EEP_COMPRESS, AH_FALSE);
720 ath_hal_eepromSet(ah, AR_EEP_FASTFRAME, AH_FALSE);
721 ath_hal_eepromSet(ah, AR_EEP_TURBO5DISABLE, AH_TRUE);
722 ath_hal_eepromSet(ah, AR_EEP_TURBO2DISABLE, AH_TRUE);
723 HALDEBUG(ah, HAL_DEBUG_ATTACH,
724 "%s: override caps for griffin-lite, now 0x%x (+!turbo)\n",
725 __func__, capField);
726 }
727
728 /* Modify reg domain on newer cards that need to work with older sw */
729 if (ahpriv->ah_opmode != HAL_M_HOSTAP &&
730 ahpriv->ah_subvendorid == AR_SUBVENDOR_ID_NEW_A) {
731 if (ahpriv->ah_currentRD == 0x64 ||
732 ahpriv->ah_currentRD == 0x65)
733 ahpriv->ah_currentRD += 5;
734 else if (ahpriv->ah_currentRD == 0x41)
735 ahpriv->ah_currentRD = 0x43;
736 HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: regdomain mapped to 0x%x\n",
737 __func__, ahpriv->ah_currentRD);
738 }
739
740 if (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_2417 ||
741 AH_PRIVATE(ah)->ah_macVersion == AR_SREV_2425) {
742 HALDEBUG(ah, HAL_DEBUG_ATTACH,
743 "%s: enable Bmode and disable turbo for Swan/Nala\n",
744 __func__);
745 ath_hal_eepromSet(ah, AR_EEP_BMODE, AH_TRUE);
746 ath_hal_eepromSet(ah, AR_EEP_COMPRESS, AH_FALSE);
747 ath_hal_eepromSet(ah, AR_EEP_FASTFRAME, AH_FALSE);
748 ath_hal_eepromSet(ah, AR_EEP_TURBO5DISABLE, AH_TRUE);
749 ath_hal_eepromSet(ah, AR_EEP_TURBO2DISABLE, AH_TRUE);
750 }
751
752 /* Construct wireless mode from EEPROM */
753 pCap->halWirelessModes = 0;
754 if (ath_hal_eepromGetFlag(ah, AR_EEP_AMODE)) {
755 pCap->halWirelessModes |= HAL_MODE_11A;
756 if (!ath_hal_eepromGetFlag(ah, AR_EEP_TURBO5DISABLE))
757 pCap->halWirelessModes |= HAL_MODE_TURBO;
758 }
759 if (ath_hal_eepromGetFlag(ah, AR_EEP_BMODE))
760 pCap->halWirelessModes |= HAL_MODE_11B;
761 if (ath_hal_eepromGetFlag(ah, AR_EEP_GMODE) &&
762 ahpriv->ah_subvendorid != AR_SUBVENDOR_ID_NOG) {
763 pCap->halWirelessModes |= HAL_MODE_11G;
764 if (!ath_hal_eepromGetFlag(ah, AR_EEP_TURBO2DISABLE))
765 pCap->halWirelessModes |= HAL_MODE_108G;
766 }
767
768 pCap->halLow2GhzChan = 2312;
769 /* XXX 2417 too? */
770 if (IS_RAD5112_ANY(ah) || IS_5413(ah) || IS_2425(ah) || IS_2417(ah))
771 pCap->halHigh2GhzChan = 2500;
772 else
773 pCap->halHigh2GhzChan = 2732;
774
775 pCap->halLow5GhzChan = 4915;
776 pCap->halHigh5GhzChan = 6100;
777
778 pCap->halCipherCkipSupport = AH_FALSE;
779 pCap->halCipherTkipSupport = AH_TRUE;
780 pCap->halCipherAesCcmSupport =
781 (ath_hal_eepromGetFlag(ah, AR_EEP_AES) &&
782 ((AH_PRIVATE(ah)->ah_macVersion > AR_SREV_VERSION_VENICE) ||
783 ((AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_VENICE) &&
784 (AH_PRIVATE(ah)->ah_macRev >= AR_SREV_VERSION_OAHU))));
785
786 pCap->halMicCkipSupport = AH_FALSE;
787 pCap->halMicTkipSupport = AH_TRUE;
788 pCap->halMicAesCcmSupport = ath_hal_eepromGetFlag(ah, AR_EEP_AES);
789 /*
790 * Starting with Griffin TX+RX mic keys can be combined
791 * in one key cache slot.
792 */
793 if (AH_PRIVATE(ah)->ah_macVersion >= AR_SREV_VERSION_GRIFFIN)
794 pCap->halTkipMicTxRxKeySupport = AH_TRUE;
795 else
796 pCap->halTkipMicTxRxKeySupport = AH_FALSE;
797 pCap->halChanSpreadSupport = AH_TRUE;
798 pCap->halSleepAfterBeaconBroken = AH_TRUE;
799
800 if (ahpriv->ah_macRev > 1 || IS_COBRA(ah)) {
801 pCap->halCompressSupport =
802 ath_hal_eepromGetFlag(ah, AR_EEP_COMPRESS) &&
803 (pCap->halWirelessModes & (HAL_MODE_11A|HAL_MODE_11G)) != 0;
804 pCap->halBurstSupport = ath_hal_eepromGetFlag(ah, AR_EEP_BURST);
805 pCap->halFastFramesSupport =
806 ath_hal_eepromGetFlag(ah, AR_EEP_FASTFRAME) &&
807 (pCap->halWirelessModes & (HAL_MODE_11A|HAL_MODE_11G)) != 0;
808 pCap->halChapTuningSupport = AH_TRUE;
809 pCap->halTurboPrimeSupport = AH_TRUE;
810 }
811 pCap->halTurboGSupport = pCap->halWirelessModes & HAL_MODE_108G;
812
813 pCap->halPSPollBroken = AH_TRUE; /* XXX fixed in later revs? */
814 pCap->halVEOLSupport = AH_TRUE;
815 pCap->halBssIdMaskSupport = AH_TRUE;
816 pCap->halMcastKeySrchSupport = AH_TRUE;
817 if ((ahpriv->ah_macVersion == AR_SREV_VERSION_VENICE &&
818 ahpriv->ah_macRev == 8) ||
819 ahpriv->ah_macVersion > AR_SREV_VERSION_VENICE)
820 pCap->halTsfAddSupport = AH_TRUE;
821
822 if (ath_hal_eepromGet(ah, AR_EEP_MAXQCU, &val) == HAL_OK)
823 pCap->halTotalQueues = val;
824 else
825 pCap->halTotalQueues = HAL_NUM_TX_QUEUES;
826
827 if (ath_hal_eepromGet(ah, AR_EEP_KCENTRIES, &val) == HAL_OK)
828 pCap->halKeyCacheSize = val;
829 else
830 pCap->halKeyCacheSize = AR_KEYTABLE_SIZE;
831
832 pCap->halChanHalfRate = AH_TRUE;
833 pCap->halChanQuarterRate = AH_TRUE;
834
835 if (ath_hal_eepromGetFlag(ah, AR_EEP_RFKILL) &&
836 ath_hal_eepromGet(ah, AR_EEP_RFSILENT, &ahpriv->ah_rfsilent) == HAL_OK) {
837 /* NB: enabled by default */
838 ahpriv->ah_rfkillEnabled = AH_TRUE;
839 pCap->halRfSilentSupport = AH_TRUE;
840 }
841
842 /* NB: this is a guess, noone seems to know the answer */
843 ahpriv->ah_rxornIsFatal =
844 (AH_PRIVATE(ah)->ah_macVersion < AR_SREV_VERSION_VENICE);
845
846 /* enable features that first appeared in Hainan */
847 if ((AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_VENICE &&
848 AH_PRIVATE(ah)->ah_macRev == AR_SREV_HAINAN) ||
849 AH_PRIVATE(ah)->ah_macVersion > AR_SREV_VERSION_VENICE) {
850 /* h/w phy counters */
851 pCap->halHwPhyCounterSupport = AH_TRUE;
852 /* bssid match disable */
853 pCap->halBssidMatchSupport = AH_TRUE;
854 }
855
856 pCap->halTstampPrecision = 15;
857 pCap->halIntrMask = HAL_INT_COMMON
858 | HAL_INT_RX
859 | HAL_INT_TX
860 | HAL_INT_FATAL
861 | HAL_INT_BNR
862 | HAL_INT_BMISC
863 ;
864
865 if (AH_PRIVATE(ah)->ah_macVersion < AR_SREV_VERSION_GRIFFIN)
866 pCap->halIntrMask &= ~HAL_INT_TBTT;
867
868 return AH_TRUE;
869 #undef IS_COBRA
870 #undef IS_GRIFFIN_LITE
871 #undef AR_KEYTABLE_SIZE
872 }
873
874 static const char*
ar5212Probe(uint16_t vendorid,uint16_t devid)875 ar5212Probe(uint16_t vendorid, uint16_t devid)
876 {
877 if (vendorid == ATHEROS_VENDOR_ID ||
878 vendorid == ATHEROS_3COM_VENDOR_ID ||
879 vendorid == ATHEROS_3COM2_VENDOR_ID) {
880 switch (devid) {
881 case AR5212_FPGA:
882 return "Atheros 5212 (FPGA)";
883 case AR5212_DEVID:
884 case AR5212_DEVID_IBM:
885 case AR5212_DEFAULT:
886 return "Atheros 5212";
887 case AR5212_AR2413:
888 return "Atheros 2413";
889 case AR5212_AR2417:
890 return "Atheros 2417";
891 case AR5212_AR5413:
892 return "Atheros 5413";
893 case AR5212_AR5424:
894 return "Atheros 5424/2424";
895 }
896 }
897 return AH_NULL;
898 }
899 AH_CHIP(AR5212, ar5212Probe, ar5212Attach);
900