Ejemplo n.º 1
0
/*
 * Once configured for I/O - set output lines
 */
HAL_BOOL
ar5416GpioSet(struct ath_hal *ah, uint32_t gpio, uint32_t val)
{
	uint32_t reg;

	HALASSERT(gpio < AH_PRIVATE(ah)->ah_caps.halNumGpioPins);
	HALDEBUG(ah, HAL_DEBUG_GPIO,
	   "%s: gpio=%d, val=%d\n", __func__, gpio, val);

	reg = OS_REG_READ(ah, AR_GPIO_IN_OUT);
	if (val & 1)
		reg |= AR_GPIO_BIT(gpio);
	else 
		reg &= ~AR_GPIO_BIT(gpio);
	OS_REG_WRITE(ah, AR_GPIO_IN_OUT, reg);	
	return AH_TRUE;
}
Ejemplo n.º 2
0
/*
 * Initialize RX descriptor, by clearing the status and setting
 * the size (and any other flags).
 */
HAL_BOOL
ar5212SetupRxDesc(struct ath_hal *ah, struct ath_desc *ds,
	uint32_t size, u_int flags)
{
	struct ar5212_desc *ads = AR5212DESC(ds);

	HALASSERT((size &~ AR_BufLen) == 0);

	ads->ds_ctl0 = 0;
	ads->ds_ctl1 = size & AR_BufLen;

	if (flags & HAL_RXDESC_INTREQ)
		ads->ds_ctl1 |= AR_RxInterReq;
	ads->ds_rxstatus0 = ads->ds_rxstatus1 = 0;

	return AH_TRUE;
}
Ejemplo n.º 3
0
static void
ar5416AniCckErrTrigger(struct ath_hal *ah)
{
	struct ath_hal_5212 *ahp = AH5212(ah);
	const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
	struct ar5212AniState *aniState;
	const struct ar5212AniParams *params;

	HALASSERT(chan != AH_NULL);

	if (!ANI_ENA(ah))
		return;

	/* first, raise noise immunity level, up to max */
	aniState = ahp->ah_curani;
	params = aniState->params;
	if ((AH5416(ah)->ah_ani_function & (1 << HAL_ANI_NOISE_IMMUNITY_LEVEL) &&
	    aniState->noiseImmunityLevel+1 < params->maxNoiseImmunityLevel)) {
		ar5416AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
				 aniState->noiseImmunityLevel + 1);
		return;
	}

	if (ANI_ENA_RSSI(ah)) {
		int32_t rssi = BEACON_RSSI(ahp);
		if (rssi >  params->rssiThrLow) {
			/*
			 * Beacon signal in mid and high range,
			 * raise firstep level.
			 */
			if (aniState->firstepLevel+1 < params->maxFirstepLevel)
				ar5416AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
						 aniState->firstepLevel + 1);
		} else {
			/*
			 * Beacon rssi is low, zero firstep level to maximize
			 * CCK sensitivity in 11b/g mode.
			 */
			if (IEEE80211_IS_CHAN_CCK(chan)) {
				if (aniState->firstepLevel > 0)
					ar5416AniControl(ah,
					    HAL_ANI_FIRSTEP_LEVEL, 0);
			}
		}
	}
}
Ejemplo n.º 4
0
/*
 * Initialize RX descriptor, by clearing the status and setting
 * the size (and any other flags).
 */
HAL_BOOL
ar5416SetupRxDesc(struct ath_hal *ah, struct ath_desc *ds,
    uint32_t size, u_int flags)
{
	struct ar5416_desc *ads = AR5416DESC(ds);

	HALASSERT((size &~ AR_BufLen) == 0);

	ads->ds_ctl1 = size & AR_BufLen;
	if (flags & HAL_RXDESC_INTREQ)
		ads->ds_ctl1 |= AR_RxIntrReq;

	/* this should be enough */
	ads->ds_rxstatus8 &= ~AR_RxDone;

	return AH_TRUE;
}
Ejemplo n.º 5
0
/*
 * Return a reference to the requested RF Bank.
 */
static u_int32_t *
ar2316GetRfBank(struct ath_hal *ah, int bank)
{
	struct ath_hal_5212 *ahp = AH5212(ah);
	AR5212_RF_BANKS_2316 *pRfBank2316 = ahp->ah_analogBanks;

	HALASSERT(ahp->ah_analogBanks != AH_NULL);
	switch (bank) {
	case 1: return pRfBank2316->Bank1Data;
	case 2: return pRfBank2316->Bank2Data;
	case 3: return pRfBank2316->Bank3Data;
	case 6: return pRfBank2316->Bank6Data;
	case 7: return pRfBank2316->Bank7Data;
	}
	HALDEBUG(ah, "%s: unknown RF Bank %d requested\n", __func__, bank);
	return AH_NULL;
}
Ejemplo n.º 6
0
/*
 * Return a reference to the requested RF Bank.
 */
static u_int32_t *
ar2425GetRfBank(struct ath_hal *ah, int bank)
{
	struct ath_hal_5212 *ahp = AH5212(ah);
	AR5212_RF_BANKS_2425 *pRfBank2425 = ahp->ah_analogBanks;

	HALASSERT(ahp->ah_analogBanks != AH_NULL);
	switch (bank) {
	case 1: return pRfBank2425->Bank1Data;
	case 2: return pRfBank2425->Bank2Data;
	case 3: return pRfBank2425->Bank3Data;
	case 6: return pRfBank2425->Bank6Data;
	case 7: return pRfBank2425->Bank7Data;
	}
	HDPRINTF(ah, HAL_DBG_RF_PARAM, "%s: unknown RF Bank %d requested\n", __func__, bank);
	return AH_NULL;
}
Ejemplo n.º 7
0
/*
 * Return a reference to the requested RF Bank.
 */
static uint32_t *
ar2316GetRfBank(struct ath_hal *ah, int bank)
{
	struct ar2316State *priv = AR2316(ah);

	HALASSERT(priv != AH_NULL);
	switch (bank) {
	case 1: return priv->Bank1Data;
	case 2: return priv->Bank2Data;
	case 3: return priv->Bank3Data;
	case 6: return priv->Bank6Data;
	case 7: return priv->Bank7Data;
	}
	HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unknown RF Bank %d requested\n",
	    __func__, bank);
	return AH_NULL;
}
Ejemplo n.º 8
0
static void
ar5212AniCckErrTrigger(struct ath_hal *ah)
{
	struct ath_hal_5212 *ahp = AH5212(ah);
	HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
	struct ar5212AniState *aniState;
	WIRELESS_MODE mode;
	int32_t rssi;

	HALASSERT(chan != AH_NULL);

	if (!DO_ANI(ah))
		return;

	/* first, raise noise immunity level, up to max */
	aniState = ahp->ah_curani;
	if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
		ar5212AniControl(ah, HAL_ANI_NOISE_IMMUNITY_LEVEL,
				 aniState->noiseImmunityLevel + 1);
		return;
	}
	/* Do not play with OFDM and CCK weak detection in AP mode */
        if( AH_PRIVATE(ah)->ah_opmode == HAL_M_HOSTAP) {
		return;
	}
	rssi = BEACON_RSSI(aniState);
	if (rssi >  aniState->rssiThrLow) {
		/*
		 * Beacon signal in mid and high range, raise firsteplevel.
		 */
		if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
			ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL,
					 aniState->firstepLevel + 1);
	} else {
		/*
		 * Beacon rssi is low, zero firstepLevel to maximize
		 * CCK sensitivity.
		 */
		mode = ath_hal_chan2wmode(ah, (HAL_CHANNEL *) chan);
		if (mode == WIRELESS_MODE_11g || mode == WIRELESS_MODE_11b) {
			if (aniState->firstepLevel > 0)
				ar5212AniControl(ah, HAL_ANI_FIRSTEP_LEVEL, 0);
		}
	}
}
Ejemplo n.º 9
0
/*
 * Configure GPIO Output lines
 */
HAL_BOOL
ar5416GpioCfgOutput(struct ath_hal *ah, uint32_t gpio)
{
	uint32_t gpio_shift, reg;

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

	/* NB: type maps directly to hardware */
	//cfgOutputMux(ah, gpio, type);
	gpio_shift = gpio << 1;			/* 2 bits per output mode */

	reg = OS_REG_READ(ah, AR_GPIO_OE_OUT);
	reg &= ~(AR_GPIO_OE_OUT_DRV << gpio_shift);
	reg |= AR_GPIO_OE_OUT_DRV_ALL << gpio_shift;
	OS_REG_WRITE(ah, AR_GPIO_OE_OUT, reg);

	return AH_TRUE;
}
Ejemplo n.º 10
0
/*
 * Configure GPIO Input lines
 */
HAL_BOOL
ar5416GpioCfgInput(struct ath_hal *ah, u_int32_t gpio)
{
    u_int32_t    gpio_shift;

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

    /* TODO: configure input mux for AR5416 */
    /* If configured as input, set output to tristate */
    gpio_shift = 2*gpio;

    OS_REG_RMW(ah, 
               AR_GPIO_OE_OUT, 
               (AR_GPIO_OE_OUT_DRV_NO << gpio_shift), 
               (AR_GPIO_OE_OUT_DRV << gpio_shift));

    return AH_TRUE;
}
Ejemplo n.º 11
0
/*
 * Configure GPIO Input lines
 */
HAL_BOOL
ar7010GpioCfgInput(struct ath_hal *ah, u_int32_t gpio)
{
    u_int32_t    gpio_shift;

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

    /* If configured as input, set output to tristate */
    gpio_shift = gpio;

    /* Per bit output enable. 1: enable the input driver */
    OS_REG_RMW(ah, 
               AR7010_GPIO_OE, 
               (AR7010_GPIO_OE_AS_INPUT << gpio_shift), 
               (AR7010_GPIO_OE_MASK << gpio_shift));

    return AH_TRUE;
}
Ejemplo n.º 12
0
/*
 * Configure GPIO Input lines
 */
HAL_BOOL
ar5416GpioCfgInput(struct ath_hal *ah, uint32_t gpio)
{
	uint32_t gpio_shift, reg;

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

	/* TODO: configure input mux for AR5416 */
	/* If configured as input, set output to tristate */
	gpio_shift = gpio << 1;

	reg = OS_REG_READ(ah, AR_GPIO_OE_OUT);
	reg &= ~(AR_GPIO_OE_OUT_DRV << gpio_shift);
	reg |= AR_GPIO_OE_OUT_DRV_ALL << gpio_shift;
	OS_REG_WRITE(ah, AR_GPIO_OE_OUT, reg);

	return AH_TRUE;
}
Ejemplo n.º 13
0
HAL_BOOL
ar5416FillTxDesc(struct ath_hal *ah, void *ds, dma_addr_t *bufAddr,
        u_int32_t *seg_len, u_int desc_id, u_int qcu, HAL_KEY_TYPE keyType, HAL_BOOL first_seg,
        HAL_BOOL last_seg, const void *ds0)
{
        struct ar5416_desc *ads = AR5416DESC(ds);

        HALASSERT((seg_len[0] &~ AR_BufLen) == 0);
		OS_MEMZERO(&(ads->u.tx.tx_status), sizeof(ads->u.tx.tx_status));
        /* Set the buffer addresses */
        ads->ds_data = bufAddr[0];

        if (first_seg) {
                /*
                 * First descriptor, don't clobber xmit control data
                 * setup by ar5416SetupTxDesc.
                 */
                ads->ds_ctl1 |= seg_len[0] | (last_seg ? 0 : AR_TxMore);
        } else if (last_seg) {           /* !first_seg && last_seg */
                /*
                 * Last descriptor in a multi-descriptor frame,
                 * copy the multi-rate transmit parameters from
                 * the first frame for processing on completion.
                 */
                ads->ds_ctl0 = 0;
                ads->ds_ctl1 = seg_len[0];
#ifdef AH_NEED_DESC_SWAP
                ads->ds_ctl2 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl2);
                ads->ds_ctl3 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl3);
#else
                ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
                ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
#endif
        } else {                        /* !first_seg && !last_seg */
                /*
                 * Intermediate descriptor in a multi-descriptor frame.
                 */
                ads->ds_ctl0 = 0;
                ads->ds_ctl1 = seg_len[0] | AR_TxMore;
                ads->ds_ctl2 = 0;
                ads->ds_ctl3 = 0;
        }
        return AH_TRUE;
}
Ejemplo n.º 14
0
/*
 * Calculate air time of a transmit packet
 */
u_int32_t
ar5416CalcTxAirtime(struct ath_hal *ah, void *ds, struct ath_tx_status *ts,
        HAL_BOOL comp_wastedt, u_int8_t nbad, u_int8_t nframes)
{
    struct ar5416_desc *ads = AR5416DESC(ds);
    int finalindex_tries;
	int status9;
    /*
     * Number of attempts made on the final index
     * Note: If no BA was recv, then the data_fail_cnt is the number of tries
     * made on the final index.  If BA was recv, then add 1 to account for the
     * successful attempt.
     */
    finalindex_tries = ts->ts_longretry + (ts->ts_flags & HAL_TX_BA)? 1 : 0;

	/*
	 * Use a local copy of the ads in the cacheable memory to
	 * improve the d-cache efficiency.
	 */
	status9 = ads->ds_txstatus9;
	status9 = MS(status9, AR_FinalTxIdx);
    /*
     * Calculate time of transmit on air for packet including retries
     * at different rates.
     */
	if (status9 == 0) {
        return  MS(ads->ds_ctl4, AR_PacketDur0) * finalindex_tries;
	} else if (status9 == 1) {
        return (MS(ads->ds_ctl4, AR_PacketDur1) * finalindex_tries) +
               (MS(ads->ds_ctl2, AR_XmitDataTries0) * MS(ads->ds_ctl4, AR_PacketDur0));
	} else if (status9 == 2) {
        return (MS(ads->ds_ctl5, AR_PacketDur2) * finalindex_tries) +
               (MS(ads->ds_ctl2, AR_XmitDataTries1) * MS(ads->ds_ctl4, AR_PacketDur1)) +
               (MS(ads->ds_ctl2, AR_XmitDataTries0) * MS(ads->ds_ctl4, AR_PacketDur0));
	} else if (status9 == 3) {
        return (MS(ads->ds_ctl5, AR_PacketDur3) * finalindex_tries) +
               (MS(ads->ds_ctl2, AR_XmitDataTries2) * MS(ads->ds_ctl5, AR_PacketDur2)) +
               (MS(ads->ds_ctl2, AR_XmitDataTries1) * MS(ads->ds_ctl4, AR_PacketDur1)) +
               (MS(ads->ds_ctl2, AR_XmitDataTries0) * MS(ads->ds_ctl4, AR_PacketDur0));
	} else {
        HALASSERT(0);
        return 0;
    }
}
Ejemplo n.º 15
0
/*
 * Configure GPIO Output lines - LED Off
 */
HAL_BOOL
ar5416GpioCfgOutputLEDoff(struct ath_hal *ah, u_int32_t gpio, HAL_GPIO_OUTPUT_MUX_TYPE halSignalType)
{
#define N(a)    (sizeof(a)/sizeof(a[0]))
    u_int32_t    ah_signal_type;
    u_int32_t    gpio_shift;

    static const u_int32_t    MuxSignalConversionTable[] = {
        /* HAL_GPIO_OUTPUT_MUX_AS_OUTPUT             */ AR_GPIO_OUTPUT_MUX_AS_OUTPUT,
        /* HAL_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED */ AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED,
        /* HAL_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED     */ AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED,
        /* HAL_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED    */ AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED,
        /* HAL_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED      */ AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED,
        /* HAL_GPIO_OUTPUT_MUX_AS_WLAN_ACTIVE        */ AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL,
        /* HAL_GPIO_OUTPUT_MUX_AS_TX_FRAME           */ AR_GPIO_OUTPUT_MUX_AS_TX_FRAME,
    };

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

    // Convert HAL signal type definitions to hardware-specific values.
    if ((halSignalType >= 0) && (halSignalType < N(MuxSignalConversionTable)))
    {
        ah_signal_type = MuxSignalConversionTable[halSignalType];
    }
    else
    {
        return AH_FALSE;
    }

    // Configure the MUX
    ar5416GpioCfgOutputMux(ah, gpio, ah_signal_type);

    // 2 bits per output mode
    gpio_shift = 2*gpio;

    OS_REG_RMW(ah, 
               AR_GPIO_OE_OUT, 
               (AR_GPIO_OE_OUT_DRV_NO << gpio_shift), 
               (AR_GPIO_OE_OUT_DRV << gpio_shift));

    return AH_TRUE;
#undef N
}
Ejemplo n.º 16
0
/*
 * Return indices surrounding the value in sorted integer lists.
 *
 * NB: the input list is assumed to be sorted in ascending order
 */
static void
GetLowerUpperIndex(int16_t v, const uint16_t *lp, uint16_t listSize,
                          uint32_t *vlo, uint32_t *vhi)
{
	int16_t target = v;
	const int16_t *ep = lp+listSize;
	const int16_t *tp;

	/*
	 * Check first and last elements for out-of-bounds conditions.
	 */
	if (target < lp[0]) {
		*vlo = *vhi = 0;
		return;
	}
	if (target >= ep[-1]) {
		*vlo = *vhi = listSize - 1;
		return;
	}

	/* look for value being near or between 2 values in list */
	for (tp = lp; tp < ep; tp++) {
		/*
		 * If value is close to the current value of the list
		 * then target is not between values, it is one of the values
		 */
		if (*tp == target) {
			*vlo = *vhi = tp - (const int16_t *) lp;
			return;
		}
		/*
		 * Look for value being between current value and next value
		 * if so return these 2 values
		 */
		if (target < tp[1]) {
			*vlo = tp - (const int16_t *) lp;
			*vhi = *vlo + 1;
			return;
		}
	}
	HALASSERT(AH_FALSE);		/* should not reach here */
	*vlo = *vhi = 0;
}
Ejemplo n.º 17
0
/*
 * Configure GPIO Input lines
 */
HAL_BOOL
ar9300GpioCfgInput(struct ath_hal *ah, u_int32_t gpio)
{
#ifndef AR9340_EMULATION
    u_int32_t    gpio_shift;

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

    /* TODO: configure input mux for AR9300 */
    /* If configured as input, set output to tristate */
    gpio_shift = 2*gpio;

    OS_REG_RMW(ah,
               AR_HOSTIF_REG(ah, AR_GPIO_OE_OUT),
               (AR_GPIO_OE_OUT_DRV_NO << gpio_shift),
               (AR_GPIO_OE_OUT_DRV << gpio_shift));

#endif
    return AH_TRUE;
}
Ejemplo n.º 18
0
HAL_BOOL
ar5416SetupRxDesc(struct ath_hal *ah, struct ath_desc *ds,
    u_int32_t size, u_int flags)
{
    struct ar5416_desc *ads = AR5416DESC(ds);
    HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;

    HALASSERT((size &~ AR_BufLen) == 0);

    ads->ds_ctl1 = size & AR_BufLen;
    if (flags & HAL_RXDESC_INTREQ)
        ads->ds_ctl1 |= AR_RxIntrReq;

    /* this should be enough */
    ads->ds_rxstatus8 &= ~AR_RxDone;
    if (! pCap->halAutoSleepSupport) {
        /* If AutoSleep not supported, clear all fields. */
        OS_MEMZERO(&(ads->u), sizeof(ads->u));
    }
    return AH_TRUE;
}
Ejemplo n.º 19
0
/*
 * Get the TXDP for the "main" data queue.  Needs to be extended
 * for multiple Q functionality
 */
uint32_t
ar5210GetTxDP(struct ath_hal *ah, u_int q)
{
	struct ath_hal_5210 *ahp = AH5210(ah);
	HAL_TX_QUEUE_INFO *qi;

	HALASSERT(q < HAL_NUM_TX_QUEUES);

	qi = &ahp->ah_txq[q];
	switch (qi->tqi_type) {
	case HAL_TX_QUEUE_DATA:
		return OS_REG_READ(ah, AR_TXDP0);
	case HAL_TX_QUEUE_INACTIVE:
		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: inactive queue %u\n",
		    __func__, q);
		/* fall thru... */
	default:
		break;
	}
	return 0xffffffff;
}
Ejemplo n.º 20
0
/*
 * Initializes all of the hardware registers used to
 * send beacons.  Note that for station operation the
 * driver calls ar9300_set_sta_beacon_timers instead.
 */
static void
ar9300_beacon_set_beacon_timers(struct ath_hal *ah,
    const HAL_BEACON_TIMERS *bt)
{
	uint32_t bperiod;

#if 0
    HALASSERT(opmode == HAL_M_IBSS || opmode == HAL_M_HOSTAP);
    if (opmode == HAL_M_IBSS) {
        OS_REG_SET_BIT(ah, AR_TXCFG, AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
    }
#endif

	/* XXX TODO: should migrate the HAL code to always use ONE_EIGHTH_TU */
	OS_REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bt->bt_nexttbtt));
	OS_REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, ONE_EIGHTH_TU_TO_USEC(bt->bt_nextdba));
	OS_REG_WRITE(ah, AR_NEXT_SWBA, ONE_EIGHTH_TU_TO_USEC(bt->bt_nextswba));
	OS_REG_WRITE(ah, AR_NEXT_NDP_TIMER, TU_TO_USEC(bt->bt_nextatim));

	bperiod = TU_TO_USEC(bt->bt_intval & HAL_BEACON_PERIOD);
	/* XXX TODO! */
//        ahp->ah_beaconInterval = bt->bt_intval & HAL_BEACON_PERIOD;
	OS_REG_WRITE(ah, AR_BEACON_PERIOD, bperiod);
	OS_REG_WRITE(ah, AR_DMA_BEACON_PERIOD, bperiod);
	OS_REG_WRITE(ah, AR_SWBA_PERIOD, bperiod);
	OS_REG_WRITE(ah, AR_NDP_PERIOD, bperiod);

	/*
	 * Reset TSF if required.
	 */
	if (bt->bt_intval & HAL_BEACON_RESET_TSF)
		ar9300_reset_tsf(ah);

	/* enable timers */
	/* NB: flags == 0 handled specially for backwards compatibility */
	OS_REG_SET_BIT(ah, AR_TIMER_MODE,
	    bt->bt_flags != 0 ? bt->bt_flags :
	    AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN);
}
Ejemplo n.º 21
0
/*
 * Update ani stats in preparation for listen time processing.
 */
static void
updateMIBStats(struct ath_hal *ah, struct ar5212AniState *aniState)
{
	struct ath_hal_5212 *ahp = AH5212(ah);
	const struct ar5212AniParams *params = aniState->params;
	uint32_t phyCnt1, phyCnt2;
	int32_t ofdmPhyErrCnt, cckPhyErrCnt;

	HALASSERT(ahp->ah_hasHwPhyCounters);

	/* Clear the mib counters and save them in the stats */
	ar5212UpdateMibCounters(ah, &ahp->ah_mibStats);

	/* NB: these are not reset-on-read */
	phyCnt1 = OS_REG_READ(ah, AR_PHYCNT1);
	phyCnt2 = OS_REG_READ(ah, AR_PHYCNT2);

	/* NB: these are spec'd to never roll-over */
	ofdmPhyErrCnt = phyCnt1 - params->ofdmPhyErrBase;
	if (ofdmPhyErrCnt < 0) {
		HALDEBUG(ah, HAL_DEBUG_ANI, "OFDM phyErrCnt %d phyCnt1 0x%x\n",
		    ofdmPhyErrCnt, phyCnt1);
		ofdmPhyErrCnt = AR_PHY_COUNTMAX;
	}
	ahp->ah_stats.ast_ani_ofdmerrs +=
	     ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
	aniState->ofdmPhyErrCount = ofdmPhyErrCnt;

	cckPhyErrCnt = phyCnt2 - params->cckPhyErrBase;
	if (cckPhyErrCnt < 0) {
		HALDEBUG(ah, HAL_DEBUG_ANI, "CCK phyErrCnt %d phyCnt2 0x%x\n",
		    cckPhyErrCnt, phyCnt2);
		cckPhyErrCnt = AR_PHY_COUNTMAX;
	}
	ahp->ah_stats.ast_ani_cckerrs +=
		cckPhyErrCnt - aniState->cckPhyErrCount;
	aniState->cckPhyErrCount = cckPhyErrCnt;
}
Ejemplo n.º 22
0
/*
 * Set the TxDP for the "main" data queue.
 */
HAL_BOOL
ar5210SetTxDP(struct ath_hal *ah, u_int q, uint32_t txdp)
{
	struct ath_hal_5210 *ahp = AH5210(ah);
	HAL_TX_QUEUE_INFO *qi;

	HALASSERT(q < HAL_NUM_TX_QUEUES);

	HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: queue %u 0x%x\n",
	    __func__, q, txdp);
	qi = &ahp->ah_txq[q];
	switch (qi->tqi_type) {
	case HAL_TX_QUEUE_DATA:
#ifdef AH_DEBUG
		/*
		 * Make sure that TXE is deasserted before setting the
		 * TXDP.  If TXE is still asserted, setting TXDP will
		 * have no effect.
		 */
		if (OS_REG_READ(ah, AR_CR) & AR_CR_TXE0)
			ath_hal_printf(ah, "%s: TXE asserted; AR_CR=0x%x\n",
				__func__, OS_REG_READ(ah, AR_CR));
#endif
		OS_REG_WRITE(ah, AR_TXDP0, txdp);
		break;
	case HAL_TX_QUEUE_BEACON:
	case HAL_TX_QUEUE_CAB:
		OS_REG_WRITE(ah, AR_TXDP1, txdp);
		break;
	case HAL_TX_QUEUE_INACTIVE:
		HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: inactive queue %u\n",
		    __func__, q);
		/* fall thru... */
	default:
		return AH_FALSE;
	}
	return AH_TRUE;
}
Ejemplo n.º 23
0
/*
 * Set the GPIO Interrupt
 */
void
ar5416GpioSetIntr(struct ath_hal *ah, u_int gpio, uint32_t ilevel)
{
    uint32_t val;

    HALASSERT(gpio < AR_NUM_GPIO);
    /* XXX bounds check gpio */
    val = MS(OS_REG_READ(ah, AR_GPIO_INTR_OUT), AR_GPIO_INTR_CTRL);
    if (ilevel)		/* 0 == interrupt on pin high */
        val &= ~AR_GPIO_BIT(gpio);
    else			/* 1 == interrupt on pin low */
        val |= AR_GPIO_BIT(gpio);
    OS_REG_RMW_FIELD(ah, AR_GPIO_INTR_OUT, AR_GPIO_INTR_CTRL, val);

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

    val = MS(OS_REG_READ(ah, AR_INTR_ASYNC_MASK), AR_INTR_GPIO);
    val |= AR_GPIO_BIT(gpio);
    OS_REG_RMW_FIELD(ah, AR_INTR_ASYNC_MASK, AR_INTR_GPIO, val);
}
Ejemplo n.º 24
0
HAL_BOOL
ar5210FillTxDesc(struct ath_hal *ah, struct ath_desc *ds,
	HAL_DMA_ADDR *bufAddrList, uint32_t *segLenList, u_int descId,
	u_int qcuId, HAL_BOOL firstSeg, HAL_BOOL lastSeg,
	const struct ath_desc *ds0)
{
	struct ar5210_desc *ads = AR5210DESC(ds);
	uint32_t segLen = segLenList[0];

	HALASSERT((segLen &~ AR_BufLen) == 0);

	ds->ds_data = bufAddrList[0];

	if (firstSeg) {
		/*
		 * First descriptor, don't clobber xmit control data
		 * setup by ar5210SetupTxDesc.
		 */
		ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_More);
	} else if (lastSeg) {		/* !firstSeg && lastSeg */
		/*
		 * Last descriptor in a multi-descriptor frame,
		 * copy the transmit parameters from the first
		 * frame for processing on completion. 
		 */
		ads->ds_ctl0 = AR5210DESC_CONST(ds0)->ds_ctl0;
		ads->ds_ctl1 = segLen;
	} else {			/* !firstSeg && !lastSeg */
		/*
		 * Intermediate descriptor in a multi-descriptor frame.
		 */
		ads->ds_ctl0 = 0;
		ads->ds_ctl1 = segLen | AR_More;
	}
	ads->ds_status0 = ads->ds_status1 = 0;
	return AH_TRUE;
}
Ejemplo n.º 25
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;
}
Ejemplo n.º 26
0
int16_t
ar9300_get_rate_txpower(struct ath_hal *ah, u_int mode, u_int8_t rate_index,
                     u_int8_t chainmask, u_int8_t xmit_mode)
{
    struct ath_hal_9300 *ahp = AH9300(ah);
    int num_chains = ar9300_get_ntxchains(chainmask);

    switch (xmit_mode) {
    case AR9300_DEF_MODE:
        return ahp->txpower[rate_index][num_chains-1];

    
    case AR9300_STBC_MODE:
        return ahp->txpower_stbc[rate_index][num_chains-1];
       
    default:
        HALDEBUG(ah, HAL_DEBUG_POWER_MGMT, "%s: invalid mode 0x%x\n",
             __func__, xmit_mode);
        HALASSERT(0);
        break;
    }

    return ahp->txpower[rate_index][num_chains-1];
}
Ejemplo n.º 27
0
/*
 * Configure GPIO Output lines
 */
HAL_BOOL
ar7010GpioCfgOutput(struct ath_hal *ah, u_int32_t gpio, HAL_GPIO_OUTPUT_MUX_TYPE halSignalType)
{
    u_int32_t    gpio_shift;

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

    /* Magpie only support GPIO normal output */
    if (halSignalType > HAL_GPIO_OUTPUT_MUX_AS_OUTPUT)
    {
        return AH_FALSE;
    }

    /* 1 bits per output mode */
    gpio_shift = gpio;

    /* Per bit output enable. 0: enable the output driver */
    OS_REG_RMW(ah, 
               AR7010_GPIO_OE, 
               (AR7010_GPIO_OE_AS_OUTPUT<< gpio_shift), 
               (AR7010_GPIO_OE_MASK << gpio_shift));

    return AH_TRUE;
}
Ejemplo n.º 28
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);
	}
}
Ejemplo n.º 29
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
}
Ejemplo n.º 30
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;
        }
    }