Пример #1
0
/*
 * Process an RX descriptor, and return the status to the caller.
 * Copy some hardware specific items into the software portion
 * of the descriptor.
 *
 * NB: the caller is responsible for validating the memory contents
 *     of the descriptor (e.g. flushing any cached copy).
 */
HAL_STATUS
ar5212ProcRxDesc(struct ath_hal *ah, struct ath_desc *ds,
	u_int32_t pa, struct ath_desc *nds)
{
	struct ar5212_desc *ads = AR5212DESC(ds);
	struct ar5212_desc *ands = AR5212DESC(nds);

	if ((ads->ds_rxstatus1 & AR_Done) == 0)
		return HAL_EINPROGRESS;
	/*
	 * Given the use of a self-linked tail be very sure that the hw is
	 * done with this descriptor; the hw may have done this descriptor
	 * once and picked it up again...make sure the hw has moved on.
	 */
	if ((ands->ds_rxstatus1&AR_Done) == 0 && OS_REG_READ(ah, AR_RXDP) == pa)
		return HAL_EINPROGRESS;

	ds->ds_rxstat.rs_datalen = ads->ds_rxstatus0 & AR_DataLen;
	ds->ds_rxstat.rs_tstamp = MS(ads->ds_rxstatus1, AR_RcvTimestamp);
	ds->ds_rxstat.rs_status = 0;
	/* XXX what about KeyCacheMiss? */
	ds->ds_rxstat.rs_rssi = MS(ads->ds_rxstatus0, AR_RcvSigStrength);
	if (ads->ds_rxstatus1 & AR_KeyIdxValid)
		ds->ds_rxstat.rs_keyix = MS(ads->ds_rxstatus1, AR_KeyIdx);
	else
		ds->ds_rxstat.rs_keyix = HAL_RXKEYIX_INVALID;
	/* NB: caller expected to do rate table mapping */
	ds->ds_rxstat.rs_rate = MS(ads->ds_rxstatus0, AR_RcvRate);
	ds->ds_rxstat.rs_antenna  = MS(ads->ds_rxstatus0, AR_RcvAntenna);
	ds->ds_rxstat.rs_more = (ads->ds_rxstatus0 & AR_More) ? 1 : 0;

	if ((ads->ds_rxstatus1 & AR_FrmRcvOK) == 0) {
		/*
		 * These four bits should not be set together.  The
		 * 5212 spec states a Michael error can only occur if
		 * DecryptCRCErr not set (and TKIP is used).  Experience
		 * indicates however that you can also get Michael errors
		 * when a CRC error is detected, but these are specious.
		 * Consequently we filter them out here so we don't
		 * confuse and/or complicate drivers.
		 */
		if (ads->ds_rxstatus1 & AR_CRCErr)
			ds->ds_rxstat.rs_status |= HAL_RXERR_CRC;
		else if (ads->ds_rxstatus1 & AR_PHYErr) {
			u_int phyerr;

			ds->ds_rxstat.rs_status |= HAL_RXERR_PHY;
			phyerr = MS(ads->ds_rxstatus1, AR_PHYErrCode);
			ds->ds_rxstat.rs_phyerr = phyerr;
			if ((!AH5212(ah)->ah_hasHwPhyCounters) &&
			    (phyerr != HAL_PHYERR_RADAR))
				ar5212AniPhyErrReport(ah, &ds->ds_rxstat);
		} else if (ads->ds_rxstatus1 & AR_DecryptCRCErr)
			ds->ds_rxstat.rs_status |= HAL_RXERR_DECRYPT;
		else if (ads->ds_rxstatus1 & AR_MichaelErr)
			ds->ds_rxstat.rs_status |= HAL_RXERR_MIC;
	}
	return HAL_OK;
}
Пример #2
0
/*
 * Process an RX descriptor, and return the status to the caller.
 * Copy some hardware specific items into the software portion
 * of the descriptor.
 *
 * NB: the caller is responsible for validating the memory contents
 *     of the descriptor (e.g. flushing any cached copy).
 */
HAL_STATUS
ar5212ProcRxDesc(struct ath_hal *ah, struct ath_desc *ds,
	uint32_t pa, struct ath_desc *nds, uint64_t tsf,
	struct ath_rx_status *rs)
{
	struct ar5212_desc *ads = AR5212DESC(ds);
	struct ar5212_desc *ands = AR5212DESC(nds);

	if ((ads->ds_rxstatus1 & AR_Done) == 0)
		return HAL_EINPROGRESS;
	/*
	 * Given the use of a self-linked tail be very sure that the hw is
	 * done with this descriptor; the hw may have done this descriptor
	 * once and picked it up again...make sure the hw has moved on.
	 */
	if ((ands->ds_rxstatus1&AR_Done) == 0 && OS_REG_READ(ah, AR_RXDP) == pa)
		return HAL_EINPROGRESS;

	rs->rs_datalen = ads->ds_rxstatus0 & AR_DataLen;
	rs->rs_tstamp = MS(ads->ds_rxstatus1, AR_RcvTimestamp);
	rs->rs_status = 0;
	/* XXX what about KeyCacheMiss? */
	rs->rs_rssi = MS(ads->ds_rxstatus0, AR_RcvSigStrength);
	/* discard invalid h/w rssi data */
	if (rs->rs_rssi == -128)
		rs->rs_rssi = 0;
	if (ads->ds_rxstatus1 & AR_KeyIdxValid)
		rs->rs_keyix = MS(ads->ds_rxstatus1, AR_KeyIdx);
	else
		rs->rs_keyix = HAL_RXKEYIX_INVALID;
	/* NB: caller expected to do rate table mapping */
	rs->rs_rate = MS(ads->ds_rxstatus0, AR_RcvRate);
	rs->rs_antenna  = MS(ads->ds_rxstatus0, AR_RcvAntenna);
	rs->rs_more = (ads->ds_rxstatus0 & AR_More) ? 1 : 0;

	/*
	 * The AR5413 (at least) sometimes sets both AR_CRCErr and
	 * AR_PHYErr when reporting radar pulses.  In this instance
	 * set HAL_RXERR_PHY as well as HAL_RXERR_CRC and
	 * let the driver layer figure out what to do.
	 *
	 * See PR kern/169362.
	 */
	if ((ads->ds_rxstatus1 & AR_FrmRcvOK) == 0) {
		/*
		 * These four bits should not be set together.  The
		 * 5212 spec states a Michael error can only occur if
		 * DecryptCRCErr not set (and TKIP is used).  Experience
		 * indicates however that you can also get Michael errors
		 * when a CRC error is detected, but these are specious.
		 * Consequently we filter them out here so we don't
		 * confuse and/or complicate drivers.
		 */
		if (ads->ds_rxstatus1 & AR_PHYErr) {
			u_int phyerr;

			rs->rs_status |= HAL_RXERR_PHY;
			phyerr = MS(ads->ds_rxstatus1, AR_PHYErrCode);
			rs->rs_phyerr = phyerr;
			if (!AH5212(ah)->ah_hasHwPhyCounters &&
			    phyerr != HAL_PHYERR_RADAR)
				ar5212AniPhyErrReport(ah, rs);
		}

		if (ads->ds_rxstatus1 & AR_CRCErr)
			rs->rs_status |= HAL_RXERR_CRC;
		else if (ads->ds_rxstatus1 & AR_DecryptCRCErr)
			rs->rs_status |= HAL_RXERR_DECRYPT;
		else if (ads->ds_rxstatus1 & AR_MichaelErr)
			rs->rs_status |= HAL_RXERR_MIC;
	}
	return HAL_OK;
}