2 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
3 * Copyright (c) 2002-2008 Atheros Communications, Inc.
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.
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.
17 * $Id: ar5312_attach.c,v 1.2 2008/12/11 05:30:29 alc Exp $
22 #include "ah_internal.h"
25 #include "ar5312/ar5312.h"
26 #include "ar5312/ar5312reg.h"
27 #include "ar5312/ar5312phy.h"
29 /* Add static register initialization vectors */
30 #define AH_5212_COMMON
31 #include "ar5212/ar5212.ini"
33 static HAL_BOOL
ar5312GetMacAddr(struct ath_hal
*ah
);
36 ar5312AniSetup(struct ath_hal
*ah
)
38 static const struct ar5212AniParams aniparams
= {
39 .maxNoiseImmunityLevel
= 4, /* levels 0..4 */
40 .totalSizeDesired
= { -41, -41, -48, -48, -48 },
41 .coarseHigh
= { -18, -18, -16, -14, -12 },
42 .coarseLow
= { -56, -56, -60, -60, -60 },
43 .firpwr
= { -72, -72, -75, -78, -80 },
44 .maxSpurImmunityLevel
= 2,
45 .cycPwrThr1
= { 2, 4, 6 },
46 .maxFirstepLevel
= 2, /* levels 0..2 */
47 .firstep
= { 0, 4, 8 },
56 ar5212AniAttach(ah
, &aniparams
, &aniparams
, AH_TRUE
);
60 * Attach for an AR5312 part.
62 static struct ath_hal
*
63 ar5312Attach(uint16_t devid
, HAL_SOFTC sc
,
64 HAL_BUS_TAG st
, HAL_BUS_HANDLE sh
, HAL_STATUS
*status
)
66 struct ath_hal_5212
*ahp
= AH_NULL
;
68 struct ath_hal_rf
*rf
;
73 HALDEBUG(AH_NULL
, HAL_DEBUG_ATTACH
, "%s: sc %p st %p sh %p\n",
74 __func__
, sc
, st
, (void*) sh
);
76 /* NB: memory is returned zero'd */
77 ahp
= ath_hal_malloc(sizeof (struct ath_hal_5212
));
79 HALDEBUG(AH_NULL
, HAL_DEBUG_ANY
,
80 "%s: cannot allocate memory for state block\n", __func__
);
84 ar5212InitState(ahp
, devid
, sc
, st
, sh
, status
);
87 /* override 5212 methods for our needs */
88 ah
->ah_reset
= ar5312Reset
;
89 ah
->ah_phyDisable
= ar5312PhyDisable
;
90 ah
->ah_setLedState
= ar5312SetLedState
;
91 ah
->ah_detectCardPresent
= ar5312DetectCardPresent
;
92 ah
->ah_setPowerMode
= ar5312SetPowerMode
;
93 ah
->ah_getPowerMode
= ar5312GetPowerMode
;
94 ah
->ah_isInterruptPending
= ar5312IsInterruptPending
;
96 ahp
->ah_priv
.ah_eepromRead
= ar5312EepromRead
;
97 #ifdef AH_SUPPORT_WRITE_EEPROM
98 ahp
->ah_priv
.ah_eepromWrite
= ar5312EepromWrite
;
100 #if ( AH_SUPPORT_2316 || AH_SUPPORT_2317)
102 ahp
->ah_priv
.ah_gpioCfgOutput
= ar5315GpioCfgOutput
;
103 ahp
->ah_priv
.ah_gpioCfgInput
= ar5315GpioCfgInput
;
104 ahp
->ah_priv
.ah_gpioGet
= ar5315GpioGet
;
105 ahp
->ah_priv
.ah_gpioSet
= ar5315GpioSet
;
106 ahp
->ah_priv
.ah_gpioSetIntr
= ar5315GpioSetIntr
;
110 ahp
->ah_priv
.ah_gpioCfgOutput
= ar5312GpioCfgOutput
;
111 ahp
->ah_priv
.ah_gpioCfgInput
= ar5312GpioCfgInput
;
112 ahp
->ah_priv
.ah_gpioGet
= ar5312GpioGet
;
113 ahp
->ah_priv
.ah_gpioSet
= ar5312GpioSet
;
114 ahp
->ah_priv
.ah_gpioSetIntr
= ar5312GpioSetIntr
;
117 ah
->ah_gpioCfgInput
= ahp
->ah_priv
.ah_gpioCfgInput
;
118 ah
->ah_gpioCfgOutput
= ahp
->ah_priv
.ah_gpioCfgOutput
;
119 ah
->ah_gpioGet
= ahp
->ah_priv
.ah_gpioGet
;
120 ah
->ah_gpioSet
= ahp
->ah_priv
.ah_gpioSet
;
121 ah
->ah_gpioSetIntr
= ahp
->ah_priv
.ah_gpioSetIntr
;
123 /* setup common ini data; rf backends handle remainder */
124 HAL_INI_INIT(&ahp
->ah_ini_modes
, ar5212Modes
, 6);
125 HAL_INI_INIT(&ahp
->ah_ini_common
, ar5212Common
, 6);
127 if (!ar5312ChipReset(ah
, AH_NULL
)) { /* reset chip */
128 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: chip reset failed\n", __func__
);
133 #if ( AH_SUPPORT_2316 || AH_SUPPORT_2317)
134 if ((devid
== AR5212_AR2315_REV6
) ||
135 (devid
== AR5212_AR2315_REV7
) ||
136 (devid
== AR5212_AR2317_REV1
) ||
137 (devid
== AR5212_AR2317_REV2
) ) {
138 val
= ((OS_REG_READ(ah
, (AR5315_RSTIMER_BASE
-((uint32_t) sh
)) + AR5315_WREV
)) >> AR5315_WREV_S
)
140 AH_PRIVATE(ah
)->ah_macVersion
= val
>> AR5315_WREV_ID_S
;
141 AH_PRIVATE(ah
)->ah_macRev
= val
& AR5315_WREV_REVISION
;
142 HALDEBUG(ah
, HAL_DEBUG_ATTACH
,
143 "%s: Mac Chip Rev 0x%02x.%x\n" , __func__
,
144 AH_PRIVATE(ah
)->ah_macVersion
, AH_PRIVATE(ah
)->ah_macRev
);
148 val
= OS_REG_READ(ah
, (AR5312_RSTIMER_BASE
- ((uint32_t) sh
)) + 0x0020);
149 val
= OS_REG_READ(ah
, (AR5312_RSTIMER_BASE
- ((uint32_t) sh
)) + 0x0080);
150 /* Read Revisions from Chips */
151 val
= ((OS_REG_READ(ah
, (AR5312_RSTIMER_BASE
- ((uint32_t) sh
)) + AR5312_WREV
)) >> AR5312_WREV_S
) & AR5312_WREV_ID
;
152 AH_PRIVATE(ah
)->ah_macVersion
= val
>> AR5312_WREV_ID_S
;
153 AH_PRIVATE(ah
)->ah_macRev
= val
& AR5312_WREV_REVISION
;
155 /* XXX - THIS IS WRONG. NEEDS TO BE FIXED */
156 if (((AH_PRIVATE(ah
)->ah_macVersion
!= AR_SREV_VERSION_VENICE
&&
157 AH_PRIVATE(ah
)->ah_macVersion
!= AR_SREV_VERSION_VENICE
) ||
158 AH_PRIVATE(ah
)->ah_macRev
< AR_SREV_D2PLUS
) &&
159 AH_PRIVATE(ah
)->ah_macVersion
!= AR_SREV_VERSION_COBRA
) {
161 ath_hal_printf(ah
, "%s: Mac Chip Rev 0x%02x.%x is not supported by "
162 "this driver\n", __func__
,
163 AH_PRIVATE(ah
)->ah_macVersion
,
164 AH_PRIVATE(ah
)->ah_macRev
);
166 ecode
= HAL_ENOTSUPP
;
170 AH_PRIVATE(ah
)->ah_phyRev
= OS_REG_READ(ah
, AR_PHY_CHIP_ID
);
172 if (!ar5212ChipTest(ah
)) {
173 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: hardware self-test failed\n",
175 ecode
= HAL_ESELFTEST
;
180 * Set correct Baseband to analog shift
181 * setting to access analog chips.
183 OS_REG_WRITE(ah
, AR_PHY(0), 0x00000007);
185 /* Read Radio Chip Rev Extract */
186 AH_PRIVATE(ah
)->ah_analog5GhzRev
= ar5212GetRadioRev(ah
);
188 rf
= ath_hal_rfprobe(ah
, &ecode
);
191 if (IS_RAD5112(ah
) && !IS_RADX112_REV2(ah
)) {
193 ath_hal_printf(ah
, "%s: 5112 Rev 1 is not supported by this "
194 "driver (analog5GhzRev 0x%x)\n", __func__
,
195 AH_PRIVATE(ah
)->ah_analog5GhzRev
);
197 ecode
= HAL_ENOTSUPP
;
201 ecode
= ath_hal_legacyEepromAttach(ah
);
202 if (ecode
!= HAL_OK
) {
207 * If Bmode and AR5212, verify 2.4 analog exists
209 if (ath_hal_eepromGetFlag(ah
, AR_EEP_BMODE
) &&
210 (AH_PRIVATE(ah
)->ah_analog5GhzRev
& 0xF0) == AR_RAD5111_SREV_MAJOR
) {
212 * Set correct Baseband to analog shift
213 * setting to access analog chips.
215 OS_REG_WRITE(ah
, AR_PHY(0), 0x00004007);
217 AH_PRIVATE(ah
)->ah_analog2GhzRev
= ar5212GetRadioRev(ah
);
219 /* Set baseband for 5GHz chip */
220 OS_REG_WRITE(ah
, AR_PHY(0), 0x00000007);
222 if ((AH_PRIVATE(ah
)->ah_analog2GhzRev
& 0xF0) != AR_RAD2111_SREV_MAJOR
) {
224 ath_hal_printf(ah
, "%s: 2G Radio Chip Rev 0x%02X is not "
225 "supported by this driver\n", __func__
,
226 AH_PRIVATE(ah
)->ah_analog2GhzRev
);
228 ecode
= HAL_ENOTSUPP
;
233 ecode
= ath_hal_eepromGet(ah
, AR_EEP_REGDMN_0
, &eeval
);
234 if (ecode
!= HAL_OK
) {
235 HALDEBUG(ah
, HAL_DEBUG_ANY
,
236 "%s: cannot read regulatory domain from EEPROM\n",
240 AH_PRIVATE(ah
)->ah_currentRD
= eeval
;
241 /* XXX record serial number */
243 /* XXX other capabilities */
245 * Got everything we need now to setup the capabilities.
247 if (!ar5212FillCapabilityInfo(ah
)) {
248 HALDEBUG(ah
, HAL_DEBUG_ANY
,
249 "%s: failed ar5212FillCapabilityInfo\n", __func__
);
254 if (!rf
->attach(ah
, &ecode
)) {
255 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: RF setup failed, status %u\n",
259 /* arrange a direct call instead of thunking */
260 AH_PRIVATE(ah
)->ah_getNfAdjust
= ahp
->ah_rfHal
->getNfAdjust
;
262 /* Initialize gain ladder thermal calibration structure */
263 ar5212InitializeGainValues(ah
);
265 /* BSP specific call for MAC address of this WMAC device */
266 if (!ar5312GetMacAddr(ah
)) {
267 ecode
= HAL_EEBADMAC
;
272 ar5212InitNfCalHistBuffer(ah
);
274 /* XXX EAR stuff goes here */
279 ar5212Detach((struct ath_hal
*) ahp
);
286 ar5312GetMacAddr(struct ath_hal
*ah
)
288 const struct ar531x_boarddata
*board
= AR5312_BOARDCONFIG(ah
);
289 int wlanNum
= AR5312_UNIT(ah
);
290 const uint8_t *macAddr
;
294 macAddr
= board
->wlan0Mac
;
297 macAddr
= board
->wlan1Mac
;
301 ath_hal_printf(ah
, "Invalid WLAN wmac index (%d)\n",
306 OS_MEMCPY(AH5212(ah
)->ah_macaddr
, macAddr
, 6);
311 ar5312Probe(uint16_t vendorid
, uint16_t devid
)
313 if (vendorid
== ATHEROS_VENDOR_ID
) {
315 case AR5212_AR5312_REV2
:
316 case AR5212_AR5312_REV7
:
317 return "Atheros 5312 WiSoC";
318 case AR5212_AR2313_REV8
:
319 return "Atheros 2313 WiSoC";
320 case AR5212_AR2315_REV6
:
321 case AR5212_AR2315_REV7
:
322 return "Atheros 2315 WiSoC";
323 case AR5212_AR2317_REV1
:
324 return "Atheros 2317 WiSoC";
326 return "Atheros 2413";
328 return "Atheros 2417";
333 AH_CHIP(AR5312
, ar5312Probe
, ar5312Attach
);