📄 ar5416_eeprom.c
字号:
/* write previous IQ results */ OS_REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4, AR_PHY_TIMING_CTRL4_IQCORR_ENABLE); OS_REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, pModal->switchSettling); OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize); OS_REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_PGA, pModal->pgaDesiredSize); OS_REG_WRITE(ah, AR_PHY_RF_CTL4, SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON)); OS_REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, pModal->txEndToRxOn); OS_REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62, pModal->thresh62); return AH_TRUE;}#if 0/************************************************************** * ar5416GetEChan * * Construct EEPROM channel makeup from local structs */voidar5416GetEChan(WLAN_DEV_INFO *pDev, CHAN_VALUES *pChval, A_UCHAR txChainSelect, HAL_HT *ht, EEPROM_CHANNEL *pEChan){ ASSERT(txChainSelect); /* Otherwise negative indexing in EEPROM */ pEChan->activeTxChains = ( ((txChainSelect >> 2) & 1) + ((txChainSelect >> 1) & 1) + (txChainSelect & 1)); pEChan->isHt40 = IS_CHAN_HT40(pChval->channelFlags) && (ht->ht_phymode == HAL_HT_PHYMODE_2040); pEChan->is2GHz = IS_CHAN_2GHZ(pChval->channelFlags); if (pEChan->isHt40 && ht) { int ctlDir; pEChan->synthCenter = pEChan->ht40Center = ar5416GetChannelCenter(pDev, ht, pChval); ctlDir = ((ht->ht_extoff == 1) ? (1) : (-1)); pEChan->ctlCenter = (A_UINT16)(pEChan->synthCenter + (ctlDir * 10)); pEChan->extCenter = (A_UINT16)(pEChan->synthCenter - (ctlDir * ((ht->ht_extprotspacing == HAL_HT_EXTPROTSPACING_20) ? (10) : (15)))); } else { pEChan->synthCenter = pEChan->ht40Center = pEChan->ctlCenter = pEChan->extCenter = pChval->channel; }}#endif/************************************************************** * ar5416SetTransmitPower * * Set the transmit power in the baseband for the given * operating channel and mode. */static HAL_BOOLar5416SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *chan, u_int16_t *rfXpdGain){#define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))#define N(a) (sizeof (a) / sizeof (a[0])) MODAL_EEP_HEADER *pModal; struct ath_hal_5416 *ahp; //int16_t ratesArray[Ar5416RateSize] = { 0 }; int16_t ratesArray[Ar5416RateSize]; int16_t txPowerIndexOffset = 0; int i; HAL_HT *ht; u_int16_t cfgCtl; u_int16_t powerLimit; u_int16_t twiceAntennaReduction; u_int16_t twiceMaxRegulatoryPower; ar5416_eeprom_t *pEepData; ahp = AH5416(ah); HALASSERT(owl_get_eep_ver(ahp) == AR5416_EEP_VER); if (IS_5416_EMU_EEP(ah)) return AH_TRUE; /* Setup info for the actual eeprom */ ath_hal_memzero(ratesArray,sizeof(ratesArray)); cfgCtl = ath_hal_getctl(ah, (HAL_CHANNEL *)chan); powerLimit = chan->maxRegTxPower * 2; twiceAntennaReduction = chan->antennaMax; twiceMaxRegulatoryPower = AH_MIN(MAX_RATE_POWER, AH_PRIVATE(ah)->ah_powerLimit); pEepData = (ar5416_eeprom_t *)ahp->ah_5416eeprom; ht = ahp->ah_ht; pModal = &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]); HALDEBUG(ah,"%s Channel=%u CfgCtl=%u\n", __func__,chan->channel, cfgCtl ); if (!ar5416SetPowerPerRateTable(ah, pEepData, ht, chan, &ratesArray[0],cfgCtl, twiceAntennaReduction, twiceMaxRegulatoryPower, powerLimit)) { HALDEBUG(ah, "ar5416EepromSetTransmitPower: unable to set tx power per rate table\n"); return AH_FALSE; } if (!ar5416SetPowerCalTable(ah, ht, pEepData, chan, &txPowerIndexOffset)) { HALDEBUG(ah, "ar5416EepromSetTransmitPower: unable to set power table\n"); return AH_FALSE; } /* * txPowerIndexOffset is set by the SetPowerTable() call - * adjust the rate table (0 offset if rates EEPROM not loaded) */ for (i = 0; i < N(ratesArray); i++) { ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); if (ratesArray[i] > AR5416_MAX_RATE_POWER) ratesArray[i] = AR5416_MAX_RATE_POWER;#ifdef TEMP_POWER_CAP /* * workaround: cap on max power * ratesArray table is in half dB steps */ if (ratesArray[i] > 2 * ath_hal_maxTPC) { ratesArray[i] = 2 * ath_hal_maxTPC; }#endif }#ifdef EEPROM_DUMP ar5416PrintPowerPerRate(ah, ratesArray);#endif /* Write the OFDM power per rate set */ OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, POW_SM(ratesArray[rate18mb], 24) | POW_SM(ratesArray[rate12mb], 16) | POW_SM(ratesArray[rate9mb], 8) | POW_SM(ratesArray[rate6mb], 0) ); OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE2, POW_SM(ratesArray[rate54mb], 24) | POW_SM(ratesArray[rate48mb], 16) | POW_SM(ratesArray[rate36mb], 8) | POW_SM(ratesArray[rate24mb], 0) ); if (IS_CHAN_2GHZ(chan)) { /* Write the CCK power per rate set */ OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, POW_SM(ratesArray[rate2s], 24) | POW_SM(ratesArray[rate2l], 16) | POW_SM(ratesArray[rateXr], 8) /* XR target power */ | POW_SM(ratesArray[rate1l], 0) ); OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, POW_SM(ratesArray[rate11s], 24) | POW_SM(ratesArray[rate11l], 16) | POW_SM(ratesArray[rate5_5s], 8) | POW_SM(ratesArray[rate5_5l], 0) ); } /* Write the HT20 power per rate set */ OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, POW_SM(ratesArray[rateHt20_3], 24) | POW_SM(ratesArray[rateHt20_2], 16) | POW_SM(ratesArray[rateHt20_1], 8) | POW_SM(ratesArray[rateHt20_0], 0) ); OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE6, POW_SM(ratesArray[rateHt20_7], 24) | POW_SM(ratesArray[rateHt20_6], 16) | POW_SM(ratesArray[rateHt20_5], 8) | POW_SM(ratesArray[rateHt20_4], 0) ); if (ht && ht->ht_phymode == HAL_HT_PHYMODE_2040) { /* Write the HT40 power per rate set */ OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE7, POW_SM(ratesArray[rateHt40_3], 24) | POW_SM(ratesArray[rateHt40_2], 16) | POW_SM(ratesArray[rateHt40_1], 8) | POW_SM(ratesArray[rateHt40_0], 0) ); OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE8, POW_SM(ratesArray[rateHt40_7], 24) | POW_SM(ratesArray[rateHt40_6], 16) | POW_SM(ratesArray[rateHt40_5], 8) | POW_SM(ratesArray[rateHt40_4], 0) ); /* Write the Dup/Ext 40 power per rate set */ OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, POW_SM(ratesArray[rateExtOfdm], 24) | POW_SM(ratesArray[rateExtCck], 16) | POW_SM(ratesArray[rateDupOfdm], 8) | POW_SM(ratesArray[rateDupCck], 0) ); } /* Write the Power subtraction for dynamic chain changing */ OS_REG_WRITE(ah, AR_PHY_POWER_TX_SUB, POW_SM(pModal->pwrDecreaseFor3Chain, 6) | POW_SM(pModal->pwrDecreaseFor2Chain, 0) ); return AH_TRUE;}/*************************************** * Helper functions common for AP/CB/XB **************************************//************************************************************** * ar5416SetPowerPerRateTable * * Sets the transmit power in the baseband for the given * operating channel and mode. */static HAL_BOOLar5416SetPowerPerRateTable(struct ath_hal *ah, ar5416_eeprom_t *pEepData, HAL_HT *ht, HAL_CHANNEL_INTERNAL *chan, int16_t *ratesArray, u_int16_t cfgCtl, u_int16_t AntennaReduction, u_int16_t twiceMaxRegulatoryPower, u_int16_t powerLimit){/* Local defines to distinguish between extension and control CTL's */#define EXT_ADDITIVE (0x8000)#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE) u_int16_t twiceMaxEdgePower = AR5416_MAX_RATE_POWER; int i; int16_t twiceLargestAntenna; CAL_CTL_DATA *rep; CAL_TARGET_POWER_LEG targetPowerOfdm, targetPowerCck = {0, {0, 0, 0, 0}}; CAL_TARGET_POWER_LEG targetPowerOfdmExt = {0, {0, 0, 0, 0}}, targetPowerCckExt = {0, {0, 0, 0, 0}}; CAL_TARGET_POWER_HT targetPowerHt20, targetPowerHt40 = {0, {0, 0, 0, 0}}; int16_t scaledPower, minCtlPower; u_int16_t ctlModesFor11a[] = {CTL_11A, CTL_5GHT20, CTL_5GHT40}; u_int16_t ctlModesFor11g[] = {CTL_11B, CTL_11G, CTL_2GHT20, CTL_2GHT40}; u_int16_t numCtlModes, *pCtlMode, ctlMode, freq; CHAN_CENTERS centers; ar5416GetChannelCenters(ah, ht, chan, ¢ers); /* Compute TxPower reduction due to Antenna Gain */ twiceLargestAntenna = AH_MAX(AH_MAX(pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[0], pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[1]), pEepData->modalHeader[IS_CHAN_2GHZ(chan)].antennaGainCh[0]); twiceLargestAntenna = (int16_t)AH_MIN((AntennaReduction) - twiceLargestAntenna, 0); /* scaledPower is the minimum of the user input power level and the regulatory allowed power level */ scaledPower = AH_MIN(powerLimit, twiceMaxRegulatoryPower + twiceLargestAntenna); /* Reduce scaled Power by number of chains active to get to per chain tx power level */ /* TODO: better value than these? */ switch (owl_get_ntxchains(ath_hal_tx_chainmask)) { case 1: break; case 2: scaledPower -= pEepData->modalHeader[IS_CHAN_2GHZ(chan)].pwrDecreaseFor2Chain; break; case 3: scaledPower -= pEepData->modalHeader[IS_CHAN_2GHZ(chan)].pwrDecreaseFor3Chain; break; default: HALASSERT(0); /* Unsupported number of chains */ } scaledPower = AH_MAX(0, scaledPower); /* Get target powers from EEPROM - our baseline for TX Power */ if (IS_CHAN_2GHZ(chan)) { /* Setup for CTL modes */ numCtlModes = N(ctlModesFor11g) - 3; // No ExtCck, ExtOfd, HT40 pCtlMode = ctlModesFor11g; ar5416GetTargetPowersLeg(ah, ht, chan, pEepData->calTargetPowerCck, AR5416_NUM_2G_CCK_TARGET_POWERS, &targetPowerCck, 4, AH_FALSE); ar5416GetTargetPowersLeg(ah, ht, chan, pEepData->calTargetPower2G, AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerOfdm, 4, AH_FALSE); ar5416GetTargetPowers(ah, ht, chan, pEepData->calTargetPower2GHT20, AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerHt20, 8, AH_FALSE); if (ht && ht->ht_phymode == HAL_HT_PHYMODE_2040) { numCtlModes = N(ctlModesFor11g); ar5416GetTargetPowers(ah, ht, chan, pEepData->calTargetPower2GHT40, AR5416_NUM_2G_40_TARGET_POWERS, &targetPowerHt40, 8, AH_TRUE); ar5416GetTargetPowersLeg(ah, ht, chan, pEepData->calTargetPowerCck, AR5416_NUM_2G_CCK_TARGET_POWERS, &targetPowerCckExt, 4, AH_TRUE); ar5416GetTargetPowersLeg(ah, ht, chan, pEepData->calTargetPower2G, AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerOfdmExt, 4, AH_TRUE); } } else { /* Setup for CTL modes */ numCtlModes = N(ctlModesFor11a) - 2; // No Ext or HT40 pCtlMode = ctlModesFor11a; ar5416GetTargetPowersLeg(ah, ht, chan, pEepData->calTargetPower5G, AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerOfdm, 4, AH_FALSE); ar5416GetTargetPowers(ah, ht, chan, pEepData->calTargetPower5GHT20, AR5416_NUM_2G_20_TARGET_POWERS, &targetPowerHt20, 8, AH_FALSE); if (ht && ht->ht_phymode == HAL_HT_PHYMODE_2040) { numCtlModes = N(ctlModesFor11a); // No Ext or HT40 ar5416GetTargetPowers(ah, ht, chan, pEepData->calTargetPower5GHT40, AR5416_NUM_2G_40_TARGET_POWERS, &targetPowerHt40, 8, AH_TRUE); ar5416GetTargetPowersLeg(ah, ht, chan, pEepData->calTargetPower5G, AR5416_NUM_5G_20_TARGET_POWERS, &targetPowerOfdmExt, 4, AH_TRUE); } } /* For MIMO, need to apply regulatory caps individually across dynamically running modes: CCK, OFDM, HT20, HT40 */ for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) { HAL_BOOL isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) || (pCtlMode[ctlMode] == CTL_2GHT40); if (isHt40CtlMode) { freq = centers.ctl_center; } else if (pCtlMode[ctlMode] & EXT_ADDITIVE) { freq = centers.ext_center; } else { freq = centers.ctl_center; } for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) { u_int16_t twiceMinEdgePower; if (((cfgCtl | (pCtlMode[ctlMode] & CTL_MODE_M)) == pEepData->ctlIndex[i]) || ((cfgCtl | (pCtlMode[ctlMode] & CTL_MODE_M))== ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) { rep = &(pEepData->ctlData[i]); twiceMinEdgePower = ar5416GetMaxEdgePower(freq, rep->ctlEdges[owl_get_ntxchains(ath_hal_tx_chainmask)], IS_CHAN_2GHZ(chan)); if (cfgCtl == SD_NO_CTL) { /* Find the minimum of all CTL edge powers that apply to this channel */ twiceMaxEdgePower = AH_MIN(twiceMaxEdgePower, twiceMinEdgePower);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -