📄 ar5416_eeprom.c
字号:
} /* 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, ¢ers); /* 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 + -