📄 ar5212_eeprom.c
字号:
if (ahp->ah_eeversion >= AR_EEPROM_VER5_1) { /* for now always disabled */ OS_REG_WRITE(ah, AR_PHY_HEAVY_CLIP_ENABLE, 0); } return AH_TRUE;#undef AR_PHY_BIS#undef NO_FALSE_DETECT_BACKOFF#undef CB22_FALSE_DETECT_BACKOFF}static HAL_BOOLar5212IsSpurChannel(struct ath_hal *ah, HAL_CHANNEL *chan){ u_int32_t clockFreq = ((IS_5413(ah) || IS_2413(ah) || IS_5112(ah)) ? 40 : 32); return ( ((chan->channel % clockFreq) != 0) && (((chan->channel % clockFreq) < 10) || (((chan->channel) % clockFreq) > 22)) );}static u_int16_t ar5212EepromGetSpurChan(struct ath_hal *ah, u_int16_t i,HAL_BOOL is2GHz){ HAL_EEPROM *eep = (HAL_EEPROM *)&(AH5212(ah)->ah_eeprom); HALASSERT(i < AR_EEPROM_MODAL_SPURS ); return eep->ee_spurChans[i][is2GHz];}/* * Set the transmit power in the baseband for the given * operating channel and mode. */HAL_BOOLar5212SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, u_int16_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 u_int16_t tpcScaleReductionTable[5] = { 0, 3, 6, 9, MAX_RATE_POWER }; struct ath_hal_5212 *ahp = AH5212(ah); int16_t minPower, maxPower, tpcInDb, powerLimit; int i; 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, "%s: unable to set rate table\n", __func__); return AH_FALSE; } if (!ahp->ah_rfHal.setPowerTable(ah, &minPower, &maxPower, chan, rfXpdGain)) { HALDEBUG(ah, "%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 (ahp->ah_eepMap < 2) { /* * WAR to 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)) { u_int16_t cckOfdmPwrDelta; if (chan->channel == 2484) cckOfdmPwrDelta = SCALE_OC_DELTA( ahp->ah_cckOfdmPwrDelta - ahp->ah_scaledCh14FilterCckDelta); else cckOfdmPwrDelta = SCALE_OC_DELTA( ahp->ah_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); u_int16_t *rpow = ahp->ah_ratesArray; u_int16_t twiceMaxEdgePower = MAX_RATE_POWER; u_int16_t twiceMaxEdgePowerCck = MAX_RATE_POWER; u_int16_t twiceMaxRDPower = MAX_RATE_POWER; int i; u_int8_t cfgCtl; int8_t twiceAntennaGain, twiceAntennaReduction; RD_EDGES_POWER *rep; TRGT_POWER_INFO targetPowerOfdm, targetPowerCck; int16_t scaledPower, maxAvailPower = 0; int16_t r13, r9, r7, r0; 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 < ahp->ah_numCtls; i++) { u_int16_t twiceMinEdgePower; if (ahp->ah_ctl[i] == 0) continue; if (ahp->ah_ctl[i] == cfgCtl || cfgCtl == ((ahp->ah_ctl[i] & CTL_MODE_M) | SD_NO_CTL)) { rep = &ahp->ah_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 < ahp->ah_numCtls; i++) { u_int16_t twiceMinEdgePowerCck; if (ahp->ah_ctl[i] == 0) continue; if (ahp->ah_ctl[i] == cfgCtl || cfgCtl == ((ahp->ah_ctl[i] & CTL_MODE_M) | SD_NO_CTL)) { rep = &ahp->ah_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)) { twiceAntennaGain = ahp->ah_antennaGainMax[0]; } else { twiceAntennaGain = ahp->ah_antennaGainMax[1]; } 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, ahp->ah_trgtPwr_11g, ahp->ah_numTargetPwr_11g, &targetPowerOfdm); } else { ar5212GetTargetPowers(ah, chan, ahp->ah_trgtPwr_11a, ahp->ah_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 (ahp->ah_eeversion >= AR_EEPROM_VER3_1) scaledPower = AH_MIN(scaledPower, ahp->ah_turbo2WMaxPower5); /* * EEPROM version 4.0 added an additional * constraint on 2.4GHz channels. */ if (ahp->ah_eeversion >= AR_EEPROM_VER4_0 && IS_CHAN_2GHZ(chan)) scaledPower = AH_MIN(scaledPower, ahp->ah_turbo2WMaxPower2); } maxAvailPower = AH_MIN(scaledPower, targetPowerOfdm.twicePwr6_24); /* Reduce power by max regulatory domain allowed restrictions */ scaledPower = maxAvailPower - (tpcScaleReduction * 2); scaledPower = (scaledPower < 0) ? 0 : scaledPower; scaledPower = AH_MIN(scaledPower, powerLimit); if (commit) { /* Set OFDM rates 9, 12, 18, 24 */ r0 = rpow[0] = rpow[1] = rpow[2] = rpow[3] = rpow[4] = scaledPower; /* Set OFDM rates 36, 48, 54, XR */ rpow[5] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr36); rpow[6] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr48); r7 = rpow[7] = AH_MIN(rpow[0], targetPowerOfdm.twicePwr54); if (ahp->ah_eeversion >= AR_EEPROM_VER4_0) { /* Setup XR target power from EEPROM */ rpow[15] = AH_MIN(scaledPower, IS_CHAN_2GHZ(chan) ? ahp->ah_xrTargetPower2 : ahp->ah_xrTargetPower5); } else { /* XR uses 6mb power */ rpow[15] = rpow[0]; } ahp->ah_ofdmTxPower = *pMaxPower; } else { r0 = scaledPower; r7 = AH_MIN(r0, targetPowerOfdm.twicePwr54); } *pMinPower = r7; *pMaxPower = r0; HALDEBUG(ah, "%s: MaxRD: %d TurboMax: %d MaxCTL: %d " "TPC_Reduction %d chan=%d (0x%x) maxAvailPower=%d pwr6_24=%d, maxPower=%d\n", __func__, twiceMaxRDPower, ahp->ah_turbo2WMaxPower5, twiceMaxEdgePower, tpcScaleReduction * 2, chan->channel, chan->channelFlags, maxAvailPower, targetPowerOfdm.twicePwr6_24, *pMaxPower); } if (IS_CHAN_CCK(chan) || IS_CHAN_G(chan)) { /* Get final CCK target powers */ ar5212GetTargetPowers(ah, chan, ahp->ah_trgtPwr_11b, ahp->ah_numTargetPwr_11b, &targetPowerCck); /* Reduce power by max regulatory domain allowed restrictions */ scaledPower = AH_MIN(twiceMaxEdgePowerCck, twiceMaxRDPower - twiceAntennaReduction); if (maxAvailPower < AH_MIN(scaledPower, targetPowerCck.twicePwr6_24)) maxAvailPower = AH_MIN(scaledPower, targetPowerCck.twicePwr6_24); /* Reduce power by user selection */ scaledPower = AH_MIN(scaledPower, targetPowerCck.twicePwr6_24) - (tpcScaleReduction * 2); scaledPower = (scaledPower < 0) ? 0 : scaledPower; scaledPower = AH_MIN(scaledPower, powerLimit); if (commit) { /* Set CCK rates 2L, 2S, 5.5L, 5.5S, 11L, 11S */ rpow[8] = AH_MIN(scaledPower, targetPowerCck.twicePwr6_24); r9 = rpow[9] = AH_MIN(scaledPower, targetPowerCck.twicePwr36); rpow[10] = rpow[9]; rpow[11] = AH_MIN(scaledPower, targetPowerCck.twicePwr48); rpow[12] = rpow[11]; r13 = rpow[13] = AH_MIN(scaledPower, targetPowerCck.twicePwr54); rpow[14] = rpow[13]; } else { r9 = AH_MIN(scaledPower, targetPowerCck.twicePwr36); r13 = AH_MIN(scaledPower, targetPowerCck.twicePwr54); } /* Set min/max power based off OFDM values or initialization */ if (r13 < *pMinPower) *pMinPower = r13; if (r9 > *pMaxPower) *pMaxPower = r9; HALDEBUG(ah, "%s: cck: MaxRD: %d MaxCTL: %d " "TPC_Reduction %d chan=%d (0x%x) maxAvailPower=%d pwr6_24=%d, maxPower=%d\n", __func__, twiceMaxRDPower, twiceMaxEdgePowerCck, tpcScaleReduction * 2, chan->channel, chan->channelFlags, maxAvailPower, targetPowerCck.twicePwr6_24, *pMaxPower); } if (commit) { ahp->ah_tx6PowerInHalfDbm = *pMaxPower; AH_PRIVATE(ah)->ah_maxPowerLevel = ahp->ah_tx6PowerInHalfDbm; } return AH_TRUE;}/* * Correct for the gain-delta between ofdm and cck mode target * powers. Write the results to the rate table and the power table. * * Conventions : * 1. rpow[ii] is the integer value of 2*(desired power * for the rate ii in dBm) to provide 0.5dB resolution. rate * mapping is as following : * [0..7] --> ofdm 6, 9, .. 48, 54
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -