📄 ar5211_attach.c
字号:
AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID); if (!ar5211ChipTest(ah)) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n", __func__); ecode = HAL_ESELFTEST; goto bad; } /* Set correct Baseband to analog shift setting to access analog chips. */ if (AH_PRIVATE(ah)->ah_macVersion >= AR_SREV_VERSION_OAHU) { OS_REG_WRITE(ah, AR_PHY_BASE, 0x00000007); } else { OS_REG_WRITE(ah, AR_PHY_BASE, 0x00000047); } OS_DELAY(2000); /* Read Radio Chip Rev Extract */ AH_PRIVATE(ah)->ah_analog5GhzRev = ar5211GetRadioRev(ah); if ((AH_PRIVATE(ah)->ah_analog5GhzRev & 0xf0) != RAD5_SREV_MAJOR) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: 5G Radio Chip Rev 0x%02X is not supported by this " "driver\n", __func__, AH_PRIVATE(ah)->ah_analog5GhzRev); ecode = HAL_ENOTSUPP; goto bad; } val = (OS_REG_READ(ah, AR_PCICFG) & AR_PCICFG_EEPROM_SIZE_M) >> AR_PCICFG_EEPROM_SIZE_S; if (val != AR_PCICFG_EEPROM_SIZE_16K) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unsupported EEPROM size " "%u (0x%x) found\n", __func__, val, val); ecode = HAL_EESIZE; goto bad; } ecode = ath_hal_legacyEepromAttach(ah); if (ecode != HAL_OK) { goto bad; } /* If Bmode and AR5211, verify 2.4 analog exists */ if (AH_PRIVATE(ah)->ah_macVersion >= AR_SREV_VERSION_OAHU && ath_hal_eepromGetFlag(ah, AR_EEP_BMODE)) { /* Set correct Baseband to analog shift setting to access analog chips. */ OS_REG_WRITE(ah, AR_PHY_BASE, 0x00004007); OS_DELAY(2000); AH_PRIVATE(ah)->ah_analog2GhzRev = ar5211GetRadioRev(ah); /* Set baseband for 5GHz chip */ OS_REG_WRITE(ah, AR_PHY_BASE, 0x00000007); OS_DELAY(2000); if ((AH_PRIVATE(ah)->ah_analog2GhzRev & 0xF0) != RAD2_SREV_MAJOR) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: 2G Radio Chip Rev 0x%x is not supported by " "this driver\n", __func__, AH_PRIVATE(ah)->ah_analog2GhzRev); ecode = HAL_ENOTSUPP; goto bad; } } else { ath_hal_eepromSet(ah, AR_EEP_BMODE, AH_FALSE); } ecode = ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, &eeval); if (ecode != HAL_OK) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: cannot read regulatory domain from EEPROM\n", __func__); goto bad; } AH_PRIVATE(ah)->ah_currentRD = eeval; AH_PRIVATE(ah)->ah_getNfAdjust = ar5211GetNfAdjust; /* * Got everything we need now to setup the capabilities. */ (void) ar5211FillCapabilityInfo(ah); /* Initialize gain ladder thermal calibration structure */ ar5211InitializeGainValues(ah); ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr); if (ecode != HAL_OK) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: error getting mac address from EEPROM\n", __func__); goto bad; } HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__); return ah;bad: if (ahp) ar5211Detach((struct ath_hal *) ahp); if (status) *status = ecode; return AH_NULL;#undef N}voidar5211Detach(struct ath_hal *ah){ HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s:\n", __func__); HALASSERT(ah != AH_NULL); HALASSERT(ah->ah_magic == AR5211_MAGIC); ath_hal_eepromDetach(ah); ath_hal_free(ah);}static HAL_BOOLar5211ChipTest(struct ath_hal *ah){ uint32_t regAddr[2] = { AR_STA_ID0, AR_PHY_BASE+(8 << 2) }; uint32_t regHold[2]; uint32_t patternData[4] = { 0x55555555, 0xaaaaaaaa, 0x66666666, 0x99999999 }; int i, j; /* Test PHY & MAC registers */ for (i = 0; i < 2; i++) { uint32_t addr = regAddr[i]; uint32_t wrData, rdData; regHold[i] = OS_REG_READ(ah, addr); for (j = 0; j < 0x100; j++) { wrData = (j << 16) | j; OS_REG_WRITE(ah, addr, wrData); rdData = OS_REG_READ(ah, addr); if (rdData != wrData) { HALDEBUG(ah, HAL_DEBUG_ANY,"%s: address test failed addr: 0x%08x - wr:0x%08x != rd:0x%08x\n", __func__, addr, wrData, rdData); return AH_FALSE; } } for (j = 0; j < 4; j++) { wrData = patternData[j]; OS_REG_WRITE(ah, addr, wrData); rdData = OS_REG_READ(ah, addr); if (wrData != rdData) { HALDEBUG(ah, HAL_DEBUG_ANY,"%s: address test failed addr: 0x%08x - wr:0x%08x != rd:0x%08x\n", __func__, addr, wrData, rdData); return AH_FALSE; } } OS_REG_WRITE(ah, regAddr[i], regHold[i]); } OS_DELAY(100); return AH_TRUE;}/* * Store the channel edges for the requested operational mode */static HAL_BOOLar5211GetChannelEdges(struct ath_hal *ah, uint16_t flags, uint16_t *low, uint16_t *high){ if (flags & CHANNEL_5GHZ) { *low = 4920; *high = 6100; return AH_TRUE; } if (flags & CHANNEL_2GHZ && ath_hal_eepromGetFlag(ah, AR_EEP_BMODE)) { *low = 2312; *high = 2732; return AH_TRUE; } return AH_FALSE;}static HAL_BOOLar5211GetChipPowerLimits(struct ath_hal *ah, HAL_CHANNEL *chans, uint32_t nchans){ HAL_CHANNEL *chan; int i; /* XXX fill in, this is just a placeholder */ for (i = 0; i < nchans; i++) { chan = &chans[i]; HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: no min/max power for %u/0x%x\n", __func__, chan->channel, chan->channelFlags); chan->maxTxPower = MAX_RATE_POWER; chan->minTxPower = 0; } return AH_TRUE;}/* * Fill all software cached or static hardware state information. */static HAL_BOOLar5211FillCapabilityInfo(struct ath_hal *ah){ struct ath_hal_private *ahpriv = AH_PRIVATE(ah); HAL_CAPABILITIES *pCap = &ahpriv->ah_caps; /* Construct wireless mode from EEPROM */ pCap->halWirelessModes = 0; if (ath_hal_eepromGetFlag(ah, AR_EEP_AMODE)) { pCap->halWirelessModes |= HAL_MODE_11A; if (!ath_hal_eepromGetFlag(ah, AR_EEP_TURBO5DISABLE)) pCap->halWirelessModes |= HAL_MODE_TURBO; } if (ath_hal_eepromGetFlag(ah, AR_EEP_BMODE)) pCap->halWirelessModes |= HAL_MODE_11B; pCap->halLow2GhzChan = 2312; pCap->halHigh2GhzChan = 2732; pCap->halLow5GhzChan = 4920; pCap->halHigh5GhzChan = 6100; pCap->halChanSpreadSupport = AH_TRUE; pCap->halSleepAfterBeaconBroken = AH_TRUE; pCap->halPSPollBroken = AH_TRUE; pCap->halVEOLSupport = AH_TRUE; pCap->halTotalQueues = HAL_NUM_TX_QUEUES; pCap->halKeyCacheSize = 128; /* XXX not needed */ pCap->halChanHalfRate = AH_FALSE; pCap->halChanQuarterRate = AH_FALSE; if (ath_hal_eepromGetFlag(ah, AR_EEP_RFKILL) && ath_hal_eepromGet(ah, AR_EEP_RFSILENT, &ahpriv->ah_rfsilent) == HAL_OK) { /* NB: enabled by default */ ahpriv->ah_rfkillEnabled = AH_TRUE; pCap->halRfSilentSupport = AH_TRUE; } pCap->halTstampPrecision = 13; /* XXX might be ok w/ some chip revs */ ahpriv->ah_rxornIsFatal = AH_TRUE; return AH_TRUE;}static const char*ar5211Probe(uint16_t vendorid, uint16_t devid){ if (vendorid == ATHEROS_VENDOR_ID) { if (devid == AR5211_DEVID || devid == AR5311_DEVID || devid == AR5211_DEFAULT) return "Atheros 5211"; if (devid == AR5211_FPGA11B) return "Atheros 5211 (FPGA)"; } return AH_NULL;}AH_CHIP(AR5211, ar5211Probe, ar5211Attach);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -