Пример #1
0
static void
ar9280WriteIni(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
    u_int modesIndex, freqIndex;
    int regWrites = 0;

    /* Setup the indices for the next set of register array writes */
    /* XXX Ignore 11n dynamic mode on the AR5416 for the moment */
    if (IEEE80211_IS_CHAN_2GHZ(chan)) {
        freqIndex = 2;
        if (IEEE80211_IS_CHAN_HT40(chan))
            modesIndex = 3;
        else if (IEEE80211_IS_CHAN_108G(chan))
            modesIndex = 5;
        else
            modesIndex = 4;
    } else {
        freqIndex = 1;
        if (IEEE80211_IS_CHAN_HT40(chan) ||
                IEEE80211_IS_CHAN_TURBO(chan))
            modesIndex = 2;
        else
            modesIndex = 1;
    }

    /* Set correct Baseband to analog shift setting to access analog chips. */
    OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
    OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);

    /* XXX Merlin ini fixups */
    /* XXX Merlin 100us delay for shift registers */
    regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_modes,
                                  modesIndex, regWrites);
    if (AR_SREV_MERLIN_20_OR_LATER(ah)) {
        regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_rxgain,
                                      modesIndex, regWrites);
        regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_txgain,
                                      modesIndex, regWrites);
    }
    /* XXX Merlin 100us delay for shift registers */
    regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_common,
                                  1, regWrites);

    if (AR_SREV_MERLIN_20(ah) && IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
        /* 5GHz channels w/ Fast Clock use different modal values */
        regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_xmodes,
                                      modesIndex, regWrites);
    }
}
Пример #2
0
void
ar9280olcGetTxGainIndex(struct ath_hal *ah,
    const struct ieee80211_channel *chan,
    struct calDataPerFreqOpLoop *rawDatasetOpLoop,
    uint8_t *calChans, uint16_t availPiers, uint8_t *pwr, uint8_t *pcdacIdx)
{
	uint8_t pcdac, i = 0;
	uint16_t idxL = 0, idxR = 0, numPiers;
	HAL_BOOL match;
	CHAN_CENTERS centers;

	ar5416GetChannelCenters(ah, chan, &centers);

	for (numPiers = 0; numPiers < availPiers; numPiers++)
		if (calChans[numPiers] == AR5416_BCHAN_UNUSED)
			break;

	match = ath_ee_getLowerUpperIndex((uint8_t)FREQ2FBIN(centers.synth_center,
		    IEEE80211_IS_CHAN_2GHZ(chan)), calChans, numPiers,
		    &idxL, &idxR);
	if (match) {
		pcdac = rawDatasetOpLoop[idxL].pcdac[0][0];
		*pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0];
	} else {
		pcdac = rawDatasetOpLoop[idxR].pcdac[0][0];
		*pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] +
				rawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
	}
	while (pcdac > AH9280(ah)->originalGain[i] &&
			i < (AR9280_TX_GAIN_TABLE_SIZE - 1))
		i++;

	*pcdacIdx = i;
}
Пример #3
0
void
ar9280olcInit(struct ath_hal *ah)
{
	uint32_t i;

	/* Only do OLC if it's enabled for this chipset */
	if (! ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL))
		return;

	HALDEBUG(ah, HAL_DEBUG_RESET, "%s: Setting up TX gain tables.\n", __func__);

	for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++)
		AH9280(ah)->originalGain[i] = MS(OS_REG_READ(ah,
		    AR_PHY_TX_GAIN_TBL1 + i * 4), AR_PHY_TX_GAIN);

	AH9280(ah)->PDADCdelta = 0;
}
Пример #4
0
/*
 * Run temperature compensation calibration.
 *
 * The TX gain table is adjusted depending upon the difference
 * between the initial PDADC value and the currently read
 * average TX power sample value. This value is only valid if
 * frames have been transmitted, so currPDADC will be 0 if
 * no frames have yet been transmitted.
 */
