📄 ar5212_misc.c
字号:
if (us > ath_hal_mac_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) { HALDEBUG(ah, "%s: bad ack timeout %u\n", __func__, us); ahp->ah_acktimeout = (u_int) -1; /* restore default handling */ return AH_FALSE; } else { /* convert to system clocks */ OS_REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, ath_hal_mac_clks(ah, us)); ahp->ah_acktimeout = us; return AH_TRUE; }}u_intar5212GetAckTimeout(struct ath_hal *ah){ u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_ACK); return ath_hal_mac_usec(ah, clks); /* convert from system clocks */}HAL_BOOLar5212SetCTSTimeout(struct ath_hal *ah, u_int us){ struct ath_hal_5212 *ahp = AH5212(ah); if (us > ath_hal_mac_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) { HALDEBUG(ah, "%s: bad cts timeout %u\n", __func__, us); ahp->ah_ctstimeout = (u_int) -1; /* restore default handling */ return AH_FALSE; } else { /* convert to system clocks */ OS_REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_CTS, ath_hal_mac_clks(ah, us)); ahp->ah_ctstimeout = us; return AH_TRUE; }}u_intar5212GetCTSTimeout(struct ath_hal *ah){ u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_CTS); return ath_hal_mac_usec(ah, clks); /* convert from system clocks */}/* Setup decompression for given key index */HAL_BOOLar5212SetDecompMask(struct ath_hal *ah, u_int16_t keyidx, int en){ if (IS_5416(ah)) return HAL_OK; if (keyidx > HAL_DECOMP_MASK_SIZE) { return HAL_EINVAL; } OS_REG_WRITE(ah, AR_DCM_A, keyidx); OS_REG_WRITE(ah, AR_DCM_D, en ? AR_DCM_D_EN : 0); ah->ah_decompMask[keyidx] = en; return HAL_OK;}/* Setup coverage class */voidar5212SetCoverageClass(struct ath_hal *ah, u_int8_t coverageclass, int now){ u_int32_t slot, timeout, eifs; u_int clkRate; AH_PRIVATE(ah)->ah_coverageClass = coverageclass; if (now) { if (AH_PRIVATE(ah)->ah_coverageClass == 0) return; /* Don't apply coverage class to non A channels */ if (!IS_CHAN_A(AH_PRIVATE(ah)->ah_curchan)) return; /* Get clock rate */ clkRate = ath_hal_mac_clks(ah, 1); /* Compute EIFS */ if (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) { slot = IFS_SLOT_HALF_RATE + (coverageclass * 3 * (clkRate >> 1)); eifs = IFS_EIFS_HALF_RATE + (coverageclass * 6 * (clkRate >> 1)); } else if (IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan)) { slot = IFS_SLOT_QUARTER_RATE + (coverageclass * 3 * (clkRate >> 2)); eifs = IFS_EIFS_QUARTER_RATE + (coverageclass * 6 * (clkRate >> 2)); } else { /* full rate */ slot = IFS_SLOT_FULL_RATE + (coverageclass * 3 * clkRate); eifs = IFS_EIFS_FULL_RATE + (coverageclass * 6 * clkRate); } /* Add additional time for air propagation for ACK and CTS * timeouts. This value is in core clocks. */ timeout = (ACK_CTS_TIMEOUT_11A + ((coverageclass * 3) * clkRate)) & AR_TIME_OUT_ACK; /* Write the values back to registers: slot, eifs, ack/cts * timeouts. */ OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, slot); OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS, eifs); OS_REG_WRITE(ah, AR_TIME_OUT, ((timeout << AR_TIME_OUT_CTS_S) | timeout)); } return;}voidar5212SetPCUConfig(struct ath_hal *ah){ ar5212SetOperatingMode(ah, AH_PRIVATE(ah)->ah_opmode);}/* * Return whether an external 32KHz crystal should be used * to reduce power consumption when sleeping. We do so if * the crystal is present (obtained from EEPROM) and if we * are not running as an AP and are configured to use it. */HAL_BOOLar5212Use32KHzclock(struct ath_hal *ah, HAL_OPMODE opmode){ if (opmode != HAL_M_HOSTAP) { struct ath_hal_5212 *ahp = AH5212(ah); return ahp->ah_exist32kHzCrystal && (ahp->ah_enable32kHzClock == USE_32KHZ || ahp->ah_enable32kHzClock == AUTO_32KHZ); } else return AH_FALSE;}/* * If 32KHz clock exists, use it to lower power consumption during sleep * * Note: If clock is set to 32 KHz, delays on accessing certain * baseband registers (27-31, 124-127) are required. */voidar5212SetupClock(struct ath_hal *ah, HAL_OPMODE opmode){ if (ar5212Use32KHzclock(ah, opmode)) { /* * Enable clocks to be turned OFF in BB during sleep * and also enable turning OFF 32MHz/40MHz Refclk * from A2. */ OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_CONTROL, 0x1f); OS_REG_WRITE(ah, AR_PHY_REFCLKPD, IS_5112(ah) ? 0x14 : 0x18); OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32, 1); OS_REG_WRITE(ah, AR_TSF_PARM, 61); /* 32 KHz TSF incr */ OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_SEL, 1); if (IS_2413(ah) || IS_5413(ah)) { OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_LIMIT, 0x26); OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0d); OS_REG_WRITE(ah, AR_PHY_M_SLEEP, 0x07); OS_REG_WRITE(ah, AR_PHY_REFCLKDLY, 0x3f); /* # Set sleep clock rate to 32 KHz. */ OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_RATE_IND, 0x2); } else { OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_LIMIT, 0x0a); OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0c); OS_REG_WRITE(ah, AR_PHY_M_SLEEP, 0x03); OS_REG_WRITE(ah, AR_PHY_REFCLKDLY, 0x20); OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_RATE_IND, 0x3); } } else { OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_CONTROL, 0x1f); OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_LIMIT, 0x7f); OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e); OS_REG_WRITE(ah, AR_PHY_M_SLEEP, 0x0c); OS_REG_WRITE(ah, AR_PHY_REFCLKDLY, 0xff); OS_REG_WRITE(ah, AR_PHY_REFCLKPD, IS_5112(ah) ? 0x14 : 0x18); }}/* * If 32KHz clock exists, turn it off and turn back on the 32Mhz */voidar5212RestoreClock(struct ath_hal *ah, HAL_OPMODE opmode){ if (ar5212Use32KHzclock(ah, opmode)) { /* # Set sleep clock rate back to 32 MHz. */ OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_RATE_IND, 0); OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_SEL, 0); OS_REG_WRITE(ah, AR_TSF_PARM, 1); /* 32 MHz TSF incr */ OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32, IS_5112(ah) ? 39 : 31); /* * Restore BB registers to power-on defaults */ OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_CONTROL, 0x1f); OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_LIMIT, 0x7f); OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e); OS_REG_WRITE(ah, AR_PHY_M_SLEEP, 0x0c); OS_REG_WRITE(ah, AR_PHY_REFCLKDLY, 0xff); OS_REG_WRITE(ah, AR_PHY_REFCLKPD, IS_5112(ah) ? 0x14 : 0x18); }}HAL_STATUSar5212GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, u_int32_t capability, u_int32_t *result){ struct ath_hal_5212 *ahp = AH5212(ah); const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;#define IS_COBRA(ah) \ (AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_COBRA) switch (type) { case HAL_CAP_CIPHER: /* cipher handled in hardware */ switch (capability) { case HAL_CIPHER_AES_CCM: /* CCM non-compliant upto rev 3 */ return (((AH_PRIVATE(ah)->ah_macRev >= AR_SREV_CRETE) || IS_COBRA(ah)) ? HAL_OK : HAL_ENOTSUPP); case HAL_CIPHER_AES_OCB: case HAL_CIPHER_TKIP: case HAL_CIPHER_WEP: case HAL_CIPHER_MIC: case HAL_CIPHER_CLR: return HAL_OK; default: return HAL_ENOTSUPP; } case HAL_CAP_TKIP_MIC: /* handle TKIP MIC in hardware */ switch (capability) { case 0: /* hardware capability */ return HAL_OK; case 1: return (ahp->ah_staId1Defaults & AR_STA_ID1_CRPT_MIC_ENABLE) ? HAL_OK : HAL_ENXIO; } case HAL_CAP_TKIP_SPLIT: /* hardware TKIP uses split keys */ /* XXX check rev when new parts are available */ return HAL_OK; case HAL_CAP_WME_TKIPMIC: /* hardware can do TKIP MIC when WMM is turned on */ return ((AH_PRIVATE(ah)->ah_macVersion > AR_SREV_VERSION_VENICE) || ((AH_PRIVATE(ah)->ah_macVersion == AR_SREV_VERSION_VENICE) && (AH_PRIVATE(ah)->ah_macRev >= 8))) ? HAL_OK : HAL_ENOTSUPP; case HAL_CAP_PHYCOUNTERS: /* hardware PHY error counters */ return ahp->ah_hasHwPhyCounters ? HAL_OK : HAL_ENXIO; case HAL_CAP_DIVERSITY: /* hardware supports fast diversity */ switch (capability) { case 0: /* hardware capability */ return HAL_OK; case 1: /* current setting */ return (OS_REG_READ(ah, AR_PHY_CCK_DETECT) & AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ? HAL_OK : HAL_ENXIO; case HAL_CAP_STRONG_DIV: *result = OS_REG_READ(ah, AR_PHY_RESTART); *result = MS(*result, AR_PHY_RESTART_DIV_GC); return HAL_OK; } return HAL_EINVAL; case HAL_CAP_TPC: switch (capability) { case 0: /* hardware capability */ return HAL_OK; case 1: return ahp->ah_tpcEnabled ? HAL_OK : HAL_ENXIO; } return HAL_OK; case HAL_CAP_PHYDIAG: /* radar pulse detection capability */ switch(capability) { case HAL_CAP_RADAR: return (ahp->ah_Amode ? HAL_OK: HAL_ENXIO); case HAL_CAP_AR: if ((ahp->ah_Gmode) || (ahp->ah_Bmode)) return HAL_OK; else return HAL_ENXIO; } return HAL_ENXIO; case HAL_CAP_MCAST_KEYSRCH: /* multicast frame keycache search */ switch (capability) { case 0: /* hardware capability */ return HAL_OK; case 1: return (ahp->ah_staId1Defaults & AR_STA_ID1_MCAST_KSRCH) ? HAL_OK : HAL_ENXIO; } return HAL_EINVAL; case HAL_CAP_TSF_ADJUST: /* hardware has beacon tsf adjust */ switch (capability) { case 0: /* hardware capability */ return pCap->halTsfAddSupport ? HAL_OK : HAL_ENOTSUPP; case 1: return (ahp->ah_miscMode & AR_MISC_MODE_TX_ADD_TSF) ? HAL_OK : HAL_ENXIO; } return HAL_EINVAL; default: return ath_hal_getcapability(ah, type, capability, result); }#undef IS_COBRA}HAL_BOOLar5212SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, u_int32_t capability, u_int32_t setting, HAL_STATUS *status){ struct ath_hal_5212 *ahp = AH5212(ah); const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps; u_int32_t v; switch (type) { case HAL_CAP_TKIP_MIC: /* handle TKIP MIC in hardware */ if (setting) ahp->ah_staId1Defaults |= AR_STA_ID1_CRPT_MIC_ENABLE; else ahp->ah_staId1Defaults &= ~AR_STA_ID1_CRPT_MIC_ENABLE; return AH_TRUE; case HAL_CAP_DIVERSITY: if (capability == HAL_CAP_STRONG_DIV) { v = OS_REG_READ(ah, AR_PHY_RESTART); v &= ~AR_PHY_RESTART_DIV_GC; v |= SM(setting, AR_PHY_RESTART_DIV_GC); OS_REG_WRITE(ah, AR_PHY_RESTART, v); return AH_TRUE; } v = OS_REG_READ(ah, AR_PHY_CCK_DETECT); if (setting) v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; else v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, v); return AH_TRUE; case HAL_CAP_DIAG: /* hardware diagnostic support */ /* * NB: could split this up into virtual capabilities, * (e.g. 1 => ACK, 2 => CTS, etc.) but it hardly * seems worth the additional complexity. */#ifdef AH_DEBUG AH_PRIVATE(ah)->ah_diagreg = setting;#else AH_PRIVATE(ah)->ah_diagreg = setting & 0x6; /* ACK+CTS */#endif OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg); return AH_TRUE; case HAL_CAP_TPC: ahp->ah_tpcEnabled = (setting != 0); return AH_TRUE; case HAL_CAP_MCAST_KEYSRCH: /* multicast frame keycache search */ if (setting) ahp->ah_staId1Defaults |= AR_STA_ID1_MCAST_KSRCH; else ahp->ah_staId1Defaults &= ~AR_STA_ID1_MCAST_KSRCH; return AH_TRUE; case HAL_CAP_TSF_ADJUST: /* hardware has beacon tsf adjust */ if (pCap->halTsfAddSupport) { if (setting) ahp->ah_miscMode |= AR_MISC_MODE_TX_ADD_TSF; else ahp->ah_miscMode &= ~AR_MISC_MODE_TX_ADD_TSF; return AH_TRUE; } /* fall thru... */ default: return ath_hal_setcapability(ah, type, capability, setting, status); }}HAL_BOOLar5212GetDiagState(struct ath_hal *ah, int request, const void *args, u_int32_t argsize, void **result, u_int32_t *resultsize){ struct ath_hal_5212 *ahp = AH5212(ah); (void) ahp; if (ath_hal_getdiagstate(ah, request, args, argsize, result, resultsize)) return AH_TRUE;#ifdef AH_PRIVATE_DIAG switch (request) { const EEPROM_POWER_EXPN_5112 *pe; case HAL_DIAG_EEPROM: *result = &ahp->ah_eeprom; *resultsize = sizeof(HAL_EEPROM); return AH_TRUE; case HAL_DIAG_EEPROM_EXP_11A: case HAL_DIAG_EEPROM_EXP_11B: case HAL_DIAG_EEPROM_EXP_11G: pe = &ahp->ah_modePowerArray5112[ request - HAL_DIAG_EEPROM_EXP_11A]; *result = pe->pChannels; *resultsize = (*result == AH_NULL) ? 0 : roundup(sizeof(u_int16_t) * pe->numChannels, sizeof(u_int32_t)) + sizeof(EXPN_DATA_PER_CHANNEL_5112) * pe->numChannels; return AH_TRUE; case HAL_DIAG_RFGAIN: *result = &ahp->ah_gainValues; *resultsize = sizeof(GAIN_VALUES); return AH_TRUE; case HAL_DIAG_RFGAIN_CURSTEP: *result = __DECONST(void *, ahp->ah_gainValues.currStep); *resultsize = (*result == AH_NULL) ? 0 : sizeof(GAIN_OPTIMIZATION_STEP); return AH_TRUE; case HAL_DIAG_PCDAC: *result = ahp->ah_pcdacTable; *resultsize = ahp->ah_pcdacTableSize; return AH_TRUE; case HAL_DIAG_TXRATES: *result = &ahp->ah_ratesArray[0]; *resultsize = sizeof(ahp->ah_ratesArray); return AH_TRUE; case HAL_DIAG_ANI_CURRENT: *result = ar5212AniGetCurrentState(ah); *resultsize = (*result == AH_NULL) ? 0 : sizeof(struct ar5212AniState); return AH_TRUE; case HAL_DIAG_ANI_STATS: *result = ar5212AniGetCurrentStats(ah); *resultsize = (*result == AH_NULL) ? 0 : sizeof(struct ar5212Stats); return AH_TRUE; case HAL_DIAG_ANI_CMD: if (argsize != 2*sizeof(u_int32_t)) return AH_FALSE; ar5212AniControl(ah, ((const u_int32_t *)args)[0], ((const u_int32_t *)args)[1]); return AH_TRUE; case HAL_DIAG_TXCONT: ar5212_ContTxMode(ah, __DECONST(struct ath_desc *, args), argsize); return AH_TRUE;#ifdef AH_SUPPORT_DFS#endif#if 0 case HAL_DIAG_SET_RADAR: if (argsize != 2*sizeof(u_int32_t)) return AH_FALSE; return ar5212SetRadarThresholds(ah, ((const u_int32_t *) args)[0], ((const u_int32_t *) args)[1]); case HAL_DIAG_GET_RADAR: ar5212GetRadarThresholds(ah, (struct ar5212RadarState *) *result); *resultsize = sizeof(struct ar5212RadarState); return AH_TRUE; case HAL_DIAG_USENOL: if (argsize != sizeof(u_int32_t)) return AH_FALSE; ahp->ah_rinfo.rn_useNol = (*((const u_int32_t *) args) != 0) ? AH_TRUE : AH_FALSE; return AH_TRUE; case HAL_DIAG_GET_USENOL: *resultsize = sizeof(u_int32_t); *((u_int32_t *) *result) = ahp->ah_rinfo.rn_useNol; return AH_TRUE;#endif }#endif /* AH_PRIVATE_DIAG */ return AH_FALSE;}voidar5212XrEnable(struct ath_hal *ah){ struct ath_hal_5212 *ahp=AH5212(ah); ahp->ah_xrEnable = AH_TRUE;} voidar5212XrDisable(struct ath_hal *ah){ struct ath_hal_5212 *ahp=AH5212(ah); ahp->ah_xrEnable = AH_FALSE;}#endif /* AH_SUPPORT_AR5212 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -