1 | /* |
2 | * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting |
3 | * Copyright (c) 2002-2006 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: ar5211_attach.c,v 1.3 2011/03/07 11:25:42 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 "ar5211/ar5211.h" |
26 | #include "ar5211/ar5211reg.h" |
27 | #include "ar5211/ar5211phy.h" |
28 | |
29 | #include "ah_eeprom_v3.h" |
30 | |
31 | static HAL_BOOL ar5211GetChannelEdges(struct ath_hal *ah, |
32 | uint16_t flags, uint16_t *low, uint16_t *high); |
33 | static HAL_BOOL ar5211GetChipPowerLimits(struct ath_hal *ah, |
34 | HAL_CHANNEL *chans, uint32_t nchans); |
35 | |
36 | static void ar5211ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore); |
37 | static void ar5211DisablePCIE(struct ath_hal *ah); |
38 | |
39 | static const struct ath_hal_private ar5211hal = {{ |
40 | .ah_magic = AR5211_MAGIC, |
41 | .ah_abi = HAL_ABI_VERSION, |
42 | .ah_countryCode = CTRY_DEFAULT, |
43 | |
44 | .ah_getRateTable = ar5211GetRateTable, |
45 | .ah_detach = ar5211Detach, |
46 | |
47 | /* Reset Functions */ |
48 | .ah_reset = ar5211Reset, |
49 | .ah_phyDisable = ar5211PhyDisable, |
50 | .ah_disable = ar5211Disable, |
51 | .ah_configPCIE = ar5211ConfigPCIE, |
52 | .ah_disablePCIE = ar5211DisablePCIE, |
53 | .ah_setPCUConfig = ar5211SetPCUConfig, |
54 | .ah_perCalibration = ar5211PerCalibration, |
55 | .ah_perCalibrationN = ar5211PerCalibrationN, |
56 | .ah_resetCalValid = ar5211ResetCalValid, |
57 | .ah_setTxPowerLimit = ar5211SetTxPowerLimit, |
58 | .ah_getChanNoise = ath_hal_getChanNoise, |
59 | |
60 | /* Transmit functions */ |
61 | .ah_updateTxTrigLevel = ar5211UpdateTxTrigLevel, |
62 | .ah_setupTxQueue = ar5211SetupTxQueue, |
63 | .ah_setTxQueueProps = ar5211SetTxQueueProps, |
64 | .ah_getTxQueueProps = ar5211GetTxQueueProps, |
65 | .ah_releaseTxQueue = ar5211ReleaseTxQueue, |
66 | .ah_resetTxQueue = ar5211ResetTxQueue, |
67 | .ah_getTxDP = ar5211GetTxDP, |
68 | .ah_setTxDP = ar5211SetTxDP, |
69 | .ah_numTxPending = ar5211NumTxPending, |
70 | .ah_startTxDma = ar5211StartTxDma, |
71 | .ah_stopTxDma = ar5211StopTxDma, |
72 | .ah_setupTxDesc = ar5211SetupTxDesc, |
73 | .ah_setupXTxDesc = ar5211SetupXTxDesc, |
74 | .ah_fillTxDesc = ar5211FillTxDesc, |
75 | .ah_procTxDesc = ar5211ProcTxDesc, |
76 | .ah_getTxIntrQueue = ar5211GetTxIntrQueue, |
77 | .ah_reqTxIntrDesc = ar5211IntrReqTxDesc, |
78 | |
79 | /* RX Functions */ |
80 | .ah_getRxDP = ar5211GetRxDP, |
81 | .ah_setRxDP = ar5211SetRxDP, |
82 | .ah_enableReceive = ar5211EnableReceive, |
83 | .ah_stopDmaReceive = ar5211StopDmaReceive, |
84 | .ah_startPcuReceive = ar5211StartPcuReceive, |
85 | .ah_stopPcuReceive = ar5211StopPcuReceive, |
86 | .ah_setMulticastFilter = ar5211SetMulticastFilter, |
87 | .ah_setMulticastFilterIndex = ar5211SetMulticastFilterIndex, |
88 | .ah_clrMulticastFilterIndex = ar5211ClrMulticastFilterIndex, |
89 | .ah_getRxFilter = ar5211GetRxFilter, |
90 | .ah_setRxFilter = ar5211SetRxFilter, |
91 | .ah_setupRxDesc = ar5211SetupRxDesc, |
92 | .ah_procRxDesc = ar5211ProcRxDesc, |
93 | .ah_rxMonitor = ar5211AniPoll, |
94 | .ah_procMibEvent = ar5211MibEvent, |
95 | |
96 | /* Misc Functions */ |
97 | .ah_getCapability = ar5211GetCapability, |
98 | .ah_setCapability = ar5211SetCapability, |
99 | .ah_getDiagState = ar5211GetDiagState, |
100 | .ah_getMacAddress = ar5211GetMacAddress, |
101 | .ah_setMacAddress = ar5211SetMacAddress, |
102 | .ah_getBssIdMask = ar5211GetBssIdMask, |
103 | .ah_setBssIdMask = ar5211SetBssIdMask, |
104 | .ah_setRegulatoryDomain = ar5211SetRegulatoryDomain, |
105 | .ah_setLedState = ar5211SetLedState, |
106 | .ah_writeAssocid = ar5211WriteAssocid, |
107 | .ah_gpioCfgInput = ar5211GpioCfgInput, |
108 | .ah_gpioCfgOutput = ar5211GpioCfgOutput, |
109 | .ah_gpioGet = ar5211GpioGet, |
110 | .ah_gpioSet = ar5211GpioSet, |
111 | .ah_gpioSetIntr = ar5211GpioSetIntr, |
112 | .ah_getTsf32 = ar5211GetTsf32, |
113 | .ah_getTsf64 = ar5211GetTsf64, |
114 | .ah_resetTsf = ar5211ResetTsf, |
115 | .ah_detectCardPresent = ar5211DetectCardPresent, |
116 | .ah_updateMibCounters = ar5211UpdateMibCounters, |
117 | .ah_getRfGain = ar5211GetRfgain, |
118 | .ah_getDefAntenna = ar5211GetDefAntenna, |
119 | .ah_setDefAntenna = ar5211SetDefAntenna, |
120 | .ah_getAntennaSwitch = ar5211GetAntennaSwitch, |
121 | .ah_setAntennaSwitch = ar5211SetAntennaSwitch, |
122 | .ah_setSifsTime = ar5211SetSifsTime, |
123 | .ah_getSifsTime = ar5211GetSifsTime, |
124 | .ah_setSlotTime = ar5211SetSlotTime, |
125 | .ah_getSlotTime = ar5211GetSlotTime, |
126 | .ah_setAckTimeout = ar5211SetAckTimeout, |
127 | .ah_getAckTimeout = ar5211GetAckTimeout, |
128 | .ah_setAckCTSRate = ar5211SetAckCTSRate, |
129 | .ah_getAckCTSRate = ar5211GetAckCTSRate, |
130 | .ah_setCTSTimeout = ar5211SetCTSTimeout, |
131 | .ah_getCTSTimeout = ar5211GetCTSTimeout, |
132 | .ah_setDecompMask = ar5211SetDecompMask, |
133 | .ah_setCoverageClass = ar5211SetCoverageClass, |
134 | |
135 | /* Key Cache Functions */ |
136 | .ah_getKeyCacheSize = ar5211GetKeyCacheSize, |
137 | .ah_resetKeyCacheEntry = ar5211ResetKeyCacheEntry, |
138 | .ah_isKeyCacheEntryValid = ar5211IsKeyCacheEntryValid, |
139 | .ah_setKeyCacheEntry = ar5211SetKeyCacheEntry, |
140 | .ah_setKeyCacheEntryMac = ar5211SetKeyCacheEntryMac, |
141 | |
142 | /* Power Management Functions */ |
143 | .ah_setPowerMode = ar5211SetPowerMode, |
144 | .ah_getPowerMode = ar5211GetPowerMode, |
145 | |
146 | /* Beacon Functions */ |
147 | .ah_setBeaconTimers = ar5211SetBeaconTimers, |
148 | .ah_beaconInit = ar5211BeaconInit, |
149 | .ah_setStationBeaconTimers = ar5211SetStaBeaconTimers, |
150 | .ah_resetStationBeaconTimers = ar5211ResetStaBeaconTimers, |
151 | |
152 | /* Interrupt Functions */ |
153 | .ah_isInterruptPending = ar5211IsInterruptPending, |
154 | .ah_getPendingInterrupts = ar5211GetPendingInterrupts, |
155 | .ah_getInterrupts = ar5211GetInterrupts, |
156 | .ah_setInterrupts = ar5211SetInterrupts }, |
157 | |
158 | .ah_getChannelEdges = ar5211GetChannelEdges, |
159 | .ah_getWirelessModes = ar5211GetWirelessModes, |
160 | .ah_eepromRead = ar5211EepromRead, |
161 | #ifdef AH_SUPPORT_WRITE_EEPROM |
162 | .ah_eepromWrite = ar5211EepromWrite, |
163 | #endif |
164 | .ah_gpioCfgInput = ar5211GpioCfgInput, |
165 | .ah_gpioCfgOutput = ar5211GpioCfgOutput, |
166 | .ah_gpioGet = ar5211GpioGet, |
167 | .ah_gpioSet = ar5211GpioSet, |
168 | .ah_gpioSetIntr = ar5211GpioSetIntr, |
169 | .ah_getChipPowerLimits = ar5211GetChipPowerLimits, |
170 | }; |
171 | |
172 | static HAL_BOOL ar5211ChipTest(struct ath_hal *); |
173 | static HAL_BOOL ar5211FillCapabilityInfo(struct ath_hal *ah); |
174 | |
175 | /* |
176 | * Return the revsion id for the radio chip. This |
177 | * fetched via the PHY. |
178 | */ |
179 | static uint32_t |
180 | ar5211GetRadioRev(struct ath_hal *ah) |
181 | { |
182 | uint32_t val; |
183 | int i; |
184 | |
185 | OS_REG_WRITE(ah, (AR_PHY_BASE + (0x34 << 2)), 0x00001c16); |
186 | for (i = 0; i < 8; i++) |
187 | OS_REG_WRITE(ah, (AR_PHY_BASE + (0x20 << 2)), 0x00010000); |
188 | val = (OS_REG_READ(ah, AR_PHY_BASE + (256 << 2)) >> 24) & 0xff; |
189 | val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4); |
190 | return ath_hal_reverseBits(val, 8); |
191 | } |
192 | |
193 | /* |
194 | * Attach for an AR5211 part. |
195 | */ |
196 | struct ath_hal * |
197 | ar5211Attach(uint16_t devid, HAL_SOFTC sc, |
198 | HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status) |
199 | { |
200 | #define N(a) (sizeof(a)/sizeof(a[0])) |
201 | struct ath_hal_5211 *ahp; |
202 | struct ath_hal *ah; |
203 | uint32_t val; |
204 | uint16_t eeval; |
205 | HAL_STATUS ecode; |
206 | |
207 | HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n" , |
208 | __func__, sc, (void*) st, (void*) sh); |
209 | |
210 | /* NB: memory is returned zero'd */ |
211 | ahp = ath_hal_malloc(sizeof (struct ath_hal_5211)); |
212 | if (ahp == AH_NULL) { |
213 | HALDEBUG(AH_NULL, HAL_DEBUG_ANY, |
214 | "%s: cannot allocate memory for state block\n" , __func__); |
215 | ecode = HAL_ENOMEM; |
216 | goto bad; |
217 | } |
218 | ah = &ahp->ah_priv.h; |
219 | /* set initial values */ |
220 | OS_MEMCPY(&ahp->ah_priv, &ar5211hal, sizeof(struct ath_hal_private)); |
221 | ah->ah_sc = sc; |
222 | ah->ah_st = st; |
223 | ah->ah_sh = sh; |
224 | |
225 | ah->ah_devid = devid; /* NB: for AH_DEBUG_ALQ */ |
226 | AH_PRIVATE(ah)->ah_devid = devid; |
227 | AH_PRIVATE(ah)->ah_subvendorid = 0; /* XXX */ |
228 | |
229 | AH_PRIVATE(ah)->ah_powerLimit = MAX_RATE_POWER; |
230 | AH_PRIVATE(ah)->ah_tpScale = HAL_TP_SCALE_MAX; /* no scaling */ |
231 | |
232 | ahp->ah_diversityControl = HAL_ANT_VARIABLE; |
233 | ahp->ah_staId1Defaults = 0; |
234 | ahp->ah_rssiThr = INIT_RSSI_THR; |
235 | ahp->ah_sifstime = (u_int) -1; |
236 | ahp->ah_slottime = (u_int) -1; |
237 | ahp->ah_acktimeout = (u_int) -1; |
238 | ahp->ah_ctstimeout = (u_int) -1; |
239 | |
240 | if (!ar5211ChipReset(ah, AH_FALSE)) { /* reset chip */ |
241 | HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n" , __func__); |
242 | ecode = HAL_EIO; |
243 | goto bad; |
244 | } |
245 | if (AH_PRIVATE(ah)->ah_devid == AR5211_FPGA11B) { |
246 | /* set it back to OFDM mode to be able to read analog rev id */ |
247 | OS_REG_WRITE(ah, AR5211_PHY_MODE, AR5211_PHY_MODE_OFDM); |
248 | OS_REG_WRITE(ah, AR_PHY_PLL_CTL, AR_PHY_PLL_CTL_44); |
249 | OS_DELAY(1000); |
250 | } |
251 | |
252 | /* Read Revisions from Chips */ |
253 | val = OS_REG_READ(ah, AR_SREV) & AR_SREV_ID_M; |
254 | AH_PRIVATE(ah)->ah_macVersion = val >> AR_SREV_ID_S; |
255 | AH_PRIVATE(ah)->ah_macRev = val & AR_SREV_REVISION_M; |
256 | |
257 | if (AH_PRIVATE(ah)->ah_macVersion < AR_SREV_VERSION_MAUI_2 || |
258 | AH_PRIVATE(ah)->ah_macVersion > AR_SREV_VERSION_OAHU) { |
259 | HALDEBUG(ah, HAL_DEBUG_ANY, |
260 | "%s: Mac Chip Rev 0x%x is not supported by this driver\n" , |
261 | __func__, AH_PRIVATE(ah)->ah_macVersion); |
262 | ecode = HAL_ENOTSUPP; |
263 | goto bad; |
264 | } |
265 | |
266 | AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID); |
267 | |
268 | if (!ar5211ChipTest(ah)) { |
269 | HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n" , |
270 | __func__); |
271 | ecode = HAL_ESELFTEST; |
272 | goto bad; |
273 | } |
274 | |
275 | /* Set correct Baseband to analog shift setting to access analog chips. */ |
276 | if (AH_PRIVATE(ah)->ah_macVersion >= AR_SREV_VERSION_OAHU) { |
277 | OS_REG_WRITE(ah, AR_PHY_BASE, 0x00000007); |
278 | } else { |
279 | OS_REG_WRITE(ah, AR_PHY_BASE, 0x00000047); |
280 | } |
281 | OS_DELAY(2000); |
282 | |
283 | /* Read Radio Chip Rev Extract */ |
284 | AH_PRIVATE(ah)->ah_analog5GhzRev = ar5211GetRadioRev(ah); |
285 | if ((AH_PRIVATE(ah)->ah_analog5GhzRev & 0xf0) != RAD5_SREV_MAJOR) { |
286 | HALDEBUG(ah, HAL_DEBUG_ANY, |
287 | "%s: 5G Radio Chip Rev 0x%02X is not supported by this " |
288 | "driver\n" , __func__, AH_PRIVATE(ah)->ah_analog5GhzRev); |
289 | ecode = HAL_ENOTSUPP; |
290 | goto bad; |
291 | } |
292 | |
293 | val = (OS_REG_READ(ah, AR_PCICFG) & AR_PCICFG_EEPROM_SIZE_M) >> |
294 | AR_PCICFG_EEPROM_SIZE_S; |
295 | if (val != AR_PCICFG_EEPROM_SIZE_16K) { |
296 | HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unsupported EEPROM size " |
297 | "%u (0x%x) found\n" , __func__, val, val); |
298 | ecode = HAL_EESIZE; |
299 | goto bad; |
300 | } |
301 | ecode = ath_hal_legacyEepromAttach(ah); |
302 | if (ecode != HAL_OK) { |
303 | goto bad; |
304 | } |
305 | |
306 | /* If Bmode and AR5211, verify 2.4 analog exists */ |
307 | if (AH_PRIVATE(ah)->ah_macVersion >= AR_SREV_VERSION_OAHU && |
308 | ath_hal_eepromGetFlag(ah, AR_EEP_BMODE)) { |
309 | /* Set correct Baseband to analog shift setting to access analog chips. */ |
310 | OS_REG_WRITE(ah, AR_PHY_BASE, 0x00004007); |
311 | OS_DELAY(2000); |
312 | AH_PRIVATE(ah)->ah_analog2GhzRev = ar5211GetRadioRev(ah); |
313 | |
314 | /* Set baseband for 5GHz chip */ |
315 | OS_REG_WRITE(ah, AR_PHY_BASE, 0x00000007); |
316 | OS_DELAY(2000); |
317 | if ((AH_PRIVATE(ah)->ah_analog2GhzRev & 0xF0) != RAD2_SREV_MAJOR) { |
318 | HALDEBUG(ah, HAL_DEBUG_ANY, |
319 | "%s: 2G Radio Chip Rev 0x%x is not supported by " |
320 | "this driver\n" , __func__, |
321 | AH_PRIVATE(ah)->ah_analog2GhzRev); |
322 | ecode = HAL_ENOTSUPP; |
323 | goto bad; |
324 | } |
325 | } else { |
326 | ath_hal_eepromSet(ah, AR_EEP_BMODE, AH_FALSE); |
327 | } |
328 | |
329 | ecode = ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, &eeval); |
330 | if (ecode != HAL_OK) { |
331 | HALDEBUG(ah, HAL_DEBUG_ANY, |
332 | "%s: cannot read regulatory domain from EEPROM\n" , |
333 | __func__); |
334 | goto bad; |
335 | } |
336 | AH_PRIVATE(ah)->ah_currentRD = eeval; |
337 | AH_PRIVATE(ah)->ah_getNfAdjust = ar5211GetNfAdjust; |
338 | |
339 | /* |
340 | * Got everything we need now to setup the capabilities. |
341 | */ |
342 | (void) ar5211FillCapabilityInfo(ah); |
343 | |
344 | /* Initialize gain ladder thermal calibration structure */ |
345 | ar5211InitializeGainValues(ah); |
346 | |
347 | ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr); |
348 | if (ecode != HAL_OK) { |
349 | HALDEBUG(ah, HAL_DEBUG_ANY, |
350 | "%s: error getting mac address from EEPROM\n" , __func__); |
351 | goto bad; |
352 | } |
353 | |
354 | HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n" , __func__); |
355 | |
356 | return ah; |
357 | bad: |
358 | if (ahp) |
359 | ar5211Detach((struct ath_hal *) ahp); |
360 | if (status) |
361 | *status = ecode; |
362 | return AH_NULL; |
363 | #undef N |
364 | } |
365 | |
366 | void |
367 | ar5211Detach(struct ath_hal *ah) |
368 | { |
369 | HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s:\n" , __func__); |
370 | |
371 | HALASSERT(ah != AH_NULL); |
372 | HALASSERT(ah->ah_magic == AR5211_MAGIC); |
373 | |
374 | ath_hal_eepromDetach(ah); |
375 | ath_hal_free(ah); |
376 | } |
377 | |
378 | static HAL_BOOL |
379 | ar5211ChipTest(struct ath_hal *ah) |
380 | { |
381 | uint32_t regAddr[2] = { AR_STA_ID0, AR_PHY_BASE+(8 << 2) }; |
382 | uint32_t regHold[2]; |
383 | uint32_t patternData[4] = |
384 | { 0x55555555, 0xaaaaaaaa, 0x66666666, 0x99999999 }; |
385 | int i, j; |
386 | |
387 | /* Test PHY & MAC registers */ |
388 | for (i = 0; i < 2; i++) { |
389 | uint32_t addr = regAddr[i]; |
390 | uint32_t wrData, rdData; |
391 | |
392 | regHold[i] = OS_REG_READ(ah, addr); |
393 | for (j = 0; j < 0x100; j++) { |
394 | wrData = (j << 16) | j; |
395 | OS_REG_WRITE(ah, addr, wrData); |
396 | rdData = OS_REG_READ(ah, addr); |
397 | if (rdData != wrData) { |
398 | HALDEBUG(ah, HAL_DEBUG_ANY, |
399 | "%s: address test failed addr: 0x%08x - wr:0x%08x != rd:0x%08x\n" , |
400 | __func__, addr, wrData, rdData); |
401 | return AH_FALSE; |
402 | } |
403 | } |
404 | for (j = 0; j < 4; j++) { |
405 | wrData = patternData[j]; |
406 | OS_REG_WRITE(ah, addr, wrData); |
407 | rdData = OS_REG_READ(ah, addr); |
408 | if (wrData != rdData) { |
409 | HALDEBUG(ah, HAL_DEBUG_ANY, |
410 | "%s: address test failed addr: 0x%08x - wr:0x%08x != rd:0x%08x\n" , |
411 | __func__, addr, wrData, rdData); |
412 | return AH_FALSE; |
413 | } |
414 | } |
415 | OS_REG_WRITE(ah, regAddr[i], regHold[i]); |
416 | } |
417 | OS_DELAY(100); |
418 | return AH_TRUE; |
419 | } |
420 | |
421 | /* |
422 | * Store the channel edges for the requested operational mode |
423 | */ |
424 | static HAL_BOOL |
425 | ar5211GetChannelEdges(struct ath_hal *ah, |
426 | uint16_t flags, uint16_t *low, uint16_t *high) |
427 | { |
428 | if (flags & CHANNEL_5GHZ) { |
429 | *low = 4920; |
430 | *high = 6100; |
431 | return AH_TRUE; |
432 | } |
433 | if (flags & CHANNEL_2GHZ && ath_hal_eepromGetFlag(ah, AR_EEP_BMODE)) { |
434 | *low = 2312; |
435 | *high = 2732; |
436 | return AH_TRUE; |
437 | } |
438 | return AH_FALSE; |
439 | } |
440 | |
441 | static HAL_BOOL |
442 | ar5211GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, uint32_t nchans) |
443 | { |
444 | HAL_CHANNEL *chan; |
445 | int i; |
446 | |
447 | /* XXX fill in, this is just a placeholder */ |
448 | for (i = 0; i < nchans; i++) { |
449 | chan = &chans[i]; |
450 | HALDEBUG(ah, HAL_DEBUG_ATTACH, |
451 | "%s: no min/max power for %u/0x%x\n" , |
452 | __func__, chan->channel, chan->channelFlags); |
453 | chan->maxTxPower = MAX_RATE_POWER; |
454 | chan->minTxPower = 0; |
455 | } |
456 | return AH_TRUE; |
457 | } |
458 | |
459 | static void |
460 | ar5211ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore) |
461 | { |
462 | } |
463 | |
464 | static void |
465 | ar5211DisablePCIE(struct ath_hal *ah) |
466 | { |
467 | } |
468 | |
469 | /* |
470 | * Fill all software cached or static hardware state information. |
471 | */ |
472 | static HAL_BOOL |
473 | ar5211FillCapabilityInfo(struct ath_hal *ah) |
474 | { |
475 | struct ath_hal_private *ahpriv = AH_PRIVATE(ah); |
476 | HAL_CAPABILITIES *pCap = &ahpriv->ah_caps; |
477 | |
478 | /* Construct wireless mode from EEPROM */ |
479 | pCap->halWirelessModes = 0; |
480 | if (ath_hal_eepromGetFlag(ah, AR_EEP_AMODE)) { |
481 | pCap->halWirelessModes |= HAL_MODE_11A; |
482 | if (!ath_hal_eepromGetFlag(ah, AR_EEP_TURBO5DISABLE)) |
483 | pCap->halWirelessModes |= HAL_MODE_TURBO; |
484 | } |
485 | if (ath_hal_eepromGetFlag(ah, AR_EEP_BMODE)) |
486 | pCap->halWirelessModes |= HAL_MODE_11B; |
487 | |
488 | pCap->halLow2GhzChan = 2312; |
489 | pCap->halHigh2GhzChan = 2732; |
490 | pCap->halLow5GhzChan = 4920; |
491 | pCap->halHigh5GhzChan = 6100; |
492 | |
493 | pCap->halChanSpreadSupport = AH_TRUE; |
494 | pCap->halSleepAfterBeaconBroken = AH_TRUE; |
495 | pCap->halPSPollBroken = AH_TRUE; |
496 | pCap->halVEOLSupport = AH_TRUE; |
497 | |
498 | pCap->halTotalQueues = HAL_NUM_TX_QUEUES; |
499 | pCap->halKeyCacheSize = 128; |
500 | |
501 | /* XXX not needed */ |
502 | pCap->halChanHalfRate = AH_FALSE; |
503 | pCap->halChanQuarterRate = AH_FALSE; |
504 | |
505 | if (ath_hal_eepromGetFlag(ah, AR_EEP_RFKILL) && |
506 | ath_hal_eepromGet(ah, AR_EEP_RFSILENT, &ahpriv->ah_rfsilent) == HAL_OK) { |
507 | /* NB: enabled by default */ |
508 | ahpriv->ah_rfkillEnabled = AH_TRUE; |
509 | pCap->halRfSilentSupport = AH_TRUE; |
510 | } |
511 | |
512 | pCap->halTstampPrecision = 13; |
513 | pCap->halIntrMask = HAL_INT_COMMON |
514 | | HAL_INT_RX |
515 | | HAL_INT_TX |
516 | | HAL_INT_FATAL |
517 | | HAL_INT_BNR |
518 | | HAL_INT_TIM |
519 | ; |
520 | |
521 | /* XXX might be ok w/ some chip revs */ |
522 | ahpriv->ah_rxornIsFatal = AH_TRUE; |
523 | return AH_TRUE; |
524 | } |
525 | |
526 | static const char* |
527 | ar5211Probe(uint16_t vendorid, uint16_t devid) |
528 | { |
529 | if (vendorid == ATHEROS_VENDOR_ID) { |
530 | if (devid == AR5211_DEVID || devid == AR5311_DEVID || |
531 | devid == AR5211_DEFAULT) |
532 | return "Atheros 5211" ; |
533 | if (devid == AR5211_FPGA11B) |
534 | return "Atheros 5211 (FPGA)" ; |
535 | } |
536 | return AH_NULL; |
537 | } |
538 | AH_CHIP(AR5211, ar5211Probe, ar5211Attach); |
539 | |