📄 ar5212_reset.c
字号:
HAL_BOOLar5212SetTxPowerLimit(struct ath_hal *ah, u_int32_t limit){ u_int16_t dummyXpdGains[2]; AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER); return AH_PRIVATE(ah)->ah_setTransmitPower(ah, AH_PRIVATE(ah)->ah_curchan, dummyXpdGains);}static const GAIN_OPTIMIZATION_LADDER gainLadder = { 9, /* numStepsInLadder */ 4, /* defaultStepNum */ { { {4, 1, 1, 1}, 6, "FG8"}, { {4, 0, 1, 1}, 4, "FG7"}, { {3, 1, 1, 1}, 3, "FG6"}, { {4, 0, 0, 1}, 1, "FG5"}, { {4, 1, 1, 0}, 0, "FG4"}, /* noJack */ { {4, 0, 1, 0}, -2, "FG3"}, /* halfJack */ { {3, 1, 1, 0}, -3, "FG2"}, /* clip3 */ { {4, 0, 0, 0}, -4, "FG1"}, /* noJack */ { {2, 1, 1, 0}, -6, "FG0"} /* clip2 */ }};const static GAIN_OPTIMIZATION_LADDER gainLadder5112 = { 8, /* numStepsInLadder */ 1, /* defaultStepNum */ { { {3, 0,0,0, 0,0,0}, 6, "FG7"}, /* most fixed gain */ { {2, 0,0,0, 0,0,0}, 0, "FG6"}, { {1, 0,0,0, 0,0,0}, -3, "FG5"}, { {0, 0,0,0, 0,0,0}, -6, "FG4"}, { {0, 1,1,0, 0,0,0}, -8, "FG3"}, { {0, 1,1,0, 1,1,0}, -10, "FG2"}, { {0, 1,0,1, 1,1,0}, -13, "FG1"}, { {0, 1,0,1, 1,0,1}, -16, "FG0"}, /* least fixed gain */ }};/* * Initialize the gain structure to good values */voidar5212InitializeGainValues(struct ath_hal *ah){ struct ath_hal_5212 *ahp = AH5212(ah); GAIN_VALUES *gv = &ahp->ah_gainValues; /* initialize gain optimization values */ if (IS_5112(ah)) { gv->currStepNum = gainLadder5112.defaultStepNum; gv->currStep = &gainLadder5112.optStep[gainLadder5112.defaultStepNum]; gv->active = AH_TRUE; gv->loTrig = 20; gv->hiTrig = 85; } else { gv->currStepNum = gainLadder.defaultStepNum; gv->currStep = &gainLadder.optStep[gainLadder.defaultStepNum]; gv->active = AH_TRUE; gv->loTrig = 20; gv->hiTrig = 35; }}static HAL_BOOLar5212InvalidGainReadback(struct ath_hal *ah, GAIN_VALUES *gv){ u_int32_t gStep, g, mixOvr; u_int32_t L1, L2, L3, L4; if (IS_5112(ah)) { mixOvr = ar5212GetRfField(ar5212GetRfBank(ah, 7), 1, 36, 0); L1 = 0; L2 = 107; L3 = 0; L4 = 107; if (mixOvr == 1) { L2 = 83; L4 = 83; gv->hiTrig = 55; } } else { gStep = ar5212GetRfField(ar5212GetRfBank(ah, 7), 6, 37, 0); L1 = 0; L2 = (gStep == 0x3f) ? 50 : gStep + 4; L3 = (gStep != 0x3f) ? 0x40 : L1; L4 = L3 + 50; gv->loTrig = L1 + (gStep == 0x3f ? DYN_ADJ_LO_MARGIN : 0); /* never adjust if != 0x3f */ gv->hiTrig = L4 - (gStep == 0x3f ? DYN_ADJ_UP_MARGIN : -5); } g = gv->currGain; return !((g >= L1 && g<= L2) || (g >= L3 && g <= L4));}/* * Enable the probe gain check on the next packet */static voidar5212RequestRfgain(struct ath_hal *ah){ struct ath_hal_5212 *ahp = AH5212(ah); u_int32_t probePowerIndex; /* Enable the gain readback probe */ probePowerIndex = ahp->ah_ofdmTxPower + ahp->ah_txPowerIndexOffset; OS_REG_WRITE(ah, AR_PHY_PAPD_PROBE, SM(probePowerIndex, AR_PHY_PAPD_PROBE_POWERTX) | AR_PHY_PAPD_PROBE_NEXT_TX); ahp->ah_rfgainState = HAL_RFGAIN_READ_REQUESTED;}/* * Exported call to check for a recent gain reading and return * the current state of the thermal calibration gain engine. */HAL_RFGAINar5212GetRfgain(struct ath_hal *ah){ struct ath_hal_5212 *ahp = AH5212(ah); GAIN_VALUES *gv = &ahp->ah_gainValues; u_int32_t rddata, probeType; if (IS_5416(ah)) return HAL_RFGAIN_INACTIVE; if (!gv->active) return HAL_RFGAIN_INACTIVE; if (ahp->ah_rfgainState == HAL_RFGAIN_READ_REQUESTED) { /* Caller had asked to setup a new reading. Check it. */ rddata = OS_REG_READ(ah, AR_PHY_PAPD_PROBE); if ((rddata & AR_PHY_PAPD_PROBE_NEXT_TX) == 0) { /* bit got cleared, we have a new reading. */ gv->currGain = rddata >> AR_PHY_PAPD_PROBE_GAINF_S; probeType = MS(rddata, AR_PHY_PAPD_PROBE_TYPE); if (probeType == AR_PHY_PAPD_PROBE_TYPE_CCK) { HALASSERT(IS_5112(ah)); if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2) gv->currGain += ahp->ah_cckOfdmGainDelta; else gv->currGain += PHY_PROBE_CCK_CORRECTION; } if (IS_5112(ah)) { ar5212GetGainFCorrection(ah); if (gv->currGain >= gv->gainFCorrection) gv->currGain -= gv->gainFCorrection; else gv->currGain = 0; } /* inactive by default */ ahp->ah_rfgainState = HAL_RFGAIN_INACTIVE; if (!ar5212InvalidGainReadback(ah, gv) && ar5212IsGainAdjustNeeded(ah, gv) && ar5212AdjustGain(ah, gv) > 0) { /* * Change needed. Copy ladder info * into eeprom info. */ ahp->ah_rfgainState = HAL_RFGAIN_NEED_CHANGE; /* WAR 18034 */ AH_PRIVATE(ah)->ah_cwCalRequire = AH_TRUE; /* Request IQ recalibration for temperature chang */ ahp->ah_bIQCalibration = IQ_CAL_INACTIVE; } } } return ahp->ah_rfgainState;}/* * Check to see if our readback gain level sits within the linear * region of our current variable attenuation window */static HAL_BOOLar5212IsGainAdjustNeeded(struct ath_hal *ah, const GAIN_VALUES *gv){ return (gv->currGain <= gv->loTrig || gv->currGain >= gv->hiTrig);}/* * Move the rabbit ears in the correct direction. */static int32_t ar5212AdjustGain(struct ath_hal *ah, GAIN_VALUES *gv){ const GAIN_OPTIMIZATION_LADDER *gl; if (IS_5112(ah)) gl = &gainLadder5112; else gl = &gainLadder; gv->currStep = &gl->optStep[gv->currStepNum]; if (gv->currGain >= gv->hiTrig) { if (gv->currStepNum == 0) { HALDEBUG(ah, "%s: Max gain limit.\n", __func__); return -1; } HALDEBUG(ah, "%s: Adding gain: currG=%d [%s] --> ", __func__, gv->currGain, gv->currStep->stepName); gv->targetGain = gv->currGain; while (gv->targetGain >= gv->hiTrig && gv->currStepNum > 0) { gv->targetGain -= 2 * (gl->optStep[--(gv->currStepNum)].stepGain - gv->currStep->stepGain); gv->currStep = &gl->optStep[gv->currStepNum]; } HALDEBUG(ah, "targG=%d [%s]\n", gv->targetGain, gv->currStep->stepName); return 1; } if (gv->currGain <= gv->loTrig) { if (gv->currStepNum == gl->numStepsInLadder-1) { HALDEBUG(ah, "%s: Min gain limit.\n", __func__); return -2; } HALDEBUG(ah, "%s: Deducting gain: currG=%d [%s] --> ", __func__, gv->currGain, gv->currStep->stepName); gv->targetGain = gv->currGain; while (gv->targetGain <= gv->loTrig && gv->currStepNum < (gl->numStepsInLadder - 1)) { gv->targetGain -= 2 * (gl->optStep[++(gv->currStepNum)].stepGain - gv->currStep->stepGain); gv->currStep = &gl->optStep[gv->currStepNum]; } HALDEBUG(ah, "targG=%d [%s]\n", gv->targetGain, gv->currStep->stepName); return 2; } return 0; /* caller didn't call needAdjGain first */}/* * Read rf register to determine if gainF needs correction */static voidar5212GetGainFCorrection(struct ath_hal *ah){ struct ath_hal_5212 *ahp = AH5212(ah); GAIN_VALUES *gv = &ahp->ah_gainValues; HALASSERT(IS_RADX112_REV2(ah)); gv->gainFCorrection = 0; if (ar5212GetRfField(ar5212GetRfBank(ah, 7), 1, 36, 0) == 1) { u_int32_t mixGain = gv->currStep->paramVal[0]; u_int32_t gainStep = ar5212GetRfField(ar5212GetRfBank(ah, 7), 4, 32, 0); switch (mixGain) { case 0 : gv->gainFCorrection = 0; break; case 1 : gv->gainFCorrection = gainStep; break; case 2 : gv->gainFCorrection = 2 * gainStep - 5; break; case 3 : gv->gainFCorrection = 2 * gainStep; break; } }}/* * Perform analog "swizzling" of parameters into their location */voidar5212ModifyRfBuffer(u_int32_t *rfBuf, u_int32_t reg32, u_int32_t numBits, u_int32_t firstBit, u_int32_t column){ u_int32_t tmp32, mask, arrayEntry, lastBit; int32_t bitPosition, bitsLeft; HALASSERT(column <= 3); HALASSERT(numBits <= 32); HALASSERT(firstBit + numBits <= MAX_ANALOG_START); tmp32 = ath_hal_reverseBits(reg32, numBits); arrayEntry = (firstBit - 1) / 8; bitPosition = (firstBit - 1) % 8; bitsLeft = numBits; while (bitsLeft > 0) { lastBit = (bitPosition + bitsLeft > 8) ? 8 : bitPosition + bitsLeft; mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) << (column * 8); rfBuf[arrayEntry] &= ~mask; rfBuf[arrayEntry] |= ((tmp32 << bitPosition) << (column * 8)) & mask; bitsLeft -= 8 - bitPosition; tmp32 = tmp32 >> (8 - bitPosition); bitPosition = 0; arrayEntry++; }}/* * Sets the rate to duration values in MAC - used for multi- * rate retry. * The rate duration table needs to cover all valid rate codes; * the XR table covers all ofdm and xr rates, while the 11b table * covers all cck rates => all valid rates get covered between * these two mode's ratetables! * But if we're turbo, the ofdm phy is replaced by the turbo phy * and xr or cck is not valid with turbo => all rates get covered * by the turbo ratetable only */voidar5212SetRateDurationTable(struct ath_hal *ah, HAL_CHANNEL *chan){#define WLAN_CTRL_FRAME_SIZE (2+2+6+4) /* ACK+FCS */ const HAL_RATE_TABLE *rt; int i; if (IS_5416(ah)) return; if (IS_CHAN_HALF_RATE(chan)) { rt = ah->ah_getRateTable(ah, HAL_MODE_11A_HALF_RATE); } else if (IS_CHAN_QUARTER_RATE(chan)) { rt = ah->ah_getRateTable(ah, HAL_MODE_11A_QUARTER_RATE); } else { rt = ah->ah_getRateTable(ah, IS_CHAN_TURBO(chan) ? HAL_MODE_TURBO : HAL_MODE_XR); } for (i = 0; i < rt->rateCount; ++i) OS_REG_WRITE(ah, AR_RATE_DURATION(rt->info[i].rateCode), ath_hal_computetxtime(ah, rt, WLAN_CTRL_FRAME_SIZE, rt->info[i].controlRate, AH_FALSE)); if (!IS_CHAN_TURBO(chan)) { /* 11g Table is used to cover the CCK rates. */ rt = ah->ah_getRateTable(ah, HAL_MODE_11G); for (i = 0; i < rt->rateCount; ++i) { u_int32_t reg = AR_RATE_DURATION(rt->info[i].rateCode); if (rt->info[i].phy != IEEE80211_T_CCK) continue; OS_REG_WRITE(ah, reg, ath_hal_computetxtime(ah, rt, WLAN_CTRL_FRAME_SIZE, rt->info[i].controlRate, AH_FALSE)); /* cck rates have short preamble option also */ if (rt->info[i].shortPreamble) { reg += rt->info[i].shortPreamble << 2; OS_REG_WRITE(ah, reg, ath_hal_computetxtime(ah, rt, WLAN_CTRL_FRAME_SIZE, rt->info[i].controlRate, AH_TRUE)); } } }#undef WLAN_CTRL_FRAME_SIZE}/* Adjust various register settings based on half/quarter rate clock setting. * This includes: +USEC, TX/RX latency, * + IFS params: slot, eifs, misc etc. */void ar5212SetIFSTiming(struct ath_hal *ah, HAL_CHANNEL *chan){ u_int32_t txLat, rxLat, usec, slot, refClock, eifs, init_usec; refClock = OS_REG_READ(ah, AR_USEC) & AR_USEC_USEC32; if (IS_CHAN_HALF_RATE(chan)) { slot = IFS_SLOT_HALF_RATE; rxLat = RX_NON_FULL_RATE_LATENCY << AR5212_USEC_RX_LAT_S; txLat = TX_HALF_RATE_LATENCY << AR5212_USEC_TX_LAT_S; usec = HALF_RATE_USEC; eifs = IFS_EIFS_HALF_RATE; init_usec = INIT_USEC >> 1; } else { /* quarter rate */ slot = IFS_SLOT_QUARTER_RATE; rxLat = RX_NON_FULL_RATE_LATENCY << AR5212_USEC_RX_LAT_S; txLat = TX_QUARTER_RATE_LATENCY << AR5212_USEC_TX_LAT_S; usec = QUARTER_RATE_USEC; eifs = IFS_EIFS_QUARTER_RATE; init_usec = INIT_USEC >> 2; } OS_REG_WRITE(ah, AR_USEC, (usec | refClock | txLat | rxLat)); OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, slot); OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS, eifs); OS_REG_RMW_FIELD(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_USEC_DURATION, init_usec); return;}#endif /* AH_SUPPORT_AR5212 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -