📄 ar5212_reset.c
字号:
HALDEBUG(ah, "iqCorrMeas = 0x%08x\n", iqCorrMeas); HALDEBUG(ah, "iCoff = %d\n", iCoff); HALDEBUG(ah, "qCoff = %d\n", qCoff);#endif /* Write values and enable correction */ OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4, AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, iCoff); OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4, AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, qCoff); OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4, AR_PHY_TIMING_CTRL4_IQCORR_ENABLE); ahp->ah_bIQCalibration = IQ_CAL_DONE; ichan->iqCalValid = AH_TRUE; ichan->iCoff = iCoff; ichan->qCoff = qCoff; } } else if (!IS_CHAN_B(chan) && ahp->ah_bIQCalibration == IQ_CAL_DONE && !ichan->iqCalValid) { /* * Start IQ calibration if configured channel has changed. * Use a magic number of 15 based on default value. */ OS_REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4, AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX, INIT_IQCAL_LOG_COUNT_MAX); OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4, AR_PHY_TIMING_CTRL4_DO_IQCAL); ahp->ah_bIQCalibration = IQ_CAL_RUNNING; } /* XXX EAR */ /* Check noise floor results */ ar5212GetNf(ah, ichan); if ((ichan->channelFlags & CHANNEL_CW_INT) == 0) { /* run noise floor calibration */ OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); /* Perform calibration for 5Ghz channels and any OFDM on 5112 */ if ((IS_CHAN_5GHZ(chan) || (IS_5112(ah) && IS_CHAN_OFDM(chan))) && !(IS_2413(ah) || IS_5413(ah))) ar5212RequestRfgain(ah); /* XXX EAR */ } else { /* report up and clear internal state */ chan->channelFlags |= CHANNEL_CW_INT; ichan->channelFlags &= ~CHANNEL_CW_INT; } return AH_TRUE;#undef IQ_CAL_TRIES}/* * Write the given reset bit mask into the reset register */static HAL_BOOLar5212SetResetReg(struct ath_hal *ah, u_int32_t resetMask){ u_int32_t mask = resetMask ? resetMask : ~0; HAL_BOOL rt; /* XXX ar5212MacStop & co. */ if (IS_PCIE(ah)) { resetMask &= ~AR_RC_PCI; } (void) OS_REG_READ(ah, AR_RXDP);/* flush any pending MMR writes */ OS_REG_WRITE(ah, AR_RC, resetMask); OS_DELAY(15); /* need to wait at least 128 clocks when reseting PCI before read */ mask &= (AR_RC_MAC | AR_RC_BB); resetMask &= (AR_RC_MAC | AR_RC_BB); rt = ath_hal_wait(ah, AR_RC, mask, resetMask); if ((resetMask & AR_RC_MAC) == 0) { if (isBigEndian()) { /* * Set CFG, little-endian for register * and descriptor accesses. */ mask = INIT_CONFIG_STATUS | AR_CFG_SWRD | AR_CFG_SWRG;#ifndef AH_NEED_DESC_SWAP mask |= AR_CFG_SWTD;#endif OS_REG_WRITE(ah, AR_CFG, LE_READ_4(&mask)); } else OS_REG_WRITE(ah, AR_CFG, INIT_CONFIG_STATUS); if (ar5212SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) (void) OS_REG_READ(ah, AR_ISR_RAC); } return rt;}int16_tar5212GetNoiseFloor(struct ath_hal *ah){ int16_t nf; nf = (OS_REG_READ(ah, AR_PHY(25)) >> 19) & 0x1ff; if (nf & 0x100) nf = 0 - ((nf ^ 0x1ff) + 1); return nf;}/* * Read the NF and check it against the noise floor threshhold */int16_tar5212GetNf(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan){ int16_t nf, nfThresh; if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { HALDEBUG(ah, "%s: NF did not complete in calibration window\n", __func__); nf = 0; } else { /* Finished NF cal, check against threshold */ if (IS_5416(ah)) { u_int16_t nfarray[NUM_NOISEFLOOR_READINGS]= {0}; /* TODO - enhance for multiple chains and ext ch */ ar5416GetNoiseFloor(ah,nfarray); nf = nfarray[0]; } else { nf = ar5212GetNoiseFloor(ah); } if (AH_PRIVATE(ah)->ah_getEepromNoiseFloorThresh(ah, chan, &nfThresh)) { if (nf > nfThresh) { HALDEBUG(ah, "%s: noise floor failed detected; " "detected %d, threshold %d\n", __func__, nf, nfThresh); /* * NB: Don't discriminate 2.4 vs 5Ghz, if this * happens it indicates a problem regardless * of the band. */ chan->channelFlags |= CHANNEL_CW_INT; nf = 0; } } else { nf = 0; } chan->rawNoiseFloor = nf; } return (chan->rawNoiseFloor = nf);}/* * Set up compression configuration registers */voidar5212SetCompRegs(struct ath_hal *ah){ u_int32_t i; /* Check if h/w supports compression */ if (ath_hal_getcapability(ah, HAL_CAP_COMPRESSION, 0, 0) != HAL_OK) { return; } OS_REG_WRITE(ah, AR_DCCFG, 1); OS_REG_WRITE(ah, AR_CCFG, (AR_COMPRESSION_WINDOW_SIZE >> 8) & AR_CCFG_WIN_M); OS_REG_WRITE(ah, AR_CCFG, OS_REG_READ(ah, AR_CCFG) | AR_CCFG_MIB_INT_EN); OS_REG_WRITE(ah, AR_CCUCFG, AR_CCUCFG_RESET_VAL | AR_CCUCFG_CATCHUP_EN); OS_REG_WRITE(ah, AR_CPCOVF, 0); /* reset decompression mask */ for (i = 0; i < HAL_DECOMP_MASK_SIZE; i++) { OS_REG_WRITE(ah, AR_DCM_A, i); OS_REG_WRITE(ah, AR_DCM_D, ah->ah_decompMask[i]); }}#define MAX_ANALOG_START 319 /* XXX *//* * Find analog bits of given parameter data and return a reversed value */static u_int32_tar5212GetRfField(u_int32_t *rfBuf, u_int32_t numBits, u_int32_t firstBit, u_int32_t column){ u_int32_t reg32 = 0, mask, arrayEntry, lastBit; u_int32_t bitPosition, bitsShifted; int32_t bitsLeft; HALASSERT(column <= 3); HALASSERT(numBits <= 32); HALASSERT(firstBit + numBits <= MAX_ANALOG_START); arrayEntry = (firstBit - 1) / 8; bitPosition = (firstBit - 1) % 8; bitsLeft = numBits; bitsShifted = 0; while (bitsLeft > 0) { lastBit = (bitPosition + bitsLeft > 8) ? (8) : (bitPosition + bitsLeft); mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) << (column * 8); reg32 |= (((rfBuf[arrayEntry] & mask) >> (column * 8)) >> bitPosition) << bitsShifted; bitsShifted += lastBit - bitPosition; bitsLeft -= (8 - bitPosition); bitPosition = 0; arrayEntry++; } reg32 = ath_hal_reverseBits(reg32, numBits); return reg32;}/* * Apply Spur Immunity to Boards that require it. * Applies only to OFDM RX operation. */voidar5212SetSpurMitigation(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan){ //struct ath_hal_5212 *ahp=AH5212(ah); u_int32_t pilotMask[2] = {0, 0}, binMagMask[4] = {0, 0, 0 , 0}; u_int16_t i, finalSpur, curChanAsSpur, binWidth = 0, spurDetectWidth, spurChan; int32_t spurDeltaPhase = 0, spurFreqSd = 0, spurOffset, binOffsetNumT16, curBinOffset; int16_t numBinOffsets; u_int16_t magMapFor4[4] = {1, 2, 2, 1}; u_int16_t magMapFor3[3] = {1, 2, 1}; u_int16_t *pMagMap; HAL_BOOL is2GHz = IS_CHAN_2GHZ(ichan); //HAL_EEPROM *ee = &(ahp->ah_eeprom); u_int32_t val;#define CHAN_TO_SPUR(_f, _freq) ( ((_freq) - ((_f) ? 2300 : 4900)) * 10 ) curChanAsSpur = CHAN_TO_SPUR(is2GHz, ichan->channel); if (ichan->mainSpur) { /* Pull out the saved spur value */ finalSpur = ichan->mainSpur; } else { /* * Check if spur immunity should be performed for this channel * Should only be performed once per channel and then saved */ finalSpur = AR_NO_SPUR; spurDetectWidth = HAL_SPUR_CHAN_WIDTH; if (IS_CHAN_TURBO(ichan)) spurDetectWidth *= 2; /* Decide if any spur affects the current channel */ for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { //spurChan = ee->ee_spurChans[i][is2GHz]; spurChan = AH_PRIVATE(ah)->ah_eepromGetSpurChan(ah,i,is2GHz); if (spurChan == AR_NO_SPUR) { break; } if ((curChanAsSpur - spurDetectWidth <= (spurChan & HAL_SPUR_VAL_MASK)) && (curChanAsSpur + spurDetectWidth >= (spurChan & HAL_SPUR_VAL_MASK))) { finalSpur = spurChan & HAL_SPUR_VAL_MASK; break; } } /* Save detected spur (or no spur) for this channel */ ichan->mainSpur = finalSpur; } /* Write spur immunity data */ if (finalSpur == AR_NO_SPUR) { /* Disable Spur Immunity Regs if they appear set */ if (OS_REG_READ(ah, AR_PHY_TIMING_CTRL4) & AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER) { /* Clear Spur Delta Phase, Spur Freq, and enable bits */ OS_REG_RMW_FIELD(ah, AR_PHY_MASK_CTL, AR_PHY_MASK_CTL_RATE, 0); val = OS_REG_READ(ah, AR_PHY_TIMING_CTRL4); val &= ~(AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); OS_REG_WRITE(ah, AR_PHY_MASK_CTL, val); OS_REG_WRITE(ah, AR_PHY_TIMING11, 0); /* Clear pilot masks */ OS_REG_WRITE(ah, AR_PHY_TIMING7, 0); OS_REG_RMW_FIELD(ah, AR_PHY_TIMING8, AR_PHY_TIMING8_PILOT_MASK_2, 0); OS_REG_WRITE(ah, AR_PHY_TIMING9, 0); OS_REG_RMW_FIELD(ah, AR_PHY_TIMING10, AR_PHY_TIMING10_PILOT_MASK_2, 0); /* Clear magnitude masks */ OS_REG_WRITE(ah, AR_PHY_BIN_MASK_1, 0); OS_REG_WRITE(ah, AR_PHY_BIN_MASK_2, 0); OS_REG_WRITE(ah, AR_PHY_BIN_MASK_3, 0); OS_REG_RMW_FIELD(ah, AR_PHY_MASK_CTL, AR_PHY_MASK_CTL_MASK_4, 0); OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_1, 0); OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_2, 0); OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_3, 0); OS_REG_RMW_FIELD(ah, AR_PHY_BIN_MASK2_4, AR_PHY_BIN_MASK2_4_MASK_4, 0); } } else { spurOffset = finalSpur - curChanAsSpur; /* * Spur calculations: * spurDeltaPhase is (spurOffsetIn100KHz / chipFrequencyIn100KHz) << 21 * spurFreqSd is (spurOffsetIn100KHz / sampleFrequencyIn100KHz) << 11 */ switch (ichan->channelFlags & CHANNEL_ALL) { case CHANNEL_A: /* Chip Frequency & sampleFrequency are 40 MHz */ spurDeltaPhase = (spurOffset << 17) / 25; spurFreqSd = spurDeltaPhase >> 10; binWidth = HAL_BIN_WIDTH_BASE_100HZ; break; case CHANNEL_G: /* Chip Frequency is 44MHz, sampleFrequency is 40 MHz */ spurFreqSd = (spurOffset << 8) / 55; spurDeltaPhase = (spurOffset << 17) / 25; binWidth = HAL_BIN_WIDTH_BASE_100HZ; break; case CHANNEL_T: /* Chip Frequency & sampleFrequency are 80 MHz */ case CHANNEL_108G: spurDeltaPhase = (spurOffset << 16) / 25; spurFreqSd = spurDeltaPhase >> 10; binWidth = HAL_BIN_WIDTH_TURBO_100HZ; break; } /* Compute Pilot Mask */ binOffsetNumT16 = ((spurOffset * 1000) << 4) / binWidth; /* The spur is on a bin if it's remainder at times 16 is 0 */ if (binOffsetNumT16 & 0xF) { numBinOffsets = 4; pMagMap = magMapFor4; } else { numBinOffsets = 3; pMagMap = magMapFor3; } for (i = 0; i < numBinOffsets; i++) { if ((binOffsetNumT16 >> 4) > HAL_MAX_BINS_ALLOWED) { HALDEBUG(ah, "Too man bins in spur mitigation\n"); return; } /* Get Pilot Mask values */ curBinOffset = (binOffsetNumT16 >> 4) + i + 25; if ((curBinOffset >= 0) && (curBinOffset <= 32)) { if (curBinOffset <= 25) pilotMask[0] |= 1 << curBinOffset; else if (curBinOffset >= 27) pilotMask[0] |= 1 << (curBinOffset - 1); } else if ((curBinOffset >= 33) && (curBinOffset <= 52)) pilotMask[1] |= 1 << (curBinOffset - 33); /* Get viterbi values */ if ((curBinOffset >= -1) && (curBinOffset <= 14)) binMagMask[0] |= pMagMap[i] << (curBinOffset + 1) * 2; else if ((curBinOffset >= 15) && (curBinOffset <= 30)) binMagMask[1] |= pMagMap[i] << (curBinOffset - 15) * 2; else if ((curBinOffset >= 31) && (curBinOffset <= 46)) binMagMask[2] |= pMagMap[i] << (curBinOffset -31) * 2; else if((curBinOffset >= 47) && (curBinOffset <= 53)) binMagMask[3] |= pMagMap[i] << (curBinOffset -47) * 2; } /* Write Spur Delta Phase, Spur Freq, and enable bits */ OS_REG_RMW_FIELD(ah, AR_PHY_MASK_CTL, AR_PHY_MASK_CTL_RATE, 0xFF); val = OS_REG_READ(ah, AR_PHY_TIMING_CTRL4); val |= (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); OS_REG_WRITE(ah, AR_PHY_TIMING_CTRL4, val); OS_REG_WRITE(ah, AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_IN_AGC | SM(spurFreqSd, AR_PHY_TIMING11_SPUR_FREQ_SD) | SM(spurDeltaPhase, AR_PHY_TIMING11_SPUR_DELTA_PHASE)); /* Write pilot masks */ OS_REG_WRITE(ah, AR_PHY_TIMING7, pilotMask[0]); OS_REG_RMW_FIELD(ah, AR_PHY_TIMING8, AR_PHY_TIMING8_PILOT_MASK_2, pilotMask[1]); OS_REG_WRITE(ah, AR_PHY_TIMING9, pilotMask[0]); OS_REG_RMW_FIELD(ah, AR_PHY_TIMING10, AR_PHY_TIMING10_PILOT_MASK_2, pilotMask[1]); /* Write magnitude masks */ OS_REG_WRITE(ah, AR_PHY_BIN_MASK_1, binMagMask[0]); OS_REG_WRITE(ah, AR_PHY_BIN_MASK_2, binMagMask[1]); OS_REG_WRITE(ah, AR_PHY_BIN_MASK_3, binMagMask[2]); OS_REG_RMW_FIELD(ah, AR_PHY_MASK_CTL, AR_PHY_MASK_CTL_MASK_4, binMagMask[3]); OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_1, binMagMask[0]); OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_2, binMagMask[1]); OS_REG_WRITE(ah, AR_PHY_BIN_MASK2_3, binMagMask[2]); OS_REG_RMW_FIELD(ah, AR_PHY_BIN_MASK2_4, AR_PHY_BIN_MASK2_4_MASK_4, binMagMask[3]); }#undef CHAN_TO_SPUR}/* * Set a limit on the overall output power. Used for dynamic * transmit power control and the like. * * NB: limit is in units of 0.5 dbM. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -