Ejemplo n.º 1
0
static void
ar9300_force_agc_gain(struct ath_hal *ah)
{
    struct ath_hal_9300 *ahp = AH9300(ah);
    int i;
    static const struct {
        int rxtx1, rxtx2;
    } chn_reg[AR9300_MAX_CHAINS] = {
        {AR_PHY_65NM_CH0_RXTX1, AR_PHY_65NM_CH0_RXTX2},
        {AR_PHY_65NM_CH1_RXTX1, AR_PHY_65NM_CH1_RXTX2},
        {AR_PHY_65NM_CH2_RXTX1, AR_PHY_65NM_CH2_RXTX2}
    };
    /* 
     * for Osprey 1.0, force Rx gain through long shift (analog) interface
     * this works for Osprey 2.0 too
     * TODO: for Osprey 2.0, we can set gain via baseband registers 
     */
    for (i = 0; i < AR9300_MAX_CHAINS; i++) {
        if (ahp->ah_rx_chainmask & (1 << i)) {
            if (AH_PRIVATE(ah)->ah_curchan != NULL &&
                IS_CHAN_2GHZ(AH_PRIVATE(ah)->ah_curchan)) 
            {
                // For 2G band:
                OS_REG_RMW_FIELD(ah, chn_reg[i].rxtx2, 
                    AR_PHY_RX1DB_BIQUAD_LONG_SHIFT, 0x1);  // 10db=3
                OS_REG_RMW_FIELD(ah, chn_reg[i].rxtx2, 
                    AR_PHY_RX6DB_BIQUAD_LONG_SHIFT, 0x2);  // 10db=2
                OS_REG_RMW_FIELD(ah, chn_reg[i].rxtx2, 
                    AR_PHY_LNAGAIN_LONG_SHIFT,      0x7);  // 10db=6
                OS_REG_RMW_FIELD(ah, chn_reg[i].rxtx2, 
                    AR_PHY_MXRGAIN_LONG_SHIFT,      0x3);  // 10db=3
                OS_REG_RMW_FIELD(ah, chn_reg[i].rxtx2, 
                    AR_PHY_VGAGAIN_LONG_SHIFT,      0x0);  // 10db=0
                OS_REG_RMW_FIELD(ah, chn_reg[i].rxtx1, 
                    AR_PHY_SCFIR_GAIN_LONG_SHIFT,   0x1);  // 10db=1
                OS_REG_RMW_FIELD(ah, chn_reg[i].rxtx1, 
                    AR_PHY_MANRXGAIN_LONG_SHIFT,    0x1);  // 10db=1
                /* force external LNA on to disable strong signal mechanism */
                OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN(i), 
                    AR_PHY_SWITCH_TABLE_R0,  0x1); 
                OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN(i), 
                    AR_PHY_SWITCH_TABLE_R1,  0x1); 
                OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN(i), 
                    AR_PHY_SWITCH_TABLE_R12, 0x1); 
            } else {
                // For 5G band:
                OS_REG_RMW_FIELD(ah, chn_reg[i].rxtx2, 
                    AR_PHY_RX1DB_BIQUAD_LONG_SHIFT, 0x2); // was 3=10/15db,
                                                          // 2=+1db
                OS_REG_RMW_FIELD(ah, chn_reg[i].rxtx2, 
                    AR_PHY_RX6DB_BIQUAD_LONG_SHIFT, 0x2); // was 1
                OS_REG_RMW_FIELD(ah, chn_reg[i].rxtx2, 
                    AR_PHY_LNAGAIN_LONG_SHIFT,      0x7);
                OS_REG_RMW_FIELD(ah, chn_reg[i].rxtx2, 
                    AR_PHY_MXRGAIN_LONG_SHIFT,      0x3); // was 2=15db, 3=10db
                OS_REG_RMW_FIELD(ah, chn_reg[i].rxtx2, 
                    AR_PHY_VGAGAIN_LONG_SHIFT,      0x6);
                OS_REG_RMW_FIELD(ah, chn_reg[i].rxtx1, 
                    AR_PHY_SCFIR_GAIN_LONG_SHIFT,   0x1);
                OS_REG_RMW_FIELD(ah, chn_reg[i].rxtx1, 
                    AR_PHY_MANRXGAIN_LONG_SHIFT,    0x1);
                /* force external LNA on to disable strong signal mechanism */
                OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN(i), 
                    AR_PHY_SWITCH_TABLE_R0,  0x0); 
                OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN(i), 
                    AR_PHY_SWITCH_TABLE_R1,  0x0); 
                OS_REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN(i), 
                    AR_PHY_SWITCH_TABLE_R12, 0x0); 
            }
        }
    }
}
Ejemplo n.º 2
0
void
ar9380_init_from_rom(struct athn_softc *sc, struct ieee80211_channel *c,
    struct ieee80211_channel *extc)
{
	const struct ar9380_eeprom *eep = sc->eep;
	const struct ar9380_modal_eep_header *modal;
	uint8_t db, margin, ant_div_ctrl;
	uint32_t reg;
	int i, maxchains;

	if (IEEE80211_IS_CHAN_2GHZ(c))
		modal = &eep->modalHeader2G;
	else
		modal = &eep->modalHeader5G;

	/* Apply XPA bias level. */
	if (AR_SREV_9485(sc)) {
		reg = AR_READ(sc, AR9485_PHY_65NM_CH0_TOP2);
		reg = RW(reg, AR9485_PHY_65NM_CH0_TOP2_XPABIASLVL,
		    modal->xpaBiasLvl);
		AR_WRITE(sc, AR9485_PHY_65NM_CH0_TOP2, reg);
	} else {
		reg = AR_READ(sc, AR_PHY_65NM_CH0_TOP);
		reg = RW(reg, AR_PHY_65NM_CH0_TOP_XPABIASLVL,
		    modal->xpaBiasLvl & 0x3);
		AR_WRITE(sc, AR_PHY_65NM_CH0_TOP, reg);
		reg = AR_READ(sc, AR_PHY_65NM_CH0_THERM);
		reg = RW(reg, AR_PHY_65NM_CH0_THERM_XPABIASLVL_MSB,
		    modal->xpaBiasLvl >> 2);
		reg |= AR_PHY_65NM_CH0_THERM_XPASHORT2GND;
		AR_WRITE(sc, AR_PHY_65NM_CH0_THERM, reg);
	}

	/* Apply antenna control. */
	reg = AR_READ(sc, AR_PHY_SWITCH_COM);
	reg = RW(reg, AR_SWITCH_TABLE_COM_ALL, modal->antCtrlCommon);
	AR_WRITE(sc, AR_PHY_SWITCH_COM, reg);
	reg = AR_READ(sc, AR_PHY_SWITCH_COM_2);
	reg = RW(reg, AR_SWITCH_TABLE_COM_2_ALL, modal->antCtrlCommon2);
	AR_WRITE(sc, AR_PHY_SWITCH_COM_2, reg);

	maxchains = AR_SREV_9485(sc) ? 1 : AR9380_MAX_CHAINS;
	for (i = 0; i < maxchains; i++) {
		reg = AR_READ(sc, AR_PHY_SWITCH_CHAIN(i));
		reg = RW(reg, AR_SWITCH_TABLE_ALL, modal->antCtrlChain[i]);
		AR_WRITE(sc, AR_PHY_SWITCH_CHAIN(i), reg);
	}

	if (AR_SREV_9485(sc)) {
		ant_div_ctrl = eep->base_ext1.ant_div_control;
		reg = AR_READ(sc, AR_PHY_MC_GAIN_CTRL);
		reg = RW(reg, AR_PHY_MC_GAIN_CTRL_ANT_DIV_CTRL_ALL,
		    MS(ant_div_ctrl, AR_EEP_ANT_DIV_CTRL_ALL));
		if (ant_div_ctrl & AR_EEP_ANT_DIV_CTRL_ANT_DIV)
			reg |= AR_PHY_MC_GAIN_CTRL_ENABLE_ANT_DIV;
		else
			reg &= ~AR_PHY_MC_GAIN_CTRL_ENABLE_ANT_DIV;
		AR_WRITE(sc, AR_PHY_MC_GAIN_CTRL, reg);
		reg = AR_READ(sc, AR_PHY_CCK_DETECT);
		if (ant_div_ctrl & AR_EEP_ANT_DIV_CTRL_FAST_DIV)
			reg |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
		else
			reg &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
		AR_WRITE(sc, AR_PHY_CCK_DETECT, reg);
	}

	if (eep->baseEepHeader.miscConfiguration & AR_EEP_DRIVE_STRENGTH) {
		/* Apply drive strength. */
		reg = AR_READ(sc, AR_PHY_65NM_CH0_BIAS1);
		reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_0, 5);
		reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_1, 5);
		reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_2, 5);
		reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_3, 5);
		reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_4, 5);
		reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_5, 5);
		AR_WRITE(sc, AR_PHY_65NM_CH0_BIAS1, reg);

		reg = AR_READ(sc, AR_PHY_65NM_CH0_BIAS2);
		reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_0, 5);
		reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_1, 5);
		reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_2, 5);
		reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_3, 5);
		reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_4, 5);
		reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_5, 5);
		reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_6, 5);
		reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_7, 5);
		reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_8, 5);
		AR_WRITE(sc, AR_PHY_65NM_CH0_BIAS2, reg);

		reg = AR_READ(sc, AR_PHY_65NM_CH0_BIAS4);
		reg = RW(reg, AR_PHY_65NM_CH0_BIAS4_0, 5);
		reg = RW(reg, AR_PHY_65NM_CH0_BIAS4_1, 5);
		reg = RW(reg, AR_PHY_65NM_CH0_BIAS4_2, 5);
		AR_WRITE(sc, AR_PHY_65NM_CH0_BIAS4, reg);
	}

	/* Apply attenuation settings. */
	maxchains = AR_SREV_9485(sc) ? 1 : AR9380_MAX_CHAINS;
	for (i = 0; i < maxchains; i++) {
		if (IEEE80211_IS_CHAN_5GHZ(c) &&
		    eep->base_ext2.xatten1DBLow[i] != 0) {
			if (c->ic_freq <= 5500) {
				db = athn_interpolate(c->ic_freq,
				    5180, eep->base_ext2.xatten1DBLow[i],
				    5500, modal->xatten1DB[i]);
			} else {
				db = athn_interpolate(c->ic_freq,
				    5500, modal->xatten1DB[i],
				    5785, eep->base_ext2.xatten1DBHigh[i]);
			}
		} else
			db = modal->xatten1DB[i];
		if (IEEE80211_IS_CHAN_5GHZ(c) &&
		    eep->base_ext2.xatten1MarginLow[i] != 0) {
			if (c->ic_freq <= 5500) {
				margin = athn_interpolate(c->ic_freq,
				    5180, eep->base_ext2.xatten1MarginLow[i],
				    5500, modal->xatten1Margin[i]);
			} else {
				margin = athn_interpolate(c->ic_freq,
				    5500, modal->xatten1Margin[i],
				    5785, eep->base_ext2.xatten1MarginHigh[i]);
			}
		} else
			margin = modal->xatten1Margin[i];
		reg = AR_READ(sc, AR_PHY_EXT_ATTEN_CTL(i));
		reg = RW(reg, AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, db);
		reg = RW(reg, AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, margin);
		AR_WRITE(sc, AR_PHY_EXT_ATTEN_CTL(i), reg);
	}

	/* Initialize switching regulator. */
	if (AR_SREV_9485(sc))
		ar9485_init_swreg(sc);
	else
		ar9485_init_swreg(sc);

	/* Apply tuning capabilities. */
	if (AR_SREV_9485(sc) &&
	    (eep->baseEepHeader.featureEnable & AR_EEP_TUNING_CAPS)) {
		reg = AR_READ(sc, AR9485_PHY_CH0_XTAL);
		reg = RW(reg, AR9485_PHY_CH0_XTAL_CAPINDAC,
		    eep->baseEepHeader.params_for_tuning_caps[0]);
		reg = RW(reg, AR9485_PHY_CH0_XTAL_CAPOUTDAC,
		    eep->baseEepHeader.params_for_tuning_caps[0]);
		AR_WRITE(sc, AR9485_PHY_CH0_XTAL, reg);
	}
	AR_WRITE_BARRIER(sc);
}