ar9130_attach.c revision 230147
11590Srgrimes/*
21590Srgrimes * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd
31590Srgrimes * Copyright (c) 2008 Sam Leffler, Errno Consulting
496201Sdes * Copyright (c) 2008 Atheros Communications, Inc.
596201Sdes *
61590Srgrimes * Permission to use, copy, modify, and/or distribute this software for any
796201Sdes * purpose with or without fee is hereby granted, provided that the above
896201Sdes * copyright notice and this permission notice appear in all copies.
996201Sdes *
1096201Sdes * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1196201Sdes * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
121590Srgrimes * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
131590Srgrimes * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
141590Srgrimes * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
151590Srgrimes * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
161590Srgrimes * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
171590Srgrimes *
181590Srgrimes * $FreeBSD: head/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c 230147 2012-01-15 19:22:34Z adrian $
191590Srgrimes */
201590Srgrimes#include "opt_ah.h"
211590Srgrimes
221590Srgrimes#include "ah.h"
231590Srgrimes#include "ah_internal.h"
241590Srgrimes#include "ah_devid.h"
251590Srgrimes
261590Srgrimes#include "ar5416/ar5416.h"
271590Srgrimes#include "ar5416/ar5416reg.h"
281590Srgrimes#include "ar5416/ar5416phy.h"
291590Srgrimes
301590Srgrimes#include "ar9001/ar9130reg.h"
311590Srgrimes#include "ar9001/ar9130_phy.h"
321590Srgrimes#include "ar9001/ar9130_eeprom.h"
331590Srgrimes
341590Srgrimes#include "ar9001/ar9130.ini"
351590Srgrimes
361590Srgrimesstatic const HAL_PERCAL_DATA ar9130_iq_cal = {		/* multi sample */
371590Srgrimes	.calName = "IQ", .calType = IQ_MISMATCH_CAL,
381590Srgrimes	.calNumSamples	= MAX_CAL_SAMPLES,
391590Srgrimes	.calCountMax	= PER_MIN_LOG_COUNT,
401590Srgrimes	.calCollect	= ar5416IQCalCollect,
4193423Sdwmalone	.calPostProc	= ar5416IQCalibration
421590Srgrimes};
4393423Sdwmalonestatic const HAL_PERCAL_DATA ar9130_adc_gain_cal = {	/* multi sample */
441590Srgrimes	.calName = "ADC Gain", .calType = ADC_GAIN_CAL,
4593423Sdwmalone	.calNumSamples	= MAX_CAL_SAMPLES,
461590Srgrimes	.calCountMax	= PER_MIN_LOG_COUNT,
4793086Smarkm	.calCollect	= ar5416AdcGainCalCollect,
4893086Smarkm	.calPostProc	= ar5416AdcGainCalibration
4993086Smarkm};
501590Srgrimesstatic const HAL_PERCAL_DATA ar9130_adc_dc_cal = {	/* multi sample */
511590Srgrimes	.calName = "ADC DC", .calType = ADC_DC_CAL,
521590Srgrimes	.calNumSamples	= MAX_CAL_SAMPLES,
531590Srgrimes	.calCountMax	= PER_MIN_LOG_COUNT,
541590Srgrimes	.calCollect	= ar5416AdcDcCalCollect,
551590Srgrimes	.calPostProc	= ar5416AdcDcCalibration
561590Srgrimes};
571590Srgrimesstatic const HAL_PERCAL_DATA ar9130_adc_init_dc_cal = {
581590Srgrimes	.calName = "ADC Init DC", .calType = ADC_DC_INIT_CAL,
591590Srgrimes	.calNumSamples	= MIN_CAL_SAMPLES,
601590Srgrimes	.calCountMax	= INIT_LOG_COUNT,
611590Srgrimes	.calCollect	= ar5416AdcDcCalCollect,
621590Srgrimes	.calPostProc	= ar5416AdcDcCalibration
631590Srgrimes};
6496201Sdes
651590Srgrimesstatic HAL_BOOL ar9130FillCapabilityInfo(struct ath_hal *ah);
661590Srgrimes
671590Srgrimes/*
6896201Sdes * Attach for an AR9130 part.
6996201Sdes */
701590Srgrimesstatic struct ath_hal *
7196201Sdesar9130Attach(uint16_t devid, HAL_SOFTC sc,
7296201Sdes	HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata, HAL_STATUS *status)
731590Srgrimes{
7496201Sdes	struct ath_hal_5416 *ahp5416;
7596201Sdes	struct ath_hal_5212 *ahp;
7696201Sdes	struct ath_hal *ah;
771590Srgrimes	uint32_t val;
7896201Sdes	HAL_STATUS ecode;
7996201Sdes	HAL_BOOL rfStatus;
801590Srgrimes
8196201Sdes	HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",
8296201Sdes	    __func__, sc, (void*) st, (void*) sh);
8396201Sdes
8496201Sdes	/* NB: memory is returned zero'd */
8596201Sdes	ahp5416 = ath_hal_malloc(sizeof (struct ath_hal_5416));
8696201Sdes	if (ahp5416 == AH_NULL) {
8796201Sdes		HALDEBUG(AH_NULL, HAL_DEBUG_ANY,
881590Srgrimes		    "%s: cannot allocate memory for state block\n", __func__);
8996201Sdes		*status = HAL_ENOMEM;
9096201Sdes		return AH_NULL;
9196201Sdes	}
9296201Sdes	ar5416InitState(ahp5416, devid, sc, st, sh, status);
9396201Sdes	ahp = &ahp5416->ah_5212;
9496201Sdes	ah = &ahp->ah_priv.h;
9596201Sdes
9696201Sdes	/* XXX override with 9100 specific state */
9796201Sdes	AH5416(ah)->ah_initPLL = ar9130InitPLL;
9896201Sdes	/* XXX should force chainmasks to 0x7, as per ath9k calibration bugs */
9996201Sdes
1001590Srgrimes	/* override 5416 methods for our needs */
1011590Srgrimes
1021590Srgrimes	AH5416(ah)->ah_cal.iqCalData.calData = &ar9130_iq_cal;
1031590Srgrimes	AH5416(ah)->ah_cal.adcGainCalData.calData = &ar9130_adc_gain_cal;
1041590Srgrimes	AH5416(ah)->ah_cal.adcDcCalData.calData = &ar9130_adc_dc_cal;
1051590Srgrimes	AH5416(ah)->ah_cal.adcDcCalInitData.calData = &ar9130_adc_init_dc_cal;
1061590Srgrimes	AH5416(ah)->ah_cal.suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
1071590Srgrimes
10896201Sdes	/*
10996201Sdes	 * This was hard-set because the initial ath9k port of this
1101590Srgrimes	 * code kept their runtime conditional register #defines.
1111590Srgrimes	 * AR_SREV and the RTC registers have shifted for Howl;
112113304Sdes	 * they detected this and changed the values at runtime.
1131590Srgrimes	 * The current port doesn't yet do this; it may do at a
11496201Sdes	 * later stage, so this is set early so any routines which
11596201Sdes	 * manipulate the registers have ah_macVersion set to base
11696201Sdes	 * the above decision upon.
11796201Sdes	 */
1181590Srgrimes	AH_PRIVATE((ah))->ah_macVersion = AR_XSREV_VERSION_HOWL;
1191590Srgrimes
12096201Sdes	/*
12196201Sdes	 * Use the "local" EEPROM data given to us by the higher layers.
1221590Srgrimes	 * This is a private copy out of system flash.
1231590Srgrimes	 * By this stage the SoC SPI flash may have disabled the memory-
12480424Smike	 * mapping and rely purely on port-based SPI IO.
12580424Smike	 */
12680424Smike	AH_PRIVATE((ah))->ah_eepromRead = ath_hal_EepromDataRead;
1271590Srgrimes	AH_PRIVATE((ah))->ah_eepromWrite = NULL;
1281590Srgrimes	ah->ah_eepromdata = eepromdata;
1291590Srgrimes
1301590Srgrimes	if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) {
1311590Srgrimes		/* reset chip */
1321590Srgrimes		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n",
1331590Srgrimes		    __func__);
1341590Srgrimes		ecode = HAL_EIO;
1351590Srgrimes		goto bad;
1361590Srgrimes	}
13746081Simp
1381590Srgrimes	if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
1391590Srgrimes		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n",
1401590Srgrimes		    __func__);
1411590Srgrimes		ecode = HAL_EIO;
1421590Srgrimes		goto bad;
14314212Swpaul	}
14496201Sdes	/* Read Revisions from Chips before taking out of reset */
14596201Sdes	val = OS_REG_READ(ah, AR_SREV_CHIP_HOWL) & AR_SREV_CHIP_HOWL_ID;
14614212Swpaul
14714212Swpaul	/* XXX are these values even valid for the mac/radio revision? -adrian */
14814212Swpaul	HALDEBUG(ah, HAL_DEBUG_ATTACH,
14914212Swpaul	    "%s: ID 0x%x VERSION 0x%x TYPE 0x%x REVISION 0x%x\n",
15014212Swpaul	    __func__, MS(val, AR_XSREV_ID), MS(val, AR_XSREV_VERSION),
1511590Srgrimes	    MS(val, AR_XSREV_TYPE), MS(val, AR_XSREV_REVISION));
1521590Srgrimes	AH_PRIVATE(ah)->ah_macRev = MS(val, AR_XSREV_REVISION);
1531590Srgrimes	AH_PRIVATE(ah)->ah_ispcie = 0;
154113304Sdes
1556269Sjkh	/* setup common ini data; rf backends handle remainder */
156113304Sdes	HAL_INI_INIT(&ahp->ah_ini_modes, ar5416Modes_9100, 6);
157113304Sdes	HAL_INI_INIT(&ahp->ah_ini_common, ar5416Common_9100, 2);
158113304Sdes
159113304Sdes	HAL_INI_INIT(&AH5416(ah)->ah_ini_bb_rfgain, ar5416BB_RfGain_9100, 3);
160113304Sdes	HAL_INI_INIT(&AH5416(ah)->ah_ini_bank0, ar5416Bank0_9100, 2);
161113304Sdes	HAL_INI_INIT(&AH5416(ah)->ah_ini_bank1, ar5416Bank1_9100, 2);
1621590Srgrimes	HAL_INI_INIT(&AH5416(ah)->ah_ini_bank2, ar5416Bank2_9100, 2);
16354968Simp	HAL_INI_INIT(&AH5416(ah)->ah_ini_bank3, ar5416Bank3_9100, 3);
16454968Simp	HAL_INI_INIT(&AH5416(ah)->ah_ini_bank6, ar5416Bank6TPC_9100, 3);
16596201Sdes	HAL_INI_INIT(&AH5416(ah)->ah_ini_bank7, ar5416Bank7_9100, 2);
16654968Simp	HAL_INI_INIT(&AH5416(ah)->ah_ini_addac, ar5416Addac_9100, 2);
1678874Srgrimes
16896201Sdes	ecode = ath_hal_v14EepromAttach(ah);
16954968Simp	if (ecode != HAL_OK)
17054968Simp		goto bad;
17196201Sdes
17254968Simp	if (!ar5416ChipReset(ah, AH_NULL)) {	/* reset chip */
1738874Srgrimes		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
17496201Sdes		ecode = HAL_EIO;
17554968Simp		goto bad;
17654968Simp	}
17796201Sdes
17854968Simp	AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID);
1798874Srgrimes
18096201Sdes	if (!ar5212ChipTest(ah)) {
18154968Simp		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n",
18254968Simp		    __func__);
18396201Sdes		ecode = HAL_ESELFTEST;
18454968Simp		goto bad;
1851590Srgrimes	}
18654968Simp
18754968Simp	/*
18896201Sdes	 * Set correct Baseband to analog shift
18954968Simp	 * setting to access analog chips.
19038307Sthepish	 */
191113304Sdes	OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
192113304Sdes
19396201Sdes	/* Read Radio Chip Rev Extract */
1941590Srgrimes	AH_PRIVATE(ah)->ah_analog5GhzRev = ar5416GetRadioRev(ah);
19596201Sdes	switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) {
1961590Srgrimes        case AR_RAD2133_SREV_MAJOR:	/* Sowl: 2G/3x3 */
1971590Srgrimes	case AR_RAD5133_SREV_MAJOR:	/* Sowl: 2+5G/3x3 */
19896201Sdes		break;
19996201Sdes	default:
2001590Srgrimes		if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) {
20196201Sdes			AH_PRIVATE(ah)->ah_analog5GhzRev =
2021590Srgrimes				AR_RAD5133_SREV_MAJOR;
20396201Sdes			break;
2041590Srgrimes		}
2051590Srgrimes#ifdef AH_DEBUG
20696201Sdes		HALDEBUG(ah, HAL_DEBUG_ANY,
20796201Sdes		    "%s: 5G Radio Chip Rev 0x%02X is not supported by "
2081590Srgrimes		    "this driver\n", __func__,
20996201Sdes		    AH_PRIVATE(ah)->ah_analog5GhzRev);
21096201Sdes		ecode = HAL_ENOTSUPP;
21196201Sdes		goto bad;
21296201Sdes#endif
21396201Sdes	}
21496201Sdes	rfStatus = ar2133RfAttach(ah, &ecode);
21596201Sdes	if (!rfStatus) {
21696201Sdes		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n",
2171590Srgrimes		    __func__, ecode);
2181590Srgrimes		goto bad;
21996201Sdes	}
22096201Sdes
22196201Sdes	/*
2221590Srgrimes	 * Got everything we need now to setup the capabilities.
22396201Sdes	 */
22496201Sdes	if (!ar9130FillCapabilityInfo(ah)) {
22596201Sdes		ecode = HAL_EEREAD;
2261590Srgrimes		goto bad;
22796201Sdes	}
22896201Sdes
2291590Srgrimes	ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr);
2301590Srgrimes	if (ecode != HAL_OK) {
23196201Sdes		HALDEBUG(ah, HAL_DEBUG_ANY,
23296201Sdes		    "%s: error getting mac address from EEPROM\n", __func__);
2331590Srgrimes		goto bad;
2341590Srgrimes        }
23596201Sdes	/* XXX How about the serial number ? */
23696201Sdes	/* Read Reg Domain */
23796201Sdes	AH_PRIVATE(ah)->ah_currentRD =
23896201Sdes	    ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL);
23996201Sdes	AH_PRIVATE(ah)->ah_currentRDext =
24096201Sdes	    ath_hal_eepromGet(ah, AR_EEP_REGDMN_1, AH_NULL);
24196201Sdes
24296201Sdes
2431590Srgrimes	/*
24496201Sdes	 * ah_miscMode is populated by ar5416FillCapabilityInfo()
24596201Sdes	 * starting from griffin. Set here to make sure that
24696201Sdes	 * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is
24796201Sdes	 * placed into hardware.
24896201Sdes	 */
24996201Sdes	if (ahp->ah_miscMode != 0)
25096201Sdes		OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);
25196201Sdes
25296201Sdes	/* XXX no ANI for AR9130 */
25396201Sdes	AH5416(ah)->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ;
25496201Sdes	AH5416(ah)->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ;
25596201Sdes	AH5416(ah)->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_5416_2GHZ;
25696201Sdes	AH5416(ah)->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ;
25796201Sdes	AH5416(ah)->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ;
25896201Sdes	AH5416(ah)->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_5416_5GHZ;
25996201Sdes
26096201Sdes	ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist);
26196201Sdes
26296201Sdes	HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);
26396201Sdes
2641590Srgrimes	return ah;
2651590Srgrimesbad:
26696201Sdes	if (ahp)
26796201Sdes		ar5416Detach((struct ath_hal *) ahp);
2681590Srgrimes	if (status)
2691590Srgrimes		*status = ecode;
27096201Sdes	return AH_NULL;
27196201Sdes}
27296201Sdes
27396201Sdes/*
27496201Sdes * Fill all software cached or static hardware state information.
27596201Sdes * Return failure if capabilities are to come from EEPROM and
27696201Sdes * cannot be read.
2771590Srgrimes */
27896201Sdesstatic HAL_BOOL
27996201Sdesar9130FillCapabilityInfo(struct ath_hal *ah)
28096201Sdes{
28196201Sdes	HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
28296201Sdes
28326921Scharnier	HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: begin\n", __func__);
28496201Sdes	if (!ar5416FillCapabilityInfo(ah))
28596201Sdes		return AH_FALSE;
28696201Sdes	HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: fill'ed; now setting\n", __func__);
28796201Sdes	pCap->halCSTSupport = AH_TRUE;
28896201Sdes	pCap->halRifsRxSupport = AH_TRUE;
28996201Sdes	pCap->halRifsTxSupport = AH_TRUE;
29096201Sdes	pCap->halRtsAggrLimit = 64*1024;	/* 802.11n max */
29196201Sdes	pCap->halExtChanDfsSupport = AH_TRUE;
29296201Sdes	pCap->halUseCombinedRadarRssi = AH_TRUE;
29396201Sdes	pCap->halAutoSleepSupport = AH_FALSE;	/* XXX? */
29496201Sdes	/*
29596201Sdes	 * MBSSID aggregation is broken in Howl v1.1, v1.2, v1.3
2961590Srgrimes	 * and works fine in v1.4.
297	 * XXX todo, enable it for v1.4.
298	 */
299	pCap->halMbssidAggrSupport = AH_FALSE;
300	pCap->hal4AddrAggrSupport = AH_TRUE;
301	/* BB Read WAR */
302	pCap->halHasBBReadWar = AH_TRUE;
303
304	return AH_TRUE;
305}
306
307static const char*
308ar9130Probe(uint16_t vendorid, uint16_t devid)
309{
310        if (vendorid == ATHEROS_VENDOR_ID && devid == AR5416_AR9130_DEVID)
311                return "Atheros 9130";
312	return AH_NULL;
313}
314AH_CHIP(AR9130, ar9130Probe, ar9130Attach);
315