ar9130_attach.c revision 225883
1208562Srwatson/* 2208562Srwatson * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd 3208562Srwatson * Copyright (c) 2008 Sam Leffler, Errno Consulting 4208562Srwatson * Copyright (c) 2008 Atheros Communications, Inc. 5208562Srwatson * 6208562Srwatson * Permission to use, copy, modify, and/or distribute this software for any 7208562Srwatson * purpose with or without fee is hereby granted, provided that the above 8208562Srwatson * copyright notice and this permission notice appear in all copies. 9208562Srwatson * 10208562Srwatson * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11208562Srwatson * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12208562Srwatson * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13208562Srwatson * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14208562Srwatson * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15208562Srwatson * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16208562Srwatson * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17208562Srwatson * 18208562Srwatson * $FreeBSD: head/sys/dev/ath/ath_hal/ar9001/ar9130_attach.c 225883 2011-09-30 05:17:57Z adrian $ 19208562Srwatson */ 20208562Srwatson#include "opt_ah.h" 21208562Srwatson 22208562Srwatson#include "ah.h" 23208562Srwatson#include "ah_internal.h" 24208562Srwatson#include "ah_devid.h" 25208562Srwatson 26208562Srwatson#include "ar5416/ar5416.h" 27208562Srwatson#include "ar5416/ar5416reg.h" 28208562Srwatson#include "ar5416/ar5416phy.h" 29208562Srwatson 30208562Srwatson#include "ar9001/ar9130reg.h" 31208562Srwatson#include "ar9001/ar9130_phy.h" 32208562Srwatson#include "ar9001/ar9130_eeprom.h" 33208562Srwatson 34208562Srwatson#include "ar9001/ar9130.ini" 35208562Srwatson 36208562Srwatsonstatic const HAL_PERCAL_DATA ar9130_iq_cal = { /* multi sample */ 37208562Srwatson .calName = "IQ", .calType = IQ_MISMATCH_CAL, 38208562Srwatson .calNumSamples = MAX_CAL_SAMPLES, 39208562Srwatson .calCountMax = PER_MIN_LOG_COUNT, 40208562Srwatson .calCollect = ar5416IQCalCollect, 41208562Srwatson .calPostProc = ar5416IQCalibration 42208562Srwatson}; 43208562Srwatsonstatic const HAL_PERCAL_DATA ar9130_adc_gain_cal = { /* multi sample */ 44208562Srwatson .calName = "ADC Gain", .calType = ADC_GAIN_CAL, 45208562Srwatson .calNumSamples = MAX_CAL_SAMPLES, 46208562Srwatson .calCountMax = PER_MIN_LOG_COUNT, 47208562Srwatson .calCollect = ar5416AdcGainCalCollect, 48208562Srwatson .calPostProc = ar5416AdcGainCalibration 49208562Srwatson}; 50208562Srwatsonstatic const HAL_PERCAL_DATA ar9130_adc_dc_cal = { /* multi sample */ 51208562Srwatson .calName = "ADC DC", .calType = ADC_DC_CAL, 52208562Srwatson .calNumSamples = MAX_CAL_SAMPLES, 53208562Srwatson .calCountMax = PER_MIN_LOG_COUNT, 54208562Srwatson .calCollect = ar5416AdcDcCalCollect, 55208562Srwatson .calPostProc = ar5416AdcDcCalibration 56208562Srwatson}; 57281400Sngiestatic const HAL_PERCAL_DATA ar9130_adc_init_dc_cal = { 58281400Sngie .calName = "ADC Init DC", .calType = ADC_DC_INIT_CAL, 59208562Srwatson .calNumSamples = MIN_CAL_SAMPLES, 60208562Srwatson .calCountMax = INIT_LOG_COUNT, 61208562Srwatson .calCollect = ar5416AdcDcCalCollect, 62208562Srwatson .calPostProc = ar5416AdcDcCalibration 63281400Sngie}; 64208562Srwatson 65208562Srwatsonstatic HAL_BOOL ar9130FillCapabilityInfo(struct ath_hal *ah); 66208562Srwatson 67208562Srwatson/* 68208562Srwatson * Attach for an AR9130 part. 69208562Srwatson */ 70208562Srwatsonstatic struct ath_hal * 71208562Srwatsonar9130Attach(uint16_t devid, HAL_SOFTC sc, 72208562Srwatson HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata, HAL_STATUS *status) 73208562Srwatson{ 74208562Srwatson struct ath_hal_5416 *ahp5416; 75208562Srwatson struct ath_hal_5212 *ahp; 76208562Srwatson struct ath_hal *ah; 77208562Srwatson uint32_t val; 78281400Sngie HAL_STATUS ecode; 79281400Sngie HAL_BOOL rfStatus; 80281400Sngie 81281400Sngie HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n", 82208562Srwatson __func__, sc, (void*) st, (void*) sh); 83208602Srwatson 84208602Srwatson /* NB: memory is returned zero'd */ 85208562Srwatson ahp5416 = ath_hal_malloc(sizeof (struct ath_hal_5416)); 86208562Srwatson if (ahp5416 == AH_NULL) { 87208562Srwatson HALDEBUG(AH_NULL, HAL_DEBUG_ANY, 88281400Sngie "%s: cannot allocate memory for state block\n", __func__); 89208562Srwatson *status = HAL_ENOMEM; 90208562Srwatson return AH_NULL; 91281400Sngie } 92208562Srwatson ar5416InitState(ahp5416, devid, sc, st, sh, status); 93208562Srwatson ahp = &ahp5416->ah_5212; 94208562Srwatson ah = &ahp->ah_priv.h; 95208562Srwatson 96208562Srwatson /* XXX override with 9100 specific state */ 97208562Srwatson AH5416(ah)->ah_initPLL = ar9130InitPLL; 98208562Srwatson /* XXX should force chainmasks to 0x7, as per ath9k calibration bugs */ 99208562Srwatson 100208562Srwatson /* override 5416 methods for our needs */ 101208562Srwatson 102208562Srwatson AH5416(ah)->ah_cal.iqCalData.calData = &ar9130_iq_cal; 103208562Srwatson AH5416(ah)->ah_cal.adcGainCalData.calData = &ar9130_adc_gain_cal; 104208562Srwatson AH5416(ah)->ah_cal.adcDcCalData.calData = &ar9130_adc_dc_cal; 105208562Srwatson AH5416(ah)->ah_cal.adcDcCalInitData.calData = &ar9130_adc_init_dc_cal; 106208562Srwatson AH5416(ah)->ah_cal.suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL; 107208562Srwatson 108208562Srwatson /* 109208562Srwatson * This was hard-set because the initial ath9k port of this 110281400Sngie * code kept their runtime conditional register #defines. 111208562Srwatson * AR_SREV and the RTC registers have shifted for Howl; 112208602Srwatson * they detected this and changed the values at runtime. 113208602Srwatson * The current port doesn't yet do this; it may do at a 114208602Srwatson * later stage, so this is set early so any routines which 115208602Srwatson * manipulate the registers have ah_macVersion set to base 116208562Srwatson * the above decision upon. 117208602Srwatson */ 118208602Srwatson AH_PRIVATE((ah))->ah_macVersion = AR_XSREV_VERSION_HOWL; 119208602Srwatson 120208602Srwatson /* 121208602Srwatson * Use the "local" EEPROM data given to us by the higher layers. 122208602Srwatson * This is a private copy out of system flash. The Linux ath9k 123208602Srwatson * commit for the initial AR9130 support mentions MMIO flash 124208602Srwatson * access is "unreliable." -adrian 125208562Srwatson */ 126208562Srwatson AH_PRIVATE((ah))->ah_eepromRead = ar9130EepromRead; 127208562Srwatson AH_PRIVATE((ah))->ah_eepromWrite = NULL; 128208562Srwatson ah->ah_eepromdata = eepromdata; 129208562Srwatson 130208562Srwatson if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) { 131208562Srwatson /* reset chip */ 132208562Srwatson HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n", 133208562Srwatson __func__); 134208562Srwatson ecode = HAL_EIO; 135208562Srwatson goto bad; 136208602Srwatson } 137208562Srwatson 138208602Srwatson if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) { 139208562Srwatson HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n", 140208562Srwatson __func__); 141208562Srwatson ecode = HAL_EIO; 142208562Srwatson goto bad; 143208562Srwatson } 144 /* Read Revisions from Chips before taking out of reset */ 145 val = OS_REG_READ(ah, AR_SREV_CHIP_HOWL) & AR_SREV_CHIP_HOWL_ID; 146 147 /* XXX are these values even valid for the mac/radio revision? -adrian */ 148 HALDEBUG(ah, HAL_DEBUG_ATTACH, 149 "%s: ID 0x%x VERSION 0x%x TYPE 0x%x REVISION 0x%x\n", 150 __func__, MS(val, AR_XSREV_ID), MS(val, AR_XSREV_VERSION), 151 MS(val, AR_XSREV_TYPE), MS(val, AR_XSREV_REVISION)); 152 AH_PRIVATE(ah)->ah_macRev = MS(val, AR_XSREV_REVISION); 153 AH_PRIVATE(ah)->ah_ispcie = 0; 154 155 /* setup common ini data; rf backends handle remainder */ 156 HAL_INI_INIT(&ahp->ah_ini_modes, ar5416Modes_9100, 6); 157 HAL_INI_INIT(&ahp->ah_ini_common, ar5416Common_9100, 2); 158 159 HAL_INI_INIT(&AH5416(ah)->ah_ini_bb_rfgain, ar5416BB_RfGain_9100, 3); 160 HAL_INI_INIT(&AH5416(ah)->ah_ini_bank0, ar5416Bank0_9100, 2); 161 HAL_INI_INIT(&AH5416(ah)->ah_ini_bank1, ar5416Bank1_9100, 2); 162 HAL_INI_INIT(&AH5416(ah)->ah_ini_bank2, ar5416Bank2_9100, 2); 163 HAL_INI_INIT(&AH5416(ah)->ah_ini_bank3, ar5416Bank3_9100, 3); 164 HAL_INI_INIT(&AH5416(ah)->ah_ini_bank6, ar5416Bank6TPC_9100, 3); 165 HAL_INI_INIT(&AH5416(ah)->ah_ini_bank7, ar5416Bank7_9100, 2); 166 HAL_INI_INIT(&AH5416(ah)->ah_ini_addac, ar5416Addac_9100, 2); 167 168 ecode = ath_hal_v14EepromAttach(ah); 169 if (ecode != HAL_OK) 170 goto bad; 171 172 if (!ar5416ChipReset(ah, AH_NULL)) { /* reset chip */ 173 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__); 174 ecode = HAL_EIO; 175 goto bad; 176 } 177 178 AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID); 179 180 if (!ar5212ChipTest(ah)) { 181 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n", 182 __func__); 183 ecode = HAL_ESELFTEST; 184 goto bad; 185 } 186 187 /* 188 * Set correct Baseband to analog shift 189 * setting to access analog chips. 190 */ 191 OS_REG_WRITE(ah, AR_PHY(0), 0x00000007); 192 193 /* Read Radio Chip Rev Extract */ 194 AH_PRIVATE(ah)->ah_analog5GhzRev = ar5416GetRadioRev(ah); 195 switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) { 196 case AR_RAD2133_SREV_MAJOR: /* Sowl: 2G/3x3 */ 197 case AR_RAD5133_SREV_MAJOR: /* Sowl: 2+5G/3x3 */ 198 break; 199 default: 200 if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) { 201 AH_PRIVATE(ah)->ah_analog5GhzRev = 202 AR_RAD5133_SREV_MAJOR; 203 break; 204 } 205#ifdef AH_DEBUG 206 HALDEBUG(ah, HAL_DEBUG_ANY, 207 "%s: 5G Radio Chip Rev 0x%02X is not supported by " 208 "this driver\n", __func__, 209 AH_PRIVATE(ah)->ah_analog5GhzRev); 210 ecode = HAL_ENOTSUPP; 211 goto bad; 212#endif 213 } 214 rfStatus = ar2133RfAttach(ah, &ecode); 215 if (!rfStatus) { 216 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n", 217 __func__, ecode); 218 goto bad; 219 } 220 221 /* 222 * Got everything we need now to setup the capabilities. 223 */ 224 if (!ar9130FillCapabilityInfo(ah)) { 225 ecode = HAL_EEREAD; 226 goto bad; 227 } 228 229 ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr); 230 if (ecode != HAL_OK) { 231 HALDEBUG(ah, HAL_DEBUG_ANY, 232 "%s: error getting mac address from EEPROM\n", __func__); 233 goto bad; 234 } 235 /* XXX How about the serial number ? */ 236 /* Read Reg Domain */ 237 AH_PRIVATE(ah)->ah_currentRD = 238 ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL); 239 AH_PRIVATE(ah)->ah_currentRDext = 240 ath_hal_eepromGet(ah, AR_EEP_REGDMN_1, AH_NULL); 241 242 243 /* 244 * ah_miscMode is populated by ar5416FillCapabilityInfo() 245 * starting from griffin. Set here to make sure that 246 * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is 247 * placed into hardware. 248 */ 249 if (ahp->ah_miscMode != 0) 250 OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode); 251 252 /* XXX no ANI for AR9130 */ 253 AH5416(ah)->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ; 254 AH5416(ah)->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ; 255 AH5416(ah)->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_5416_2GHZ; 256 AH5416(ah)->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ; 257 AH5416(ah)->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ; 258 AH5416(ah)->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_5416_5GHZ; 259 260 ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist); 261 262 HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__); 263 264 return ah; 265bad: 266 if (ahp) 267 ar5416Detach((struct ath_hal *) ahp); 268 if (status) 269 *status = ecode; 270 return AH_NULL; 271} 272 273/* 274 * Fill all software cached or static hardware state information. 275 * Return failure if capabilities are to come from EEPROM and 276 * cannot be read. 277 */ 278static HAL_BOOL 279ar9130FillCapabilityInfo(struct ath_hal *ah) 280{ 281 HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps; 282 283 HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: begin\n", __func__); 284 if (!ar5416FillCapabilityInfo(ah)) 285 return AH_FALSE; 286 HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: fill'ed; now setting\n", __func__); 287 pCap->halCSTSupport = AH_TRUE; 288 pCap->halRifsRxSupport = AH_TRUE; 289 pCap->halRifsTxSupport = AH_TRUE; 290 pCap->halRtsAggrLimit = 64*1024; /* 802.11n max */ 291 pCap->halExtChanDfsSupport = AH_TRUE; 292 pCap->halUseCombinedRadarRssi = AH_TRUE; 293 pCap->halAutoSleepSupport = AH_FALSE; /* XXX? */ 294 /* 295 * MBSSID aggregation is broken in Howl v1.1, v1.2, v1.3 296 * 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 302 return AH_TRUE; 303} 304 305static const char* 306ar9130Probe(uint16_t vendorid, uint16_t devid) 307{ 308 if (vendorid == ATHEROS_VENDOR_ID && devid == AR5416_AR9130_DEVID) 309 return "Atheros 9130"; 310 return AH_NULL; 311} 312AH_CHIP(AR9130, ar9130Probe, ar9130Attach); 313