static void ar9002_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val) { struct ar5416_desc *ads = AR5416DESC(ds); if (val) ads->ds_ctl0 |= AR_ClrDestMask; else ads->ds_ctl0 &= ~AR_ClrDestMask; }
static void ar9002_hw_set11n_aggr_first(struct ath_hw *ah, void *ds, u32 aggrLen) { struct ar5416_desc *ads = AR5416DESC(ds); ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr); ads->ds_ctl6 &= ~AR_AggrLen; ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen); }
void ar5416Set11nAggrLast(struct ath_hal *ah, void *ds) { struct ar5416_desc *ads = AR5416DESC(ds); ads->ds_ctl1 |= AR_IsAggr; ads->ds_ctl1 &= ~AR_MoreAggr; ads->ds_ctl6 &= ~AR_PadDelim; }
void ar5416Set11nBurstDuration(struct ath_hal *ah, void *ds, u_int burst_duration) { struct ar5416_desc *ads = AR5416DESC(ds); ads->ds_ctl2 &= ~AR_BurstDur; ads->ds_ctl2 |= SM(burst_duration, AR_BurstDur); }
void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds) { struct ar5416_desc *ads = AR5416DESC(ds); ads->ds_txstatus0 = ads->ds_txstatus1 = 0; ads->ds_txstatus2 = ads->ds_txstatus3 = 0; ads->ds_txstatus4 = ads->ds_txstatus5 = 0; ads->ds_txstatus6 = ads->ds_txstatus7 = 0; ads->ds_txstatus8 = ads->ds_txstatus9 = 0; }
void ar5416Set11nAggrFirst(struct ath_hal *ah, void *ds, u_int aggr_len) { struct ar5416_desc *ads = AR5416DESC(ds); ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr); ads->ds_ctl6 &= ~AR_AggrLen; ads->ds_ctl6 |= SM(aggr_len, AR_AggrLen); }
void ar5416Set11nVirtualMoreFrag_20(struct ath_hal *ah, struct ath_tx_desc *ds, a_uint32_t vmf) { struct ar5416_desc *ads = AR5416DESC(ds); if (vmf) { ads->ds_ctl0 |= AR_VirtMoreFrag; } else { ads->ds_ctl0 &= ~AR_VirtMoreFrag; } }
void ar5416Set11nAggrFirst_20(struct ath_hal *ah, struct ath_tx_desc *ds, a_uint32_t aggrLen, a_uint32_t numDelims) { struct ar5416_desc *ads = AR5416DESC(ds); ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr); ads->ds_ctl6 &= ~(AR_AggrLen | AR_PadDelim); ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen) | SM(numDelims, AR_PadDelim); }
void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, u32 size, u32 flags) { struct ar5416_desc *ads = AR5416DESC(ds); ads->ds_ctl1 = size & AR_BufLen; if (flags & ATH9K_RXDESC_INTREQ) ads->ds_ctl1 |= AR_RxIntrReq; memset(&ads->u.rx, 0, sizeof(ads->u.rx)); }
void ar5416Set11nRateScenario_20(struct ath_hal *ah, struct ath_tx_desc *ds, a_uint32_t durUpdateEn, a_uint32_t rtsctsRate, a_uint32_t rtsctsDuration, HAL_11N_RATE_SERIES series[], a_uint32_t nseries, a_uint32_t flags) { struct ar5416_desc *ads = AR5416DESC(ds); a_uint32_t ds_ctl0; HALASSERT(nseries == 4); (void)nseries; /* * Rate control settings override */ if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) { ds_ctl0 = ads->ds_ctl0; if (flags & HAL_TXDESC_RTSENA) { ds_ctl0 &= ~AR_CTSEnable; ds_ctl0 |= AR_RTSEnable; } else { ds_ctl0 &= ~AR_RTSEnable; ds_ctl0 |= AR_CTSEnable; } ads->ds_ctl0 = ds_ctl0; } 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); }
static void ar9002_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds, u32 numDelims) { struct ar5416_desc *ads = AR5416DESC(ds); unsigned int ctl6; ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr); ctl6 = ads->ds_ctl6; ctl6 &= ~AR_PadDelim; ctl6 |= SM(numDelims, AR_PadDelim); ads->ds_ctl6 = ctl6; }
void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, u32 size, u32 flags) { struct ar5416_desc *ads = AR5416DESC(ds); struct ath9k_hw_capabilities *pCap = &ah->caps; ads->ds_ctl1 = size & AR_BufLen; if (flags & ATH9K_RXDESC_INTREQ) ads->ds_ctl1 |= AR_RxIntrReq; ads->ds_rxstatus8 &= ~AR_RxDone; if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) memset(&(ads->u), 0, sizeof(ads->u)); }
HAL_BOOL ar5416FillTxDesc_20(struct ath_hal *ah, struct ath_tx_desc *ds, a_uint32_t segLen, HAL_BOOL firstSeg, HAL_BOOL lastSeg, const struct ath_tx_desc *ds0) { struct ar5416_desc *ads = AR5416DESC(ds); // a_uint32_t offset = 70; // char *data_ptr = ds->ds_data; // data_ptr[offset+0] = 'w'; // data_ptr[offset+1] = 'e'; // data_ptr[offset+2] = 'a'; // data_ptr[offset+3] = 'r'; // data_ptr[offset+4] = 'e'; // data_ptr[offset+5] = 'h'; // data_ptr[offset+6] = 'e'; // data_ptr[offset+7] = 'r'; // data_ptr[offset+8] = 'e'; HALASSERT((segLen &~ AR_BufLen) == 0); if (firstSeg) { /* * First descriptor, don't clobber xmit control data * setup by ar5416SetupTxDesc. */ ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore); } else if (lastSeg) { /* * 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 = segLen; ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2; ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3; } else { /* * Intermediate descriptor in a multi-descriptor frame. */ ads->ds_ctl0 = 0; ads->ds_ctl1 = segLen | AR_TxMore; ads->ds_ctl2 = 0; ads->ds_ctl3 = 0; } ads->ds_txstatus0 = ads->ds_txstatus1 = 0; return AH_TRUE; }
void ar5416Set11nTxDesc(struct ath_hal *ah, void *ds, u_int pktLen, HAL_PKT_TYPE type, u_int txPower, u_int key_ix, HAL_KEY_TYPE keyType, u_int flags) { struct ar5416_desc *ads = AR5416DESC(ds); u_int32_t ctl0, ctl1, ctl6; HALASSERT(isValidPktType(type)); HALASSERT(isValidKeyType(keyType)); /* * If descriptor-based tpc, tx power is controlled by * ar5416Set11nRateScenario(). * If not, what you put in the descriptor is ignored anyway. */ txPower = 0; ctl0 = (pktLen & AR_FrameLen) | (flags & HAL_TXDESC_VMF ? AR_VirtMoreFrag : 0) | SM(txPower, AR_XmitPower0) | (flags & HAL_TXDESC_VEOL ? AR_VEOL : 0) | (flags & HAL_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) | (flags & HAL_TXDESC_INTREQ ? AR_TxIntrReq : 0) | (key_ix != HAL_TXKEYIX_INVALID ? AR_DestIdxValid : 0) | (flags & HAL_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0); ctl1 = (key_ix != HAL_TXKEYIX_INVALID ? SM(key_ix, AR_DestIdx) : 0) | SM(type, AR_FrameType) | (flags & HAL_TXDESC_NOACK ? AR_NoAck : 0) | (flags & HAL_TXDESC_EXT_ONLY ? AR_ExtOnly : 0) | (flags & HAL_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0); ctl6 = SM(keyType, AR_EncrType); ads->ds_ctl0 = ctl0; ads->ds_ctl1 = ctl1; ads->ds_ctl6 = ctl6; /* For Kite set the tx antenna selection */ if (AR_SREV_KITE(ah) || AR_SREV_K2(ah)) { /* FIXME: For now set the tx antenna to always 0, * till tx selection diverisity is implementated */ ads->ds_ctl8 = 0; ads->ds_ctl9 = 0; ads->ds_ctl10 = 0; ads->ds_ctl11 = 0; } }
void ar5416Set11nVirtualMoreFrag(struct ath_hal *ah, void *ds, u_int vmf) { struct ar5416_desc *ads = AR5416DESC(ds); if (vmf) { ads->ds_ctl0 |= AR_VirtMoreFrag; } else { ads->ds_ctl0 &= ~AR_VirtMoreFrag; } }
void ar5416Set11nAggrMiddle_20(struct ath_hal *ah, struct ath_tx_desc *ds, a_uint32_t numDelims) { struct ar5416_desc *ads = AR5416DESC(ds); a_uint32_t ctl6; ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr); /* * We use a stack variable to manipulate ctl6 to reduce uncached * read modify, modfiy, write. */ ctl6 = ads->ds_ctl6; ctl6 &= ~AR_PadDelim; ctl6 |= SM(numDelims, AR_PadDelim); ads->ds_ctl6 = ctl6; }
HAL_BOOL ar5416SetupRxDesc_20(struct ath_hal *ah, struct ath_rx_desc *ds, a_uint32_t size, a_uint32_t 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; }
/* * Process an RX descriptor, and return the status to the caller. * Copy some hardware specific items into a rx status object * provided by the caller. * * NB: the caller is responsible for validating the memory contents * of the descriptor (e.g. flushing any cached copy). */ HAL_STATUS ar5416ProcRxDescFast(struct ath_hal *ah, struct ath_desc *ds, u_int32_t pa, struct ath_desc *nds, struct ath_rx_status *rx_stats, void *buf_addr) { struct ar5416_desc *ands = AR5416DESC(nds); /* * 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_rxstatus8 & AR_RxDone) == 0 && OS_REG_READ(ah, AR_RXDP) == pa) return HAL_EINPROGRESS; return ar5416ProcRxDescBase(ah, ds, rx_stats); }
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; }
/* * 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; } }
/* * 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; /* clear the rest of the status fields */ OS_MEMZERO(&(ads->u), sizeof(ads->u)); return AH_TRUE; }
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; }
void ar5416TxReqIntrDesc(struct ath_hal *ah, void *ds) { struct ar5416_desc *ads = AR5416DESC(ds); ads->ds_ctl0 |= AR_TxIntrReq; }
static void ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i) { struct ar5416_desc *ads = AR5416DESC(ds); u32 ctl1, ctl6; ads->ds_txstatus0 = ads->ds_txstatus1 = 0; ads->ds_txstatus2 = ads->ds_txstatus3 = 0; ads->ds_txstatus4 = ads->ds_txstatus5 = 0; ads->ds_txstatus6 = ads->ds_txstatus7 = 0; ads->ds_txstatus8 = ads->ds_txstatus9 = 0; ACCESS_ONCE(ads->ds_link) = i->link; ACCESS_ONCE(ads->ds_data) = i->buf_addr[0]; ctl1 = i->buf_len[0] | (i->is_last ? 0 : AR_TxMore); ctl6 = SM(i->keytype, AR_EncrType); if (AR_SREV_9285(ah)) { ads->ds_ctl8 = 0; ads->ds_ctl9 = 0; ads->ds_ctl10 = 0; ads->ds_ctl11 = 0; } if ((i->is_first || i->is_last) && i->aggr != AGGR_BUF_MIDDLE && i->aggr != AGGR_BUF_LAST) { ACCESS_ONCE(ads->ds_ctl2) = set11nTries(i->rates, 0) | set11nTries(i->rates, 1) | set11nTries(i->rates, 2) | set11nTries(i->rates, 3) | (i->dur_update ? AR_DurUpdateEna : 0) | SM(0, AR_BurstDur); ACCESS_ONCE(ads->ds_ctl3) = set11nRate(i->rates, 0) | set11nRate(i->rates, 1) | set11nRate(i->rates, 2) | set11nRate(i->rates, 3); } else { ACCESS_ONCE(ads->ds_ctl2) = 0; ACCESS_ONCE(ads->ds_ctl3) = 0; } if (!i->is_first) { ACCESS_ONCE(ads->ds_ctl0) = 0; ACCESS_ONCE(ads->ds_ctl1) = ctl1; ACCESS_ONCE(ads->ds_ctl6) = ctl6; return; } ctl1 |= (i->keyix != ATH9K_TXKEYIX_INVALID ? SM(i->keyix, AR_DestIdx) : 0) | SM(i->type, AR_FrameType) | (i->flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0) | (i->flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0) | (i->flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0); switch (i->aggr) { case AGGR_BUF_FIRST: ctl6 |= SM(i->aggr_len, AR_AggrLen); /* fall through */ case AGGR_BUF_MIDDLE: ctl1 |= AR_IsAggr | AR_MoreAggr; ctl6 |= SM(i->ndelim, AR_PadDelim); break; case AGGR_BUF_LAST: ctl1 |= AR_IsAggr; break; case AGGR_BUF_NONE: break; } ACCESS_ONCE(ads->ds_ctl0) = (i->pkt_len & AR_FrameLen) | (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) | SM(i->txpower, AR_XmitPower) | (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) | (i->flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0) | (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0) | (i->flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) | (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable : (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0)); ACCESS_ONCE(ads->ds_ctl1) = ctl1; ACCESS_ONCE(ads->ds_ctl6) = ctl6; if (i->aggr == AGGR_BUF_MIDDLE || i->aggr == AGGR_BUF_LAST) return; ACCESS_ONCE(ads->ds_ctl4) = set11nPktDurRTSCTS(i->rates, 0) | set11nPktDurRTSCTS(i->rates, 1); ACCESS_ONCE(ads->ds_ctl5) = set11nPktDurRTSCTS(i->rates, 2) | set11nPktDurRTSCTS(i->rates, 3); ACCESS_ONCE(ads->ds_ctl7) = set11nRateFlags(i->rates, 0) | set11nRateFlags(i->rates, 1) | set11nRateFlags(i->rates, 2) | set11nRateFlags(i->rates, 3) | SM(i->rtscts_rate, AR_RTSCTSRate); }
static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_status *ts) { struct ar5416_desc *ads = AR5416DESC(ds); u32 status; status = ACCESS_ONCE(ads->ds_txstatus9); if ((status & AR_TxDone) == 0) return -EINPROGRESS; ts->ts_tstamp = ads->AR_SendTimestamp; ts->ts_status = 0; ts->ts_flags = 0; if (status & AR_TxOpExceeded) ts->ts_status |= ATH9K_TXERR_XTXOP; ts->tid = MS(status, AR_TxTid); ts->ts_rateindex = MS(status, AR_FinalTxIdx); ts->ts_seqnum = MS(status, AR_SeqNum); status = ACCESS_ONCE(ads->ds_txstatus0); ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00); ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01); ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02); if (status & AR_TxBaStatus) { ts->ts_flags |= ATH9K_TX_BA; ts->ba_low = ads->AR_BaBitmapLow; ts->ba_high = ads->AR_BaBitmapHigh; } status = ACCESS_ONCE(ads->ds_txstatus1); if (status & AR_FrmXmitOK) ts->ts_status |= ATH9K_TX_ACKED; else { if (status & AR_ExcessiveRetries) ts->ts_status |= ATH9K_TXERR_XRETRY; if (status & AR_Filtered) ts->ts_status |= ATH9K_TXERR_FILT; if (status & AR_FIFOUnderrun) { ts->ts_status |= ATH9K_TXERR_FIFO; ath9k_hw_updatetxtriglevel(ah, true); } } if (status & AR_TxTimerExpired) ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED; if (status & AR_DescCfgErr) ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR; if (status & AR_TxDataUnderrun) { ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN; ath9k_hw_updatetxtriglevel(ah, true); } if (status & AR_TxDelimUnderrun) { ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN; ath9k_hw_updatetxtriglevel(ah, true); } ts->ts_shortretry = MS(status, AR_RTSFailCnt); ts->ts_longretry = MS(status, AR_DataFailCnt); ts->ts_virtcol = MS(status, AR_VirtRetryCnt); status = ACCESS_ONCE(ads->ds_txstatus5); ts->ts_rssi = MS(status, AR_TxRSSICombined); ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10); ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11); ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12); ts->evm0 = ads->AR_TxEVM0; ts->evm1 = ads->AR_TxEVM1; ts->evm2 = ads->AR_TxEVM2; return 0; }
void ar5416Set11nRateScenario(struct ath_hal *ah, void *ds, void *lastds, u_int dur_update_en, u_int rts_cts_rate, u_int rts_cts_duration, HAL_11N_RATE_SERIES series[], u_int nseries, u_int flags, u_int32_t smartAntenna) #endif { struct ath_hal_private *ap = AH_PRIVATE(ah); struct ar5416_desc *ads = AR5416DESC(ds); struct ar5416_desc *last_ads = AR5416DESC(lastds); u_int32_t ds_ctl0; u_int mode; HALASSERT(nseries == 4); (void)nseries; (void)rts_cts_duration; /* use H/W to calculate RTSCTSDuration */ /* * Rate control settings override */ ds_ctl0 = ads->ds_ctl0; if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) { if (flags & HAL_TXDESC_RTSENA) { ds_ctl0 &= ~AR_CTSEnable; ds_ctl0 |= AR_RTSEnable; } else { ds_ctl0 &= ~AR_RTSEnable; ds_ctl0 |= AR_CTSEnable; } } else { ds_ctl0 = (ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable)); } mode = ath_hal_get_curmode(ah, ap->ah_curchan); if (ap->ah_config.ath_hal_desc_tpc) { int16_t txpower; txpower = ar5416GetRateTxPower(ah, mode, series[0].rate_index, series[0].ch_sel); if(series[0].tx_power_cap == 0) { /*For short range mode, set txpower to MAX to put series[0].TxPowerCap into the descriptor*/ txpower = HAL_TXPOWER_MAX; } ds_ctl0 &= ~AR_XmitPower0; if (AR_SREV_MERLIN_10_OR_LATER(ah)) { u_int count; for (count=0; count < nseries; count++) { series[count].tx_power_cap -= AR5416_PWR_TABLE_OFFSET_DB * 2; } } ds_ctl0 |= set11nTxPower(0, AH_MIN(txpower, series[0].tx_power_cap)); } ads->ds_ctl0 = ds_ctl0; ads->ds_ctl2 = set11nTries(series, 0) | set11nTries(series, 1) | set11nTries(series, 2) | set11nTries(series, 3) | (dur_update_en ? AR_DurUpdateEna : 0) | SM(0, AR_BurstDur); 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(rts_cts_rate, AR_RTSCTSRate); if (ap->ah_config.ath_hal_desc_tpc && AR_SREV_OWL_20_OR_LATER(ah)) { int16_t txpower; txpower = ar5416GetRateTxPower( ah, mode, series[1].rate_index, series[1].ch_sel); ads->ds_ctl9 = set11nTxPower(1, AH_MIN(txpower, series[1].tx_power_cap)); txpower = ar5416GetRateTxPower( ah, mode, series[2].rate_index, series[2].ch_sel); ads->ds_ctl10 = set11nTxPower(2, AH_MIN(txpower, series[2].tx_power_cap)); txpower = ar5416GetRateTxPower( ah, mode, series[3].rate_index, series[3].ch_sel); ads->ds_ctl11 = set11nTxPower(3, AH_MIN(txpower, series[3].tx_power_cap)); } #ifdef AH_NEED_DESC_SWAP last_ads->ds_ctl2 = __bswap32(ads->ds_ctl2); last_ads->ds_ctl3 = __bswap32(ads->ds_ctl3); #else last_ads->ds_ctl2 = ads->ds_ctl2; last_ads->ds_ctl3 = ads->ds_ctl3; #endif }
static void ar9002_hw_clr11n_aggr(struct ath_hw *ah, void *ds) { struct ar5416_desc *ads = AR5416DESC(ds); ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr); }
HAL_BOOL ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds, u_int pktLen, u_int hdrLen, HAL_PKT_TYPE type, u_int txPower, u_int txRate0, u_int txTries0, u_int key_ix, u_int antMode, u_int flags, u_int rts_cts_rate, u_int rts_cts_duration, u_int compicvLen, u_int compivLen, u_int comp) { #define RTSCTS (HAL_TXDESC_RTSENA|HAL_TXDESC_CTSENA) struct ar5416_desc *ads = AR5416DESC(ds); (void) hdrLen; ads->ds_txstatus9 &= ~AR_TxDone; HALASSERT(txTries0 != 0); HALASSERT(isValidPktType(type)); HALASSERT(isValidTxRate(txRate0)); HALASSERT((flags & RTSCTS) != RTSCTS); /* XXX validate antMode */ /* * If descriptor-based tpc, tx power is controlled by * ar5416Set11nRateScenario(). * If not, what you put in the descriptor is ignored anyway. */ txPower = 0; ads->ds_ctl0 = (pktLen & AR_FrameLen) | (txPower << AR_XmitPower0_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 = (type << AR_FrameType_S) | (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(AR5416_LEGACY_CHAINMASK, AR_ChainSel0) | SM(AR5416_LEGACY_CHAINMASK, AR_ChainSel1) | SM(AR5416_LEGACY_CHAINMASK, AR_ChainSel2) | SM(AR5416_LEGACY_CHAINMASK, AR_ChainSel3) ; if (key_ix != HAL_TXKEYIX_INVALID) { /* XXX validate key index */ ads->ds_ctl1 |= SM(key_ix, AR_DestIdx); ads->ds_ctl0 |= AR_DestIdxValid; } if (flags & RTSCTS) { if (!isValidTxRate(rts_cts_rate)) { HDPRINTF(ah, HAL_DBG_TXDESC, "%s: invalid rts/cts rate 0x%x\n", __func__, rts_cts_rate); return AH_FALSE; } /* XXX validate rts_cts_duration */ ads->ds_ctl0 |= (flags & HAL_TXDESC_CTSENA ? AR_CTSEnable : 0) | (flags & HAL_TXDESC_RTSENA ? AR_RTSEnable : 0) ; ads->ds_ctl2 |= SM(rts_cts_duration, AR_BurstDur); ads->ds_ctl3 |= (rts_cts_rate << AR_RTSCTSRate_S); } return AH_TRUE; #undef RTSCTS }
int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, struct ath_rx_status *rs) { struct ar5416_desc ads; struct ar5416_desc *adsp = AR5416DESC(ds); u32 phyerr; if ((adsp->ds_rxstatus8 & AR_RxDone) == 0) return -EINPROGRESS; ads.u.rx = adsp->u.rx; rs->rs_status = 0; rs->rs_flags = 0; rs->flag = 0; rs->rs_datalen = ads.ds_rxstatus1 & AR_DataLen; rs->rs_tstamp = ads.AR_RcvTimestamp; if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) { rs->rs_rssi = ATH9K_RSSI_BAD; rs->rs_rssi_ctl[0] = ATH9K_RSSI_BAD; rs->rs_rssi_ctl[1] = ATH9K_RSSI_BAD; rs->rs_rssi_ctl[2] = ATH9K_RSSI_BAD; rs->rs_rssi_ext[0] = ATH9K_RSSI_BAD; rs->rs_rssi_ext[1] = ATH9K_RSSI_BAD; rs->rs_rssi_ext[2] = ATH9K_RSSI_BAD; } else { rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined); rs->rs_rssi_ctl[0] = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00); rs->rs_rssi_ctl[1] = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01); rs->rs_rssi_ctl[2] = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02); rs->rs_rssi_ext[0] = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10); rs->rs_rssi_ext[1] = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11); rs->rs_rssi_ext[2] = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12); } if (ads.ds_rxstatus8 & AR_RxKeyIdxValid) rs->rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx); else rs->rs_keyix = ATH9K_RXKEYIX_INVALID; rs->rs_rate = MS(ads.ds_rxstatus0, AR_RxRate); rs->rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0; rs->rs_firstaggr = (ads.ds_rxstatus8 & AR_RxFirstAggr) ? 1 : 0; rs->rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0; rs->rs_moreaggr = (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0; rs->rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna); /* directly mapped flags for ieee80211_rx_status */ rs->flag |= (ads.ds_rxstatus3 & AR_GI) ? RX_FLAG_SHORT_GI : 0; rs->flag |= (ads.ds_rxstatus3 & AR_2040) ? RX_FLAG_40MHZ : 0; if (AR_SREV_9280_20_OR_LATER(ah)) rs->flag |= (ads.ds_rxstatus3 & AR_STBC) ? /* we can only Nss=1 STBC */ (1 << RX_FLAG_STBC_SHIFT) : 0; if (ads.ds_rxstatus8 & AR_PreDelimCRCErr) rs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE; if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) rs->rs_flags |= ATH9K_RX_DELIM_CRC_POST; if (ads.ds_rxstatus8 & AR_DecryptBusyErr) rs->rs_flags |= ATH9K_RX_DECRYPT_BUSY; if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) { /* * Treat these errors as mutually exclusive to avoid spurious * extra error reports from the hardware. If a CRC error is * reported, then decryption and MIC errors are irrelevant, * the frame is going to be dropped either way */ if (ads.ds_rxstatus8 & AR_PHYErr) { rs->rs_status |= ATH9K_RXERR_PHY; phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode); rs->rs_phyerr = phyerr; } else if (ads.ds_rxstatus8 & AR_CRCErr) rs->rs_status |= ATH9K_RXERR_CRC; else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) rs->rs_status |= ATH9K_RXERR_DECRYPT; else if (ads.ds_rxstatus8 & AR_MichaelErr) rs->rs_status |= ATH9K_RXERR_MIC; } else { if (ads.ds_rxstatus8 & (AR_CRCErr | AR_PHYErr | AR_DecryptCRCErr | AR_MichaelErr)) rs->rs_status |= ATH9K_RXERR_CORRUPT_DESC; /* Only up to MCS16 supported, everything above is invalid */ if (rs->rs_rate >= 0x90) rs->rs_status |= ATH9K_RXERR_CORRUPT_DESC; } if (ads.ds_rxstatus8 & AR_KeyMiss) rs->rs_status |= ATH9K_RXERR_KEYMISS; return 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 ar5416ProcRxDesc(struct ath_hal *ah, struct ath_desc *ds, uint32_t pa, struct ath_desc *nds, uint64_t tsf, struct ath_rx_status *rs) { struct ar5416_desc *ads = AR5416DESC(ds); if ((ads->ds_rxstatus8 & AR_RxDone) == 0) return HAL_EINPROGRESS; rs->rs_status = 0; rs->rs_flags = 0; rs->rs_datalen = ads->ds_rxstatus1 & AR_DataLen; rs->rs_tstamp = ads->AR_RcvTimestamp; /* XXX what about KeyCacheMiss? */ rs->rs_rssi = MS(ads->ds_rxstatus4, AR_RxRSSICombined); rs->rs_rssi_ctl[0] = MS(ads->ds_rxstatus0, AR_RxRSSIAnt00); rs->rs_rssi_ctl[1] = MS(ads->ds_rxstatus0, AR_RxRSSIAnt01); rs->rs_rssi_ctl[2] = MS(ads->ds_rxstatus0, AR_RxRSSIAnt02); rs->rs_rssi_ext[0] = MS(ads->ds_rxstatus4, AR_RxRSSIAnt10); rs->rs_rssi_ext[1] = MS(ads->ds_rxstatus4, AR_RxRSSIAnt11); rs->rs_rssi_ext[2] = MS(ads->ds_rxstatus4, AR_RxRSSIAnt12); if (ads->ds_rxstatus8 & AR_RxKeyIdxValid) rs->rs_keyix = MS(ads->ds_rxstatus8, AR_KeyIdx); else rs->rs_keyix = HAL_RXKEYIX_INVALID; /* NB: caller expected to do rate table mapping */ rs->rs_rate = RXSTATUS_RATE(ah, ads); rs->rs_more = (ads->ds_rxstatus1 & AR_RxMore) ? 1 : 0; rs->rs_isaggr = (ads->ds_rxstatus8 & AR_RxAggr) ? 1 : 0; rs->rs_moreaggr = (ads->ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0; rs->rs_antenna = MS(ads->ds_rxstatus3, AR_RxAntenna); if (ads->ds_rxstatus3 & AR_GI) rs->rs_flags |= HAL_RX_GI; if (ads->ds_rxstatus3 & AR_2040) rs->rs_flags |= HAL_RX_2040; /* * Only the AR9280 and later chips support STBC RX, so * ensure we only set this bit for those chips. */ if (AR_SREV_MERLIN_10_OR_LATER(ah) && ads->ds_rxstatus3 & AR_STBCFrame) rs->rs_flags |= HAL_RX_STBC; if (ads->ds_rxstatus8 & AR_PreDelimCRCErr) rs->rs_flags |= HAL_RX_DELIM_CRC_PRE; if (ads->ds_rxstatus8 & AR_PostDelimCRCErr) rs->rs_flags |= HAL_RX_DELIM_CRC_POST; if (ads->ds_rxstatus8 & AR_DecryptBusyErr) rs->rs_flags |= HAL_RX_DECRYPT_BUSY; if (ads->ds_rxstatus8 & AR_HiRxChain) rs->rs_flags |= HAL_RX_HI_RX_CHAIN; if ((ads->ds_rxstatus8 & AR_RxFrameOK) == 0) { /* * These four bits should not be set together. The * 5416 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. */ /* * The AR5416 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_rxstatus8 & AR_PHYErr) { u_int phyerr; /* * Packets with OFDM_RESTART on post delimiter are CRC OK and * usable and MAC ACKs them. * To avoid packet from being lost, we remove the PHY Err flag * so that driver layer does not drop them. */ phyerr = MS(ads->ds_rxstatus8, AR_PHYErrCode); if ((phyerr == HAL_PHYERR_OFDM_RESTART) && (ads->ds_rxstatus8 & AR_PostDelimCRCErr)) { ath_hal_printf(ah, "%s: OFDM_RESTART on post-delim CRC error\n", __func__); rs->rs_phyerr = 0; } else { rs->rs_status |= HAL_RXERR_PHY; rs->rs_phyerr = phyerr; } } if (ads->ds_rxstatus8 & AR_CRCErr) rs->rs_status |= HAL_RXERR_CRC; else if (ads->ds_rxstatus8 & AR_DecryptCRCErr) rs->rs_status |= HAL_RXERR_DECRYPT; else if (ads->ds_rxstatus8 & AR_MichaelErr) rs->rs_status |= HAL_RXERR_MIC; } return HAL_OK; }