sys/dev/netif/ath/hal/ath_hal/ar5416/ar5416_reset.c
static HAL_BOOL
ar5416SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData,
	const struct ieee80211_channel *chan, int16_t *pTxPowerIndexOffset)
{
    CAL_DATA_PER_FREQ *pRawDataset;
    uint8_t  *pCalBChans = AH_NULL;
    uint16_t pdGainOverlap_t2;
    static uint8_t  pdadcValues[AR5416_NUM_PDADC_VALUES];
    uint16_t gainBoundaries[AR5416_PD_GAINS_IN_MASK];
    uint16_t numPiers, i, j;
    int16_t  tMinCalPower;
    uint16_t numXpdGain, xpdMask;
    uint16_t xpdGainValues[AR5416_NUM_PD_GAINS];
    uint32_t reg32, regOffset, regChainOffset;

    OS_MEMZERO(xpdGainValues, sizeof(xpdGainValues));
    
    xpdMask = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].xpdGain;

    if (IS_EEP_MINOR_V2(ah)) {
        pdGainOverlap_t2 = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pdGainOverlap;
    } else { 
    	pdGainOverlap_t2 = (uint16_t)(MS(OS_REG_READ(ah, AR_PHY_TPCRG5), AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
    }

    if (IEEE80211_IS_CHAN_2GHZ(chan)) {
        pCalBChans = pEepData->calFreqPier2G;
        numPiers = AR5416_NUM_2G_CAL_PIERS;
    } else {
        pCalBChans = pEepData->calFreqPier5G;
        numPiers = AR5416_NUM_5G_CAL_PIERS;
    }

    numXpdGain = 0;
    /* Calculate the value of xpdgains from the xpdGain Mask */
    for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
        if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
            if (numXpdGain >= AR5416_NUM_PD_GAINS) {
                HALASSERT(0);
                break;
            }
            xpdGainValues[numXpdGain] = (uint16_t)(AR5416_PD_GAINS_IN_MASK - i);
            numXpdGain++;
        }
    }
    
    /* Write the detector gain biases and their number */
    OS_REG_WRITE(ah, AR_PHY_TPCRG1, (OS_REG_READ(ah, AR_PHY_TPCRG1) & 
    	~(AR_PHY_TPCRG1_NUM_PD_GAIN | AR_PHY_TPCRG1_PD_GAIN_1 | AR_PHY_TPCRG1_PD_GAIN_2 | AR_PHY_TPCRG1_PD_GAIN_3)) | 
	SM(numXpdGain - 1, AR_PHY_TPCRG1_NUM_PD_GAIN) | SM(xpdGainValues[0], AR_PHY_TPCRG1_PD_GAIN_1 ) |
	SM(xpdGainValues[1], AR_PHY_TPCRG1_PD_GAIN_2) | SM(xpdGainValues[2],  AR_PHY_TPCRG1_PD_GAIN_3));

    for (i = 0; i < AR5416_MAX_CHAINS; i++) {

            if (AR_SREV_OWL_20_OR_LATER(ah) && 
            ( AH5416(ah)->ah_rx_chainmask == 0x5 || AH5416(ah)->ah_tx_chainmask == 0x5) && (i != 0)) {
            /* Regs are swapped from chain 2 to 1 for 5416 2_0 with 
             * only chains 0 and 2 populated 
             */
            regChainOffset = (i == 1) ? 0x2000 : 0x1000;
        } else {
            regChainOffset = i * 0x1000;
        }

        if (pEepData->baseEepHeader.txMask & (1 << i)) {
            if (IEEE80211_IS_CHAN_2GHZ(chan)) {
                pRawDataset = pEepData->calPierData2G[i];
            } else {
                pRawDataset = pEepData->calPierData5G[i];
            }

            ar5416GetGainBoundariesAndPdadcs(ah,  chan, pRawDataset,
                                             pCalBChans, numPiers,
                                             pdGainOverlap_t2,
                                             &tMinCalPower, gainBoundaries,
                                             pdadcValues, numXpdGain);

            if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) {
                /*
                 * Note the pdadc table may not start at 0 dBm power, could be
                 * negative or greater than 0.  Need to offset the power
                 * values by the amount of minPower for griffin
                 */

                OS_REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
                     SM(pdGainOverlap_t2, AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
                     SM(gainBoundaries[0], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)  |
                     SM(gainBoundaries[1], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)  |
                     SM(gainBoundaries[2], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)  |
                     SM(gainBoundaries[3], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
            }

            /* Write the power values into the baseband power table */
            regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;

            for (j = 0; j < 32; j++) {
                reg32 = ((pdadcValues[4*j + 0] & 0xFF) << 0)  |
                    ((pdadcValues[4*j + 1] & 0xFF) << 8)  |
                    ((pdadcValues[4*j + 2] & 0xFF) << 16) |
                    ((pdadcValues[4*j + 3] & 0xFF) << 24) ;
                OS_REG_WRITE(ah, regOffset, reg32);

#ifdef PDADC_DUMP
		ath_hal_printf(ah, "PDADC: Chain %d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d |\n",
			       i,
			       4*j, pdadcValues[4*j],
			       4*j+1, pdadcValues[4*j + 1],
			       4*j+2, pdadcValues[4*j + 2],
			       4*j+3, pdadcValues[4*j + 3]);
#endif
                regOffset += 4;
            }
        }
    }
    *pTxPowerIndexOffset = 0;

    return AH_TRUE;
}
/**************************************************************
 * ar5416SetPowerCalTable
 *
 * Pull the PDADC piers from cal data and interpolate them across the given
 * points as well as from the nearest pier(s) to get a power detector
 * linear voltage to power level table.
 */
