⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ar5416_eeprom.c

📁 Atheros wifi driver source code
💻 C
📖 第 1 页 / 共 5 页
字号:
            }            /* 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);//printf("Reg %x = %x\n", regOffset, reg32);                regOffset += 4;            }        }    }    *pTxPowerIndexOffset = 0;    return AH_TRUE;}/************************************************************** * ar5416GetGainBoundariesAndPdadcs * * Uses the data points read from EEPROM to reconstruct the pdadc power table * Called by ar5416SetPowerCalTable only. */static voidar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah, HAL_HT *ht,                                 HAL_CHANNEL_INTERNAL *chan, CAL_DATA_PER_FREQ *pRawDataSet,                                 u_int8_t * bChans,  u_int16_t availPiers,                                 u_int16_t tPdGainOverlap, int16_t *pMinCalPower, u_int16_t * pPdGainBoundaries,                                 u_int8_t * pPDADCValues, u_int16_t numXpdGains){    int       i, j, k;    int16_t   ss;         /* potentially -ve index for taking care of pdGainOverlap */    u_int16_t  idxL, idxR, numPiers; /* Pier indexes */    /* filled out Vpd table for all pdGains (chanL) */    static u_int8_t   vpdTableL[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB];    /* filled out Vpd table for all pdGains (chanR) */    static u_int8_t   vpdTableR[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB];    /* filled out Vpd table for all pdGains (interpolated) */    static u_int8_t   vpdTableI[AR5416_NUM_PD_GAINS][AR5416_MAX_PWR_RANGE_IN_HALF_DB];    u_int8_t   *pVpdL, *pVpdR, *pPwrL, *pPwrR;    u_int8_t   minPwrT4[AR5416_NUM_PD_GAINS];    u_int8_t   maxPwrT4[AR5416_NUM_PD_GAINS];    int16_t   vpdStep;    int16_t   tmpVal;    u_int16_t  sizeCurrVpdTable, maxIndex, tgtIndex;    HAL_BOOL    match;    int16_t  minDelta = 0;    CHAN_CENTERS centers;    ar5416GetChannelCenters(ah, ht, chan, &centers);    /* Trim numPiers for the number of populated channel Piers */    for (numPiers = 0; numPiers < availPiers; numPiers++) {        if (bChans[numPiers] == AR5416_BCHAN_UNUSED) {            break;        }    }    /* Find pier indexes around the current channel */    match = getLowerUpperIndex((u_int8_t)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),        bChans, numPiers, &idxL,        &idxR);    if (match) {        /* Directly fill both vpd tables from the matching index */        for (i = 0; i < numXpdGains; i++) {            minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];            maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];            ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pRawDataSet[idxL].pwrPdg[i],                               pRawDataSet[idxL].vpdPdg[i], AR5416_PD_GAIN_ICEPTS, vpdTableI[i]);        }    } else {        for (i = 0; i < numXpdGains; i++) {            pVpdL = pRawDataSet[idxL].vpdPdg[i];            pPwrL = pRawDataSet[idxL].pwrPdg[i];            pVpdR = pRawDataSet[idxR].vpdPdg[i];            pPwrR = pRawDataSet[idxR].pwrPdg[i];            /* Start Vpd interpolation from the max of the minimum powers */            minPwrT4[i] = AH_MAX(pPwrL[0], pPwrR[0]);            /* End Vpd interpolation from the min of the max powers */            maxPwrT4[i] = AH_MIN(pPwrL[AR5416_PD_GAIN_ICEPTS - 1], pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);            HALASSERT(maxPwrT4[i] > minPwrT4[i]);            /* Fill pier Vpds */            ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrL, pVpdL, AR5416_PD_GAIN_ICEPTS, vpdTableL[i]);            ar5416FillVpdTable(minPwrT4[i], maxPwrT4[i], pPwrR, pVpdR, AR5416_PD_GAIN_ICEPTS, vpdTableR[i]);            /* Interpolate the final vpd */            for (j = 0; j < (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {                vpdTableI[i][j] = (u_int8_t)(interpolate((u_int16_t)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),                    bChans[idxL], bChans[idxR], vpdTableL[i][j], vpdTableR[i][j]));            }        }    }    *pMinCalPower = (int16_t)(minPwrT4[0] / 2);    k = 0; /* index for the final table */    for (i = 0; i < numXpdGains; i++) {        if (i == (numXpdGains - 1)) {            pPdGainBoundaries[i] = (u_int16_t)(maxPwrT4[i] / 2);        } else {            pPdGainBoundaries[i] = (u_int16_t)((maxPwrT4[i] + minPwrT4[i+1]) / 4);        }        pPdGainBoundaries[i] = (u_int16_t)AH_MIN(AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);        //WORKAROUND for OWL 1.0 until we get a per chain gain boundary register.        //this is not the best solution        if ((i == 0) && IS_5416V1(ah) ) {	    //!(AH_PRIVATE(ah)->ah_macRev >= AR_SREV_REVISION_OWL_20)){            //fix the gain delta, but get a delta that can be applied to min to            //keep the upper power values accurate, don't think max needs to            //be adjusted because should not be at that area of the table?            minDelta = pPdGainBoundaries[0] - 23;            pPdGainBoundaries[0] = 23;        }        else {            minDelta = 0;        }        /* Find starting index for this pdGain */        if (i == 0) {            ss = 0; /* for the first pdGain, start from index 0 */        } else {            ss = (int16_t)((pPdGainBoundaries[i-1] - (minPwrT4[i] / 2)) - tPdGainOverlap + 1 + minDelta);        }        vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);        vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);        /*         *-ve ss indicates need to extrapolate data below for this pdGain         */        while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {            tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);            pPDADCValues[k++] = (u_int8_t)((tmpVal < 0) ? 0 : tmpVal);            ss++;        }        sizeCurrVpdTable = (u_int8_t)((maxPwrT4[i] - minPwrT4[i]) / 2);        tgtIndex = (u_int8_t)(pPdGainBoundaries[i] + tPdGainOverlap - (minPwrT4[i] / 2));        maxIndex = (tgtIndex < sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable;        while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {            pPDADCValues[k++] = vpdTableI[i][ss++];        }        vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] - vpdTableI[i][sizeCurrVpdTable - 2]);        vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);        /*         * for last gain, pdGainBoundary == Pmax_t2, so will         * have to extrapolate         */        if (tgtIndex > maxIndex) {  /* need to extrapolate above */            while ((ss <= tgtIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {                tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +                          (ss - maxIndex) * vpdStep));                pPDADCValues[k++] = (u_int8_t)((tmpVal > 255) ? 255 : tmpVal);                ss++;            }        }               /* extrapolated above */    }                   /* for all pdGainUsed */    /* Fill out pdGainBoundaries - only up to 2 allowed here, but hardware allows up to 4 */    while (i < AR5416_PD_GAINS_IN_MASK) {        pPdGainBoundaries[i] = pPdGainBoundaries[i-1];        i++;    }    while (k < AR5416_NUM_PDADC_VALUES) {        pPDADCValues[k] = pPDADCValues[k-1];        k++;    }    return;}/************************************************************** * getLowerUppderIndex * * Return indices surrounding the value in sorted integer lists. * Requirement: the input list must be monotonically increasing *     and populated up to the list size * Returns: match is set if an index in the array matches exactly *     or a the target is before or after the range of the array. */ HAL_BOOLgetLowerUpperIndex(u_int8_t target, u_int8_t *pList, u_int16_t listSize,                   u_int16_t *indexL, u_int16_t *indexR){    u_int16_t i;    /*     * Check first and last elements for beyond ordered array cases.     */    if (target <= pList[0]) {        *indexL = *indexR = 0;        return AH_TRUE;    }    if (target >= pList[listSize-1]) {        *indexL = *indexR = (u_int16_t)(listSize - 1);        return AH_TRUE;    }    /* look for value being near or between 2 values in list */    for (i = 0; i < listSize - 1; i++) {        /*         * If value is close to the current value of the list         * then target is not between values, it is one of the values         */        if (pList[i] == target) {            *indexL = *indexR = i;            return AH_TRUE;        }        /*         * Look for value being between current value and next value         * if so return these 2 values         */        if (target < pList[i + 1]) {            *indexL = i;            *indexR = (u_int16_t)(i + 1);            return AH_FALSE;        }    }    HALASSERT(0);    return AH_FALSE;}/************************************************************** * ar5416FillVpdTable * * Fill the Vpdlist for indices Pmax-Pmin * Note: pwrMin, pwrMax and Vpdlist are all in dBm * 4 */static HAL_BOOLar5416FillVpdTable(u_int8_t pwrMin, u_int8_t pwrMax, u_int8_t *pPwrList,                   u_int8_t *pVpdList, u_int16_t numIntercepts, u_int8_t *pRetVpdList){    u_int16_t  i, k;    u_int8_t   currPwr = pwrMin;    u_int16_t  idxL, idxR;    HALASSERT(pwrMax > pwrMin);    for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {        getLowerUpperIndex(currPwr, pPwrList, numIntercepts,                           &(idxL), &(idxR));        if (idxR < 1)            idxR = 1;           /* extrapolate below */        if (idxL == numIntercepts - 1)            idxL = (u_int16_t)(numIntercepts - 2);   /* extrapolate above */        if (pPwrList[idxL] == pPwrList[idxR])            k = pVpdList[idxL];        else            k = (u_int16_t)( ((currPwr - pPwrList[idxL]) * pVpdList[idxR] + (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /                  (pPwrList[idxR] - pPwrList[idxL]) );        HALASSERT(k < 256);        pRetVpdList[i] = (u_int8_t)k;        currPwr += 2;               /* half dB steps */    }    return AH_TRUE;}/************************************************************************** * interpolate * * Returns signed interpolated or the scaled up interpolated value */static int16_tinterpolate(u_int16_t target, u_int16_t srcLeft, u_int16_t srcRight,            int16_t targetLeft, int16_t targetRight){    int16_t rv;    if (srcRight == srcLeft) {        rv = targetLeft;    } else {        rv = (int16_t)( ((target - srcLeft) * targetRight +              (srcRight - target) * targetLeft) / (srcRight - srcLeft) );    }    return rv;}/************************************************************************** * fbin2freq * * Get channel value from binary representation held in eeprom * RETURNS: the frequency in MHz */static u_int16_tfbin2freq(u_int8_t fbin, HAL_BOOL is2GHz){    /*     * Reserved value 0xFF provides an empty definition both as     * an fbin and as a frequency - do not convert     */    if (fbin == AR5416_BCHAN_UNUSED) {        return fbin;    }    return (u_int16_t)((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));}static HAL_STATUSar5416CheckEeprom(struct ath_hal *ah){    u_int32_t sum,len = 0;    u_int16_t *eepdata;    int i;    struct ath_hal_5416 *ahp = AH5416(ah);    ar5416_eeprom_t *pEeprom = (ar5416_eeprom_t *)ahp->ah_5416eeprom;    /*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -