📄 ar5211_reset.c
字号:
freqIndex = (chan->channelFlags & CHANNEL_2GHZ) ? 2 : 1; /* * TODO: This array mode correspondes with the index used * during the read. * For readability, this should be changed to an enum or #define */ switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) { case CHANNEL_A: if (chan->channel > 4000 && chan->channel < 5260) { tempOB = ahp->ah_ob1; tempDB = ahp->ah_db1; } else if (chan->channel >= 5260 && chan->channel < 5500) { tempOB = ahp->ah_ob2; tempDB = ahp->ah_db2; } else if (chan->channel >= 5500 && chan->channel < 5725) { tempOB = ahp->ah_ob3; tempDB = ahp->ah_db3; } else if (chan->channel >= 5725) { tempOB = ahp->ah_ob4; tempDB = ahp->ah_db4; } else { /* XXX panic?? */ tempOB = tempDB = 0; } rfXpdGain = ahp->ah_xgain[0]; rfPloSel = ahp->ah_xpd[0]; rfPwdXpd = !ahp->ah_xpd[0]; ar5211Rf6n7[5][freqIndex] = (ar5211Rf6n7[5][freqIndex] & ~0x10000000) | (ahp->ah_cornerCal.pd84<< 28); ar5211Rf6n7[6][freqIndex] = (ar5211Rf6n7[6][freqIndex] & ~0x04000000) | (ahp->ah_cornerCal.pd90 << 26); ar5211Rf6n7[21][freqIndex] = (ar5211Rf6n7[21][freqIndex] & ~0x08) | (ahp->ah_cornerCal.gSel << 3); break; case CHANNEL_CCK|CHANNEL_2GHZ: tempOB = ahp->ah_obFor24; tempDB = ahp->ah_dbFor24; rfXpdGain = ahp->ah_xgain[1]; rfPloSel = ahp->ah_xpd[1]; rfPwdXpd = !ahp->ah_xpd[1]; break; case CHANNEL_OFDM|CHANNEL_2GHZ: tempOB = ahp->ah_obFor24g; tempDB = ahp->ah_dbFor24g; rfXpdGain = ahp->ah_xgain[2]; rfPloSel = ahp->ah_xpd[2]; rfPwdXpd = !ahp->ah_xpd[2]; break; default: HALDEBUG(ah, "%s: invalid channel flags 0x%x\n", __func__, chan->channelFlags); return AH_FALSE; } HALASSERT(1 <= tempOB && tempOB <= 5); HALASSERT(1 <= tempDB && tempDB <= 5); /* Set rfXpdGain and rfPwdXpd */ ar5211Rf6n7[11][freqIndex] = (ar5211Rf6n7[11][freqIndex] & ~0xC0) | (((ath_hal_reverseBits(rfXpdGain, 4) << 7) | (rfPwdXpd << 6)) & 0xC0); ar5211Rf6n7[12][freqIndex] = (ar5211Rf6n7[12][freqIndex] & ~0x07) | ((ath_hal_reverseBits(rfXpdGain, 4) >> 1) & 0x07); /* Set OB */ ar5211Rf6n7[12][freqIndex] = (ar5211Rf6n7[12][freqIndex] & ~0x80) | ((ath_hal_reverseBits(tempOB, 3) << 7) & 0x80); ar5211Rf6n7[13][freqIndex] = (ar5211Rf6n7[13][freqIndex] & ~0x03) | ((ath_hal_reverseBits(tempOB, 3) >> 1) & 0x03); /* Set DB */ ar5211Rf6n7[13][freqIndex] = (ar5211Rf6n7[13][freqIndex] & ~0x1C) | ((ath_hal_reverseBits(tempDB, 3) << 2) & 0x1C); /* Set rfPloSel */ ar5211Rf6n7[17][freqIndex] = (ar5211Rf6n7[17][freqIndex] & ~0x08) | ((rfPloSel << 3) & 0x08); /* Write the Rf registers 6 & 7 */ for (i = 0; i < N(ar5211Rf6n7); i++) OS_REG_WRITE(ah, ar5211Rf6n7[i][0], ar5211Rf6n7[i][freqIndex]); /* Now that we have reprogrammed rfgain value, clear the flag. */ ahp->ah_rfgainState = RFGAIN_INACTIVE; return AH_TRUE;#undef N}/* * Reads EEPROM header info and programs the device for correct operation * given the channel value */static HAL_BOOLar5211SetBoardValues(struct ath_hal *ah, HAL_CHANNEL *chan){ struct ath_hal_5211 *ahp = AH5211(ah); int arrayMode, falseDectectBackoff; switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) { case CHANNEL_A: arrayMode = 0; OS_REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP, ahp->ah_cornerCal.clip); break; case CHANNEL_CCK|CHANNEL_2GHZ: arrayMode = 1; break; case CHANNEL_OFDM|CHANNEL_2GHZ: arrayMode = 2; break; default: HALDEBUG(ah, "%s: invalid channel flags 0x%x\n", __func__, chan->channelFlags); return AH_FALSE; } /* Set the antenna register(s) correctly for the chip revision */ if (AH_PRIVATE(ah)->ah_macVersion < AR_SREV_VERSION_OAHU) { OS_REG_WRITE(ah, AR_PHY(68), (OS_REG_READ(ah, AR_PHY(68)) & 0xFFFFFFFC) | 0x3); } else { OS_REG_WRITE(ah, AR_PHY(68), (OS_REG_READ(ah, AR_PHY(68)) & 0xFFFFFC06) | (ahp->ah_antennaControl[0][arrayMode] << 4) | 0x1); ar5211SetAntennaSwitch(ah, ahp->ah_diversityControl, chan); /* Set the Noise Floor Thresh on ar5211 devices */ OS_REG_WRITE(ah, AR_PHY_BASE + (90 << 2), (ahp->ah_noiseFloorThresh[arrayMode] & 0x1FF) | (1<<9)); } OS_REG_WRITE(ah, AR_PHY_BASE + (17 << 2), (OS_REG_READ(ah, AR_PHY_BASE + (17 << 2)) & 0xFFFFC07F) | ((ahp->ah_switchSettling[arrayMode] << 7) & 0x3F80)); OS_REG_WRITE(ah, AR_PHY_BASE + (18 << 2), (OS_REG_READ(ah, AR_PHY_BASE + (18 << 2)) & 0xFFFC0FFF) | ((ahp->ah_txrxAtten[arrayMode] << 12) & 0x3F000)); OS_REG_WRITE(ah, AR_PHY_BASE + (20 << 2), (OS_REG_READ(ah, AR_PHY_BASE + (20 << 2)) & 0xFFFF0000) | ((ahp->ah_pgaDesiredSize[arrayMode] << 8) & 0xFF00) | (ahp->ah_adcDesiredSize[arrayMode] & 0x00FF)); OS_REG_WRITE(ah, AR_PHY_BASE + (13 << 2), (ahp->ah_txEndToXPAOff[arrayMode] << 24) | (ahp->ah_txEndToXPAOff[arrayMode] << 16) | (ahp->ah_txFrameToXPAOn[arrayMode] << 8) | ahp->ah_txFrameToXPAOn[arrayMode]); OS_REG_WRITE(ah, AR_PHY_BASE + (10 << 2), (OS_REG_READ(ah, AR_PHY_BASE + (10 << 2)) & 0xFFFF00FF) | (ahp->ah_txEndToXLNAOn[arrayMode] << 8)); OS_REG_WRITE(ah, AR_PHY_BASE + (25 << 2), (OS_REG_READ(ah, AR_PHY_BASE + (25 << 2)) & 0xFFF80FFF) | ((ahp->ah_thresh62[arrayMode] << 12) & 0x7F000));#define NO_FALSE_DETECT_BACKOFF 2#define CB22_FALSE_DETECT_BACKOFF 6 /* * False detect backoff - suspected 32 MHz spur causes * false detects in OFDM, causing Tx Hangs. Decrease * weak signal sensitivity for this card. */ falseDectectBackoff = NO_FALSE_DETECT_BACKOFF; if (ahp->ah_eeversion < AR_EEPROM_VER3_3) { if (AH_PRIVATE(ah)->ah_subvendorid == 0x1022 && IS_CHAN_OFDM(chan)) falseDectectBackoff += CB22_FALSE_DETECT_BACKOFF; } else { u_int32_t remainder = chan->channel % 32; if (remainder && (remainder < 10 || remainder > 22)) falseDectectBackoff += ahp->ah_falseDetectBackoff[arrayMode]; } OS_REG_WRITE(ah, 0x9924, (OS_REG_READ(ah, 0x9924) & 0xFFFFFF01) | ((falseDectectBackoff << 1) & 0xF7)); return AH_TRUE;#undef NO_FALSE_DETECT_BACKOFF#undef CB22_FALSE_DETECT_BACKOFF}/* * Set the limit on the overall output power. Used for dynamic * transmit power control and the like. * * NOTE: The power is passed in is in units of 0.5 dBm. */HAL_BOOLar5211SetTxPowerLimit(struct ath_hal *ah, u_int32_t limit){ AH_PRIVATE(ah)->ah_powerLimit = AH_MIN(limit, MAX_RATE_POWER); OS_REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX, limit); return AH_TRUE;}/* * Sets the transmit power in the baseband for the given * operating channel and mode. */HAL_BOOLar5211SetTransmitPower(struct ath_hal *ah, HAL_CHANNEL *chan){ struct ath_hal_5211 *ahp = AH5211(ah); TRGT_POWER_INFO *pi; RD_EDGES_POWER *rep; PCDACS_EEPROM eepromPcdacs; u_int nchan, cfgCtl; int i; /* setup the pcdac struct to point to the correct info, based on mode */ switch (chan->channelFlags & CHANNEL_ALL_NOTURBO) { case CHANNEL_A: eepromPcdacs.numChannels = ahp->ah_numChannels11a; eepromPcdacs.pChannelList= ahp->ah_channels11a; eepromPcdacs.pDataPerChannel = ahp->ah_dataPerChannel11a; nchan = ahp->ah_numTargetPwr_11a; pi = ahp->ah_trgtPwr_11a; break; case CHANNEL_OFDM|CHANNEL_2GHZ: eepromPcdacs.numChannels = ahp->ah_numChannels2_4; eepromPcdacs.pChannelList= ahp->ah_channels11g; eepromPcdacs.pDataPerChannel = ahp->ah_dataPerChannel11g; nchan = ahp->ah_numTargetPwr_11g; pi = ahp->ah_trgtPwr_11g; break; case CHANNEL_CCK|CHANNEL_2GHZ: eepromPcdacs.numChannels = ahp->ah_numChannels2_4; eepromPcdacs.pChannelList= ahp->ah_channels11b; eepromPcdacs.pDataPerChannel = ahp->ah_dataPerChannel11b; nchan = ahp->ah_numTargetPwr_11b; pi = ahp->ah_trgtPwr_11b; break; default: HALDEBUG(ah, "%s: invalid channel flags 0x%x\n", __func__, chan->channelFlags); return AH_FALSE; } ar5211SetPowerTable(ah, &eepromPcdacs, chan->channel); rep = AH_NULL; /* Match CTL to EEPROM value */ cfgCtl = ath_hal_getctl(ah, chan); for (i = 0; i < ahp->ah_numCtls; i++) if (ahp->ah_ctl[i] != 0 && ahp->ah_ctl[i] == cfgCtl) { rep = &ahp->ah_rdEdgesPower[i * NUM_EDGES]; break; } ar5211SetRateTable(ah, rep, pi, nchan, chan); return AH_TRUE;}/* * Read the transmit power levels from the structures taken * from EEPROM. Interpolate read transmit power values for * this channel. Organize the transmit power values into a * table for writing into the hardware. */voidar5211SetPowerTable(struct ath_hal *ah, PCDACS_EEPROM *pSrcStruct, u_int16_t channel){ static FULL_PCDAC_STRUCT pcdacStruct; static u_int16_t pcdacTable[PWR_TABLE_SIZE]; u_int16_t i, j; u_int16_t *pPcdacValues; int16_t *pScaledUpDbm; int16_t minScaledPwr; int16_t maxScaledPwr; int16_t pwr; u_int16_t pcdacMin = 0; u_int16_t pcdacMax = 63; u_int16_t pcdacTableIndex; u_int16_t scaledPcdac; u_int32_t addr; u_int32_t temp32; OS_MEMZERO(&pcdacStruct, sizeof(FULL_PCDAC_STRUCT)); OS_MEMZERO(pcdacTable, sizeof(u_int16_t) * PWR_TABLE_SIZE); pPcdacValues = pcdacStruct.PcdacValues; pScaledUpDbm = pcdacStruct.PwrValues; /* Initialize the pcdacs to dBM structs pcdacs to be 1 to 63 */ for (i = PCDAC_START, j = 0; i <= PCDAC_STOP; i+= PCDAC_STEP, j++) pPcdacValues[j] = i; pcdacStruct.numPcdacValues = j; pcdacStruct.pcdacMin = PCDAC_START; pcdacStruct.pcdacMax = PCDAC_STOP; /* Fill out the power values for this channel */ for (j = 0; j < pcdacStruct.numPcdacValues; j++ ) pScaledUpDbm[j] = ar5211GetScaledPower(channel, pPcdacValues[j], pSrcStruct); /* Now scale the pcdac values to fit in the 64 entry power table */ minScaledPwr = pScaledUpDbm[0]; maxScaledPwr = pScaledUpDbm[pcdacStruct.numPcdacValues - 1]; /* find minimum and make monotonic */ for (j = 0; j < pcdacStruct.numPcdacValues; j++) { if (minScaledPwr >= pScaledUpDbm[j]) { minScaledPwr = pScaledUpDbm[j]; pcdacMin = j; } /* * Make the full_hsh monotonically increasing otherwise * interpolation algorithm will get fooled gotta start * working from the top, hence i = 63 - j. */ i = (u_int16_t)(pcdacStruct.numPcdacValues - 1 - j); if (i == 0) break; if (pScaledUpDbm[i-1] > pScaledUpDbm[i]) { /* * It could be a glitch, so make the power for * this pcdac the same as the power from the * next highest pcdac. */ pScaledUpDbm[i - 1] = pScaledUpDbm[i]; } } for (j = 0; j < pcdacStruct.numPcdacValues; j++) if (maxScaledPwr < pScaledUpDbm[j]) { maxScaledPwr = pScaledUpDbm[j]; pcdacMax = j; } /* Find the first power level with a pcdac */ pwr = (u_int16_t)(PWR_STEP * ((minScaledPwr - PWR_MIN + PWR_STEP / 2) / PWR_STEP) + PWR_MIN); /* Write all the first pcdac entries based off the pcdacMin */ pcdacTableIndex = 0; for (i = 0; i < (2 * (pwr - PWR_MIN) / EEP_SCALE + 1); i++) pcdacTable[pcdacTableIndex++] = pcdacMin; i = 0; while (pwr < pScaledUpDbm[pcdacStruct.numPcdacValues - 1]) { pwr += PWR_STEP; /* stop if dbM > max_power_possible */ while (pwr < pScaledUpDbm[pcdacStruct.numPcdacValues - 1] && (pwr - pScaledUpDbm[i])*(pwr - pScaledUpDbm[i+1]) > 0) i++; /* scale by 2 and add 1 to enable round up or down as needed */ scaledPcdac = (u_int16_t)(ar5211GetInterpolatedValue(pwr, pScaledUpDbm[i], pScaledUpDbm[i+1], (u_int16_t)(pPcdacValues[i] * 2), (u_int16_t)(pPcdacValues[i+1] * 2), 0) + 1); pcdacTable[pcdacTableIndex] = scaledPcdac / 2; if (pcdacTable[pcdacTableIndex] > pcdacMax) pcdacTable[pcdacTableIndex] = pcdacMax; pcdacTableIndex++; } /* Write all the last pcdac entries based off the last valid pcdac */ while (pcdacTableIndex < PWR_TABLE_SIZE) { pcdacTable[pcdacTableIndex] = pcdacTable[pcdacTableIndex - 1]; pcdacTableIndex++; } /* Finally, write the power values into the baseband power table */ addr = AR_PHY_BASE + (608 << 2); for (i = 0; i < 32; i++) { temp32 = 0xffff & ((pcdacTable[2 * i + 1] << 8) | 0xff); temp32 = (temp32 << 16) | (0xffff & ((pcdacTable[2 * i] << 8) | 0xff)); OS_REG_WRITE(ah, addr, temp32); addr += 4; }}/* * Set the transmit power in the baseband for the given * operating channel and mode. */voidar5211SetRateTable(struct ath_hal *ah, RD_EDGES_POWER *pRdEdgesPower, TRGT_POWER_INFO *pPowerInfo, u_int16_t numChannels, HAL_CHANNEL *chan){ struct ath_hal_5211 *ahp = AH5211(ah); static u_int16_t ratesArray[NUM_RATES]; static const u_int16_t tpcScaleReductionTable[5] = { 0, 3, 6, 9, MAX_RATE_POWER }; u_int16_t *pRatesPower; u_int16_t lowerChannel, lowerIndex=0, lowerPower=0; u_int16_t upperChannel, upperIndex=0, upperPower=0; u_int16_t twiceMaxEdgePower=63; u_int16_t twicePower = 0; u_int16_t i, numEdges; u_int16_t tempChannelList[NUM_EDGES]; /* temp array for holding edge channels */ u_int16_t twiceMaxRDPower; int16_t scaledPower = 0; /* for gcc -O2 */ u_int16_t mask = 0x3f; HAL_BOOL paPreDEnable = 0; int8_t twiceAntennaGain, twiceAntennaReduction = 0; pRatesPower = ratesArray; twiceMaxRDPower = chan->maxRegTxPower * 2; if (IS_CHAN_5GHZ(chan)) { twiceAntennaGain = ahp->ah_antennaGainMax[0]; } else { twiceAntennaGain = ahp->ah_antennaGainMax[1]; } twiceAntennaReduction = ath_hal_getantennareduction(ah, chan, twiceAntennaGain); if (pRdEdgesPower) { /* Get the edge power */ for (i = 0; i < NUM_EDGES; i++) { if (pRdEdgesPower[i].rdEdge == 0) break; tempChannelList[i] = pRdEdgesPower[i].rdEdge; } numEdges = i; ar5211GetLowerUpperValues(chan->channel, tempChannelList, numEdges, &lowerChannel, &upperChannel); /* Get the index for this channel */ for (i = 0; i < numEdges; i++) if (lowerChannel == tempChannelList[i]) break; HALASSERT(i != numEdges); if ((lowerChannel == upperChannel && lowerChannel == chan->channel) || pRdEdgesPower[i].flag) { twiceMaxEdgePower = pRdEdgesPower[i].twice_rdEdgePower; HALASSERT(twiceMaxEdgePower > 0); } } /* extrapolate the power values for the test Groups */ for (i = 0; i < numChannels; i++) tempChannelList[i] = pPowerInfo[i].testChannel; ar5211GetLowerUpperValues(chan->channel, tempChannelList, numChannels, &lowerChannel, &upperChannel); /* get the index for the channel */ for (i = 0; i < numChannels; i++) { if (lowerChannel == tempChannelList[i]) lowerIndex = i; if (upperChannel == tempChannelList[i]) { upperIndex = i; break; } } for (i = 0; i < NUM_RATES; i++) { if (IS_CHAN_OFDM(chan)) { /* power for rates 6,9,12,18,24 is all the same */ if (i < 5) { lowerPower = pPowerInfo[lowerIndex].twicePwr6_24; upperPower = pPowerInfo[upperIndex].twicePwr6_24; } else if (i == 5) { lowerPower = pPowerInfo[lowerIndex].twicePwr36; upperPower = pPowerInfo[upperIndex].twicePwr36; } else if (i == 6) { lowerPower = pPowerInfo[lowerIndex].twicePwr48; upperPower = pPowerInfo[upperIndex].twicePwr48; } else if (i == 7) { lowerPower = pPowerInfo[lowerIndex].twicePwr54; upperPower = pPowerInfo[upperIndex].twicePwr54; } } else { switch (i) { case 0: case 1: lowerPower = pPowerInfo[lowerIndex].twicePwr6_24; upperPower = pPowerInfo[upperIndex].twicePwr6_24; break; case 2: case 3: lowerPower = pPowerInfo[lowerIndex].twicePwr36; upperPower = pPowerInfo[upperIndex].twicePwr36; break; case 4: case 5: lowerPower = pPowerInfo[lowerIndex].twicePwr48; upperPower = pPowerInfo[upperIndex].twicePwr48; break; case 6: case 7: lowerPower = pPowerInfo[lowerIndex].twicePwr54;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -