📄 ar5212_reset.c
字号:
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, HAL_DEBUG_ANY, "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}/* * Delta slope coefficient computation. * Required for OFDM operation. */voidar5212SetDeltaSlope(struct ath_hal *ah, HAL_CHANNEL *chan){#define COEF_SCALE_S 24#define INIT_CLOCKMHZSCALED 0x64000000 unsigned long coef_scaled, coef_exp, coef_man, ds_coef_exp, ds_coef_man; unsigned long clockMhzScaled = INIT_CLOCKMHZSCALED; if (IS_CHAN_TURBO(chan)) clockMhzScaled *= 2; /* half and quarter rate can divide the scaled clock by 2 or 4 respectively */ /* scale for selected channel bandwidth */ if (IS_CHAN_HALF_RATE(chan)) { clockMhzScaled = clockMhzScaled >> 1; } else if (IS_CHAN_QUARTER_RATE(chan)) { clockMhzScaled = clockMhzScaled >> 2; } /* * ALGO -> coef = 1e8/fcarrier*fclock/40; * scaled coef to provide precision for this floating calculation */ coef_scaled = clockMhzScaled / chan->channel; /* * ALGO -> coef_exp = 14-floor(log2(coef)); * floor(log2(x)) is the highest set bit position */ for (coef_exp = 31; coef_exp > 0; coef_exp--) if ((coef_scaled >> coef_exp) & 0x1) break; /* A coef_exp of 0 is a legal bit position but an unexpected coef_exp */ HALASSERT(coef_exp); coef_exp = 14 - (coef_exp - COEF_SCALE_S); /* * ALGO -> coef_man = floor(coef* 2^coef_exp+0.5); * The coefficient is already shifted up for scaling */ coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1)); ds_coef_man = coef_man >> (COEF_SCALE_S - coef_exp); ds_coef_exp = coef_exp - 16; OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, AR_PHY_TIMING3_DSC_MAN, ds_coef_man); OS_REG_RMW_FIELD(ah, AR_PHY_TIMING3, AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);#undef INIT_CLOCKMHZSCALED#undef COEF_SCALE_S}/* * 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. */HAL_BOOLar5212SetTxPowerLimit(struct ath_hal *ah, uint32_t limit){ uint16_t dummyXpdGains[2]; HAL_BOOL ret, isBmode = AH_FALSE; SAVE_CCK(ah, AH_PRIVATE(ah)->ah_curchan, isBmode); AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER); ret = ar5212SetTransmitPower(ah, AH_PRIVATE(ah)->ah_curchan, dummyXpdGains); RESTORE_CCK(ah, AH_PRIVATE(ah)->ah_curchan, isBmode); return ret;}/* * Set the transmit power in the baseband for the given * operating channel and mode. */HAL_BOOLar5212SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, uint16_t *rfXpdGain){#define POW_OFDM(_r, _s) (((0 & 1)<< ((_s)+6)) | (((_r) & 0x3f) << (_s)))#define POW_CCK(_r, _s) (((_r) & 0x3f) << (_s))#define N(a) (sizeof (a) / sizeof (a[0])) static const uint16_t tpcScaleReductionTable[5] = { 0, 3, 6, 9, MAX_RATE_POWER }; struct ath_hal_5212 *ahp = AH5212(ah); const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom; int16_t minPower, maxPower, tpcInDb, powerLimit; int i; HALASSERT(ah->ah_magic == AR5212_MAGIC); OS_MEMZERO(ahp->ah_pcdacTable, ahp->ah_pcdacTableSize); OS_MEMZERO(ahp->ah_ratesArray, sizeof(ahp->ah_ratesArray)); powerLimit = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit); if (powerLimit >= MAX_RATE_POWER || powerLimit == 0) tpcInDb = tpcScaleReductionTable[AH_PRIVATE(ah)->ah_tpScale]; else tpcInDb = 0; if (!ar5212SetRateTable(ah, (HAL_CHANNEL *) chan, tpcInDb, powerLimit, AH_TRUE, &minPower, &maxPower)) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set rate table\n", __func__); return AH_FALSE; } if (!ahp->ah_rfHal->setPowerTable(ah, &minPower, &maxPower, chan, rfXpdGain)) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unable to set power table\n", __func__); return AH_FALSE; } /* * Adjust XR power/rate up by 2 dB to account for greater peak * to avg ratio - except in newer avg power designs */ if (!IS_2413(ah) && !IS_5413(ah)) ahp->ah_ratesArray[15] += 4; /* * txPowerIndexOffset is set by the SetPowerTable() call - * adjust the rate table */ for (i = 0; i < N(ahp->ah_ratesArray); i++) { ahp->ah_ratesArray[i] += ahp->ah_txPowerIndexOffset; if (ahp->ah_ratesArray[i] > 63) ahp->ah_ratesArray[i] = 63; } if (ee->ee_eepMap < 2) { /* * Correct gain deltas for 5212 G operation - * Removed with revised chipset */ if (AH_PRIVATE(ah)->ah_phyRev < AR_PHY_CHIP_ID_REV_2 && IS_CHAN_G(chan)) { uint16_t cckOfdmPwrDelta; if (chan->channel == 2484) cckOfdmPwrDelta = SCALE_OC_DELTA( ee->ee_cckOfdmPwrDelta - ee->ee_scaledCh14FilterCckDelta); else cckOfdmPwrDelta = SCALE_OC_DELTA( ee->ee_cckOfdmPwrDelta); ar5212CorrectGainDelta(ah, cckOfdmPwrDelta); } /* * Finally, write the power values into the * baseband power table */ for (i = 0; i < (PWR_TABLE_SIZE/2); i++) { OS_REG_WRITE(ah, AR_PHY_PCDAC_TX_POWER(i), ((((ahp->ah_pcdacTable[2*i + 1] << 8) | 0xff) & 0xffff) << 16) | (((ahp->ah_pcdacTable[2*i] << 8) | 0xff) & 0xffff) ); } } /* Write the OFDM power per rate set */ OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, POW_OFDM(ahp->ah_ratesArray[3], 24) | POW_OFDM(ahp->ah_ratesArray[2], 16) | POW_OFDM(ahp->ah_ratesArray[1], 8) | POW_OFDM(ahp->ah_ratesArray[0], 0) ); OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, POW_OFDM(ahp->ah_ratesArray[7], 24) | POW_OFDM(ahp->ah_ratesArray[6], 16) | POW_OFDM(ahp->ah_ratesArray[5], 8) | POW_OFDM(ahp->ah_ratesArray[4], 0) ); /* Write the CCK power per rate set */ OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, POW_CCK(ahp->ah_ratesArray[10], 24) | POW_CCK(ahp->ah_ratesArray[9], 16) | POW_CCK(ahp->ah_ratesArray[15], 8) /* XR target power */ | POW_CCK(ahp->ah_ratesArray[8], 0) ); OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, POW_CCK(ahp->ah_ratesArray[14], 24) | POW_CCK(ahp->ah_ratesArray[13], 16) | POW_CCK(ahp->ah_ratesArray[12], 8) | POW_CCK(ahp->ah_ratesArray[11], 0) ); /* * Set max power to 30 dBm and, optionally, * enable TPC in tx descriptors. */ OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX, MAX_RATE_POWER | (ahp->ah_tpcEnabled ? AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE : 0)); return AH_TRUE;#undef N#undef POW_CCK#undef POW_OFDM}/* * Sets the transmit power in the baseband for the given * operating channel and mode. */static HAL_BOOLar5212SetRateTable(struct ath_hal *ah, HAL_CHANNEL *chan, int16_t tpcScaleReduction, int16_t powerLimit, HAL_BOOL commit, int16_t *pMinPower, int16_t *pMaxPower){ struct ath_hal_5212 *ahp = AH5212(ah); const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom; uint16_t *rpow = ahp->ah_ratesArray; uint16_t twiceMaxEdgePower = MAX_RATE_POWER; uint16_t twiceMaxEdgePowerCck = MAX_RATE_POWER; uint16_t twiceMaxRDPower = MAX_RATE_POWER; int i; uint8_t cfgCtl; int8_t twiceAntennaGain, twiceAntennaReduction; const RD_EDGES_POWER *rep; TRGT_POWER_INFO targetPowerOfdm, targetPowerCck; int16_t scaledPower, maxAvailPower = 0; int16_t r13, r9, r7, r0; HALASSERT(ah->ah_magic == AR5212_MAGIC); twiceMaxRDPower = chan->maxRegTxPower * 2; *pMaxPower = -MAX_RATE_POWER; *pMinPower = MAX_RATE_POWER; /* Get conformance test limit maximum for this channel */ cfgCtl = ath_hal_getctl(ah, chan); for (i = 0; i < ee->ee_numCtls; i++) { uint16_t twiceMinEdgePower; if (ee->ee_ctl[i] == 0) continue; if (ee->ee_ctl[i] == cfgCtl || cfgCtl == ((ee->ee_ctl[i] & CTL_MODE_M) | SD_NO_CTL)) { rep = &ee->ee_rdEdgesPower[i * NUM_EDGES]; twiceMinEdgePower = ar5212GetMaxEdgePower(chan->channel, rep); if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { /* Find the minimum of all CTL edge powers that apply to this channel */ twiceMaxEdgePower = AH_MIN(twiceMaxEdgePower, twiceMinEdgePower); } else { twiceMaxEdgePower = twiceMinEdgePower; break; } } } if (IS_CHAN_G(chan)) { /* Check for a CCK CTL for 11G CCK powers */ cfgCtl = (cfgCtl & ~CTL_MODE_M) | CTL_11B; for (i = 0; i < ee->ee_numCtls; i++) { uint16_t twiceMinEdgePowerCck; if (ee->ee_ctl[i] == 0) continue; if (ee->ee_ctl[i] == cfgCtl || cfgCtl == ((ee->ee_ctl[i] & CTL_MODE_M) | SD_NO_CTL)) { rep = &ee->ee_rdEdgesPower[i * NUM_EDGES]; twiceMinEdgePowerCck = ar5212GetMaxEdgePower(chan->channel, rep); if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) { /* Find the minimum of all CTL edge powers that apply to this channel */ twiceMaxEdgePowerCck = AH_MIN(twiceMaxEdgePowerCck, twiceMinEdgePowerCck); } else { twiceMaxEdgePowerCck = twiceMinEdgePowerCck; break; } } } } else { /* Set the 11B cck edge power to the one found before */ twiceMaxEdgePowerCck = twiceMaxEdgePower; } /* Get Antenna Gain reduction */ if (IS_CHAN_5GHZ(chan)) { ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_5, &twiceAntennaGain); } else { ath_hal_eepromGet(ah, AR_EEP_ANTGAINMAX_2, &twiceAntennaGain); } twiceAntennaReduction = ath_hal_getantennareduction(ah, chan, twiceAntennaGain); if (IS_CHAN_OFDM(chan)) { /* Get final OFDM target powers */ if (IS_CHAN_2GHZ(chan)) { ar5212GetTargetPowers(ah, chan, ee->ee_trgtPwr_11g, ee->ee_numTargetPwr_11g, &targetPowerOfdm); } else { ar5212GetTargetPowers(ah, chan, ee->ee_trgtPwr_11a, ee->ee_numTargetPwr_11a, &targetPowerOfdm); } /* Get Maximum OFDM power */ /* Minimum of target and edge powers */ scaledPower = AH_MIN(twiceMaxEdgePower, twiceMaxRDPower - twiceAntennaReduction); /* * If turbo is set, reduce power to keep power * consumption under 2 Watts. Note that we always do * this unless specially configured. Then we limit * power only for non-AP operation. */ if (IS_CHAN_TURBO(chan)#ifdef AH_ENABLE_AP_SUPPORT && AH_PRIVATE(ah)->ah_opmode != HAL_M_HOSTAP#endif ) { /* * If turbo is set, reduce power to keep power * consumption under 2 Watts */ if (ee->ee_version >= AR_EEPROM_VER3_1) scaledPower = AH_MIN(scaledPower, ee-
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -