Example #1
0
/*
 * Set the antenna switch to control RX antenna diversity.
 *
 * If a fixed configuration is used, the LNA and div bias
 * settings are fixed and the antenna diversity scanning routine
 * is disabled.
 *
 * If a variable configuration is used, a default is programmed
 * in and sampling commences per RXed packet.
 *
 * Since this is called from ar9285SetBoardValues() to setup
 * diversity, it means that after a reset or scan, any current
 * software diversity combining settings will be lost and won't
 * re-appear until after the first successful sample run.
 * Please keep this in mind if you're seeing weird performance
 * that happens to relate to scan/diversity timing.
 */
HAL_BOOL
ar9285SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings)
{
	int regVal;
	const HAL_EEPROM_v4k *ee = AH_PRIVATE(ah)->ah_eeprom;
	const MODAL_EEP4K_HEADER *pModal = &ee->ee_base.modalHeader;
	uint8_t ant_div_control1, ant_div_control2;

	if (pModal->version < 3) {
		HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: not supported\n",
	    __func__);
		return AH_FALSE;	/* Can't do diversity */
	}

	/* Store settings */
	AH5212(ah)->ah_antControl = settings;
	AH5212(ah)->ah_diversity = (settings == HAL_ANT_VARIABLE);
	
	/* XXX don't fiddle if the PHY is in sleep mode or ! chan */

	/* Begin setting the relevant registers */

	ant_div_control1 = pModal->antdiv_ctl1;
	ant_div_control2 = pModal->antdiv_ctl2;

	regVal = OS_REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
	regVal &= (~(AR_PHY_9285_ANT_DIV_CTL_ALL));

	/* enable antenna diversity only if diversityControl == HAL_ANT_VARIABLE */
	if (settings == HAL_ANT_VARIABLE)
	    regVal |= SM(ant_div_control1, AR_PHY_9285_ANT_DIV_CTL);

	if (settings == HAL_ANT_VARIABLE) {
	    HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: HAL_ANT_VARIABLE\n",
	      __func__);
	    regVal |= SM(ant_div_control2, AR_PHY_9285_ANT_DIV_ALT_LNACONF);
	    regVal |= SM((ant_div_control2 >> 2), AR_PHY_9285_ANT_DIV_MAIN_LNACONF);
	    regVal |= SM((ant_div_control1 >> 1), AR_PHY_9285_ANT_DIV_ALT_GAINTB);
	    regVal |= SM((ant_div_control1 >> 2), AR_PHY_9285_ANT_DIV_MAIN_GAINTB);
	} else {
Example #2
0
/*
 * Read the NF and check it against the noise floor threshhold
 */
static int16_t
ar5416GetNf(struct ath_hal *ah, struct ieee80211_channel *chan)
{
	int16_t nf, nfThresh;

	if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
		HALDEBUG(ah, HAL_DEBUG_ANY,
		    "%s: NF didn't complete in calibration window\n", __func__);
		nf = 0;
	} else {
		/* Finished NF cal, check against threshold */
		int16_t nfarray[NUM_NOISEFLOOR_READINGS] = { 0 };
		HAL_CHANNEL_INTERNAL *ichan = ath_hal_checkchannel(ah, chan);
			
		/* TODO - enhance for multiple chains and ext ch */
		ath_hal_getNoiseFloor(ah, nfarray);
		nf = nfarray[0];
		if (ar5416GetEepromNoiseFloorThresh(ah, chan, &nfThresh)) {
			if (nf > nfThresh) {
				HALDEBUG(ah, HAL_DEBUG_ANY,
				    "%s: noise floor failed detected; "
				    "detected %d, threshold %d\n", __func__,
				    nf, nfThresh);
				/*
				 * NB: Don't discriminate 2.4 vs 5Ghz, if this
				 *     happens it indicates a problem regardless
				 *     of the band.
				 */
				chan->ic_state |= IEEE80211_CHANSTATE_CWINT;
				nf = 0;
			}
		} else {
			nf = 0;
		}
		ar5416UpdateNFHistBuff(AH5416(ah)->ah_cal.nfCalHist, nfarray);
		ichan->rawNoiseFloor = nf;
	}
	return nf;
}
Example #3
0
/*
 * This is like Merlin but without ADC disable
 */
HAL_BOOL
ar9287InitCalHardware(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
	OS_REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
	
	/* Calibrate the AGC */
	OS_REG_WRITE(ah, AR_PHY_AGC_CONTROL,
	    OS_REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL);

	/* Poll for offset calibration complete */
	if (!ath_hal_wait(ah, AR_PHY_AGC_CONTROL,
	    AR_PHY_AGC_CONTROL_CAL, 0)) {
		HALDEBUG(ah, HAL_DEBUG_RESET,
		    "%s: offset calibration failed to complete in 1ms; "
		    "noisy environment?\n", __func__);
		return AH_FALSE;
	}

	OS_REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);

	return AH_TRUE;
}
Example #4
0
/*
 * Set the RX abort bit.
 */
HAL_BOOL
ar9300SetRxAbort(struct ath_hal *ah, HAL_BOOL set)
{ 
    if (set) {
        /* Set the ForceRXAbort bit */
        OS_REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));

        if ( AH_PRIVATE(ah)->ah_reset_reason == HAL_RESET_BBPANIC ){
            /* depending upon the BB panic status, rx state may not return to 0,
             * so skipping the wait for BB panic reset */
            OS_REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
            return AH_FALSE;    
        } else {
            HAL_BOOL okay;
            okay = ath_hal_wait(
                ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0, AH_WAIT_TIMEOUT);
            /* Wait for Rx state to return to 0 */
            if (!okay) {
                u_int32_t    reg;

                /* abort: chip rx failed to go idle in 10 ms */
                OS_REG_CLR_BIT(ah, AR_DIAG_SW,
                    (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));

                reg = OS_REG_READ(ah, AR_OBS_BUS_1);
                HDPRINTF(ah, HAL_DBG_RX,
                    "%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
                    __func__, reg);

                return AH_FALSE;    // Indicate failure
            }
        }
    }
    else {
        OS_REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
    }

    return AH_TRUE;    // Function completed successfully
}
Example #5
0
void
ar9300GetSpectralParams(struct ath_hal *ah, HAL_SPECTRAL_PARAM *ss)
{
    u_int32_t val;
    struct ath_hal_9300 *ahp = AH9300(ah);
    HAL_POWER_MODE pwrmode = ahp->ah_powerMode;

    if (AR_SREV_WASP(ah) && (pwrmode == HAL_PM_FULL_SLEEP)) {
        ar9300SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE);
    }

    val = OS_REG_READ(ah, AR_PHY_SPECTRAL_SCAN);

    ss->ss_fft_period = MS(val, AR_PHY_SPECTRAL_SCAN_FFT_PERIOD);
    ss->ss_period = MS(val, AR_PHY_SPECTRAL_SCAN_PERIOD);
    ss->ss_count = MS(val, AR_PHY_SPECTRAL_SCAN_COUNT);
    ss->ss_short_report = MS(val, AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT);

    if (AR_SREV_WASP(ah) && (pwrmode == HAL_PM_FULL_SLEEP)) {
        ar9300SetPowerMode(ah, HAL_PM_FULL_SLEEP, AH_TRUE);
    }
}
Example #6
0
static void
ar9285WriteIni(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 */
	freqIndex = 2;
	if (IEEE80211_IS_CHAN_HT40(chan))
		modesIndex = 3;
	else if (IEEE80211_IS_CHAN_108G(chan))
		modesIndex = 5;
	else
		modesIndex = 4;

	/* 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);
	regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_modes,
	    modesIndex, regWrites);
	if (AR_SREV_KITE_12_OR_LATER(ah)) {
		regWrites = ath_hal_ini_write(ah, &AH9285(ah)->ah_ini_txgain,
		    modesIndex, regWrites);
	}
	regWrites = ath_hal_ini_write(ah, &AH5212(ah)->ah_ini_common,
	    1, regWrites);

	OS_REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));

	if (AR_SREV_MERLIN_10_OR_LATER(ah)) {
		uint32_t val;
		val = OS_REG_READ(ah, AR_PCU_MISC_MODE2) &
			(~AR_PCU_MISC_MODE2_HWWAR1);
		OS_REG_WRITE(ah, AR_PCU_MISC_MODE2, val);
		OS_REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
	}

}
/*
 * Reads the Interrupt Status Register value from the NIC, thus deasserting
 * the interrupt line, and returns both the masked and unmasked mapped ISR
 * values.  The value returned is mapped to abstract the hw-specific bit
 * locations in the Interrupt Status Register.
 *
 * Returns: A hardware-abstracted bitmap of all non-masked-out
 *          interrupts pending, as well as an unmasked value
 */
HAL_BOOL
ar5211GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked)
{
	uint32_t isr;

	isr = OS_REG_READ(ah, AR_ISR_RAC);
	if (isr == 0xffffffff) {
		*masked = 0;
		return AH_FALSE;
	}

	*masked = isr & HAL_INT_COMMON;

	if (isr & AR_ISR_HIUERR)
		*masked |= HAL_INT_FATAL;
	if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
		*masked |= HAL_INT_RX;
	if (isr & (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR | AR_ISR_TXEOL))
		*masked |= HAL_INT_TX;
	/*
	 * Receive overrun is usually non-fatal on Oahu/Spirit.
	 * BUT on some parts rx could fail and the chip must be reset.
	 * So we force a hardware reset in all cases.
	 */
	if ((isr & AR_ISR_RXORN) && AH_PRIVATE(ah)->ah_rxornIsFatal) {
		HALDEBUG(ah, HAL_DEBUG_ANY,
		    "%s: receive FIFO overrun interrupt\n", __func__);
		*masked |= HAL_INT_FATAL;
	}

	/*
	 * On fatal errors collect ISR state for debugging.
	 */
	if (*masked & HAL_INT_FATAL) {
		AH_PRIVATE(ah)->ah_fatalState[0] = isr;
		AH_PRIVATE(ah)->ah_fatalState[1] = OS_REG_READ(ah, AR_ISR_S0_S);
		AH_PRIVATE(ah)->ah_fatalState[2] = OS_REG_READ(ah, AR_ISR_S1_S);
		AH_PRIVATE(ah)->ah_fatalState[3] = OS_REG_READ(ah, AR_ISR_S2_S);
		AH_PRIVATE(ah)->ah_fatalState[4] = OS_REG_READ(ah, AR_ISR_S3_S);
		AH_PRIVATE(ah)->ah_fatalState[5] = OS_REG_READ(ah, AR_ISR_S4_S);
		HALDEBUG(ah, HAL_DEBUG_ANY,
		    "%s: fatal error, ISR_RAC=0x%x ISR_S2_S=0x%x\n",
		    __func__, isr, AH_PRIVATE(ah)->ah_fatalState[3]);
	}
	return AH_TRUE;
}
Example #8
0
/*
 * Write 16 bits of data from data to the specified EEPROM offset.
 */
HAL_BOOL
ar5416EepromWrite(struct ath_hal *ah, u_int off, u_int16_t data)
{
    u_int32_t status;
    u_int32_t write_to = 50000;      /* write timeout */
    u_int32_t eepromValue;

    eepromValue = (u_int32_t)data & 0xffff;

    /* Setup EEPROM device to write */
    OS_REG_RMW(ah, AR_GPIO_OUTPUT_MUX1, 0, 0x1f << 15);   /* Mux GPIO-3 as GPIO */
    OS_DELAY(1);
    OS_REG_RMW(ah, AR_GPIO_OE_OUT, 0xc0, 0xc0);     /* Configure GPIO-3 as output */
    OS_DELAY(1);
    OS_REG_RMW(ah, AR_GPIO_IN_OUT, 0, 1 << 3);       /* drive GPIO-3 low */
    OS_DELAY(1);

    /* Send write data, as 32 bit data */
    OS_REG_WRITE(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S), eepromValue);

    /* check busy bit to see if eeprom write succeeded */
    while (write_to > 0) {
        status = OS_REG_READ(ah, AR_EEPROM_STATUS_DATA) &
                                    (AR_EEPROM_STATUS_DATA_BUSY |
                                     AR_EEPROM_STATUS_DATA_BUSY_ACCESS |
                                     AR_EEPROM_STATUS_DATA_PROT_ACCESS |
                                     AR_EEPROM_STATUS_DATA_ABSENT_ACCESS);
        if (status == 0) {
            OS_REG_RMW(ah, AR_GPIO_IN_OUT, 1<<3, 1<<3);       /* drive GPIO-3 hi */
            return AH_TRUE;
        }
        OS_DELAY(1);
        write_to--;
    }

    OS_REG_RMW(ah, AR_GPIO_IN_OUT, 1<<3, 1<<3);       /* drive GPIO-3 hi */
    return AH_FALSE;
}
Example #9
0
/*
 * Configure GPIO Output Mux control
 */
static void
ar5416GpioCfgOutputMux(struct ath_hal *ah, u_int32_t gpio, u_int32_t type)
{
    int          addr;
    u_int32_t    gpio_shift, tmp;

    // each MUX controls 6 GPIO pins
    if (gpio > 11) {
        addr = AR_GPIO_OUTPUT_MUX3;
    } else if (gpio > 5) {
        addr = AR_GPIO_OUTPUT_MUX2;
    } else {
        addr = AR_GPIO_OUTPUT_MUX1;
    }

    // 5 bits per GPIO pin. Bits 0..4 for 1st pin in that mux, bits 5..9 for 2nd pin, etc.
    gpio_shift = (gpio % 6) * 5;

    /*
     * From Owl to Merlin 1.0, the value read from MUX1 bit 4 to bit 9 are wrong.
     * Here is hardware's coding:
     * PRDATA[4:0] <= gpio_output_mux[0];
     * PRDATA[9:4] <= gpio_output_mux[1]; <==== Bit 4 is used by both gpio_output_mux[0] [1].
     * Currently the max value for gpio_output_mux[] is 6. So bit 4 will never be used.
     * So it should be fine that bit 4 won't be able to recover.
     */

    if (AR_SREV_MERLIN_20_OR_LATER(ah) || (addr != AR_GPIO_OUTPUT_MUX1)) {
        OS_REG_RMW(ah, addr, (type << gpio_shift), (0x1f << gpio_shift));
    }
    else {
        tmp = OS_REG_READ(ah, addr);
        tmp = ((tmp & 0x1F0) << 1) | (tmp & ~0x1F0);
        tmp &= ~(0x1f << gpio_shift);
        tmp |= (type << gpio_shift);
        OS_REG_WRITE(ah, addr, tmp);
    }
}
Example #10
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
ar9287olcTemperatureCompensation(struct ath_hal *ah)
{
	uint32_t rddata;
	int32_t delta, currPDADC, slope;

	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: initPDADC=%d, currPDADC=%d\n",
	     __func__, AH5416(ah)->initPDADC, currPDADC);

	if (AH5416(ah)->initPDADC == 0 || currPDADC == 0) {
		/*
		 * Zero value indicates that no frames have been transmitted
		 * yet, can't do temperature compensation until frames are
		 * transmitted.
		 */
		return;
	} else {
		int8_t val;
		(void) (ath_hal_eepromGet(ah, AR_EEP_TEMPSENSE_SLOPE, &val));
		slope = val;

		if (slope == 0) { /* to avoid divide by zero case */
			delta = 0;
		} else {
			delta = ((currPDADC - AH5416(ah)->initPDADC)*4) / slope;
		}
		OS_REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11,
		    AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
		OS_REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11,
		    AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);

		HALDEBUG(ah, HAL_DEBUG_PERCAL, "%s: delta=%d\n", __func__, delta);
	}
}
/*
 * Configure GPIO Output Mux control
 */
static void
cfgOutputMux(struct ath_hal *ah, uint32_t gpio, uint32_t type)
{
	int addr;
	uint32_t gpio_shift, reg;

	/* each MUX controls 6 GPIO pins */
	if (gpio > 11)
		addr = AR_GPIO_OUTPUT_MUX3;
	else if (gpio > 5)
		addr = AR_GPIO_OUTPUT_MUX2;
	else
		addr = AR_GPIO_OUTPUT_MUX1;

	/*
	 * 5 bits per GPIO pin. Bits 0..4 for 1st pin in that mux,
	 * bits 5..9 for 2nd pin, etc.
	 */
	gpio_shift = (gpio % 6) * 5;

	/*
	 * From Owl to Merlin 1.0, the value read from MUX1 bit 4 to bit
	 * 9 are wrong.  Here is hardware's coding:
	 * PRDATA[4:0] <= gpio_output_mux[0];
	 * PRDATA[9:4] <= gpio_output_mux[1];
	 *	<==== Bit 4 is used by both gpio_output_mux[0] [1].
	 * Currently the max value for gpio_output_mux[] is 6. So bit 4
	 * will never be used.  So it should be fine that bit 4 won't be
	 * able to recover.
	 */
	reg = OS_REG_READ(ah, addr);
	if (addr == AR_GPIO_OUTPUT_MUX1 && !AR_SREV_MERLIN_20_OR_LATER(ah))
		reg = ((reg & 0x1F0) << 1) | (reg & ~0x1F0);
	reg &= ~(0x1f << gpio_shift);
	reg |= type << gpio_shift;
	OS_REG_WRITE(ah, addr, reg);
}
Example #12
0
uint32_t
ar5210NumTxPending(struct ath_hal *ah, u_int q)
{
	struct ath_hal_5210 *ahp = AH5210(ah);
	HAL_TX_QUEUE_INFO *qi;
	uint32_t v;

	HALASSERT(q < HAL_NUM_TX_QUEUES);

	HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: queue %u\n", __func__, q);
	qi = &ahp->ah_txq[q];
	switch (qi->tqi_type) {
	case HAL_TX_QUEUE_DATA:
		v = OS_REG_READ(ah, AR_CFG);
		return MS(v, AR_CFG_TXCNT);
	case HAL_TX_QUEUE_INACTIVE:
		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: inactive queue %u\n",
		    __func__, q);
		/* fall thru... */
	default:
		break;
	}
	return 0;
}
Example #13
0
/*
 * Update Tx FIFO trigger level.
 *
 * Set bIncTrigLevel to TRUE to increase the trigger level.
 * Set bIncTrigLevel to FALSE to decrease the trigger level.
 *
 * Returns TRUE if the trigger level was updated
 */
HAL_BOOL
ar5211UpdateTxTrigLevel(struct ath_hal *ah, HAL_BOOL bIncTrigLevel)
{
	uint32_t curTrigLevel, txcfg;
	HAL_INT ints = ar5211GetInterrupts(ah);

	/*
	 * Disable chip interrupts. This is because halUpdateTxTrigLevel
	 * is called from both ISR and non-ISR contexts.
	 */
	ar5211SetInterrupts(ah, ints &~ HAL_INT_GLOBAL);
	txcfg = OS_REG_READ(ah, AR_TXCFG);
	curTrigLevel = (txcfg & AR_TXCFG_FTRIG_M) >> AR_TXCFG_FTRIG_S;
	if (bIncTrigLevel){
		/* increase the trigger level */
		curTrigLevel = curTrigLevel +
			((MAX_TX_FIFO_THRESHOLD - curTrigLevel) / 2);
	} else {
		/* decrease the trigger level if not already at the minimum */
		if (curTrigLevel > MIN_TX_FIFO_THRESHOLD) {
			/* decrease the trigger level */
			curTrigLevel--;
		} else {
			/* no update to the trigger level */
			/* re-enable chip interrupts */
			ar5211SetInterrupts(ah, ints);
			return AH_FALSE;
		}
	}
	/* Update the trigger level */
	OS_REG_WRITE(ah, AR_TXCFG, (txcfg &~ AR_TXCFG_FTRIG_M) |
		((curTrigLevel << AR_TXCFG_FTRIG_S) & AR_TXCFG_FTRIG_M));
	/* re-enable chip interrupts */
	ar5211SetInterrupts(ah, ints);
	return AH_TRUE;
}
Example #14
0
/*
 * Attach for an AR9130 part.
 */
static struct ath_hal *
ar9130Attach(uint16_t devid, HAL_SOFTC sc,
	HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata, HAL_STATUS *status)
{
	struct ath_hal_5416 *ahp5416;
	struct ath_hal_5212 *ahp;
	struct ath_hal *ah;
	uint32_t val;
	HAL_STATUS ecode;
	HAL_BOOL rfStatus;

	HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",
	    __func__, sc, (void*) st, (void*) sh);

	/* NB: memory is returned zero'd */
	ahp5416 = ath_hal_malloc(sizeof (struct ath_hal_5416));
	if (ahp5416 == AH_NULL) {
		HALDEBUG(AH_NULL, HAL_DEBUG_ANY,
		    "%s: cannot allocate memory for state block\n", __func__);
		*status = HAL_ENOMEM;
		return AH_NULL;
	}
	ar5416InitState(ahp5416, devid, sc, st, sh, status);
	ahp = &ahp5416->ah_5212;
	ah = &ahp->ah_priv.h;

	/* XXX override with 9100 specific state */
	AH5416(ah)->ah_initPLL = ar9130InitPLL;
	/* XXX should force chainmasks to 0x7, as per ath9k calibration bugs */

	/* override 5416 methods for our needs */

	AH5416(ah)->ah_cal.iqCalData.calData = &ar9130_iq_cal;
	AH5416(ah)->ah_cal.adcGainCalData.calData = &ar9130_adc_gain_cal;
	AH5416(ah)->ah_cal.adcDcCalData.calData = &ar9130_adc_dc_cal;
	AH5416(ah)->ah_cal.adcDcCalInitData.calData = &ar9130_adc_init_dc_cal;
	AH5416(ah)->ah_cal.suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;

	/*
	 * This was hard-set because the initial ath9k port of this
	 * code kept their runtime conditional register #defines.
	 * AR_SREV and the RTC registers have shifted for Howl;
	 * they detected this and changed the values at runtime.
	 * The current port doesn't yet do this; it may do at a
	 * later stage, so this is set early so any routines which
	 * manipulate the registers have ah_macVersion set to base
	 * the above decision upon.
	 */
	AH_PRIVATE((ah))->ah_macVersion = AR_XSREV_VERSION_HOWL;

	/*
	 * Use the "local" EEPROM data given to us by the higher layers.
	 * This is a private copy out of system flash. The Linux ath9k
	 * commit for the initial AR9130 support mentions MMIO flash
	 * access is "unreliable." -adrian
	 */
	AH_PRIVATE((ah))->ah_eepromRead = ar9130EepromRead;
	AH_PRIVATE((ah))->ah_eepromWrite = NULL;
	ah->ah_eepromdata = eepromdata;

	if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) {
		/* reset chip */
		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n",
		    __func__);
		ecode = HAL_EIO;
		goto bad;
	}

	if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n",
		    __func__);
		ecode = HAL_EIO;
		goto bad;
	}
	/* Read Revisions from Chips before taking out of reset */
	val = OS_REG_READ(ah, AR_SREV_CHIP_HOWL) & AR_SREV_CHIP_HOWL_ID;

	/* XXX are these values even valid for the mac/radio revision? -adrian */
	HALDEBUG(ah, HAL_DEBUG_ATTACH,
	    "%s: ID 0x%x VERSION 0x%x TYPE 0x%x REVISION 0x%x\n",
	    __func__, MS(val, AR_XSREV_ID), MS(val, AR_XSREV_VERSION),
	    MS(val, AR_XSREV_TYPE), MS(val, AR_XSREV_REVISION));
	AH_PRIVATE(ah)->ah_macRev = MS(val, AR_XSREV_REVISION);
	AH_PRIVATE(ah)->ah_ispcie = 0;

	/* setup common ini data; rf backends handle remainder */
	HAL_INI_INIT(&ahp->ah_ini_modes, ar5416Modes_9100, 6);
	HAL_INI_INIT(&ahp->ah_ini_common, ar5416Common_9100, 2);

	HAL_INI_INIT(&AH5416(ah)->ah_ini_bb_rfgain, ar5416BB_RfGain_9100, 3);
	HAL_INI_INIT(&AH5416(ah)->ah_ini_bank0, ar5416Bank0_9100, 2);
	HAL_INI_INIT(&AH5416(ah)->ah_ini_bank1, ar5416Bank1_9100, 2);
	HAL_INI_INIT(&AH5416(ah)->ah_ini_bank2, ar5416Bank2_9100, 2);
	HAL_INI_INIT(&AH5416(ah)->ah_ini_bank3, ar5416Bank3_9100, 3);
	HAL_INI_INIT(&AH5416(ah)->ah_ini_bank6, ar5416Bank6TPC_9100, 3);
	HAL_INI_INIT(&AH5416(ah)->ah_ini_bank7, ar5416Bank7_9100, 2);
	HAL_INI_INIT(&AH5416(ah)->ah_ini_addac, ar5416Addac_9100, 2);

	ecode = ath_hal_v14EepromAttach(ah);
	if (ecode != HAL_OK)
		goto bad;

	if (!ar5416ChipReset(ah, AH_NULL)) {	/* reset chip */
		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);
		ecode = HAL_EIO;
		goto bad;
	}

	AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID);

	if (!ar5212ChipTest(ah)) {
		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n",
		    __func__);
		ecode = HAL_ESELFTEST;
		goto bad;
	}

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

	/* Read Radio Chip Rev Extract */
	AH_PRIVATE(ah)->ah_analog5GhzRev = ar5416GetRadioRev(ah);
	switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) {
        case AR_RAD2133_SREV_MAJOR:	/* Sowl: 2G/3x3 */
	case AR_RAD5133_SREV_MAJOR:	/* Sowl: 2+5G/3x3 */
		break;
	default:
		if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) {
			AH_PRIVATE(ah)->ah_analog5GhzRev =
				AR_RAD5133_SREV_MAJOR;
			break;
		}
#ifdef AH_DEBUG
		HALDEBUG(ah, HAL_DEBUG_ANY,
		    "%s: 5G Radio Chip Rev 0x%02X is not supported by "
		    "this driver\n", __func__,
		    AH_PRIVATE(ah)->ah_analog5GhzRev);
		ecode = HAL_ENOTSUPP;
		goto bad;
#endif
	}
	rfStatus = ar2133RfAttach(ah, &ecode);
	if (!rfStatus) {
		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n",
		    __func__, ecode);
		goto bad;
	}

	/*
	 * Got everything we need now to setup the capabilities.
	 */
	if (!ar9130FillCapabilityInfo(ah)) {
		ecode = HAL_EEREAD;
		goto bad;
	}

	ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr);
	if (ecode != HAL_OK) {
		HALDEBUG(ah, HAL_DEBUG_ANY,
		    "%s: error getting mac address from EEPROM\n", __func__);
		goto bad;
        }
	/* XXX How about the serial number ? */
	/* Read Reg Domain */
	AH_PRIVATE(ah)->ah_currentRD =
	    ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL);
	AH_PRIVATE(ah)->ah_currentRDext =
	    ath_hal_eepromGet(ah, AR_EEP_REGDMN_1, AH_NULL);


	/*
	 * ah_miscMode is populated by ar5416FillCapabilityInfo()
	 * starting from griffin. Set here to make sure that
	 * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is
	 * placed into hardware.
	 */
	if (ahp->ah_miscMode != 0)
		OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);

	/* XXX no ANI for AR9130 */
	AH5416(ah)->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ;
	AH5416(ah)->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ;
	AH5416(ah)->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_5416_2GHZ;
	AH5416(ah)->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ;
	AH5416(ah)->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ;
	AH5416(ah)->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_5416_5GHZ;

	ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist);

	HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);

	return ah;
bad:
	if (ahp)
		ar5416Detach((struct ath_hal *) ahp);
	if (status)
		*status = ecode;
	return AH_NULL;
}
Example #15
0
/*
 * Take the MHz channel value and set the Channel value
 *
 * ASSUMES: Writes enabled to analog bus
 *
 * Actual Expression,
 *
 * For 2GHz channel, 
 * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17) 
 * (freq_ref = 40MHz)
 *
 * For 5GHz channel,
 * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
 * (freq_ref = 40MHz/(24>>amodeRefSel))
 *
 * For 5GHz channels which are 5MHz spaced,
 * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
 * (freq_ref = 40MHz)
 */
static HAL_BOOL
ar9287SetChannel(struct ath_hal *ah, const struct ieee80211_channel *chan)
{
	uint16_t bMode, fracMode, aModeRefSel = 0;
	uint32_t freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
	CHAN_CENTERS centers;
	uint32_t refDivA = 24;

	OS_MARK(ah, AH_MARK_SETCHANNEL, chan->ic_freq);

	ar5416GetChannelCenters(ah, chan, &centers);
	freq = centers.synth_center;

	reg32 = OS_REG_READ(ah, AR_PHY_SYNTH_CONTROL);
	reg32 &= 0xc0000000;

	if (freq < 4800) {     /* 2 GHz, fractional mode */
		uint32_t txctl;
		int regWrites = 0;

		bMode = 1;
		fracMode = 1;
		aModeRefSel = 0;       
		channelSel = (freq * 0x10000)/15;

		if (AR_SREV_KIWI_11_OR_LATER(ah)) {
			if (freq == 2484) {
				ath_hal_ini_write(ah,
				    &AH9287(ah)->ah_ini_cckFirJapan2484, 1,
				    regWrites);
			} else {
				ath_hal_ini_write(ah,
				    &AH9287(ah)->ah_ini_cckFirNormal, 1,
				    regWrites);
			}
		}

		txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);
		if (freq == 2484) {
			/* Enable channel spreading for channel 14 */
			OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
			    txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
		} else {
			OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
			    txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
		}     
	} else {
		bMode = 0;
		fracMode = 0;

		if ((freq % 20) == 0) {
			aModeRefSel = 3;
		} else if ((freq % 10) == 0) {
			aModeRefSel = 2;
		} else {
			aModeRefSel = 0;
			/*
			 * Enable 2G (fractional) mode for channels which
			 * are 5MHz spaced
			 */
			fracMode = 1;
			refDivA = 1;
			channelSel = (freq * 0x8000)/15;

			/* RefDivA setting */
			OS_A_REG_RMW_FIELD(ah, AR_AN_SYNTH9,
			    AR_AN_SYNTH9_REFDIVA, refDivA);
		}
		if (!fracMode) {
			ndiv = (freq * (refDivA >> aModeRefSel))/60;
			channelSel =  ndiv & 0x1ff;         
			channelFrac = (ndiv & 0xfffffe00) * 2;
			channelSel = (channelSel << 17) | channelFrac;
		}
	}
/*
 * Reads the Interrupt Status Register value from the NIC, thus deasserting
 * the interrupt line, and returns both the masked and unmasked mapped ISR
 * values.  The value returned is mapped to abstract the hw-specific bit
 * locations in the Interrupt Status Register.
 *
 * (*masked) is cleared on initial call.
 *
 * Returns: A hardware-abstracted bitmap of all non-masked-out
 *          interrupts pending, as well as an unmasked value
 */
HAL_BOOL
ar5416GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked)
{
	uint32_t isr, isr0, isr1, sync_cause;

	/*
	 * Verify there's a mac interrupt and the RTC is on.
	 */
	if ((OS_REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) &&
	    (OS_REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) == AR_RTC_STATUS_ON)
		isr = OS_REG_READ(ah, AR_ISR);
	else
		isr = 0;
	sync_cause = OS_REG_READ(ah, AR_INTR_SYNC_CAUSE);
	sync_cause &= AR_INTR_SYNC_DEFAULT;
	*masked = 0;
	if (isr == 0 && sync_cause == 0)
		return AH_FALSE;

	if (isr != 0) {
		struct ath_hal_5212 *ahp = AH5212(ah);
		uint32_t mask2;

		mask2 = 0;
		if (isr & AR_ISR_BCNMISC) {
			uint32_t isr2 = OS_REG_READ(ah, AR_ISR_S2);
			if (isr2 & AR_ISR_S2_TIM)
				mask2 |= HAL_INT_TIM;
			if (isr2 & AR_ISR_S2_DTIM)
				mask2 |= HAL_INT_DTIM;
			if (isr2 & AR_ISR_S2_DTIMSYNC)
				mask2 |= HAL_INT_DTIMSYNC;
			if (isr2 & (AR_ISR_S2_CABEND ))
				mask2 |= HAL_INT_CABEND;
			if (isr2 & AR_ISR_S2_GTT)
				mask2 |= HAL_INT_GTT;
			if (isr2 & AR_ISR_S2_CST)
				mask2 |= HAL_INT_CST;	
			if (isr2 & AR_ISR_S2_TSFOOR)
				mask2 |= HAL_INT_TSFOOR;
		}

		isr = OS_REG_READ(ah, AR_ISR_RAC);
		if (isr == 0xffffffff) {
			*masked = 0;
			return AH_FALSE;
		}

		*masked = isr & HAL_INT_COMMON;
		if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
			*masked |= HAL_INT_RX;
		if (isr & (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR | AR_ISR_TXEOL)) {
			*masked |= HAL_INT_TX;
			isr0 = OS_REG_READ(ah, AR_ISR_S0_S);
			ahp->ah_intrTxqs |= MS(isr0, AR_ISR_S0_QCU_TXOK);
			ahp->ah_intrTxqs |= MS(isr0, AR_ISR_S0_QCU_TXDESC);
			isr1 = OS_REG_READ(ah, AR_ISR_S1_S);
			ahp->ah_intrTxqs |= MS(isr1, AR_ISR_S1_QCU_TXERR);
			ahp->ah_intrTxqs |= MS(isr1, AR_ISR_S1_QCU_TXEOL);
		}

		if (AR_SREV_MERLIN(ah) || AR_SREV_KITE(ah)) {
			uint32_t isr5;
			isr5 = OS_REG_READ(ah, AR_ISR_S5_S);
			if (isr5 & AR_ISR_S5_TIM_TIMER)
				*masked |= HAL_INT_TIM_TIMER;
		}

		/* Interrupt Mitigation on AR5416 */
#ifdef AR5416_INT_MITIGATION
		if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
			*masked |= HAL_INT_RX;
		if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM))
			*masked |= HAL_INT_TX;
#endif
		*masked |= mask2;
	}
	if (sync_cause != 0) {
		if (sync_cause & (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR)) {
			*masked |= HAL_INT_FATAL;
		}
		if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
			HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RADM CPL timeout\n",
			    __func__);
			OS_REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
			OS_REG_WRITE(ah, AR_RC, 0);
			*masked |= HAL_INT_FATAL;
		}
		/*
		 * On fatal errors collect ISR state for debugging.
		 */
		if (*masked & HAL_INT_FATAL) {
			AH_PRIVATE(ah)->ah_fatalState[0] = isr;
			AH_PRIVATE(ah)->ah_fatalState[1] = sync_cause;
			HALDEBUG(ah, HAL_DEBUG_ANY,
			    "%s: fatal error, ISR_RAC 0x%x SYNC_CAUSE 0x%x\n",
			    __func__, isr, sync_cause);
		}

		OS_REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
		/* NB: flush write */
		(void) OS_REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
	}
	return AH_TRUE;
}
/*
 * Atomically enables NIC interrupts.  Interrupts are passed in
 * via the enumerated bitmask in ints.
 */
HAL_INT
ar5416SetInterrupts(struct ath_hal *ah, HAL_INT ints)
{
	struct ath_hal_5212 *ahp = AH5212(ah);
	uint32_t omask = ahp->ah_maskReg;
	uint32_t mask, mask2;

	HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: 0x%x => 0x%x\n",
	    __func__, omask, ints);

	if (omask & HAL_INT_GLOBAL) {
		HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: disable IER\n", __func__);
		OS_REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
		(void) OS_REG_READ(ah, AR_IER);

		OS_REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
		(void) OS_REG_READ(ah, AR_INTR_ASYNC_ENABLE);

		OS_REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
		(void) OS_REG_READ(ah, AR_INTR_SYNC_ENABLE);
	}

	mask = ints & HAL_INT_COMMON;
	mask2 = 0;

	if (ints & HAL_INT_TX) {
		if (ahp->ah_txOkInterruptMask)
			mask |= AR_IMR_TXOK;
		if (ahp->ah_txErrInterruptMask)
			mask |= AR_IMR_TXERR;
		if (ahp->ah_txDescInterruptMask)
			mask |= AR_IMR_TXDESC;
		if (ahp->ah_txEolInterruptMask)
			mask |= AR_IMR_TXEOL;
	}
	if (ints & HAL_INT_RX)
		mask |= AR_IMR_RXOK | AR_IMR_RXERR | AR_IMR_RXDESC;
#ifdef AR5416_INT_MITIGATION
	/*
	 * Overwrite default mask if Interrupt mitigation
	 * is specified for AR5416
	 */
	mask = ints & HAL_INT_COMMON;
	if (ints & HAL_INT_TX)
		mask |= AR_IMR_TXMINTR | AR_IMR_TXINTM;
	if (ints & HAL_INT_RX)
		mask |= AR_IMR_RXERR | AR_IMR_RXMINTR | AR_IMR_RXINTM;
#endif
	if (ints & (HAL_INT_BMISC)) {
		mask |= AR_IMR_BCNMISC;
		if (ints & HAL_INT_TIM)
			mask2 |= AR_IMR_S2_TIM;
		if (ints & HAL_INT_DTIM)
			mask2 |= AR_IMR_S2_DTIM;
		if (ints & HAL_INT_DTIMSYNC)
			mask2 |= AR_IMR_S2_DTIMSYNC;
		if (ints & HAL_INT_CABEND)
			mask2 |= (AR_IMR_S2_CABEND );
		if (ints & HAL_INT_GTT)
			mask2 |= AR_IMR_S2_GTT;			
		if (ints & HAL_INT_CST)
			mask2 |= AR_IMR_S2_CST;
		if (ints & HAL_INT_TSFOOR)
			mask2 |= AR_IMR_S2_TSFOOR;
	}

	/* Write the new IMR and store off our SW copy. */
	HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: new IMR 0x%x\n", __func__, mask);
	OS_REG_WRITE(ah, AR_IMR, mask);
	mask = OS_REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM |
					AR_IMR_S2_DTIM |
					AR_IMR_S2_DTIMSYNC |
					AR_IMR_S2_CABEND |
					AR_IMR_S2_CABTO  |
					AR_IMR_S2_TSFOOR |
					AR_IMR_S2_GTT |
					AR_IMR_S2_CST);
	OS_REG_WRITE(ah, AR_IMR_S2, mask | mask2);

	ahp->ah_maskReg = ints;

	/* Re-enable interrupts if they were enabled before. */
	if (ints & HAL_INT_GLOBAL) {
		HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: enable IER\n", __func__);
		OS_REG_WRITE(ah, AR_IER, AR_IER_ENABLE);

		OS_REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, AR_INTR_MAC_IRQ);
		OS_REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);

		OS_REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
		OS_REG_WRITE(ah, AR_INTR_SYNC_MASK, AR_INTR_SYNC_DEFAULT);
	}

	return omask;
}
Example #18
0
/*
 * Set the GPIO Interrupt
 */
void
ar5416GpioSetIntr(struct ath_hal *ah, u_int gpio, uint32_t ilevel)
{
	uint32_t val, mask;

	HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins);

	if (ilevel == HAL_GPIO_INTR_DISABLE) {
		val = MS(OS_REG_READ(ah, AR_INTR_ASYNC_ENABLE),
			 AR_INTR_ASYNC_ENABLE_GPIO) &~ AR_GPIO_BIT(gpio);
		OS_REG_RMW_FIELD(ah, AR_INTR_ASYNC_ENABLE,
		    AR_INTR_ASYNC_ENABLE_GPIO, val);

		mask = MS(OS_REG_READ(ah, AR_INTR_ASYNC_MASK),
			  AR_INTR_ASYNC_MASK_GPIO) &~ AR_GPIO_BIT(gpio);
		OS_REG_RMW_FIELD(ah, AR_INTR_ASYNC_MASK,
		    AR_INTR_ASYNC_MASK_GPIO, mask);

		/* Clear synchronous GPIO interrupt registers and pending interrupt flag */
		val = MS(OS_REG_READ(ah, AR_INTR_SYNC_ENABLE),
			 AR_INTR_SYNC_ENABLE_GPIO) &~ AR_GPIO_BIT(gpio);
		OS_REG_RMW_FIELD(ah, AR_INTR_SYNC_ENABLE,
		    AR_INTR_SYNC_ENABLE_GPIO, val);

		mask = MS(OS_REG_READ(ah, AR_INTR_SYNC_MASK),
			  AR_INTR_SYNC_MASK_GPIO) &~ AR_GPIO_BIT(gpio);
		OS_REG_RMW_FIELD(ah, AR_INTR_SYNC_MASK,
		    AR_INTR_SYNC_MASK_GPIO, mask);

		val = MS(OS_REG_READ(ah, AR_INTR_SYNC_CAUSE),
			 AR_INTR_SYNC_ENABLE_GPIO) | AR_GPIO_BIT(gpio);
		OS_REG_RMW_FIELD(ah, AR_INTR_SYNC_CAUSE,
		    AR_INTR_SYNC_ENABLE_GPIO, val);
	} else {
		val = MS(OS_REG_READ(ah, AR_GPIO_INTR_POL),
			 AR_GPIO_INTR_POL_VAL);
		if (ilevel == HAL_GPIO_INTR_HIGH) {
			/* 0 == interrupt on pin high */
			val &= ~AR_GPIO_BIT(gpio);
		} else if (ilevel == HAL_GPIO_INTR_LOW) {
			/* 1 == interrupt on pin low */
			val |= AR_GPIO_BIT(gpio);
		}
		OS_REG_RMW_FIELD(ah, AR_GPIO_INTR_POL,
		    AR_GPIO_INTR_POL_VAL, val);

		/* Change the interrupt mask. */
		val = MS(OS_REG_READ(ah, AR_INTR_ASYNC_ENABLE),
			 AR_INTR_ASYNC_ENABLE_GPIO) | AR_GPIO_BIT(gpio);
		OS_REG_RMW_FIELD(ah, AR_INTR_ASYNC_ENABLE,
		    AR_INTR_ASYNC_ENABLE_GPIO, val);

		mask = MS(OS_REG_READ(ah, AR_INTR_ASYNC_MASK),
			  AR_INTR_ASYNC_MASK_GPIO) | AR_GPIO_BIT(gpio);
		OS_REG_RMW_FIELD(ah, AR_INTR_ASYNC_MASK,
		    AR_INTR_ASYNC_MASK_GPIO, mask);

		/* Set synchronous GPIO interrupt registers as well */
		val = MS(OS_REG_READ(ah, AR_INTR_SYNC_ENABLE),
			 AR_INTR_SYNC_ENABLE_GPIO) | AR_GPIO_BIT(gpio);
		OS_REG_RMW_FIELD(ah, AR_INTR_SYNC_ENABLE,
		    AR_INTR_SYNC_ENABLE_GPIO, val);

		mask = MS(OS_REG_READ(ah, AR_INTR_SYNC_MASK),
			  AR_INTR_SYNC_MASK_GPIO) | AR_GPIO_BIT(gpio);
		OS_REG_RMW_FIELD(ah, AR_INTR_SYNC_MASK,
		    AR_INTR_SYNC_MASK_GPIO, mask);
	}
	AH5416(ah)->ah_gpioMask = mask;		/* for ar5416SetInterrupts */
}
void 
ar9300_tx99_tgt_stop(struct ath_hal *ah)
{
    OS_REG_WRITE(ah, AR_PHY_TEST, OS_REG_READ(ah, AR_PHY_TEST) &~ PHY_AGC_CLR);
    OS_REG_WRITE(ah, AR_DIAG_SW, OS_REG_READ(ah, AR_DIAG_SW) &~ (AR_DIAG_FORCE_RX_CLEAR | AR_DIAG_IGNORE_VIRT_CS));
}
void
ar9300_tx99_tgt_set_single_carrier(struct ath_hal *ah, int tx_chain_mask, int chtype)
{
    OS_REG_WRITE(ah, AR_PHY_TST_DAC_CONST, OS_REG_READ(ah, AR_PHY_TST_DAC_CONST) | (0x7ff<<11) | 0x7ff);
    OS_REG_WRITE(ah, AR_PHY_TEST_CTL_STATUS, OS_REG_READ(ah, AR_PHY_TEST_CTL_STATUS) | (1<<7) | (1<<1));
    OS_REG_WRITE(ah, AR_PHY_ADDAC_PARA_CTL, (OS_REG_READ(ah, AR_PHY_ADDAC_PARA_CTL) | (1<<31) | (1<<15)) & ~(1<<13));

    /* 11G mode */
    if (!chtype)
    {
        OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX2, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2)
                                                    | (0x1 << 3) | (0x1 << 2));
        if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) {
            OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP)
                                                        & ~(0x1 << 4)); 
            OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP2, (OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP2)
                                                        | (0x1 << 26)  | (0x7 << 24)) 
                                                        & ~(0x1 << 22));
        } else {
            OS_REG_WRITE(ah, AR_HORNET_CH0_TOP, OS_REG_READ(ah, AR_HORNET_CH0_TOP)
                                                        & ~(0x1 << 4)); 
            OS_REG_WRITE(ah, AR_HORNET_CH0_TOP2, (OS_REG_READ(ah, AR_HORNET_CH0_TOP2)
                                                        | (0x1 << 26)  | (0x7 << 24)) 
                                                        & ~(0x1 << 22));
        }                                                    
        
        /* chain zero */
    	if((tx_chain_mask & 0x01) == 0x01) {
    		OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX1, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX1)
                                                          | (0x1 << 31) | (0x5 << 15) 
                                                          | (0x3 << 9)) & ~(0x1 << 27) 
                                                          & ~(0x1 << 12));
    		OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2)
                                                          | (0x1 << 12) | (0x1 << 10) 
                                                          | (0x1 << 9)  | (0x1 << 8)  
                                                          | (0x1 << 7)) & ~(0x1 << 11));                                      
    		OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX3, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX3)
                                                          | (0x1 << 29) | (0x1 << 25) 
                                                          | (0x1 << 23) | (0x1 << 19) 
                                                          | (0x1 << 10) | (0x1 << 9)  
                                                          | (0x1 << 8)  | (0x1 << 3))
                                                          & ~(0x1 << 28)& ~(0x1 << 24)
                                                          & ~(0x1 << 22)& ~(0x1 << 7));
    		OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TXRF1, (OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF1)
                                                          | (0x1 << 23))& ~(0x1 << 21));
    		OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BB1, OS_REG_READ(ah, AR_PHY_65NM_CH0_BB1)
                                                          | (0x1 << 12) | (0x1 << 10)
                                                          | (0x1 << 9)  | (0x1 << 8)
                                                          | (0x1 << 6)  | (0x1 << 5)
                                                          | (0x1 << 4)  | (0x1 << 3)
                                                          | (0x1 << 2));                                                          
            OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BB2, OS_REG_READ(ah, AR_PHY_65NM_CH0_BB2)
                                                          | (0x1 << 31));                                                 
        }
        if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) {
            /* chain one */
        	if ((tx_chain_mask & 0x02) == 0x02 ) {
        	    OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX1, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX1)
                                                              | (0x1 << 31) | (0x5 << 15) 
                                                              | (0x3 << 9)) & ~(0x1 << 27) 
                                                              & ~(0x1 << 12));
        		OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX2)
                                                              | (0x1 << 12) | (0x1 << 10) 
                                                              | (0x1 << 9)  | (0x1 << 8)  
                                                              | (0x1 << 7)) & ~(0x1 << 11));
                OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX3, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX3)
                                                              | (0x1 << 29) | (0x1 << 25) 
                                                              | (0x1 << 23) | (0x1 << 19) 
                                                              | (0x1 << 10) | (0x1 << 9)  
                                                              | (0x1 << 8)  | (0x1 << 3))
                                                              & ~(0x1 << 28)& ~(0x1 << 24)
                                                              & ~(0x1 << 22)& ~(0x1 << 7));
                OS_REG_WRITE(ah, AR_PHY_65NM_CH1_TXRF1, (OS_REG_READ(ah, AR_PHY_65NM_CH1_TXRF1)
                                                              | (0x1 << 23))& ~(0x1 << 21));
        		OS_REG_WRITE(ah, AR_PHY_65NM_CH1_BB1, OS_REG_READ(ah, AR_PHY_65NM_CH1_BB1)
                                                              | (0x1 << 12) | (0x1 << 10)
                                                              | (0x1 << 9)  | (0x1 << 8)
                                                              | (0x1 << 6)  | (0x1 << 5)
                                                              | (0x1 << 4)  | (0x1 << 3)
                                                              | (0x1 << 2));                                            
                OS_REG_WRITE(ah, AR_PHY_65NM_CH1_BB2, OS_REG_READ(ah, AR_PHY_65NM_CH1_BB2)
                                                              | (0x1 << 31));	
        	}
    	}
    	if (AR_SREV_OSPREY(ah)) {
        	/* chain two */
        	if ((tx_chain_mask & 0x04) == 0x04 ) {
        	    OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX1, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX1)
                                                              | (0x1 << 31) | (0x5 << 15) 
                                                              | (0x3 << 9)) & ~(0x1 << 27)
                                                              & ~(0x1 << 12));
        		OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX2)
                                                              | (0x1 << 12) | (0x1 << 10) 
                                                              | (0x1 << 9)  | (0x1 << 8)  
                                                              | (0x1 << 7)) & ~(0x1 << 11));
                OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX3, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX3)
                                                              | (0x1 << 29) | (0x1 << 25) 
                                                              | (0x1 << 23) | (0x1 << 19) 
                                                              | (0x1 << 10) | (0x1 << 9)  
                                                              | (0x1 << 8)  | (0x1 << 3)) 
                                                              & ~(0x1 << 28)& ~(0x1 << 24) 
                                                              & ~(0x1 << 22)& ~(0x1 << 7));
                OS_REG_WRITE(ah, AR_PHY_65NM_CH2_TXRF1, (OS_REG_READ(ah, AR_PHY_65NM_CH2_TXRF1)
                                                              | (0x1 << 23))& ~(0x1 << 21));
        		OS_REG_WRITE(ah, AR_PHY_65NM_CH2_BB1, OS_REG_READ(ah, AR_PHY_65NM_CH2_BB1)
                                                              | (0x1 << 12) | (0x1 << 10)
                                                              | (0x1 << 9)  | (0x1 << 8)
                                                              | (0x1 << 6)  | (0x1 << 5)
                                                              | (0x1 << 4)  | (0x1 << 3)
                                                              | (0x1 << 2));                                            
                OS_REG_WRITE(ah, AR_PHY_65NM_CH2_BB2, OS_REG_READ(ah, AR_PHY_65NM_CH2_BB2)
                                                              | (0x1 << 31));	
        	}
    	}
    	
    	OS_REG_WRITE(ah, AR_PHY_SWITCH_COM_2, 0x11111);
        OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, 0x111);      
    }
    else
    {
        /* chain zero */
    	if((tx_chain_mask & 0x01) == 0x01) {
            OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX1, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX1)
    		                                              | (0x1 << 31) | (0x1 << 27)
                                                          | (0x3 << 23) | (0x1 << 19)
                                                          | (0x1 << 15) | (0x3 << 9))
                                                          & ~(0x1 << 12));
    		OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2)
                                                          | (0x1 << 12) | (0x1 << 10) 
                                                          | (0x1 << 9)  | (0x1 << 8)  
                                                          | (0x1 << 7)  | (0x1 << 3)  
                                                          | (0x1 << 2)  | (0x1 << 1)) 
                                                          & ~(0x1 << 11)& ~(0x1 << 0));
            OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX3, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX3)
			                                              | (0x1 << 29) | (0x1 << 25) 
                                                          | (0x1 << 23) | (0x1 << 19) 
                                                          | (0x1 << 10) | (0x1 << 9)  
                                                          | (0x1 << 8)  | (0x1 << 3))
                                                          & ~(0x1 << 28)& ~(0x1 << 24)
                                                          & ~(0x1 << 22)& ~(0x1 << 7));
			OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TXRF1, (OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF1)
			                                              | (0x1 << 23))& ~(0x1 << 21));
			OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TXRF2, OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF2)
                                                          | (0x3 << 3)  | (0x3 << 0));
			OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TXRF3, (OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF3)
                                                          | (0x3 << 29) | (0x3 << 26)
                                                          | (0x2 << 23) | (0x2 << 20)
                                                          | (0x2 << 17))& ~(0x1 << 14));
			OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BB1, OS_REG_READ(ah, AR_PHY_65NM_CH0_BB1)
			                                              | (0x1 << 12) | (0x1 << 10)
                                                          | (0x1 << 9)  | (0x1 << 8)
                                                          | (0x1 << 6)  | (0x1 << 5)
                                                          | (0x1 << 4)  | (0x1 << 3)
                                                          | (0x1 << 2));
			OS_REG_WRITE(ah, AR_PHY_65NM_CH0_BB2, OS_REG_READ(ah, AR_PHY_65NM_CH0_BB2)
                                                          | (0x1 << 31));
			if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) {
    			OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP)
    			                                              & ~(0x1 << 4));
    			OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP2, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP2)
    		                                                  | (0x1 << 26) | (0x7 << 24)
    		                                                  | (0x3 << 22));
            } else {
    			OS_REG_WRITE(ah, AR_HORNET_CH0_TOP, OS_REG_READ(ah, AR_HORNET_CH0_TOP)
    			                                              & ~(0x1 << 4));
    			OS_REG_WRITE(ah, AR_HORNET_CH0_TOP2, OS_REG_READ(ah, AR_HORNET_CH0_TOP2)
    		                                                  | (0x1 << 26) | (0x7 << 24)
    		                                                  | (0x3 << 22));
		    }	                                                 
                                    
            if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) {
                OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX2)
    			                                              | (0x1 << 3)  | (0x1 << 2)
                                                              | (0x1 << 1)) & ~(0x1 << 0));
    			OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX3, OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX3)
    			                                              | (0x1 << 19) | (0x1 << 3));
                OS_REG_WRITE(ah, AR_PHY_65NM_CH1_TXRF1, OS_REG_READ(ah, AR_PHY_65NM_CH1_TXRF1)
    			                                              | (0x1 << 23));
			}
			if (AR_SREV_OSPREY(ah)) {    		
                OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX2)
    			                                              | (0x1 << 3)  | (0x1 << 2)
                                                              | (0x1 << 1)) & ~(0x1 << 0));
    			OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX3, OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX3)
    			                                              | (0x1 << 19) | (0x1 << 3));
    			OS_REG_WRITE(ah, AR_PHY_65NM_CH2_TXRF1, OS_REG_READ(ah, AR_PHY_65NM_CH2_TXRF1)
    			                                              | (0x1 << 23));
    	    }
    	}
    	if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) {
            /* chain one */
        	if ((tx_chain_mask & 0x02) == 0x02 ) {
                OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2)
                                                              | (0x1 << 3)  | (0x1 << 2)
                                                              | (0x1 << 1)) & ~(0x1 << 0));
                OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX3, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX3)
    			                                              | (0x1 << 19) | (0x1 << 3));
                OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TXRF1, OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF1)
    			                                              | (0x1 << 23));
    			if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) {
        			OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP)
                                                                  & ~(0x1 << 4));
        			OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP2, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP2)
        		                                                  | (0x1 << 26) | (0x7 << 24)
        		                                                  | (0x3 << 22));
                } else {
        			OS_REG_WRITE(ah, AR_HORNET_CH0_TOP, OS_REG_READ(ah, AR_HORNET_CH0_TOP)
                                                                  & ~(0x1 << 4));
        			OS_REG_WRITE(ah, AR_HORNET_CH0_TOP2, OS_REG_READ(ah, AR_HORNET_CH0_TOP2)
        		                                                  | (0x1 << 26) | (0x7 << 24)
        		                                                  | (0x3 << 22));
                }
                
                OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX1, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX1)
        		                                              | (0x1 << 31) | (0x1 << 27)
                                                              | (0x3 << 23) | (0x1 << 19)
                                                              | (0x1 << 15) | (0x3 << 9)) 
                                                              & ~(0x1 << 12));
    			OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX2)
                                                              | (0x1 << 12) | (0x1 << 10) 
                                                              | (0x1 << 9)  | (0x1 << 8)  
                                                              | (0x1 << 7)  | (0x1 << 3)  
                                                              | (0x1 << 2)  | (0x1 << 1))  
                                                              & ~(0x1 << 11)& ~(0x1 << 0));
    			OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX3, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX3)
    			                                              | (0x1 << 29) | (0x1 << 25) 
                                                              | (0x1 << 23) | (0x1 << 19) 
                                                              | (0x1 << 10) | (0x1 << 9)  
                                                              | (0x1 << 8)  | (0x1 << 3))
                                                              & ~(0x1 << 28)& ~(0x1 << 24)
                                                              & ~(0x1 << 22)& ~(0x1 << 7));
    			OS_REG_WRITE(ah, AR_PHY_65NM_CH1_TXRF1, (OS_REG_READ(ah, AR_PHY_65NM_CH1_TXRF1)
    			                                              | (0x1 << 23))& ~(0x1 << 21));
    			OS_REG_WRITE(ah, AR_PHY_65NM_CH1_TXRF2, OS_REG_READ(ah, AR_PHY_65NM_CH1_TXRF2)
                                                              | (0x3 << 3)  | (0x3 << 0));
    			OS_REG_WRITE(ah, AR_PHY_65NM_CH1_TXRF3, (OS_REG_READ(ah, AR_PHY_65NM_CH1_TXRF3)
                                                              | (0x3 << 29) | (0x3 << 26)
                                                              | (0x2 << 23) | (0x2 << 20)
                                                              | (0x2 << 17))& ~(0x1 << 14));
    			OS_REG_WRITE(ah, AR_PHY_65NM_CH1_BB1, OS_REG_READ(ah, AR_PHY_65NM_CH1_BB1)
    			                                              | (0x1 << 12) | (0x1 << 10)
                                                              | (0x1 << 9)  | (0x1 << 8)
                                                              | (0x1 << 6)  | (0x1 << 5)
                                                              | (0x1 << 4)  | (0x1 << 3)
                                                              | (0x1 << 2));
    			OS_REG_WRITE(ah, AR_PHY_65NM_CH1_BB2, OS_REG_READ(ah, AR_PHY_65NM_CH1_BB2)
                                                              | (0x1 << 31));
    			
    			if (AR_SREV_OSPREY(ah)) {
                    OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX2)
        			                                              | (0x1 << 3)  | (0x1 << 2)
                                                                  | (0x1 << 1)) & ~(0x1 << 0));
        			OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX3, OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX3)
        			                                              | (0x1 << 19) | (0x1 << 3));
        			OS_REG_WRITE(ah, AR_PHY_65NM_CH2_TXRF1, OS_REG_READ(ah, AR_PHY_65NM_CH2_TXRF1)
        			                                              | (0x1 << 23));
        	    }
        	}
    	}
    	if (AR_SREV_OSPREY(ah)) {
        	/* chain two */
        	if ((tx_chain_mask & 0x04) == 0x04 ) {
        		OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX2)
                                                              | (0x1 << 3)  | (0x1 << 2)
                                                              | (0x1 << 1)) & ~(0x1 << 0));
                OS_REG_WRITE(ah, AR_PHY_65NM_CH0_RXTX3, OS_REG_READ(ah, AR_PHY_65NM_CH0_RXTX3)
    			                                              | (0x1 << 19) | (0x1 << 3));
    			OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TXRF1, OS_REG_READ(ah, AR_PHY_65NM_CH0_TXRF1)
    			                                              | (0x1 << 23));
    			if (AR_SREV_OSPREY(ah) || AR_SREV_WASP(ah)) {
        			OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP)
        			                                              & ~(0x1 << 4));
        			OS_REG_WRITE(ah, AR_PHY_65NM_CH0_TOP2, OS_REG_READ(ah, AR_PHY_65NM_CH0_TOP2)
        		                                                  | (0x1 << 26) | (0x7 << 24)
        		                                                  | (0x3 << 22));
    		    } else {
        			OS_REG_WRITE(ah, AR_HORNET_CH0_TOP, OS_REG_READ(ah, AR_HORNET_CH0_TOP)
        			                                              & ~(0x1 << 4));
        			OS_REG_WRITE(ah, AR_HORNET_CH0_TOP2, OS_REG_READ(ah, AR_HORNET_CH0_TOP2)
        		                                                  | (0x1 << 26) | (0x7 << 24)
        		                                                  | (0x3 << 22));
    		    }
    		    
                OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX2)
    			                                              | (0x1 << 3)  | (0x1 << 2)
                                                              | (0x1 << 1)) & ~(0x1 << 0));
    			OS_REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX3, OS_REG_READ(ah, AR_PHY_65NM_CH1_RXTX3)
    			                                              | (0x1 << 19) | (0x1 << 3));
                OS_REG_WRITE(ah, AR_PHY_65NM_CH1_TXRF1, OS_REG_READ(ah, AR_PHY_65NM_CH1_TXRF1)
    			                                              | (0x1 << 23));
    			
                OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX1, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX1)
        		                                              | (0x1 << 31) | (0x1 << 27)
                                                              | (0x3 << 23) | (0x1 << 19)
                                                              | (0x1 << 15) | (0x3 << 9)) 
                                                              & ~(0x1 << 12));
                OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX2, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX2)
                                                              | (0x1 << 12) | (0x1 << 10) 
                                                              | (0x1 << 9)  | (0x1 << 8)  
                                                              | (0x1 << 7)  | (0x1 << 3)  
                                                              | (0x1 << 2)  | (0x1 << 1))  
                                                              & ~(0x1 << 11)& ~(0x1 << 0));
    			OS_REG_WRITE(ah, AR_PHY_65NM_CH2_RXTX3, (OS_REG_READ(ah, AR_PHY_65NM_CH2_RXTX3)
    			                                              | (0x1 << 29) | (0x1 << 25) 
                                                              | (0x1 << 23) | (0x1 << 19) 
                                                              | (0x1 << 10) | (0x1 << 9)  
                                                              | (0x1 << 8)  | (0x1 << 3))
                                                              & ~(0x1 << 28)& ~(0x1 << 24)
                                                              & ~(0x1 << 22)& ~(0x1 << 7));
    			OS_REG_WRITE(ah, AR_PHY_65NM_CH2_TXRF1, (OS_REG_READ(ah, AR_PHY_65NM_CH2_TXRF1)
    			                                              | (0x1 << 23))& ~(0x1 << 21));
        		OS_REG_WRITE(ah, AR_PHY_65NM_CH2_TXRF2, OS_REG_READ(ah, AR_PHY_65NM_CH2_TXRF2)
                                                              | (0x3 << 3)  | (0x3 << 0));
    			OS_REG_WRITE(ah, AR_PHY_65NM_CH2_TXRF3, (OS_REG_READ(ah, AR_PHY_65NM_CH2_TXRF3)
                                                              | (0x3 << 29) | (0x3 << 26)
                                                              | (0x2 << 23) | (0x2 << 20)
                                                              | (0x2 << 17))& ~(0x1 << 14));
    			OS_REG_WRITE(ah, AR_PHY_65NM_CH2_BB1, OS_REG_READ(ah, AR_PHY_65NM_CH2_BB1)
    			                                              | (0x1 << 12) | (0x1 << 10)
                                                              | (0x1 << 9)  | (0x1 << 8)
                                                              | (0x1 << 6)  | (0x1 << 5)
                                                              | (0x1 << 4)  | (0x1 << 3)
                                                              | (0x1 << 2));
    			OS_REG_WRITE(ah, AR_PHY_65NM_CH2_BB2, OS_REG_READ(ah, AR_PHY_65NM_CH2_BB2)
                                                              | (0x1 << 31));
    		}
		}
    	
        OS_REG_WRITE(ah, AR_PHY_SWITCH_COM_2, 0x22222);
        OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, 0x222);
    }
}
Example #21
0
/*
 * Attach for an AR3212 part.
 */
struct ath_hal *
ar5312Attach(u_int16_t devid, HAL_SOFTC sc,
	HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status)
{
	struct ath_hal_5212 *ahp = AH_NULL;
	struct ath_hal *ah;
	u_int i;
	u_int32_t sum, val, eepEndLoc;
	u_int16_t eeval, data16;
	HAL_STATUS ecode;
	HAL_BOOL rfStatus;

	HALDEBUG(AH_NULL, "%s: sc %p st %u sh %p\n",
		 __func__, sc, st, (void*) sh);

	/* Setup the flash table so the EEPROM emulation works */
	if (ar5312SetupFlash() == AH_FALSE) {
		HALDEBUG(AH_NULL, "%s: Cannot setup flash\n"
			 , __func__);
		ecode = HAL_ENOTSUPP;
		goto bad;
	}
	  
	/* NB: memory is returned zero'd */
	ahp = ar5212NewState(devid, sc, st, sh, status);
	if (ahp == AH_NULL)
		return AH_NULL;
	ah = &ahp->ah_priv.h;

	/* override 5212 methods for our needs */
	ah->ah_reset			= ar5312Reset;
	ah->ah_phyDisable		= ar5312PhyDisable;
	ah->ah_setLedState		= ar5312SetLedState;
	ah->ah_gpioCfgInput		= ar5312GpioCfgInput;
	ah->ah_gpioCfgOutput		= ar5312GpioCfgOutput;
	ah->ah_gpioGet			= ar5312GpioGet;
	ah->ah_gpioSet			= ar5312GpioSet;
	ah->ah_gpioSetIntr		= ar5312GpioSetIntr;
	ah->ah_detectCardPresent	= ar5312DetectCardPresent;
	ah->ah_setPowerMode		= ar5312SetPowerMode;
	ah->ah_getPowerMode		= ar5312GetPowerMode;
	ah->ah_isInterruptPending	= ar5312IsInterruptPending;

	ahp->ah_priv.ah_eepromRead	= ar5312EepromRead;
#ifdef AH_SUPPORT_WRITE_EEPROM
	ahp->ah_priv.ah_eepromWrite	= ar5312EepromWrite;
#endif
	ahp->ah_priv.ah_gpioCfgOutput	= ar5312GpioCfgOutput;
	ahp->ah_priv.ah_gpioCfgInput	= ar5312GpioCfgInput;
	ahp->ah_priv.ah_gpioGet		= ar5312GpioGet;
	ahp->ah_priv.ah_gpioSet		= ar5312GpioSet;
	ahp->ah_priv.ah_gpioSetIntr	= ar5312GpioSetIntr;

	if (!ar5312ChipReset(ah, AH_NULL)) {	/* reset chip */
		HALDEBUG(ah, "%s: chip reset failed\n", __func__);
		ecode = HAL_EIO;
		goto bad;
	}

#if AH_SUPPORT_2316
	if ((devid == AR5212_AR2315_REV6) || (devid == AR5212_AR2315_REV7)) {
		val = ((OS_REG_READ(ah, (AR5315_RSTIMER_BASE -((u_int32_t) sh)) + AR5315_WREV)) >> AR5315_WREV_S)
			& AR5315_WREV_ID;
		AH_PRIVATE(ah)->ah_macVersion = val >> AR5315_WREV_ID_S;
		AH_PRIVATE(ah)->ah_macRev = val & AR5315_WREV_REVISION;
	} 
Example #22
0
static HAL_BOOL
ar2133SetChannel(struct ath_hal *ah,  HAL_CHANNEL_INTERNAL *chan)
{
    u_int32_t channelSel  = 0;
    u_int32_t bModeSynth  = 0;
    u_int32_t aModeRefSel = 0;
    u_int32_t reg32       = 0;
    u_int16_t freq;
    CHAN_CENTERS centers;

    OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel);

    ar5416GetChannelCenters(ah, chan, &centers);
    freq = centers.synth_center;

    if (freq < 4800) {
        u_int32_t txctl;

        if (((freq - 2192) % 5) == 0) {
            channelSel = ((freq - 672) * 2 - 3040)/10;
            bModeSynth = 0;
        } else if (((freq - 2224) % 5) == 0) {
            channelSel = ((freq - 704) * 2 - 3040) / 10;
            bModeSynth = 1;
        } else {
            HDPRINTF(ah, HAL_DBG_CHANNEL, "%s: invalid channel %u MHz\n",
                __func__, freq);
            return AH_FALSE;
        }

        channelSel = (channelSel << 2) & 0xff;
        channelSel = ath_hal_reverseBits(channelSel, 8);

        txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);
        if (freq == 2484) {
            /* Enable channel spreading for channel 14 */
            OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
                txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
        } else {
            OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
                txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
        }

    } else if ((freq % 20) == 0 && freq >= 5120) {
        channelSel = ath_hal_reverseBits(
            ((freq - 4800) / 20 << 2), 8);
        if (AR_SREV_HOWL(ah) || AR_SREV_SOWL_10_OR_LATER(ah))
            aModeRefSel = ath_hal_reverseBits(3, 2);
        else
            aModeRefSel = ath_hal_reverseBits(1, 2);
    } else if ((freq % 10) == 0) {
        channelSel = ath_hal_reverseBits(
            ((freq - 4800) / 10 << 1), 8);
        if (AR_SREV_HOWL(ah) || AR_SREV_SOWL_10_OR_LATER(ah))
            aModeRefSel = ath_hal_reverseBits(2, 2);
        else
            aModeRefSel = ath_hal_reverseBits(1, 2);
    } else if ((freq % 5) == 0) {
        channelSel = ath_hal_reverseBits(
            (freq - 4800) / 5, 8);
        aModeRefSel = ath_hal_reverseBits(1, 2);
    } else {
        HDPRINTF(ah, HAL_DBG_CHANNEL, "%s: invalid channel %u MHz\n",
            __func__, freq);
        return AH_FALSE;
    }

#ifdef ATH_FORCE_BIAS
    /* FOWL orientation sensitivity workaround */
    ar5416ForceBiasCurrent(ah, freq);

    /*
     * Antenna Control with forceBias.
     * This function must be called after ar5416ForceBiasCurrent() and
     * ar5416SetRfRegs() and ar5416EepromSetBoardValues().
     */
    ar5416DecreaseChainPower(ah, (HAL_CHANNEL*)chan);
#endif

    reg32 = (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
            (1 << 5) | 0x1;

    OS_REG_WRITE(ah, AR_PHY(0x37), reg32);

    AH_PRIVATE(ah)->ah_curchan = chan;

#ifdef AH_SUPPORT_DFS
    if (chan->privFlags & CHANNEL_DFS) {
        struct ar5416RadarState *rs;
        u_int8_t index;

        rs = ar5416GetRadarChanState(ah, &index);
        if (rs != AH_NULL) {
            AH5416(ah)->ah_curchanRadIndex = (int16_t) index;
        } else {
            HDPRINTF(ah, HAL_DBG_DFS, "%s: Couldn't find radar state information\n",
                 __func__);
            return AH_FALSE;
        }
    } else
#endif
        AH5416(ah)->ah_curchanRadIndex = -1;

    return AH_TRUE;
}
Example #23
0
/*
 * Attach for an AR9285 part.
 */
static struct ath_hal *
ar9285Attach(uint16_t devid, HAL_SOFTC sc,
	HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *status)
{
	struct ath_hal_9285 *ahp9285;
	struct ath_hal_5212 *ahp;
	struct ath_hal *ah;
	uint32_t val;
	HAL_STATUS ecode;
	HAL_BOOL rfStatus;

	HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",
	    __func__, sc, (void*) st, (void*) sh);

	/* NB: memory is returned zero'd */
	ahp9285 = ath_hal_malloc(sizeof (struct ath_hal_9285));
	if (ahp9285 == AH_NULL) {
		HALDEBUG(AH_NULL, HAL_DEBUG_ANY,
		    "%s: cannot allocate memory for state block\n", __func__);
		*status = HAL_ENOMEM;
		return AH_NULL;
	}
	ahp = AH5212(ahp9285);
	ah = &ahp->ah_priv.h;

	ar5416InitState(AH5416(ah), devid, sc, st, sh, status);

	/* XXX override with 9285 specific state */
	/* override 5416 methods for our needs */
	ah->ah_setAntennaSwitch		= ar9285SetAntennaSwitch;
	ah->ah_configPCIE		= ar9285ConfigPCIE;
	ah->ah_setTxPower		= ar9285SetTransmitPower;
	ah->ah_setBoardValues		= ar9285SetBoardValues;

	AH5416(ah)->ah_cal.iqCalData.calData = &ar9280_iq_cal;
	AH5416(ah)->ah_cal.adcGainCalData.calData = &ar9280_adc_gain_cal;
	AH5416(ah)->ah_cal.adcDcCalData.calData = &ar9280_adc_dc_cal;
	AH5416(ah)->ah_cal.adcDcCalInitData.calData = &ar9280_adc_init_dc_cal;
	AH5416(ah)->ah_cal.suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;

	AH5416(ah)->ah_spurMitigate	= ar9280SpurMitigate;
	AH5416(ah)->ah_writeIni		= ar9285WriteIni;
	AH5416(ah)->ah_rx_chainmask	= AR9285_DEFAULT_RXCHAINMASK;
	AH5416(ah)->ah_tx_chainmask	= AR9285_DEFAULT_TXCHAINMASK;
	
	ahp->ah_maxTxTrigLev		= MAX_TX_FIFO_THRESHOLD >> 1;

	if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) {
		/* reset chip */
		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n",
		    __func__);
		ecode = HAL_EIO;
		goto bad;
	}

	if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n",
		    __func__);
		ecode = HAL_EIO;
		goto bad;
	}
	/* Read Revisions from Chips before taking out of reset */
	val = OS_REG_READ(ah, AR_SREV);
	HALDEBUG(ah, HAL_DEBUG_ATTACH,
	    "%s: ID 0x%x VERSION 0x%x TYPE 0x%x REVISION 0x%x\n",
	    __func__, MS(val, AR_XSREV_ID), MS(val, AR_XSREV_VERSION),
	    MS(val, AR_XSREV_TYPE), MS(val, AR_XSREV_REVISION));
	/* NB: include chip type to differentiate from pre-Sowl versions */
	AH_PRIVATE(ah)->ah_macVersion =
	    (val & AR_XSREV_VERSION) >> AR_XSREV_TYPE_S;
	AH_PRIVATE(ah)->ah_macRev = MS(val, AR_XSREV_REVISION);
	AH_PRIVATE(ah)->ah_ispcie = (val & AR_XSREV_TYPE_HOST_MODE) == 0;

	/* setup common ini data; rf backends handle remainder */
	if (AR_SREV_KITE_12_OR_LATER(ah)) {
		HAL_INI_INIT(&ahp->ah_ini_modes, ar9285Modes_v2, 6);
		HAL_INI_INIT(&ahp->ah_ini_common, ar9285Common_v2, 2);
		HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes,
		    ar9285PciePhy_clkreq_always_on_L1_v2, 2);
	} else {
		HAL_INI_INIT(&ahp->ah_ini_modes, ar9285Modes, 6);
		HAL_INI_INIT(&ahp->ah_ini_common, ar9285Common, 2);
		HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes,
		    ar9285PciePhy_clkreq_always_on_L1, 2);
	}
	ar5416AttachPCIE(ah);

	ecode = ath_hal_v4kEepromAttach(ah);
	if (ecode != HAL_OK)
		goto bad;

	if (!ar5416ChipReset(ah, AH_NULL)) {	/* reset chip */
		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n",
		    __func__);
		ecode = HAL_EIO;
		goto bad;
	}

	AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID);

	if (!ar5212ChipTest(ah)) {
		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n",
		    __func__);
		ecode = HAL_ESELFTEST;
		goto bad;
	}

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

	/* Read Radio Chip Rev Extract */
	AH_PRIVATE(ah)->ah_analog5GhzRev = ar5416GetRadioRev(ah);
	switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) {
        case AR_RAD2133_SREV_MAJOR:	/* Sowl: 2G/3x3 */
	case AR_RAD5133_SREV_MAJOR:	/* Sowl: 2+5G/3x3 */
		break;
	default:
		if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) {
			AH_PRIVATE(ah)->ah_analog5GhzRev =
				AR_RAD5133_SREV_MAJOR;
			break;
		}
#ifdef AH_DEBUG
		HALDEBUG(ah, HAL_DEBUG_ANY,
		    "%s: 5G Radio Chip Rev 0x%02X is not supported by "
		    "this driver\n", __func__,
		    AH_PRIVATE(ah)->ah_analog5GhzRev);
		ecode = HAL_ENOTSUPP;
		goto bad;
#endif
	}
	rfStatus = ar9285RfAttach(ah, &ecode);
	if (!rfStatus) {
		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n",
		    __func__, ecode);
		goto bad;
	}

	HAL_INI_INIT(&ahp9285->ah_ini_rxgain, ar9280Modes_original_rxgain_v2,
	    6);
	/* setup txgain table */
	switch (ath_hal_eepromGet(ah, AR_EEP_TXGAIN_TYPE, AH_NULL)) {
	case AR5416_EEP_TXGAIN_HIGH_POWER:
		HAL_INI_INIT(&ahp9285->ah_ini_txgain,
		    ar9285Modes_high_power_tx_gain_v2, 6);
		break;
	case AR5416_EEP_TXGAIN_ORIG:
		HAL_INI_INIT(&ahp9285->ah_ini_txgain,
		    ar9285Modes_original_tx_gain_v2, 6);
		break;
	default:
		HALASSERT(AH_FALSE);
		goto bad;		/* XXX ? try to continue */
	}

	/*
	 * Got everything we need now to setup the capabilities.
	 */
	if (!ar9285FillCapabilityInfo(ah)) {
		ecode = HAL_EEREAD;
		goto bad;
	}

	ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr);
	if (ecode != HAL_OK) {
		HALDEBUG(ah, HAL_DEBUG_ANY,
		    "%s: error getting mac address from EEPROM\n", __func__);
		goto bad;
        }
	/* XXX How about the serial number ? */
	/* Read Reg Domain */
	AH_PRIVATE(ah)->ah_currentRD =
	    ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL);

	/*
	 * ah_miscMode is populated by ar5416FillCapabilityInfo()
	 * starting from griffin. Set here to make sure that
	 * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is
	 * placed into hardware.
	 */
	if (ahp->ah_miscMode != 0)
		OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);

	ar9285AniSetup(ah);			/* Anti Noise Immunity */
	ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist);

	HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);

	return ah;
bad:
	if (ah != AH_NULL)
		ah->ah_detach(ah);
	if (status)
		*status = ecode;
	return AH_NULL;
}
Example #24
0
/*
 * Take the MHz channel value and set the Channel value
 *
 * ASSUMES: Writes enabled to analog bus
 */
static HAL_BOOL
ar2316SetChannel(struct ath_hal *ah,  struct ieee80211_channel *chan)
{
	uint16_t freq = ath_hal_gethwchannel(ah, chan);
	uint32_t channelSel  = 0;
	uint32_t bModeSynth  = 0;
	uint32_t aModeRefSel = 0;
	uint32_t reg32       = 0;

	OS_MARK(ah, AH_MARK_SETCHANNEL, freq);

	if (freq < 4800) {
		uint32_t txctl;

		if (((freq - 2192) % 5) == 0) {
			channelSel = ((freq - 672) * 2 - 3040)/10;
			bModeSynth = 0;
		} else if (((freq - 2224) % 5) == 0) {
			channelSel = ((freq - 704) * 2 - 3040) / 10;
			bModeSynth = 1;
		} else {
			HALDEBUG(ah, HAL_DEBUG_ANY,
			    "%s: invalid channel %u MHz\n",
			    __func__, freq);
			return AH_FALSE;
		}

		channelSel = (channelSel << 2) & 0xff;
		channelSel = ath_hal_reverseBits(channelSel, 8);

		txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);
		if (freq == 2484) {
			/* Enable channel spreading for channel 14 */
			OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
				txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
		} else {
			OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
				txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
		}
	} else if ((freq % 20) == 0 && freq >= 5120) {
		channelSel = ath_hal_reverseBits(
			((freq - 4800) / 20 << 2), 8);
		aModeRefSel = ath_hal_reverseBits(3, 2);
	} else if ((freq % 10) == 0) {
		channelSel = ath_hal_reverseBits(
			((freq - 4800) / 10 << 1), 8);
		aModeRefSel = ath_hal_reverseBits(2, 2);
	} else if ((freq % 5) == 0) {
		channelSel = ath_hal_reverseBits(
			(freq - 4800) / 5, 8);
		aModeRefSel = ath_hal_reverseBits(1, 2);
	} else {
		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u MHz\n",
		    __func__, freq);
		return AH_FALSE;
	}

	reg32 = (channelSel << 4) | (aModeRefSel << 2) | (bModeSynth << 1) |
			(1 << 12) | 0x1;
	OS_REG_WRITE(ah, AR_PHY(0x27), reg32 & 0xff);

	reg32 >>= 8;
	OS_REG_WRITE(ah, AR_PHY(0x36), reg32 & 0x7f);

	AH_PRIVATE(ah)->ah_curchan = chan;
	return AH_TRUE;
}
Example #25
0
static HAL_BOOL
ar9280SetChannel(struct ath_hal *ah,  HAL_CHANNEL_INTERNAL *chan)
{
    struct ath_hal_5416 *ahp = AH5416(ah);
    u_int16_t bMode, fracMode, aModeRefSel = 0;
    u_int32_t freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
    CHAN_CENTERS centers;
    u_int32_t refDivA = 24;

    OS_MARK(ah, AH_MARK_SETCHANNEL, chan->channel);

    ar5416GetChannelCenters(ah, chan, &centers);
    freq = centers.synth_center;
    
    reg32 = OS_REG_READ(ah, AR_PHY_SYNTH_CONTROL);
    reg32 &= 0xc0000000;

    if (freq < 4800) {     /* 2 GHz, fractional mode */
        u_int32_t txctl;
        int regWrites = 0;

        bMode = 1;
        fracMode = 1;
        aModeRefSel = 0;       
        channelSel = (freq * 0x10000)/15;
 
        if (AR_SREV_KIWI_11_OR_LATER(ah)) {
            if (freq == 2484) {
                REG_WRITE_ARRAY(&ahp->ah_iniCckfirJapan2484, 1, regWrites);
            } else {
                REG_WRITE_ARRAY(&ahp->ah_iniCckfirNormal, 1, regWrites);
            }     
        } else {
            txctl = OS_REG_READ(ah, AR_PHY_CCK_TX_CTRL);
            if (freq == 2484) {
                /* Enable channel spreading for channel 14 */
                OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
                    txctl | AR_PHY_CCK_TX_CTRL_JAPAN);

            } else {
                OS_REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
                    txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN);
            }     
        }
    } else {
        bMode = 0;
        fracMode = 0;

        HALASSERT(aModeRefSel == 0);
        switch (ar5416EepromGet(ahp, EEP_FRAC_N_5G)) {
        case 0:
            if ((freq % 20) == 0) {
                aModeRefSel = 3;
            } else if ((freq % 10) == 0) {
                aModeRefSel = 2;
            }
            if (aModeRefSel) break;
        case 1:
        default:
            aModeRefSel = 0;
            /* Enable 2G (fractional) mode for channels which are 5MHz spaced */
            fracMode = 1;
            refDivA = 1;
            channelSel = (freq * 0x8000)/15;

            /* RefDivA setting */
            analogShiftRegRMW(ah, AR_AN_SYNTH9, AR_AN_SYNTH9_REFDIVA,
                              AR_AN_SYNTH9_REFDIVA_S, refDivA);
        }

        if (!fracMode) {
            ndiv = (freq * (refDivA >> aModeRefSel))/60;
            channelSel =  ndiv & 0x1ff;         
            channelFrac = (ndiv & 0xfffffe00) * 2;
            channelSel = (channelSel << 17) | channelFrac;
        }
    }
Example #26
0
static u_int
ar9300GetSlotTime(struct ath_hal *ah)
{
	u_int clks = OS_REG_READ(ah, AR_D_GBL_IFS_SLOT) & 0xffff;
	return (ath_hal_mac_usec(ah, clks));	/* convert from system clocks */
}
Example #27
0
/*
 * Set all the beacon related bits on the h/w for stations
 * i.e. initializes the corresponding h/w timers;
 * also tells the h/w whether to anticipate PCF beacons
 *
 * dtim_count and cfp_count from the current beacon - their current
 * values aren't necessarily maintained in the device struct
 */
void
ar5210SetStaBeaconTimers(struct ath_hal *ah, const HAL_BEACON_STATE *bs)
{
	struct ath_hal_5210 *ahp = AH5210(ah);

	HALDEBUG(ah, HAL_DEBUG_BEACON, "%s: setting beacon timers\n", __func__);

	HALASSERT(bs->bs_intval != 0);
	/* if the AP will do PCF */
	if (bs->bs_cfpmaxduration != 0) {
		/* tell the h/w that the associated AP is PCF capable */
		OS_REG_WRITE(ah, AR_STA_ID1,
			(OS_REG_READ(ah, AR_STA_ID1) &~ AR_STA_ID1_DEFAULT_ANTENNA)
			| AR_STA_ID1_PCF);

		/* set CFP_PERIOD(1.024ms) register */
		OS_REG_WRITE(ah, AR_CFP_PERIOD, bs->bs_cfpperiod);

		/* set CFP_DUR(1.024ms) register to max cfp duration */
		OS_REG_WRITE(ah, AR_CFP_DUR, bs->bs_cfpmaxduration);

		/* set TIMER2(128us) to anticipated time of next CFP */
		OS_REG_WRITE(ah, AR_TIMER2, bs->bs_cfpnext << 3);
	} else {
		/* tell the h/w that the associated AP is not PCF capable */
		OS_REG_WRITE(ah, AR_STA_ID1,
			OS_REG_READ(ah, AR_STA_ID1) &~ (AR_STA_ID1_DEFAULT_ANTENNA | AR_STA_ID1_PCF));
	}

	/*
	 * Set TIMER0(1.024ms) to the anticipated time of the next beacon.
	 */
	OS_REG_WRITE(ah, AR_TIMER0, bs->bs_nexttbtt);

	/*
	 * Start the beacon timers by setting the BEACON register
	 * to the beacon interval; also write the tim offset which
	 * we should know by now.  The code, in ar5211WriteAssocid,
	 * also sets the tim offset once the AID is known which can
	 * be left as such for now.
	 */
	OS_REG_WRITE(ah, AR_BEACON, 
		(OS_REG_READ(ah, AR_BEACON) &~ (AR_BEACON_PERIOD|AR_BEACON_TIM))
		| SM(bs->bs_intval, AR_BEACON_PERIOD)
		| SM(bs->bs_timoffset ? bs->bs_timoffset + 4 : 0, AR_BEACON_TIM)
	);

	/*
	 * Configure the BMISS interrupt.  Note that we
	 * assume the caller blocks interrupts while enabling
	 * the threshold.
	 */

	/*
	 * Interrupt works only on Crete.
	 */
	if (AH_PRIVATE(ah)->ah_macRev < AR_SREV_CRETE)
		return;
	/*
	 * Counter is only 3-bits.
	 * Count of 0 with BMISS interrupt enabled will hang the system
	 * with too many interrupts
	 */
	if (AH_PRIVATE(ah)->ah_macRev >= AR_SREV_CRETE &&
	    (bs->bs_bmissthreshold&7) == 0) {
#ifdef AH_DEBUG
		ath_hal_printf(ah, "%s: invalid beacon miss threshold %u\n",
			__func__, bs->bs_bmissthreshold);
#endif
		return;
	}
#define	BMISS_MAX	(AR_RSSI_THR_BM_THR >> AR_RSSI_THR_BM_THR_S)
	/*
	 * Configure the BMISS interrupt.  Note that we
	 * assume the caller blocks interrupts while enabling
	 * the threshold.
	 *
	 * NB: the beacon miss count field is only 3 bits which
	 *     is much smaller than what's found on later parts;
	 *     clamp overflow values as a safeguard.
	 */
	ahp->ah_rssiThr = (ahp->ah_rssiThr &~ AR_RSSI_THR_BM_THR)
			| SM(bs->bs_bmissthreshold > BMISS_MAX ?
				BMISS_MAX : bs->bs_bmissthreshold,
			     AR_RSSI_THR_BM_THR);
	OS_REG_WRITE(ah, AR_RSSI_THR, ahp->ah_rssiThr);
#undef BMISS_MAX
}
Example #28
0
static uint64_t
ar9300_get_next_tbtt(struct ath_hal *ah)
{
	return (OS_REG_READ(ah, AR_NEXT_TBTT_TIMER));
}
Example #29
0
static void
ar9285AniSetup(struct ath_hal *ah)
{
	/*
	 * These are the parameters from the AR5416 ANI code;
	 * they likely need quite a bit of adjustment for the
	 * AR9285.
	 */
        static const struct ar5212AniParams aniparams = {
                .maxNoiseImmunityLevel  = 4,    /* levels 0..4 */
                .totalSizeDesired       = { -55, -55, -55, -55, -62 },
                .coarseHigh             = { -14, -14, -14, -14, -12 },
                .coarseLow              = { -64, -64, -64, -64, -70 },
                .firpwr                 = { -78, -78, -78, -78, -80 },
                .maxSpurImmunityLevel   = 7,
                .cycPwrThr1             = { 2, 4, 6, 8, 10, 12, 14, 16 },
                .maxFirstepLevel        = 2,    /* levels 0..2 */
                .firstep                = { 0, 4, 8 },
                .ofdmTrigHigh           = 500,
                .ofdmTrigLow            = 200,
                .cckTrigHigh            = 200,
                .cckTrigLow             = 100,
                .rssiThrHigh            = 40,
                .rssiThrLow             = 7,
                .period                 = 100,
        };
	/* NB: disable ANI noise immmunity for reliable RIFS rx */
	AH5416(ah)->ah_ani_function &= ~(1 << HAL_ANI_NOISE_IMMUNITY_LEVEL);

        ar5416AniAttach(ah, &aniparams, &aniparams, AH_TRUE);
}

static const char * ar9285_lna_conf[] = {
	"LNA1-LNA2",
	"LNA2",
	"LNA1",
	"LNA1+LNA2",
};

static void
ar9285_eeprom_print_diversity_settings(struct ath_hal *ah)
{
	const HAL_EEPROM_v4k *ee = AH_PRIVATE(ah)->ah_eeprom;
	const MODAL_EEP4K_HEADER *pModal = &ee->ee_base.modalHeader;

	ath_hal_printf(ah, "[ath] AR9285 Main LNA config: %s\n",
	    ar9285_lna_conf[(pModal->antdiv_ctl2 >> 2) & 0x3]);
	ath_hal_printf(ah, "[ath] AR9285 Alt LNA config: %s\n",
	    ar9285_lna_conf[pModal->antdiv_ctl2 & 0x3]);
	ath_hal_printf(ah, "[ath] LNA diversity %s, Diversity %s\n",
	    ((pModal->antdiv_ctl1 & 0x1) ? "enabled" : "disabled"),
	    ((pModal->antdiv_ctl1 & 0x8) ? "enabled" : "disabled"));
}

/*
 * Attach for an AR9285 part.
 */
static struct ath_hal *
ar9285Attach(uint16_t devid, HAL_SOFTC sc,
	HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
	HAL_STATUS *status)
{
	struct ath_hal_9285 *ahp9285;
	struct ath_hal_5212 *ahp;
	struct ath_hal *ah;
	uint32_t val;
	HAL_STATUS ecode;
	HAL_BOOL rfStatus;

	HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",
	    __func__, sc, (void*) st, (void*) sh);

	/* NB: memory is returned zero'd */
	ahp9285 = ath_hal_malloc(sizeof (struct ath_hal_9285));
	if (ahp9285 == AH_NULL) {
		HALDEBUG(AH_NULL, HAL_DEBUG_ANY,
		    "%s: cannot allocate memory for state block\n", __func__);
		*status = HAL_ENOMEM;
		return AH_NULL;
	}
	ahp = AH5212(ahp9285);
	ah = &ahp->ah_priv.h;

	ar5416InitState(AH5416(ah), devid, sc, st, sh, status);

	/*
	 * Use the "local" EEPROM data given to us by the higher layers.
	 * This is a private copy out of system flash. The Linux ath9k
	 * commit for the initial AR9130 support mentions MMIO flash
	 * access is "unreliable." -adrian
	 */
	if (eepromdata != AH_NULL) {
		AH_PRIVATE(ah)->ah_eepromRead = ath_hal_EepromDataRead;
		AH_PRIVATE(ah)->ah_eepromWrite = NULL;
		ah->ah_eepromdata = eepromdata;
	}

	/* override with 9285 specific state */
	AH5416(ah)->ah_initPLL = ar9280InitPLL;
	AH5416(ah)->ah_btCoexSetDiversity = ar9285BTCoexAntennaDiversity;

	ah->ah_setAntennaSwitch		= ar9285SetAntennaSwitch;
	ah->ah_configPCIE		= ar9285ConfigPCIE;
	ah->ah_disablePCIE		= ar9285DisablePCIE;
	ah->ah_setTxPower		= ar9285SetTransmitPower;
	ah->ah_setBoardValues		= ar9285SetBoardValues;
	ah->ah_btCoexSetParameter	= ar9285BTCoexSetParameter;
	ah->ah_divLnaConfGet		= ar9285_antdiv_comb_conf_get;
	ah->ah_divLnaConfSet		= ar9285_antdiv_comb_conf_set;

	AH5416(ah)->ah_cal.iqCalData.calData = &ar9280_iq_cal;
	AH5416(ah)->ah_cal.adcGainCalData.calData = &ar9280_adc_gain_cal;
	AH5416(ah)->ah_cal.adcDcCalData.calData = &ar9280_adc_dc_cal;
	AH5416(ah)->ah_cal.adcDcCalInitData.calData = &ar9280_adc_init_dc_cal;
	AH5416(ah)->ah_cal.suppCals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;

	AH5416(ah)->ah_spurMitigate	= ar9280SpurMitigate;
	AH5416(ah)->ah_writeIni		= ar9285WriteIni;
	AH5416(ah)->ah_rx_chainmask	= AR9285_DEFAULT_RXCHAINMASK;
	AH5416(ah)->ah_tx_chainmask	= AR9285_DEFAULT_TXCHAINMASK;
	
	ahp->ah_maxTxTrigLev		= MAX_TX_FIFO_THRESHOLD >> 1;

	if (!ar5416SetResetReg(ah, HAL_RESET_POWER_ON)) {
		/* reset chip */
		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't reset chip\n",
		    __func__);
		ecode = HAL_EIO;
		goto bad;
	}

	if (!ar5416SetPowerMode(ah, HAL_PM_AWAKE, AH_TRUE)) {
		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: couldn't wakeup chip\n",
		    __func__);
		ecode = HAL_EIO;
		goto bad;
	}
	/* Read Revisions from Chips before taking out of reset */
	val = OS_REG_READ(ah, AR_SREV);
	HALDEBUG(ah, HAL_DEBUG_ATTACH,
	    "%s: ID 0x%x VERSION 0x%x TYPE 0x%x REVISION 0x%x\n",
	    __func__, MS(val, AR_XSREV_ID), MS(val, AR_XSREV_VERSION),
	    MS(val, AR_XSREV_TYPE), MS(val, AR_XSREV_REVISION));
	/* NB: include chip type to differentiate from pre-Sowl versions */
	AH_PRIVATE(ah)->ah_macVersion =
	    (val & AR_XSREV_VERSION) >> AR_XSREV_TYPE_S;
	AH_PRIVATE(ah)->ah_macRev = MS(val, AR_XSREV_REVISION);
	AH_PRIVATE(ah)->ah_ispcie = (val & AR_XSREV_TYPE_HOST_MODE) == 0;

	/* setup common ini data; rf backends handle remainder */
	if (AR_SREV_KITE_12_OR_LATER(ah)) {
		HAL_INI_INIT(&ahp->ah_ini_modes, ar9285Modes_v2, 6);
		HAL_INI_INIT(&ahp->ah_ini_common, ar9285Common_v2, 2);
		HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes,
		    ar9285PciePhy_clkreq_always_on_L1_v2, 2);
	} else {
		HAL_INI_INIT(&ahp->ah_ini_modes, ar9285Modes, 6);
		HAL_INI_INIT(&ahp->ah_ini_common, ar9285Common, 2);
		HAL_INI_INIT(&AH5416(ah)->ah_ini_pcieserdes,
		    ar9285PciePhy_clkreq_always_on_L1, 2);
	}
	ar5416AttachPCIE(ah);

	/* Attach methods that require MAC version/revision info */
	if (AR_SREV_KITE_12_OR_LATER(ah))
		AH5416(ah)->ah_cal_initcal      = ar9285InitCalHardware;
	if (AR_SREV_KITE_11_OR_LATER(ah))
		AH5416(ah)->ah_cal_pacal        = ar9002_hw_pa_cal;

	ecode = ath_hal_v4kEepromAttach(ah);
	if (ecode != HAL_OK)
		goto bad;

	if (!ar5416ChipReset(ah, AH_NULL)) {	/* reset chip */
		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n",
		    __func__);
		ecode = HAL_EIO;
		goto bad;
	}

	AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID);

	if (!ar5212ChipTest(ah)) {
		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n",
		    __func__);
		ecode = HAL_ESELFTEST;
		goto bad;
	}

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

	/* Read Radio Chip Rev Extract */
	AH_PRIVATE(ah)->ah_analog5GhzRev = ar5416GetRadioRev(ah);
	switch (AH_PRIVATE(ah)->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) {
        case AR_RAD2133_SREV_MAJOR:	/* Sowl: 2G/3x3 */
	case AR_RAD5133_SREV_MAJOR:	/* Sowl: 2+5G/3x3 */
		break;
	default:
		if (AH_PRIVATE(ah)->ah_analog5GhzRev == 0) {
			AH_PRIVATE(ah)->ah_analog5GhzRev =
				AR_RAD5133_SREV_MAJOR;
			break;
		}
#ifdef AH_DEBUG
		HALDEBUG(ah, HAL_DEBUG_ANY,
		    "%s: 5G Radio Chip Rev 0x%02X is not supported by "
		    "this driver\n", __func__,
		    AH_PRIVATE(ah)->ah_analog5GhzRev);
		ecode = HAL_ENOTSUPP;
		goto bad;
#endif
	}
	rfStatus = ar9285RfAttach(ah, &ecode);
	if (!rfStatus) {
		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: RF setup failed, status %u\n",
		    __func__, ecode);
		goto bad;
	}

	HAL_INI_INIT(&ahp9285->ah_ini_rxgain, ar9280Modes_original_rxgain_v2,
	    6);

	if (AR_SREV_9285E_20(ah))
		ath_hal_printf(ah, "[ath] AR9285E_20 detected; using XE TX gain tables\n");

	/* setup txgain table */
	switch (ath_hal_eepromGet(ah, AR_EEP_TXGAIN_TYPE, AH_NULL)) {
	case AR5416_EEP_TXGAIN_HIGH_POWER:
		if (AR_SREV_9285E_20(ah))
			HAL_INI_INIT(&ahp9285->ah_ini_txgain,
			    ar9285Modes_XE2_0_high_power, 6);
		else
			HAL_INI_INIT(&ahp9285->ah_ini_txgain,
			    ar9285Modes_high_power_tx_gain_v2, 6);
		break;
	case AR5416_EEP_TXGAIN_ORIG:
		if (AR_SREV_9285E_20(ah))
			HAL_INI_INIT(&ahp9285->ah_ini_txgain,
			    ar9285Modes_XE2_0_normal_power, 6);
		else
			HAL_INI_INIT(&ahp9285->ah_ini_txgain,
			    ar9285Modes_original_tx_gain_v2, 6);
		break;
	default:
		HALASSERT(AH_FALSE);
		goto bad;		/* XXX ? try to continue */
	}

	/*
	 * Got everything we need now to setup the capabilities.
	 */
	if (!ar9285FillCapabilityInfo(ah)) {
		ecode = HAL_EEREAD;
		goto bad;
	}

	/*
	 * Print out the EEPROM antenna configuration mapping.
	 * Some devices have a hard-coded LNA configuration profile;
	 * others enable diversity.
	 */
	ar9285_eeprom_print_diversity_settings(ah);

	/* Print out whether the EEPROM settings enable AR9285 diversity */
	if (ar9285_check_div_comb(ah)) {
		ath_hal_printf(ah, "[ath] Enabling diversity for Kite\n");
	}

	/* Disable 11n for the AR2427 */
	if (devid == AR2427_DEVID_PCIE)
		AH_PRIVATE(ah)->ah_caps.halHTSupport = AH_FALSE;

	ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr);
	if (ecode != HAL_OK) {
		HALDEBUG(ah, HAL_DEBUG_ANY,
		    "%s: error getting mac address from EEPROM\n", __func__);
		goto bad;
        }
	/* XXX How about the serial number ? */
	/* Read Reg Domain */
	AH_PRIVATE(ah)->ah_currentRD =
	    ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, AH_NULL);
	/*
         * For Kite and later chipsets, the following bits are not
	 * programmed in EEPROM and so are set as enabled always.
	 */
	AH_PRIVATE(ah)->ah_currentRDext = AR9285_RDEXT_DEFAULT;

	/*
	 * ah_miscMode is populated by ar5416FillCapabilityInfo()
	 * starting from griffin. Set here to make sure that
	 * AR_MISC_MODE_MIC_NEW_LOC_ENABLE is set before a GTK is
	 * placed into hardware.
	 */
	if (ahp->ah_miscMode != 0)
		OS_REG_WRITE(ah, AR_MISC_MODE, OS_REG_READ(ah, AR_MISC_MODE) | ahp->ah_miscMode);

	ar9285AniSetup(ah);			/* Anti Noise Immunity */

	/* Setup noise floor min/max/nominal values */
	AH5416(ah)->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9285_2GHZ;
	AH5416(ah)->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9285_2GHZ;
	AH5416(ah)->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9285_2GHZ;
	/* XXX no 5ghz values? */

	ar5416InitNfHistBuff(AH5416(ah)->ah_cal.nfCalHist);

	HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);

	return ah;
bad:
	if (ah != AH_NULL)
		ah->ah_detach(ah);
	if (status)
		*status = ecode;
	return AH_NULL;
}

static void
ar9285ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore, HAL_BOOL power_off)
{
	uint32_t val;

	/*
	 * This workaround needs some integration work with the HAL
	 * config parameters and the if_ath_pci.c glue.
	 * Specifically, read the value of the PCI register 0x70c
	 * (4 byte PCI config space register) and store it in ath_hal_war70c.
	 * Then if it's non-zero, the below WAR would override register
	 * 0x570c upon suspend/resume.
	 */
#if 0
	if (AR_SREV_9285E_20(ah)) {
		val = AH_PRIVATE(ah)->ah_config.ath_hal_war70c;
		if (val) {
			val &= 0xffff00ff;
			val |= 0x6f00;
			OS_REG_WRITE(ah, 0x570c, val);
		}
	}
#endif

	if (AH_PRIVATE(ah)->ah_ispcie && !restore) {
		ath_hal_ini_write(ah, &AH5416(ah)->ah_ini_pcieserdes, 1, 0);
		OS_DELAY(1000);
	}

	/*
	 * Set PCIe workaround bits
	 *
	 * NOTE:
	 *
	 * In Merlin and Kite, bit 14 in WA register (disable L1) should only
	 * be set when device enters D3 and be cleared when device comes back
	 * to D0.
	 */
	if (power_off) {                /* Power-off */
		OS_REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);

		val = OS_REG_READ(ah, AR_WA);

		/*
		 * Disable bit 6 and 7 before entering D3 to prevent
		 * system hang.
		 */
		val &= ~(AR_WA_BIT6 | AR_WA_BIT7);

		/*
		 * See above: set AR_WA_D3_L1_DISABLE when entering D3 state.
		 *
		 * XXX The reference HAL does it this way - it only sets
		 * AR_WA_D3_L1_DISABLE if it's set in AR9280_WA_DEFAULT,
		 * which it (currently) isn't.  So the following statement
		 * is currently a NOP.
		 */
		if (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)
			val |= AR_WA_D3_L1_DISABLE;

		if (AR_SREV_9285E_20(ah))
			val |= AR_WA_BIT23;

		OS_REG_WRITE(ah, AR_WA, val);
	} else {			/* Power-on */
		val = AR9285_WA_DEFAULT;
		/*
		 * See note above: make sure L1_DISABLE is not set.
		 */
		val &= (~AR_WA_D3_L1_DISABLE);

		/* Software workaroud for ASPM system hang. */
		val |= (AR_WA_BIT6 | AR_WA_BIT7);

		if (AR_SREV_9285E_20(ah))
			val |= AR_WA_BIT23;

		OS_REG_WRITE(ah, AR_WA, val);

		/* set bit 19 to allow forcing of pcie core into L1 state */
		OS_REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
	}
}
Example #30
0
static u_int
ar9300_freebsd_get_cts_timeout(struct ath_hal *ah)
{
    u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_CTS);
    return ath_hal_mac_usec(ah, clks);      /* convert from system clocks */
}