Beispiel #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;
}
Beispiel #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,
	u_int32_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;
}
Beispiel #3
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;
}
Beispiel #4
0
void
ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
                     struct ath_desc *ds, struct ath_rc_series rcs[],
                     u_int8_t ac, int nframes, int nbad, int rts_retry_limit)
#endif
{
    struct atheros_node    *atn = an->an_rc_node;
    struct atheros_vap     *avap = atn->avp;
    const RATE_TABLE       *pRateTable = avap->rateTable;
    u_int8_t               txRateCode = ds->ds_txstat.ts_ratecode;
    u_int8_t               totalTries = 0;
#if 0
    int                    short_retry_fail = ds->ds_txstat.ts_shortretry ;
#endif
    if (sc->sc_ah->ah_magic == 0x19641014 ||
        sc->sc_ah->ah_magic == 0x19741014)
    {
#ifdef ATH_SUPPORT_VOWEXT
        ath_rate_tx_complete_11n(sc, an, &ds->ds_txstat, rcs, ac, nframes, nbad, nHeadFail, nTailFail, rts_retry_limit);
#else
        ath_rate_tx_complete_11n(sc, an, &ds->ds_txstat, rcs, ac, nframes, nbad, rts_retry_limit);
#endif
        return;
    }

    if (pRateTable->rateCodeToIndex[txRateCode] == (u_int8_t) -1) {
        /*
         * This can happen, for example, when switching bands
         * and pending tx's are processed before the queue
         * is flushed (should fix mode switch to ensure this
         * does not happen).
         */
        // DPRINTF(sc, "%s: no mapping for rate code 0x%x",
        //         __func__, txRate);
        return;
    }
#ifdef AH_SUPPORT_AR5212
    if (ds->ds_txstat.ts_rateindex != 0) {
        const struct ar5212_desc *ads = AR5212DESC(ds);
        int finalTSIdx = MS(ads->ds_txstatus1, AR_FinalTSIndex);
        int series;
        
        /*
         * Process intermediate rates that failed.
         */
        for (series = 0; series < finalTSIdx; series++) {
            int rate, tries;

            /* NB: we know series <= 2 */
            switch (series) {
            case 0:
                rate = MS(ads->ds_ctl3, AR_XmitRate0);
                tries = MS(ads->ds_ctl2, AR_XmitDataTries0);
                break;
            case 1:
                rate = MS(ads->ds_ctl3, AR_XmitRate1);
                tries = MS(ads->ds_ctl2, AR_XmitDataTries1);
                break;
            default:
                rate = MS(ads->ds_ctl3, AR_XmitRate2);
                tries = MS(ads->ds_ctl2, AR_XmitDataTries2);
                break;
            }

            if (pRateTable->rateCodeToIndex[rate] != (u_int8_t) -1) {
                /*
                 * This can happen, for example, when switching bands
                 * and pending tx's are processed before the queue
                 * is flushed (should fix mode switch to ensure this
                 * does not happen).
                 */
                // DPRINTF(sc, "%s: no mapping for rate code 0x%x",
                //         __func__, txRate);
                rcUpdate(atn
                         , 2 // Huh? Indicates an intermediate rate failure. Should use a macro instead.
                         , pRateTable->rateCodeToIndex[rate]
                         , tries
                         , ds->ds_txstat.ts_rssi
                         , ds->ds_txstat.ts_antenna
                         , pRateTable
                         , sc->sc_opmode 
                         , sc->sc_diversity
                         , sc->sc_setdefantenna
                         , (void *)sc
                         , 0 
                    );

            }

            /* Account for retries on intermediate rates */
            totalTries += tries;
        }
    }
#endif

    /* 
     * Exclude intermediate rate retries, or the last rate, which may have 
     * succeeded, will incur a penalty higher than the intermediate rates that
     * failed.
     */
    rcUpdate(atn
             , (ds->ds_txstat.ts_status & HAL_TXERR_XRETRY) != 0
             , pRateTable->rateCodeToIndex[txRateCode]
             , ds->ds_txstat.ts_longretry - totalTries
             , ds->ds_txstat.ts_rssi
             , ds->ds_txstat.ts_antenna
             , pRateTable
             , sc->sc_opmode
             , sc->sc_diversity
             , sc->sc_setdefantenna
             , (void *)sc
             , 0 
    );

#if 0
    if (short_retry_fail == rts_retry_limit) {
        atn->txRateCtrl.consecRtsFailCount++;
    } else {
        atn->txRateCtrl.consecRtsFailCount = 0;
    }
#else
        atn->txRateCtrl.consecRtsFailCount = 0;
#endif
}