ar5416SetPowerCalTable
Pull the PDADC piers from cal data and interpolate them across the given
points as well as from the nearest pier(s) to get a power detector
linear voltage to power level table.
ar5416SetPowerCalTable Pull the PDADC piers from cal data and interpolate them across the given points as well as from the nearest pier ( s ) to get a power detector linear voltage to power level table .
static HAL_BOOL
ar5416SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData,
	const struct ieee80211_channel *chan, int16_t *pTxPowerIndexOffset)
{
    CAL_DATA_PER_FREQ *pRawDataset;
    uint8_t  *pCalBChans = AH_NULL;
    uint16_t pdGainOverlap_t2;
    static uint8_t  pdadcValues[AR5416_NUM_PDADC_VALUES];
    uint16_t gainBoundaries[AR5416_PD_GAINS_IN_MASK];
    uint16_t numPiers, i, j;
    int16_t  tMinCalPower;
    uint16_t numXpdGain, xpdMask;
    uint16_t xpdGainValues[AR5416_NUM_PD_GAINS];
    uint32_t reg32, regOffset, regChainOffset;
    OS_MEMZERO(xpdGainValues, sizeof(xpdGainValues));
    xpdMask = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].xpdGain;
    if (IS_EEP_MINOR_V2(ah)) {
        pdGainOverlap_t2 = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].pdGainOverlap;
    } else { 
    	pdGainOverlap_t2 = (uint16_t)(MS(OS_REG_READ(ah, AR_PHY_TPCRG5), AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
    }
    if (IEEE80211_IS_CHAN_2GHZ(chan)) {
        pCalBChans = pEepData->calFreqPier2G;
        numPiers = AR5416_NUM_2G_CAL_PIERS;
    } else {
        pCalBChans = pEepData->calFreqPier5G;
        numPiers = AR5416_NUM_5G_CAL_PIERS;
    }
    numXpdGain = 0;
    for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
        if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
            if (numXpdGain >= AR5416_NUM_PD_GAINS) {
                HALASSERT(0);
                break;
            }
            xpdGainValues[numXpdGain] = (uint16_t)(AR5416_PD_GAINS_IN_MASK - i);
            numXpdGain++;
        }
    }
    OS_REG_WRITE(ah, AR_PHY_TPCRG1, (OS_REG_READ(ah, AR_PHY_TPCRG1) & 
    	~(AR_PHY_TPCRG1_NUM_PD_GAIN | AR_PHY_TPCRG1_PD_GAIN_1 | AR_PHY_TPCRG1_PD_GAIN_2 | AR_PHY_TPCRG1_PD_GAIN_3)) | 
	SM(numXpdGain - 1, AR_PHY_TPCRG1_NUM_PD_GAIN) | SM(xpdGainValues[0], AR_PHY_TPCRG1_PD_GAIN_1 ) |
	SM(xpdGainValues[1], AR_PHY_TPCRG1_PD_GAIN_2) | SM(xpdGainValues[2],  AR_PHY_TPCRG1_PD_GAIN_3));
    for (i = 0; i < AR5416_MAX_CHAINS; i++) {
            if (AR_SREV_OWL_20_OR_LATER(ah) && 
            ( AH5416(ah)->ah_rx_chainmask == 0x5 || AH5416(ah)->ah_tx_chainmask == 0x5) && (i != 0)) {
            regChainOffset = (i == 1) ? 0x2000 : 0x1000;
        } else {
            regChainOffset = i * 0x1000;
        }
        if (pEepData->baseEepHeader.txMask & (1 << i)) {
            if (IEEE80211_IS_CHAN_2GHZ(chan)) {
                pRawDataset = pEepData->calPierData2G[i];
            } else {
                pRawDataset = pEepData->calPierData5G[i];
            }
            ar5416GetGainBoundariesAndPdadcs(ah,  chan, pRawDataset,
                                             pCalBChans, numPiers,
                                             pdGainOverlap_t2,
                                             &tMinCalPower, gainBoundaries,
                                             pdadcValues, numXpdGain);
            if ((i == 0) || AR_SREV_OWL_20_OR_LATER(ah)) {
                OS_REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
                     SM(pdGainOverlap_t2, AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
                     SM(gainBoundaries[0], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)  |
                     SM(gainBoundaries[1], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)  |
                     SM(gainBoundaries[2], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)  |
                     SM(gainBoundaries[3], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
            }
            regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
            for (j = 0; j < 32; j++) {
                reg32 = ((pdadcValues[4*j + 0] & 0xFF) << 0)  |
                    ((pdadcValues[4*j + 1] & 0xFF) << 8)  |
                    ((pdadcValues[4*j + 2] & 0xFF) << 16) |
                    ((pdadcValues[4*j + 3] & 0xFF) << 24) ;
                OS_REG_WRITE(ah, regOffset, reg32);
#ifdef PDADC_DUMP
		ath_hal_printf(ah, "PDADC: Chain %d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d | PDADC %3d Value %3d |\n",
			       i,
			       4*j, pdadcValues[4*j],
			       4*j+1, pdadcValues[4*j + 1],
			       4*j+2, pdadcValues[4*j + 2],
			       4*j+3, pdadcValues[4*j + 3]);
#endif
                regOffset += 4;
            }
        }
    }
    *pTxPowerIndexOffset = 0;
    return AH_TRUE;
}
static HAL_BOOL ar5416SetPowerCalTable ( struct ath_hal * ah , struct ar5416eeprom * pEepData , const struct ieee80211_channel * chan , int16_t * pTxPowerIndexOffset ) { CAL_DATA_PER_FREQ * pRawDataset ; uint8_t * pCalBChans = AH_NULL ; uint16_t pdGainOverlap_t2 ; static uint8_t pdadcValues [ AR5416_NUM_PDADC_VALUES ] ; uint16_t gainBoundaries [ AR5416_PD_GAINS_IN_MASK ] ; uint16_t numPiers , i , j ; int16_t tMinCalPower ; uint16_t numXpdGain , xpdMask ; uint16_t xpdGainValues [ AR5416_NUM_PD_GAINS ] ; uint32_t reg32 , regOffset , regChainOffset ; OS_MEMZERO ( xpdGainValues , sizeof ( xpdGainValues ) ) ; xpdMask = pEepData -> modalHeader [ IEEE80211_IS_CHAN_2GHZ ( chan ) ] . xpdGain ; if ( IS_EEP_MINOR_V2 ( ah ) ) { pdGainOverlap_t2 = pEepData -> modalHeader [ IEEE80211_IS_CHAN_2GHZ ( chan ) ] . pdGainOverlap ; } else { pdGainOverlap_t2 = ( uint16_t ) ( MS ( OS_REG_READ ( ah , AR_PHY_TPCRG5 ) , AR_PHY_TPCRG5_PD_GAIN_OVERLAP ) ) ; } if ( IEEE80211_IS_CHAN_2GHZ ( chan ) ) { pCalBChans = pEepData -> calFreqPier2G ; numPiers = AR5416_NUM_2G_CAL_PIERS ; } else { pCalBChans = pEepData -> calFreqPier5G ; numPiers = AR5416_NUM_5G_CAL_PIERS ; } numXpdGain = 0 ; for ( i = 1 ; i <= AR5416_PD_GAINS_IN_MASK ; i ++ ) { if ( ( xpdMask >> ( AR5416_PD_GAINS_IN_MASK - i ) ) & 1 ) { if ( numXpdGain >= AR5416_NUM_PD_GAINS ) { HALASSERT ( 0 ) ; break ; } xpdGainValues [ numXpdGain ] = ( uint16_t ) ( AR5416_PD_GAINS_IN_MASK - i ) ; numXpdGain ++ ; } } OS_REG_WRITE ( ah , AR_PHY_TPCRG1 , ( OS_REG_READ ( ah , AR_PHY_TPCRG1 ) & ~ ( AR_PHY_TPCRG1_NUM_PD_GAIN | AR_PHY_TPCRG1_PD_GAIN_1 | AR_PHY_TPCRG1_PD_GAIN_2 | AR_PHY_TPCRG1_PD_GAIN_3 ) ) | SM ( numXpdGain - 1 , AR_PHY_TPCRG1_NUM_PD_GAIN ) | SM ( xpdGainValues [ 0 ] , AR_PHY_TPCRG1_PD_GAIN_1 ) | SM ( xpdGainValues [ 1 ] , AR_PHY_TPCRG1_PD_GAIN_2 ) | SM ( xpdGainValues [ 2 ] , AR_PHY_TPCRG1_PD_GAIN_3 ) ) ; for ( i = 0 ; i < AR5416_MAX_CHAINS ; i ++ ) { if ( AR_SREV_OWL_20_OR_LATER ( ah ) && ( AH5416 ( ah ) -> ah_rx_chainmask == 0x5 || AH5416 ( ah ) -> ah_tx_chainmask == 0x5 ) && ( i != 0 ) ) { regChainOffset = ( i == 1 ) ? 0x2000 : 0x1000 ; } else { regChainOffset = i * 0x1000 ; } if ( pEepData -> baseEepHeader . txMask & ( 1 << i ) ) { if ( IEEE80211_IS_CHAN_2GHZ ( chan ) ) { pRawDataset = pEepData -> calPierData2G [ i ] ; } else { pRawDataset = pEepData -> calPierData5G [ i ] ; } ar5416GetGainBoundariesAndPdadcs ( ah , chan , pRawDataset , pCalBChans , numPiers , pdGainOverlap_t2 , & tMinCalPower , gainBoundaries , pdadcValues , numXpdGain ) ; if ( ( i == 0 ) || AR_SREV_OWL_20_OR_LATER ( ah ) ) { OS_REG_WRITE ( ah , AR_PHY_TPCRG5 + regChainOffset , SM ( pdGainOverlap_t2 , AR_PHY_TPCRG5_PD_GAIN_OVERLAP ) | SM ( gainBoundaries [ 0 ] , AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 ) | SM ( gainBoundaries [ 1 ] , AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 ) | SM ( gainBoundaries [ 2 ] , AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 ) | SM ( gainBoundaries [ 3 ] , AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 ) ) ; } regOffset = AR_PHY_BASE + ( 672 << 2 ) + regChainOffset ; for ( j = 0 ; j < 32 ; j ++ ) { reg32 = ( ( pdadcValues [ 4 * j + 0 ] & 0xFF ) << 0 ) | ( ( pdadcValues [ 4 * j + 1 ] & 0xFF ) << 8 ) | ( ( pdadcValues [ 4 * j + 2 ] & 0xFF ) << 16 ) | ( ( pdadcValues [ 4 * j + 3 ] & 0xFF ) << 24 ) ; OS_REG_WRITE ( ah , regOffset , reg32 ) ; #ifdef PDADC_DUMP ath_hal_printf ( ah , " \n " , i , 4 * j , pdadcValues [ 4 * j ] , 4 * j + 1 , pdadcValues [ 4 * j + 1 ] , 4 * j + 2 , pdadcValues [ 4 * j + 2 ] , 4 * j + 3 , pdadcValues [ 4 * j + 3 ] ) ; #endif regOffset += 4 ; } } } * pTxPowerIndexOffset = 0 ; return AH_TRUE ; }
ar5416SetPowerCalTable
 Pull the PDADC piers from cal data and interpolate them across the given
 points as well as from the nearest pier(s) to get a power detector
 linear voltage to power level table.
ar5416SetPowerCalTable Pull the PDADC piers from cal data and interpolate them across the given points as well as from the nearest pier ( s ) to get a power detector linear voltage to power level table .
/* Calculate the value of xpdgains from the xpdGain Mask */ /* Write the detector gain biases and their number */ /* Regs are swapped from chain 2 to 1 for 5416 2_0 with 
             * only chains 0 and 2 populated 
             */ /*
                 * Note the pdadc table may not start at 0 dBm power, could be
                 * negative or greater than 0.  Need to offset the power
                 * values by the amount of minPower for griffin
                 */ /* Write the power values into the baseband power table */