Deleted Added
full compact
17c17
< * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c 219218 2011-03-03 08:38:31Z adrian $
---
> * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c 219393 2011-03-08 06:59:59Z adrian $
64,67d63
< static HAL_BOOL ar5416SetPowerCalTable(struct ath_hal *ah,
< struct ar5416eeprom *pEepData,
< const struct ieee80211_channel *chan,
< int16_t *pTxPowerIndexOffset);
74,81d69
< static void ar5416GetGainBoundariesAndPdadcs(struct ath_hal *ah,
< const struct ieee80211_channel *chan, CAL_DATA_PER_FREQ *pRawDataSet,
< uint8_t * bChans, uint16_t availPiers,
< uint16_t tPdGainOverlap, int16_t *pMinCalPower,
< uint16_t * pPdGainBoundaries, uint8_t * pPDADCValues,
< uint16_t numXpdGains);
< static HAL_BOOL getLowerUpperIndex(uint8_t target, uint8_t *pList,
< uint16_t listSize, uint16_t *indexL, uint16_t *indexR);
226a215
> AH5416(ah)->ah_olcInit(ah);
851c840
< if (!ar5416SetPowerCalTable(ah, pEepData, chan, &txPowerIndexOffset)) {
---
> if (!AH5416(ah)->ah_setPowerCalTable(ah, pEepData, chan, &txPowerIndexOffset)) {
881a871,877
> /*
> * Dump the rate array whilst it represents the intended dBm*2
> * values versus what's being adjusted before being programmed
> * in. Keep this in mind if you code up this function and enable
> * this debugging; the values won't necessarily be what's being
> * programmed into the hardware.
> */
884a881,935
> /*
> * Merlin and later have a power offset, so subtract
> * pwr_table_offset * 2 from each value. The default
> * power offset is -5 dBm - ie, a register value of 0
> * equates to a TX power of -5 dBm.
> */
> if (AR_SREV_MERLIN_20_OR_LATER(ah)) {
> int8_t pwr_table_offset;
>
> (void) ath_hal_eepromGet(ah, AR_EEP_PWR_TABLE_OFFSET,
> &pwr_table_offset);
> /* Underflow power gets clamped at raw value 0 */
> /* Overflow power gets camped at AR5416_MAX_RATE_POWER */
> for (i = 0; i < N(ratesArray); i++) {
> /*
> * + pwr_table_offset is in dBm
> * + ratesArray is in 1/2 dBm
> */
> ratesArray[i] -= (pwr_table_offset * 2);
> if (ratesArray[i] < 0)
> ratesArray[i] = 0;
> else if (ratesArray[i] > AR5416_MAX_RATE_POWER)
> ratesArray[i] = AR5416_MAX_RATE_POWER;
> }
> }
>
> /*
> * Adjust rates for OLC where needed
> *
> * The following CCK rates need adjusting when doing 2.4ghz
> * CCK transmission.
> *
> * + rate2s, rate2l, rate1l, rate11s, rate11l, rate5_5s, rate5_5l
> * + rateExtCck, rateDupCck
> *
> * They're adjusted here regardless. The hardware then gets
> * programmed as needed. 5GHz operation doesn't program in CCK
> * rates for legacy mode but they seem to be initialised for
> * HT40 regardless of channel type.
> */
> if (AR_SREV_MERLIN_20_OR_LATER(ah) &&
> ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) {
> int adj[] = {
> rate2s, rate2l, rate1l, rate11s, rate11l,
> rate5_5s, rate5_5l, rateExtCck, rateDupCck
> };
> int cck_ofdm_delta = 2;
> int i;
> for (i = 0; i < N(adj); i++) {
> ratesArray[i] -= cck_ofdm_delta;
> if (ratesArray[i] < 0)
> ratesArray[i] = 0;
> }
> }
>
1299a1351,1362
> /*
> * Get the register chain offset for the given chain.
> *
> * Take into account the register chain swapping with AR5416 v2.0.
> *
> * XXX make sure that the reg chain swapping is only done for
> * XXX AR5416 v2.0 or greater, and not later chips?
> */
> int
> ar5416GetRegChainOffset(struct ath_hal *ah, int i)
> {
> int regChainOffset;
1300a1364,1373
> 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;
> }
1301a1375,1377
> return regChainOffset;
> }
>
1326,1335c1402
< 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;
< }
---
> regChainOffset = ar5416GetRegChainOffset(ah, i);
1859a1927,2040
> /*
> * Set the gain boundaries for the given radio chain.
> *
> * The gain boundaries tell the hardware at what point in the
> * PDADC array to "switch over" from one PD gain setting
> * to another. There's also a gain overlap between two
> * PDADC array gain curves where there's valid PD values
> * for 2 gain settings.
> *
> * The hardware uses the gain overlap and gain boundaries
> * to determine which gain curve to use for the given
> * target TX power.
> */
> void
> ar5416SetGainBoundariesClosedLoop(struct ath_hal *ah, int regChainOffset,
> uint16_t pdGainOverlap_t2, uint16_t gainBoundaries[])
> {
> 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));
> }
>
> /*
> * Get the gain values and the number of gain levels given
> * in xpdMask.
> *
> * The EEPROM xpdMask determines which power detector gain
> * levels were used during calibration. Each of these mask
> * bits maps to a fixed gain level in hardware.
> */
> uint16_t
> ar5416GetXpdGainValues(struct ath_hal *ah, uint16_t xpdMask,
> uint16_t xpdGainValues[])
> {
> int i;
> uint16_t 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++;
> }
> }
> return numXpdGain;
> }
>
> /*
> * Write the detector gain and biases.
> *
> * There are four power detector gain levels. The xpdMask in the EEPROM
> * determines which power detector gain levels have TX power calibration
> * data associated with them. This function writes the number of
> * PD gain levels and their values into the hardware.
> *
> * This is valid for all TX chains - the calibration data itself however
> * will likely differ per-chain.
> */
> void
> ar5416WriteDetectorGainBiases(struct ath_hal *ah, uint16_t numXpdGain,
> uint16_t xpdGainValues[])
> {
> 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));
> }
>
> /*
> * Write the PDADC array to the given chain offset.
> *
> * The 32 PDADC registers are written without any care about
> * their contents - so if various chips treat values as "special",
> * this routine will not care.
> */
> void
> ar5416WritePdadcValues(struct ath_hal *ah, int regChainOffset,
> uint8_t pdadcValues[])
> {
> int regOffset;
> int j;
> int reg32;
>
> 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;
> }
> }
>
1867c2048
< static HAL_BOOL
---
> HAL_BOOL
1876c2057
< uint16_t numPiers, i, j;
---
> uint16_t numPiers, i;
1880c2061
< uint32_t reg32, regOffset, regChainOffset;
---
> uint32_t regChainOffset;
1900d2080
< numXpdGain = 0;
1902,1911c2082
< 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++;
< }
< }
---
> numXpdGain = ar5416GetXpdGainValues(ah, xpdMask, xpdGainValues);
1914,1917c2085
< 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));
---
> ar5416WriteDetectorGainBiases(ah, numXpdGain, xpdGainValues);
1919a2088
> regChainOffset = ar5416GetRegChainOffset(ah, i);
1921,1930d2089
< 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;
< }
<
1938c2097,2098
< ar5416GetGainBoundariesAndPdadcs(ah, chan, pRawDataset,
---
> /* Fetch the gain boundaries and the PDADC values */
> ar5416GetGainBoundariesAndPdadcs(ah, chan, pRawDataset,
1945,1956c2105,2106
< /*
< * 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));
---
> ar5416SetGainBoundariesClosedLoop(ah, regChainOffset,
> pdGainOverlap_t2, gainBoundaries);
1960,1978c2110
< 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;
< }
---
> ar5416WritePdadcValues(ah, regChainOffset, pdadcValues);
1992c2124
< static void
---
> void