Home | History | Annotate | Line # | Download | only in ar5312
ar5312_attach.c revision 1.2.2.2
      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: ar5312_attach.c,v 1.2.2.2 2009/01/17 13:29:14 mjf 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 "ar5312/ar5312.h"
     26 #include "ar5312/ar5312reg.h"
     27 #include "ar5312/ar5312phy.h"
     28 
     29 /* Add static register initialization vectors */
     30 #define AH_5212_COMMON
     31 #include "ar5212/ar5212.ini"
     32 
     33 static  HAL_BOOL ar5312GetMacAddr(struct ath_hal *ah);
     34 
     35 static void
     36 ar5312AniSetup(struct ath_hal *ah)
     37 {
     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 },
     48 		.ofdmTrigHigh		= 500,
     49 		.ofdmTrigLow		= 200,
     50 		.cckTrigHigh		= 200,
     51 		.cckTrigLow		= 100,
     52 		.rssiThrHigh		= 40,
     53 		.rssiThrLow		= 7,
     54 		.period			= 100,
     55 	};
     56 	ar5212AniAttach(ah, &aniparams, &aniparams, AH_TRUE);
     57 }
     58 
     59 /*
     60  * Attach for an AR5312 part.
     61  */
     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)
     65 {
     66 	struct ath_hal_5212 *ahp = AH_NULL;
     67 	struct ath_hal *ah;
     68 	struct ath_hal_rf *rf;
     69 	uint32_t val;
     70 	uint16_t eeval;
     71 	HAL_STATUS ecode;
     72 
     73 	HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",
     74 		 __func__, sc, st, (void*) sh);
     75 
     76 	/* NB: memory is returned zero'd */
     77 	ahp = ath_hal_malloc(sizeof (struct ath_hal_5212));
     78 	if (ahp == AH_NULL) {
     79 		HALDEBUG(AH_NULL, HAL_DEBUG_ANY,
     80 		    "%s: cannot allocate memory for state block\n", __func__);
     81 		*status = HAL_ENOMEM;
     82 		return AH_NULL;
     83 	}
     84 	ar5212InitState(ahp, devid, sc, st, sh, status);
     85 	ah = &ahp->ah_priv.h;
     86 
     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;
     95 
     96 	ahp->ah_priv.ah_eepromRead	= ar5312EepromRead;
     97 #ifdef AH_SUPPORT_WRITE_EEPROM
     98 	ahp->ah_priv.ah_eepromWrite	= ar5312EepromWrite;
     99 #endif
    100 #if ( AH_SUPPORT_2316 || AH_SUPPORT_2317)
    101 	if (IS_5315(ah)) {
    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;
    107 	} else
    108 #endif
    109 	{
    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;
    115 	}
    116 
    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;
    122 
    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);
    126 
    127 	if (!ar5312ChipReset(ah, AH_NULL)) {	/* reset chip */
    128 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
    129 		ecode = HAL_EIO;
    130 		goto bad;
    131 	}
    132 
    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)
    139 			& AR5315_WREV_ID;
    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);
    145 	} else
    146 #endif
    147 	{
    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;
    154 	}
    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) {
    160 #ifdef AH_DEBUG
    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);
    165 #endif
    166 		ecode = HAL_ENOTSUPP;
    167 		goto bad;
    168 	}
    169 
    170 	AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID);
    171 
    172 	if (!ar5212ChipTest(ah)) {
    173 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n",
    174 		    __func__);
    175 		ecode = HAL_ESELFTEST;
    176 		goto bad;
    177 	}
    178 
    179 	/*
    180 	 * Set correct Baseband to analog shift
    181 	 * setting to access analog chips.
    182 	 */
    183 	OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
    184 
    185 	/* Read Radio Chip Rev Extract */
    186 	AH_PRIVATE(ah)->ah_analog5GhzRev = ar5212GetRadioRev(ah);
    187 
    188 	rf = ath_hal_rfprobe(ah, &ecode);
    189 	if (rf == AH_NULL)
    190 		goto bad;
    191 	if (IS_RAD5112(ah) && !IS_RADX112_REV2(ah)) {
    192 #ifdef AH_DEBUG
    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);
    196 #endif
    197 		ecode = HAL_ENOTSUPP;
    198 		goto bad;
    199 	}
    200 
    201 	ecode = ath_hal_legacyEepromAttach(ah);
    202 	if (ecode != HAL_OK) {
    203 		goto bad;
    204 	}
    205 
    206 	/*
    207 	 * If Bmode and AR5212, verify 2.4 analog exists
    208 	 */
    209 	if (ath_hal_eepromGetFlag(ah, AR_EEP_BMODE) &&
    210 	    (AH_PRIVATE(ah)->ah_analog5GhzRev & 0xF0) == AR_RAD5111_SREV_MAJOR) {
    211 		/*
    212 		 * Set correct Baseband to analog shift
    213 		 * setting to access analog chips.
    214 		 */
    215 		OS_REG_WRITE(ah, AR_PHY(0), 0x00004007);
    216 		OS_DELAY(2000);
    217 		AH_PRIVATE(ah)->ah_analog2GhzRev = ar5212GetRadioRev(ah);
    218 
    219 		/* Set baseband for 5GHz chip */
    220 		OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
    221 		OS_DELAY(2000);
    222 		if ((AH_PRIVATE(ah)->ah_analog2GhzRev & 0xF0) != AR_RAD2111_SREV_MAJOR) {
    223 #ifdef AH_DEBUG
    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);
    227 #endif
    228 			ecode = HAL_ENOTSUPP;
    229 			goto bad;
    230 		}
    231 	}
    232 
    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",
    237 		    __func__);
    238 		goto bad;
    239         }
    240 	AH_PRIVATE(ah)->ah_currentRD = eeval;
    241 	/* XXX record serial number */
    242 
    243 	/* XXX other capabilities */
    244 	/*
    245 	 * Got everything we need now to setup the capabilities.
    246 	 */
    247 	if (!ar5212FillCapabilityInfo(ah)) {
    248 		HALDEBUG(ah, HAL_DEBUG_ANY,
    249 		    "%s: failed ar5212FillCapabilityInfo\n", __func__);
    250 		ecode = HAL_EEREAD;
    251 		goto bad;
    252 	}
    253 
    254 	if (!rf->attach(ah, &ecode)) {
    255 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n",
    256 		    __func__, ecode);
    257 		goto bad;
    258 	}
    259 	/* arrange a direct call instead of thunking */
    260 	AH_PRIVATE(ah)->ah_getNfAdjust = ahp->ah_rfHal->getNfAdjust;
    261 
    262 	/* Initialize gain ladder thermal calibration structure */
    263 	ar5212InitializeGainValues(ah);
    264 
    265         /* BSP specific call for MAC address of this WMAC device */
    266         if (!ar5312GetMacAddr(ah)) {
    267                 ecode = HAL_EEBADMAC;
    268                 goto bad;
    269         }
    270 
    271 	ar5312AniSetup(ah);
    272 	ar5212InitNfCalHistBuffer(ah);
    273 
    274 	/* XXX EAR stuff goes here */
    275 	return ah;
    276 
    277 bad:
    278 	if (ahp)
    279 		ar5212Detach((struct ath_hal *) ahp);
    280 	if (status)
    281 		*status = ecode;
    282 	return AH_NULL;
    283 }
    284 
    285 static HAL_BOOL
    286 ar5312GetMacAddr(struct ath_hal *ah)
    287 {
    288 	const struct ar531x_boarddata *board = AR5312_BOARDCONFIG(ah);
    289         int wlanNum = AR5312_UNIT(ah);
    290         const uint8_t *macAddr;
    291 
    292 	switch (wlanNum) {
    293 	case 0:
    294 		macAddr = board->wlan0Mac;
    295 		break;
    296 	case 1:
    297 		macAddr = board->wlan1Mac;
    298 		break;
    299 	default:
    300 #ifdef AH_DEBUG
    301 		ath_hal_printf(ah, "Invalid WLAN wmac index (%d)\n",
    302 			       wlanNum);
    303 #endif
    304 		return AH_FALSE;
    305 	}
    306 	OS_MEMCPY(AH5212(ah)->ah_macaddr, macAddr, 6);
    307 	return AH_TRUE;
    308 }
    309 
    310 static const char*
    311 ar5312Probe(uint16_t vendorid, uint16_t devid)
    312 {
    313 	if (vendorid == ATHEROS_VENDOR_ID) {
    314 		switch (devid) {
    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";
    325 		case AR5212_AR2413:
    326 			return "Atheros 2413";
    327 		case AR5212_AR2417:
    328 			return "Atheros 2417";
    329 		}
    330 	}
    331 	return AH_NULL;
    332 }
    333 AH_CHIP(AR5312, ar5312Probe, ar5312Attach);
    334