/*
 * Read rf register to determine if gainF needs correction
 */
static void
ar5212GetGainFCorrection(struct ath_hal *ah)
{
	struct ath_hal_5212 *ahp = AH5212(ah);
	GAIN_VALUES *gv = &ahp->ah_gainValues;

	HALASSERT(IS_RADX112_REV2(ah));

	gv->gainFCorrection = 0;
	if (ar5212GetRfField(ar5212GetRfBank(ah, 7), 1, 36, 0) == 1) {
		uint32_t mixGain = gv->currStep->paramVal[0];
		uint32_t gainStep =
			ar5212GetRfField(ar5212GetRfBank(ah, 7), 4, 32, 0);
		switch (mixGain) {
		case 0 :
			gv->gainFCorrection = 0;
			break;
		case 1 :
			gv->gainFCorrection = gainStep;
			break;
		case 2 :
			gv->gainFCorrection = 2 * gainStep - 5;
			break;
		case 3 :
			gv->gainFCorrection = 2 * gainStep;
			break;
		}
	}
}
Ejemplo n.º 2
0
/*
 * Exported call to check for a recent gain reading and return
 * the current state of the thermal calibration gain engine.
 */
HAL_RFGAIN
ar5212GetRfgain(struct ath_hal *ah)
{
	struct ath_hal_5212 *ahp = AH5212(ah);
	GAIN_VALUES *gv = &ahp->ah_gainValues;
	uint32_t rddata, probeType;

	/* NB: beware of touching the BB when PHY is powered down */
	if (!gv->active || !ahp->ah_phyPowerOn)
		return HAL_RFGAIN_INACTIVE;

	if (ahp->ah_rfgainState == HAL_RFGAIN_READ_REQUESTED) {
		/* Caller had asked to setup a new reading. Check it. */
		rddata = OS_REG_READ(ah, AR_PHY_PAPD_PROBE);

		if ((rddata & AR_PHY_PAPD_PROBE_NEXT_TX) == 0) {
			/* bit got cleared, we have a new reading. */
			gv->currGain = rddata >> AR_PHY_PAPD_PROBE_GAINF_S;
			probeType = MS(rddata, AR_PHY_PAPD_PROBE_TYPE);
			if (probeType == AR_PHY_PAPD_PROBE_TYPE_CCK) {
				const HAL_EEPROM *ee = AH_PRIVATE(ah)->ah_eeprom;

				HALASSERT(IS_RAD5112_ANY(ah));
				HALASSERT(ah->ah_magic == AR5212_MAGIC);
				if (AH_PRIVATE(ah)->ah_phyRev >= AR_PHY_CHIP_ID_REV_2)
					gv->currGain += ee->ee_cckOfdmGainDelta;
				else
					gv->currGain += PHY_PROBE_CCK_CORRECTION;
			}
			if (IS_RADX112_REV2(ah)) {
				uint32_t correct = ar5212GetGainFCorrection(ah);
				if (gv->currGain >= correct)
					gv->currGain -= correct;
				else
					gv->currGain = 0;
			}
			/* inactive by default */
			ahp->ah_rfgainState = HAL_RFGAIN_INACTIVE;

			if (!ar5212InvalidGainReadback(ah, gv) &&
			    ar5212IsGainAdjustNeeded(ah, gv) &&
			    ar5212AdjustGain(ah, gv) > 0) {
				/*
				 * Change needed. Copy ladder info
				 * into eeprom info.
				 */
				ahp->ah_rfgainState = HAL_RFGAIN_NEED_CHANGE;
				/* for ap51 */
				ahp->ah_cwCalRequire = AH_TRUE;
				/* Request IQ recalibration for temperature chang */
				ahp->ah_bIQCalibration = IQ_CAL_INACTIVE;
			}
		}