void
ar9280olcTemperatureCompensation(struct ath_hal *ah)
{
	uint32_t rddata, i;
	int delta, currPDADC, regval;
	uint8_t hpwr_5g = 0;

	if (! ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL))
		return;

	rddata = OS_REG_READ(ah, AR_PHY_TX_PWRCTRL4);
	currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);

	HALDEBUG(ah, HAL_DEBUG_PERCAL,
	    "%s: called: initPDADC=%d, currPDADC=%d\n",
	    __func__, AH5416(ah)->initPDADC, currPDADC);

	if (AH5416(ah)->initPDADC == 0 || currPDADC == 0)
		return;

	(void) (ath_hal_eepromGet(ah, AR_EEP_DAC_HPWR_5G, &hpwr_5g));

	if (hpwr_5g)
		delta = (currPDADC - AH5416(ah)->initPDADC + 4) / 8;
	else
		delta = (currPDADC - AH5416(ah)->initPDADC + 5) / 10;

	HALDEBUG(ah, HAL_DEBUG_PERCAL, "%s: delta=%d, PDADCdelta=%d\n",
	    __func__, delta, AH9280(ah)->PDADCdelta);

	if (delta != AH9280(ah)->PDADCdelta) {
		AH9280(ah)->PDADCdelta = delta;
		for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
			regval = AH9280(ah)->originalGain[i] - delta;
			if (regval < 0)
				regval = 0;

			OS_REG_RMW_FIELD(ah,
				      AR_PHY_TX_GAIN_TBL1 + i * 4,
				      AR_PHY_TX_GAIN, regval);
		}
	}
}
Пример #5
0
static void
ar9280WriteIni(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
	u_int modesIndex, freqIndex;
	int regWrites = 0;
	int i;
	const HAL_INI_ARRAY *ia;

	/* Setup the indices for the next set of register array writes */
	/* XXX Ignore 11n dynamic mode on the AR5416 for the moment */
	if (IEEE80211_IS_CHAN_2GHZ(chan)) {
		freqIndex = 2;
		if (IEEE80211_IS_CHAN_HT40(chan))
			modesIndex = 3;
		else if (IEEE80211_IS_CHAN_108G(chan))
			modesIndex = 5;
		else
			modesIndex = 4;
	} else {
		freqIndex = 1;
		if (IEEE80211_IS_CHAN_HT40(chan) ||
		    IEEE80211_IS_CHAN_TURBO(chan))
			modesIndex = 2;
		else
			modesIndex = 1;
	}

	/* Set correct Baseband to analog shift setting to access analog chips. */
	OS_REG_WRITE(ah, AR_PHY(0), 0x00000007);
	OS_REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);

	/*
	 * This is unwound because at the moment, there's a requirement
	 * for Merlin (and later, perhaps) to have a specific bit fixed
	 * in the AR_AN_TOP2 register before writing it.
	 */
	ia = &AH5212(ah)->ah_ini_modes;
#if 0
	regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_modes,
	    modesIndex, regWrites);
#endif
	HALASSERT(modesIndex < ia->cols);
	for (i = 0; i < ia->rows; i++) {
		uint32_t reg = HAL_INI_VAL(ia, i, 0);
		uint32_t val = HAL_INI_VAL(ia, i, modesIndex);

		if (reg == AR_AN_TOP2 && AH5416(ah)->ah_need_an_top2_fixup)
			val &= ~AR_AN_TOP2_PWDCLKIND;

		OS_REG_WRITE(ah, reg, val);

		/* Analog shift register delay seems needed for Merlin - PR kern/154220 */
		if (reg >= 0x7800 && reg < 0x7900)
			OS_DELAY(100);

		DMA_YIELD(regWrites);
	}

	if (AR_SREV_MERLIN_20_OR_LATER(ah)) {
		regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_rxgain,
		    modesIndex, regWrites);
		regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_txgain,
		    modesIndex, regWrites);
	}
	/* XXX Merlin 100us delay for shift registers */
	regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_common,
	    1, regWrites);

	if (AR_SREV_MERLIN_20(ah) && IS_5GHZ_FAST_CLOCK_EN(ah, chan)) {
		/* 5GHz channels w/ Fast Clock use different modal values */
		regWrites = ath_hal_ini_write(ah, &AH9280(ah)->ah_ini_xmodes,
		    modesIndex, regWrites);
	}
}