📄 ar5416_xmit.c
字号:
ads->ds_ctl6 = SM(keyType[cipher], AR_EncrType); if (isaggr) { ads->ds_ctl6 |= SM(delims, AR_PadDelim); } if (firstSeg) { ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore); } else if (lastSeg) { /* !firstSeg && lastSeg */ ads->ds_ctl0 = 0; ads->ds_ctl1 |= segLen; } else { /* !firstSeg && !lastSeg */ /* * Intermediate descriptor in a multi-descriptor frame. */ ads->ds_ctl0 = 0; ads->ds_ctl1 |= segLen | AR_TxMore; } ds_txstatus[0] = ds_txstatus[1] = 0; ds_txstatus[9] &= ~AR_TxDone; return AH_TRUE;}HAL_BOOLar5416SetupFirstTxDesc(struct ath_hal *ah, struct ath_desc *ds, u_int aggrLen, u_int flags, u_int txPower, u_int txRate0, u_int txTries0, u_int antMode, u_int rtsctsRate, u_int rtsctsDuration){#define RTSCTS (HAL_TXDESC_RTSENA|HAL_TXDESC_CTSENA) struct ar5416_desc *ads = AR5416DESC(ds); struct ath_hal_5212 *ahp = AH5212(ah); HALASSERT(txTries0 != 0); HALASSERT(isValidTxRate(txRate0)); HALASSERT((flags & RTSCTS) != RTSCTS); /* XXX validate antMode */ txPower = (txPower + ahp->ah_txPowerIndexOffset ); if(txPower > 63) txPower=63; ads->ds_ctl0 |= (txPower << AR_XmitPower_S) | (flags & HAL_TXDESC_VEOL ? AR_VEOL : 0) | (flags & HAL_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) | (flags & HAL_TXDESC_INTREQ ? AR_TxIntrReq : 0); ads->ds_ctl1 |= (flags & HAL_TXDESC_NOACK ? AR_NoAck : 0); ads->ds_ctl2 |= SM(txTries0, AR_XmitDataTries0); ads->ds_ctl3 |= (txRate0 << AR_XmitRate0_S); ads->ds_ctl7 = SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel0) | SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel1) | SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel2) | SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel3); /* NB: no V1 WAR */ ads->ds_ctl8 = 0; ads->ds_ctl9 = (txPower << 24); ads->ds_ctl10 = (txPower << 24); ads->ds_ctl11 = (txPower << 24); ads->ds_ctl6 &= ~(0xffff); ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen); if (flags & RTSCTS) { /* XXX validate rtsctsDuration */ ads->ds_ctl0 |= (flags & HAL_TXDESC_CTSENA ? AR_CTSEnable : 0) | (flags & HAL_TXDESC_RTSENA ? AR_RTSEnable : 0); ads->ds_ctl2 |= SM(rtsctsDuration, AR_BurstDur); } return AH_TRUE;#undef RTSCTS}HAL_BOOLar5416SetupLastTxDesc(struct ath_hal *ah, struct ath_desc *ds, const struct ath_desc *ds0){ struct ar5416_desc *ads = AR5416DESC(ds); ads->ds_ctl1 &= ~AR_MoreAggr; ads->ds_ctl6 &= ~AR_PadDelim; /* hack to copy rate info to last desc for later processing */#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 return AH_TRUE;}#endif /* 0 */#ifdef AH_NEED_DESC_SWAP/* Swap transmit descriptor */static __inline voidar5416SwapTxDesc(struct ath_desc *ds){ ds->ds_data = __bswap32(ds->ds_data); ds->ds_ctl0 = __bswap32(ds->ds_ctl0); ds->ds_ctl1 = __bswap32(ds->ds_ctl1); ds->ds_hw[0] = __bswap32(ds->ds_hw[0]); ds->ds_hw[1] = __bswap32(ds->ds_hw[1]); ds->ds_hw[2] = __bswap32(ds->ds_hw[2]); ds->ds_hw[3] = __bswap32(ds->ds_hw[3]);}#endif/* * Processing of HW TX descriptor. */HAL_STATUSar5416ProcTxDesc(struct ath_hal *ah, struct ath_desc *ds, struct ath_tx_status *ts){ struct ar5416_desc *ads = AR5416DESC(ds); uint32_t *ds_txstatus = AR5416_DS_TXSTATUS(ah,ads);#ifdef AH_NEED_DESC_SWAP if ((ds_txstatus[9] & __bswap32(AR_TxDone)) == 0) return HAL_EINPROGRESS; ar5416SwapTxDesc(ds);#else if ((ds_txstatus[9] & AR_TxDone) == 0) return HAL_EINPROGRESS;#endif /* Update software copies of the HW status */ ts->ts_seqnum = MS(ds_txstatus[9], AR_SeqNum); ts->ts_tstamp = AR_SendTimestamp(ds_txstatus); ts->ts_status = 0; if (ds_txstatus[1] & AR_ExcessiveRetries) ts->ts_status |= HAL_TXERR_XRETRY; if (ds_txstatus[1] & AR_Filtered) ts->ts_status |= HAL_TXERR_FILT; if (ds_txstatus[1] & AR_FIFOUnderrun) ts->ts_status |= HAL_TXERR_FIFO; if (ds_txstatus[9] & AR_TxOpExceeded) ts->ts_status |= HAL_TXERR_XTXOP; if (ds_txstatus[1] & AR_TxTimerExpired) ts->ts_status |= HAL_TXERR_TIMER_EXPIRED; ts->ts_flags = 0; if (ds_txstatus[0] & AR_TxBaStatus) { ts->ts_flags |= HAL_TX_BA; ts->ts_ba_low = AR_BaBitmapLow(ds_txstatus); ts->ts_ba_high = AR_BaBitmapHigh(ds_txstatus); } if (ds->ds_ctl1 & AR_IsAggr) ts->ts_flags |= HAL_TX_AGGR; if (ds_txstatus[1] & AR_DescCfgErr) ts->ts_flags |= HAL_TX_DESC_CFG_ERR; if (ds_txstatus[1] & AR_TxDataUnderrun) ts->ts_flags |= HAL_TX_DATA_UNDERRUN; if (ds_txstatus[1] & AR_TxDelimUnderrun) ts->ts_flags |= HAL_TX_DELIM_UNDERRUN; /* * Extract the transmit rate used and mark the rate as * ``alternate'' if it wasn't the series 0 rate. */ ts->ts_finaltsi = MS(ds_txstatus[9], AR_FinalTxIdx); switch (ts->ts_finaltsi) { case 0: ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate0); break; case 1: ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate1) | HAL_TXSTAT_ALTRATE; break; case 2: ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate2) | HAL_TXSTAT_ALTRATE; break; case 3: ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate3) | HAL_TXSTAT_ALTRATE; break; } ts->ts_rssi = MS(ds_txstatus[5], AR_TxRSSICombined); ts->ts_rssi_ctl[0] = MS(ds_txstatus[0], AR_TxRSSIAnt00); ts->ts_rssi_ctl[1] = MS(ds_txstatus[0], AR_TxRSSIAnt01); ts->ts_rssi_ctl[2] = MS(ds_txstatus[0], AR_TxRSSIAnt02); ts->ts_rssi_ext[0] = MS(ds_txstatus[5], AR_TxRSSIAnt10); ts->ts_rssi_ext[1] = MS(ds_txstatus[5], AR_TxRSSIAnt11); ts->ts_rssi_ext[2] = MS(ds_txstatus[5], AR_TxRSSIAnt12); ts->ts_evm0 = AR_TxEVM0(ds_txstatus); ts->ts_evm1 = AR_TxEVM1(ds_txstatus); ts->ts_evm2 = AR_TxEVM2(ds_txstatus); ts->ts_shortretry = MS(ds_txstatus[1], AR_RTSFailCnt); ts->ts_longretry = MS(ds_txstatus[1], AR_DataFailCnt); /* * The retry count has the number of un-acked tries for the * final series used. When doing multi-rate retry we must * fixup the retry count by adding in the try counts for * each series that was fully-processed. Beware that this * takes values from the try counts in the final descriptor. * These are not required by the hardware. We assume they * are placed there by the driver as otherwise we have no * access and the driver can't do the calculation because it * doesn't know the descriptor format. */ switch (ts->ts_finaltsi) { case 3: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries2); case 2: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries1); case 1: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries0); } /* * These fields are not used. Zero these to preserve compatability * with existing drivers. */ ts->ts_virtcol = MS(ads->ds_ctl1, AR_VirtRetryCnt); ts->ts_antenna = 0; /* We don't switch antennas on Owl*/ /* handle tx trigger level changes internally */ if ((ts->ts_status & HAL_TXERR_FIFO) || (ts->ts_flags & (HAL_TX_DATA_UNDERRUN | HAL_TX_DELIM_UNDERRUN))) ar5212UpdateTxTrigLevel(ah, AH_TRUE); return HAL_OK;}#if 0HAL_BOOLar5416SetGlobalTxTimeout(struct ath_hal *ah, u_int tu){ struct ath_hal_5416 *ahp = AH5416(ah); if (tu > 0xFFFF) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad global tx timeout %u\n", __func__, tu); /* restore default handling */ ahp->ah_globaltxtimeout = (u_int) -1; return AH_FALSE; } OS_REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu); ahp->ah_globaltxtimeout = tu; return AH_TRUE;}u_intar5416GetGlobalTxTimeout(struct ath_hal *ah){ return MS(OS_REG_READ(ah, AR_GTXTO), AR_GTXTO_TIMEOUT_LIMIT);}voidar5416Set11nRateScenario(struct ath_hal *ah, struct ath_desc *ds, u_int durUpdateEn, u_int rtsctsRate, HAL_11N_RATE_SERIES series[], u_int nseries){ struct ar5416_desc *ads = AR5416DESC(ds); HALASSERT(nseries == 4); (void)nseries; ads->ds_ctl2 = set11nTries(series, 0) | set11nTries(series, 1) | set11nTries(series, 2) | set11nTries(series, 3) | (durUpdateEn ? AR_DurUpdateEn : 0); ads->ds_ctl3 = set11nRate(series, 0) | set11nRate(series, 1) | set11nRate(series, 2) | set11nRate(series, 3); ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0) | set11nPktDurRTSCTS(series, 1); ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2) | set11nPktDurRTSCTS(series, 3); ads->ds_ctl7 = set11nRateFlags(series, 0) | set11nRateFlags(series, 1) | set11nRateFlags(series, 2) | set11nRateFlags(series, 3) | SM(rtsctsRate, AR_RTSCTSRate); /* * Enable RTSCTS if any of the series is flagged for RTSCTS, * but only if CTS is not enabled. */ /* * FIXME : the entire RTS/CTS handling should be moved to this * function (by passing the global RTS/CTS flags to this function). * currently it is split between this function and the * setupFiirstDescriptor. with this current implementation there * is an implicit assumption that setupFirstDescriptor is called * before this function. */ if (((series[0].RateFlags & HAL_RATESERIES_RTS_CTS) || (series[1].RateFlags & HAL_RATESERIES_RTS_CTS) || (series[2].RateFlags & HAL_RATESERIES_RTS_CTS) || (series[3].RateFlags & HAL_RATESERIES_RTS_CTS) ) && (ads->ds_ctl0 & AR_CTSEnable) == 0) { ads->ds_ctl0 |= AR_RTSEnable; ads->ds_ctl0 &= ~AR_CTSEnable; }}voidar5416Set11nAggrMiddle(struct ath_hal *ah, struct ath_desc *ds, u_int numDelims){ struct ar5416_desc *ads = AR5416DESC(ds); uint32_t *ds_txstatus = AR5416_DS_TXSTATUS(ah,ads); ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr); ads->ds_ctl6 &= ~AR_PadDelim; ads->ds_ctl6 |= SM(numDelims, AR_PadDelim); ads->ds_ctl6 &= ~AR_AggrLen; /* * Clear the TxDone status here, may need to change * func name to reflect this */ ds_txstatus[9] &= ~AR_TxDone;}voidar5416Clr11nAggr(struct ath_hal *ah, struct ath_desc *ds){ struct ar5416_desc *ads = AR5416DESC(ds); ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr); ads->ds_ctl6 &= ~AR_PadDelim; ads->ds_ctl6 &= ~AR_AggrLen;}voidar5416Set11nBurstDuration(struct ath_hal *ah, struct ath_desc *ds, u_int burstDuration){ struct ar5416_desc *ads = AR5416DESC(ds); ads->ds_ctl2 &= ~AR_BurstDur; ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -