📄 ar5212_attach.c.svn-base
字号:
} if (IS_2413(ah)) { /* Griffin */ AH_PRIVATE(ah)->ah_analog5GhzRev = AR_RAD2413_SREV_MAJOR | 0x1; break; } if (IS_5413(ah)) { /* Eagle */ AH_PRIVATE(ah)->ah_analog5GhzRev = AR_RAD5413_SREV_MAJOR | 0x2; break; } if (IS_2425(ah) || IS_2417(ah)) {/* Swan or Nala */ AH_PRIVATE(ah)->ah_analog5GhzRev = AR_RAD5424_SREV_MAJOR | 0x2; break; } }#ifdef AH_DEBUG 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;#endif } if (IS_RAD5112_REV1(ah)) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: 5112 Rev 1 is not supported by this " "driver (analog5GhzRev 0x%x)\n", __func__, AH_PRIVATE(ah)->ah_analog5GhzRev); ecode = HAL_ENOTSUPP; goto bad; } val = OS_REG_READ(ah, AR_PCICFG); val = MS(val, AR_PCICFG_EEPROM_SIZE); if (val == 0) { if (!IS_PCIE(ah)) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unsupported EEPROM size %u (0x%x) found\n", __func__, val, val); ecode = HAL_EESIZE; goto bad; } /* XXX AH_PRIVATE(ah)->ah_isPciExpress = AH_TRUE; */ } else if (val != AR_PCICFG_EEPROM_SIZE_16K) { if (AR_PCICFG_EEPROM_SIZE_FAILED == val) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unsupported EEPROM size %u (0x%x) found\n", __func__, val, val); ecode = HAL_EESIZE; goto bad; } HALDEBUG(ah, HAL_DEBUG_ANY, "%s: EEPROM size = %d. Must be %d (16k).\n", __func__, val, AR_PCICFG_EEPROM_SIZE_16K); ecode = HAL_EESIZE; goto bad; } ecode = ath_hal_legacyEepromAttach(ah); if (ecode != HAL_OK) { goto bad; } ahp->ah_isHb63 = IS_2425(ah) && ath_hal_eepromGetFlag(ah, AR_EEP_ISTALON); /* * If Bmode and AR5212, verify 2.4 analog exists */ if (ath_hal_eepromGetFlag(ah, AR_EEP_BMODE) && (AH_PRIVATE(ah)->ah_analog5GhzRev & 0xF0) == AR_RAD5111_SREV_MAJOR) { /* * Set correct Baseband to analog shift * setting to access analog chips. */ OS_REG_WRITE(ah, AR_PHY(0), 0x00004007); OS_DELAY(2000); AH_PRIVATE(ah)->ah_analog2GhzRev = ar5212GetRadioRev(ah); /* Set baseband for 5GHz chip */ OS_REG_WRITE(ah, AR_PHY(0), 0x00000007); OS_DELAY(2000); if ((AH_PRIVATE(ah)->ah_analog2GhzRev & 0xF0) != AR_RAD2111_SREV_MAJOR) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: 2G Radio Chip Rev 0x%02X is not " "supported by this driver\n", __func__, AH_PRIVATE(ah)->ah_analog2GhzRev); ecode = HAL_ENOTSUPP; goto bad; } } 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; /* XXX record serial number */ /* * Got everything we need now to setup the capabilities. */ if (!ar5212FillCapabilityInfo(ah)) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: failed ar5212FillCapabilityInfo\n", __func__); ecode = HAL_EEREAD; goto bad; } if (!rf->attach(ah, &ecode)) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n", __func__, ecode); goto bad; } /* * Set noise floor adjust method; we arrange a * direct call instead of thunking. */ AH_PRIVATE(ah)->ah_getNfAdjust = ahp->ah_rfHal->getNfAdjust; /* Initialize gain ladder thermal calibration structure */ ar5212InitializeGainValues(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; } ar5212AniSetup(ah); /* Setup of Radar/AR structures happens in ath_hal_initchannels*/ ar5212InitNfCalHistBuffer(ah); /* XXX EAR stuff goes here */ HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__); return ah;bad: if (ahp) ar5212Detach((struct ath_hal *) ahp); if (status) *status = ecode; return AH_NULL;#undef AH_EEPROM_PROTECT}voidar5212Detach(struct ath_hal *ah){ HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s:\n", __func__); HALASSERT(ah != AH_NULL); HALASSERT(ah->ah_magic == AR5212_MAGIC); ar5212AniDetach(ah); ar5212RfDetach(ah); ar5212Disable(ah); ar5212SetPowerMode(ah, HAL_PM_FULL_SLEEP, AH_TRUE); ath_hal_eepromDetach(ah); ath_hal_free(ah);}HAL_BOOLar5212ChipTest(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 */HAL_BOOLar5212GetChannelEdges(struct ath_hal *ah, uint16_t flags, uint16_t *low, uint16_t *high){ if (flags & CHANNEL_5GHZ) { *low = 4915; *high = 6100; return AH_TRUE; } if ((flags & CHANNEL_2GHZ) && (ath_hal_eepromGetFlag(ah, AR_EEP_BMODE) || ath_hal_eepromGetFlag(ah, AR_EEP_GMODE))) { *low = 2312; *high = 2732; return AH_TRUE; } return AH_FALSE;}/* * Fill all software cached or static hardware state information. * Return failure if capabilities are to come from EEPROM and * cannot be read. */HAL_BOOLar5212FillCapabilityInfo(struct ath_hal *ah){#define AR_KEYTABLE_SIZE 128#define IS_GRIFFIN_LITE(ah) \ (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_GRIFFIN && \ AH_PRIVATE(ah)->ah_macRev == AR_SREV_GRIFFIN_LITE)#define IS_COBRA(ah) \ (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_COBRA)#define IS_2112(ah) \ ((AH_PRIVATE(ah)->ah_analog5GhzRev & 0xF0) == AR_RAD2112_SREV_MAJOR) struct ath_hal_private *ahpriv = AH_PRIVATE(ah); HAL_CAPABILITIES *pCap = &ahpriv->ah_caps; uint16_t capField, val; /* Read the capability EEPROM location */ if (ath_hal_eepromGet(ah, AR_EEP_OPCAP, &capField) != HAL_OK) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to read caps from eeprom\n", __func__); return AH_FALSE; } if (IS_2112(ah)) ath_hal_eepromSet(ah, AR_EEP_AMODE, AH_FALSE); if (capField == 0 && IS_GRIFFIN_LITE(ah)) { /* * For griffin-lite cards with unprogrammed capabilities. */ ath_hal_eepromSet(ah, AR_EEP_COMPRESS, AH_FALSE); ath_hal_eepromSet(ah, AR_EEP_FASTFRAME, AH_FALSE); ath_hal_eepromSet(ah, AR_EEP_TURBO5DISABLE, AH_TRUE); ath_hal_eepromSet(ah, AR_EEP_TURBO2DISABLE, AH_TRUE); HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: override caps for griffin-lite, now 0x%x (+!turbo)\n", __func__, capField); } /* Modify reg domain on newer cards that need to work with older sw */ if (ahpriv->ah_opmode != HAL_M_HOSTAP && ahpriv->ah_subvendorid == AR_SUBVENDOR_ID_NEW_A) { if (ahpriv->ah_currentRD == 0x64 || ahpriv->ah_currentRD == 0x65) ahpriv->ah_currentRD += 5; else if (ahpriv->ah_currentRD == 0x41) ahpriv->ah_currentRD = 0x43; HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: regdomain mapped to 0x%x\n", __func__, ahpriv->ah_currentRD); } if (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_2417 || AH_PRIVATE(ah)->ah_macVersion == AR_SREV_2425) { HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: enable Bmode and disable turbo for Swan/Nala\n", __func__); ath_hal_eepromSet(ah, AR_EEP_BMODE, AH_TRUE); ath_hal_eepromSet(ah, AR_EEP_COMPRESS, AH_FALSE); ath_hal_eepromSet(ah, AR_EEP_FASTFRAME, AH_FALSE); ath_hal_eepromSet(ah, AR_EEP_TURBO5DISABLE, AH_TRUE); ath_hal_eepromSet(ah, AR_EEP_TURBO2DISABLE, AH_TRUE); } /* 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; if (ath_hal_eepromGetFlag(ah, AR_EEP_GMODE) && ahpriv->ah_subvendorid != AR_SUBVENDOR_ID_NOG) { pCap->halWirelessModes |= HAL_MODE_11G; if (!ath_hal_eepromGetFlag(ah, AR_EEP_TURBO2DISABLE)) pCap->halWirelessModes |= HAL_MODE_108G; } pCap->halLow2GhzChan = 2312; /* XXX 2417 too? */ if (IS_RAD5112_ANY(ah) || IS_5413(ah) || IS_2425(ah) || IS_2417(ah)) pCap->halHigh2GhzChan = 2500; else pCap->halHigh2GhzChan = 2732; pCap->halLow5GhzChan = 4915; pCap->halHigh5GhzChan = 6100; pCap->halCipherCkipSupport = AH_FALSE; pCap->halCipherTkipSupport = AH_TRUE; pCap->halCipherAesCcmSupport = (ath_hal_eepromGetFlag(ah, AR_EEP_AES) && ((AH_PRIVATE(ah)->ah_macVersion > AR_SREV_VERSION_VENICE) || ((AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_VENICE) && (AH_PRIVATE(ah)->ah_macRev >= AR_SREV_VERSION_OAHU)))); pCap->halMicCkipSupport = AH_FALSE; pCap->halMicTkipSupport = AH_TRUE; pCap->halMicAesCcmSupport = ath_hal_eepromGetFlag(ah, AR_EEP_AES); /* * Starting with Griffin TX+RX mic keys can be combined * in one key cache slot. */ if (AH_PRIVATE(ah)->ah_macVersion >= AR_SREV_VERSION_GRIFFIN) pCap->halTkipMicTxRxKeySupport = AH_TRUE; else pCap->halTkipMicTxRxKeySupport = AH_FALSE; pCap->halChanSpreadSupport = AH_TRUE; pCap->halSleepAfterBeaconBroken = AH_TRUE; if (ahpriv->ah_macRev > 1 || IS_COBRA(ah)) { pCap->halCompressSupport = ath_hal_eepromGetFlag(ah, AR_EEP_COMPRESS) && (pCap->halWirelessModes & (HAL_MODE_11A|HAL_MODE_11G)) != 0; pCap->halBurstSupport = ath_hal_eepromGetFlag(ah, AR_EEP_BURST); pCap->halFastFramesSupport = ath_hal_eepromGetFlag(ah, AR_EEP_FASTFRAME) && (pCap->halWirelessModes & (HAL_MODE_11A|HAL_MODE_11G)) != 0; pCap->halChapTuningSupport = AH_TRUE; pCap->halTurboPrimeSupport = AH_TRUE; } pCap->halTurboGSupport = pCap->halWirelessModes & HAL_MODE_108G; pCap->halPSPollBroken = AH_TRUE; /* XXX fixed in later revs? */ pCap->halVEOLSupport = AH_TRUE; pCap->halBssIdMaskSupport = AH_TRUE; pCap->halMcastKeySrchSupport = AH_TRUE; if ((ahpriv->ah_macVersion == AR_SREV_VERSION_VENICE && ahpriv->ah_macRev == 8) || ahpriv->ah_macVersion > AR_SREV_VERSION_VENICE) pCap->halTsfAddSupport = AH_TRUE; if (ath_hal_eepromGet(ah, AR_EEP_MAXQCU, &val) == HAL_OK) pCap->halTotalQueues = val; else pCap->halTotalQueues = HAL_NUM_TX_QUEUES; if (ath_hal_eepromGet(ah, AR_EEP_KCENTRIES, &val) == HAL_OK) pCap->halKeyCacheSize = val; else pCap->halKeyCacheSize = AR_KEYTABLE_SIZE; pCap->halChanHalfRate = AH_TRUE; pCap->halChanQuarterRate = AH_TRUE; 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; } /* NB: this is a guess, noone seems to know the answer */ ahpriv->ah_rxornIsFatal = (AH_PRIVATE(ah)->ah_macVersion < AR_SREV_VERSION_VENICE); /* h/w phy counters first appeared in Hainan */ pCap->halHwPhyCounterSupport = (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_VENICE && AH_PRIVATE(ah)->ah_macRev == AR_SREV_HAINAN) || AH_PRIVATE(ah)->ah_macVersion > AR_SREV_VERSION_VENICE; pCap->halTstampPrecision = 15; return AH_TRUE;#undef IS_COBRA#undef IS_GRIFFIN_LITE#undef AR_KEYTABLE_SIZE}static const char*ar5212Probe(uint16_t vendorid, uint16_t devid){ if (vendorid == ATHEROS_VENDOR_ID || vendorid == ATHEROS_3COM_VENDOR_ID || vendorid == ATHEROS_3COM2_VENDOR_ID) { switch (devid) { case AR5212_FPGA: return "Atheros 5212 (FPGA)"; case AR5212_DEVID: case AR5212_DEVID_IBM: case AR5212_DEFAULT: return "Atheros 5212"; case AR5212_AR2413: return "Atheros 2413"; case AR5212_AR2417: return "Atheros 2417"; case AR5212_AR5413: return "Atheros 5413"; case AR5212_AR5424: return "Atheros 5424/2424"; } } return AH_NULL;}AH_CHIP(AR5212, ar5212Probe, ar5212Attach);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -