ar5416_xmit.c revision 217621
1/*
2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
3 * Copyright (c) 2002-2008 Atheros Communications, Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 *
17 * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c 217621 2011-01-20 05:49:15Z adrian $
18 */
19#include "opt_ah.h"
20
21#include "ah.h"
22#include "ah_desc.h"
23#include "ah_internal.h"
24
25#include "ar5416/ar5416.h"
26#include "ar5416/ar5416reg.h"
27#include "ar5416/ar5416phy.h"
28#include "ar5416/ar5416desc.h"
29
30/*
31 * Stop transmit on the specified queue
32 */
33HAL_BOOL
34ar5416StopTxDma(struct ath_hal *ah, u_int q)
35{
36#define	STOP_DMA_TIMEOUT	4000	/* us */
37#define	STOP_DMA_ITER		100	/* us */
38	u_int i;
39
40	HALASSERT(q < AH_PRIVATE(ah)->ah_caps.halTotalQueues);
41
42	HALASSERT(AH5212(ah)->ah_txq[q].tqi_type != HAL_TX_QUEUE_INACTIVE);
43
44	OS_REG_WRITE(ah, AR_Q_TXD, 1 << q);
45	for (i = STOP_DMA_TIMEOUT/STOP_DMA_ITER; i != 0; i--) {
46		if (ar5212NumTxPending(ah, q) == 0)
47			break;
48		OS_DELAY(STOP_DMA_ITER);
49	}
50#ifdef AH_DEBUG
51	if (i == 0) {
52		HALDEBUG(ah, HAL_DEBUG_ANY,
53		    "%s: queue %u DMA did not stop in 400 msec\n", __func__, q);
54		HALDEBUG(ah, HAL_DEBUG_ANY,
55		    "%s: QSTS 0x%x Q_TXE 0x%x Q_TXD 0x%x Q_CBR 0x%x\n", __func__,
56		    OS_REG_READ(ah, AR_QSTS(q)), OS_REG_READ(ah, AR_Q_TXE),
57		    OS_REG_READ(ah, AR_Q_TXD), OS_REG_READ(ah, AR_QCBRCFG(q)));
58		HALDEBUG(ah, HAL_DEBUG_ANY,
59		    "%s: Q_MISC 0x%x Q_RDYTIMECFG 0x%x Q_RDYTIMESHDN 0x%x\n",
60		    __func__, OS_REG_READ(ah, AR_QMISC(q)),
61		    OS_REG_READ(ah, AR_QRDYTIMECFG(q)),
62		    OS_REG_READ(ah, AR_Q_RDYTIMESHDN));
63	}
64#endif /* AH_DEBUG */
65
66	/* ar5416 and up can kill packets at the PCU level */
67	if (ar5212NumTxPending(ah, q)) {
68		uint32_t j;
69
70		HALDEBUG(ah, HAL_DEBUG_TXQUEUE,
71		    "%s: Num of pending TX Frames %d on Q %d\n",
72		    __func__, ar5212NumTxPending(ah, q), q);
73
74		/* Kill last PCU Tx Frame */
75		/* TODO - save off and restore current values of Q1/Q2? */
76		for (j = 0; j < 2; j++) {
77			uint32_t tsfLow = OS_REG_READ(ah, AR_TSF_L32);
78			OS_REG_WRITE(ah, AR_QUIET2,
79			    SM(10, AR_QUIET2_QUIET_DUR));
80			OS_REG_WRITE(ah, AR_QUIET_PERIOD, 100);
81			OS_REG_WRITE(ah, AR_NEXT_QUIET, tsfLow >> 10);
82			OS_REG_SET_BIT(ah, AR_TIMER_MODE, AR_TIMER_MODE_QUIET);
83
84			if ((OS_REG_READ(ah, AR_TSF_L32)>>10) == (tsfLow>>10))
85				break;
86
87			HALDEBUG(ah, HAL_DEBUG_ANY,
88			    "%s: TSF moved while trying to set quiet time "
89			    "TSF: 0x%08x\n", __func__, tsfLow);
90			HALASSERT(j < 1); /* TSF shouldn't count twice or reg access is taking forever */
91		}
92
93		OS_REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_CHAN_IDLE);
94
95		/* Allow the quiet mechanism to do its work */
96		OS_DELAY(200);
97		OS_REG_CLR_BIT(ah, AR_TIMER_MODE, AR_TIMER_MODE_QUIET);
98
99		/* Verify the transmit q is empty */
100		for (i = STOP_DMA_TIMEOUT/STOP_DMA_ITER; i != 0; i--) {
101			if (ar5212NumTxPending(ah, q) == 0)
102				break;
103			OS_DELAY(STOP_DMA_ITER);
104		}
105		if (i == 0) {
106			HALDEBUG(ah, HAL_DEBUG_ANY,
107			    "%s: Failed to stop Tx DMA in %d msec after killing"
108			    " last frame\n", __func__, STOP_DMA_TIMEOUT / 1000);
109		}
110		OS_REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_CHAN_IDLE);
111	}
112
113	OS_REG_WRITE(ah, AR_Q_TXD, 0);
114	return (i != 0);
115#undef STOP_DMA_ITER
116#undef STOP_DMA_TIMEOUT
117}
118
119#define VALID_KEY_TYPES \
120        ((1 << HAL_KEY_TYPE_CLEAR) | (1 << HAL_KEY_TYPE_WEP)|\
121         (1 << HAL_KEY_TYPE_AES)   | (1 << HAL_KEY_TYPE_TKIP))
122#define isValidKeyType(_t)      ((1 << (_t)) & VALID_KEY_TYPES)
123
124#define set11nTries(_series, _index) \
125        (SM((_series)[_index].Tries, AR_XmitDataTries##_index))
126
127#define set11nRate(_series, _index) \
128        (SM((_series)[_index].Rate, AR_XmitRate##_index))
129
130#define set11nPktDurRTSCTS(_series, _index) \
131        (SM((_series)[_index].PktDuration, AR_PacketDur##_index) |\
132         ((_series)[_index].RateFlags & HAL_RATESERIES_RTS_CTS   ?\
133         AR_RTSCTSQual##_index : 0))
134
135#define set11nRateFlags(_series, _index) \
136        ((_series)[_index].RateFlags & HAL_RATESERIES_2040 ? AR_2040_##_index : 0) \
137        |((_series)[_index].RateFlags & HAL_RATESERIES_HALFGI ? AR_GI##_index : 0) \
138        |SM((_series)[_index].ChSel, AR_ChainSel##_index)
139
140/*
141 * Descriptor Access Functions
142 */
143
144#define VALID_PKT_TYPES \
145        ((1<<HAL_PKT_TYPE_NORMAL)|(1<<HAL_PKT_TYPE_ATIM)|\
146         (1<<HAL_PKT_TYPE_PSPOLL)|(1<<HAL_PKT_TYPE_PROBE_RESP)|\
147         (1<<HAL_PKT_TYPE_BEACON)|(1<<HAL_PKT_TYPE_AMPDU))
148#define isValidPktType(_t)      ((1<<(_t)) & VALID_PKT_TYPES)
149#define VALID_TX_RATES \
150        ((1<<0x0b)|(1<<0x0f)|(1<<0x0a)|(1<<0x0e)|(1<<0x09)|(1<<0x0d)|\
151         (1<<0x08)|(1<<0x0c)|(1<<0x1b)|(1<<0x1a)|(1<<0x1e)|(1<<0x19)|\
152         (1<<0x1d)|(1<<0x18)|(1<<0x1c))
153#define isValidTxRate(_r)       ((1<<(_r)) & VALID_TX_RATES)
154
155HAL_BOOL
156ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds,
157	u_int pktLen,
158	u_int hdrLen,
159	HAL_PKT_TYPE type,
160	u_int txPower,
161	u_int txRate0, u_int txTries0,
162	u_int keyIx,
163	u_int antMode,
164	u_int flags,
165	u_int rtsctsRate,
166	u_int rtsctsDuration,
167	u_int compicvLen,
168	u_int compivLen,
169	u_int comp)
170{
171#define	RTSCTS	(HAL_TXDESC_RTSENA|HAL_TXDESC_CTSENA)
172	struct ar5416_desc *ads = AR5416DESC(ds);
173	struct ath_hal_5416 *ahp = AH5416(ah);
174
175	(void) hdrLen;
176
177	HALASSERT(txTries0 != 0);
178	HALASSERT(isValidPktType(type));
179	HALASSERT(isValidTxRate(txRate0));
180	HALASSERT((flags & RTSCTS) != RTSCTS);
181	/* XXX validate antMode */
182
183        txPower = (txPower + AH5212(ah)->ah_txPowerIndexOffset);
184        if (txPower > 63)
185		txPower = 63;
186
187	ads->ds_ctl0 = (pktLen & AR_FrameLen)
188		     | (txPower << AR_XmitPower_S)
189		     | (flags & HAL_TXDESC_VEOL ? AR_VEOL : 0)
190		     | (flags & HAL_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
191		     | (flags & HAL_TXDESC_INTREQ ? AR_TxIntrReq : 0)
192		     ;
193	ads->ds_ctl1 = (type << AR_FrameType_S)
194		     | (flags & HAL_TXDESC_NOACK ? AR_NoAck : 0)
195                     ;
196	ads->ds_ctl2 = SM(txTries0, AR_XmitDataTries0)
197		     | (flags & HAL_TXDESC_DURENA ? AR_DurUpdateEn : 0)
198		     ;
199	ads->ds_ctl3 = (txRate0 << AR_XmitRate0_S)
200		     ;
201	ads->ds_ctl4 = 0;
202	ads->ds_ctl5 = 0;
203	ads->ds_ctl6 = 0;
204	ads->ds_ctl7 = SM(ahp->ah_tx_chainmask, AR_ChainSel0)
205		     | SM(ahp->ah_tx_chainmask, AR_ChainSel1)
206		     | SM(ahp->ah_tx_chainmask, AR_ChainSel2)
207		     | SM(ahp->ah_tx_chainmask, AR_ChainSel3)
208		     ;
209	ads->ds_ctl8 = 0;
210	ads->ds_ctl9 = (txPower << 24);		/* XXX? */
211	ads->ds_ctl10 = (txPower << 24);	/* XXX? */
212	ads->ds_ctl11 = (txPower << 24);	/* XXX? */
213	if (keyIx != HAL_TXKEYIX_INVALID) {
214		/* XXX validate key index */
215		ads->ds_ctl1 |= SM(keyIx, AR_DestIdx);
216		ads->ds_ctl0 |= AR_DestIdxValid;
217		ads->ds_ctl6 |= SM(ahp->ah_keytype[keyIx], AR_EncrType);
218	}
219	if (flags & RTSCTS) {
220		if (!isValidTxRate(rtsctsRate)) {
221			HALDEBUG(ah, HAL_DEBUG_ANY,
222			    "%s: invalid rts/cts rate 0x%x\n",
223			    __func__, rtsctsRate);
224			return AH_FALSE;
225		}
226		/* XXX validate rtsctsDuration */
227		ads->ds_ctl0 |= (flags & HAL_TXDESC_CTSENA ? AR_CTSEnable : 0)
228			     | (flags & HAL_TXDESC_RTSENA ? AR_RTSEnable : 0)
229			     ;
230		ads->ds_ctl2 |= SM(rtsctsDuration, AR_BurstDur);
231		ads->ds_ctl7 |= (rtsctsRate << AR_RTSCTSRate_S);
232	}
233	return AH_TRUE;
234#undef RTSCTS
235}
236
237HAL_BOOL
238ar5416SetupXTxDesc(struct ath_hal *ah, struct ath_desc *ds,
239	u_int txRate1, u_int txTries1,
240	u_int txRate2, u_int txTries2,
241	u_int txRate3, u_int txTries3)
242{
243	struct ar5416_desc *ads = AR5416DESC(ds);
244
245	if (txTries1) {
246		HALASSERT(isValidTxRate(txRate1));
247		ads->ds_ctl2 |= SM(txTries1, AR_XmitDataTries1);
248		ads->ds_ctl3 |= (txRate1 << AR_XmitRate1_S);
249	}
250	if (txTries2) {
251		HALASSERT(isValidTxRate(txRate2));
252		ads->ds_ctl2 |= SM(txTries2, AR_XmitDataTries2);
253		ads->ds_ctl3 |= (txRate2 << AR_XmitRate2_S);
254	}
255	if (txTries3) {
256		HALASSERT(isValidTxRate(txRate3));
257		ads->ds_ctl2 |= SM(txTries3, AR_XmitDataTries3);
258		ads->ds_ctl3 |= (txRate3 << AR_XmitRate3_S);
259	}
260	return AH_TRUE;
261}
262
263HAL_BOOL
264ar5416FillTxDesc(struct ath_hal *ah, struct ath_desc *ds,
265	u_int segLen, HAL_BOOL firstSeg, HAL_BOOL lastSeg,
266	const struct ath_desc *ds0)
267{
268	struct ar5416_desc *ads = AR5416DESC(ds);
269
270	HALASSERT((segLen &~ AR_BufLen) == 0);
271
272	if (firstSeg) {
273		/*
274		 * First descriptor, don't clobber xmit control data
275		 * setup by ar5212SetupTxDesc.
276		 */
277		ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
278	} else if (lastSeg) {		/* !firstSeg && lastSeg */
279		/*
280		 * Last descriptor in a multi-descriptor frame,
281		 * copy the multi-rate transmit parameters from
282		 * the first frame for processing on completion.
283		 */
284		ads->ds_ctl0 = 0;
285		ads->ds_ctl1 = segLen;
286#ifdef AH_NEED_DESC_SWAP
287		ads->ds_ctl2 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl2);
288		ads->ds_ctl3 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl3);
289#else
290		ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
291		ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
292#endif
293	} else {			/* !firstSeg && !lastSeg */
294		/*
295		 * Intermediate descriptor in a multi-descriptor frame.
296		 */
297		ads->ds_ctl0 = 0;
298		ads->ds_ctl1 = segLen | AR_TxMore;
299		ads->ds_ctl2 = 0;
300		ads->ds_ctl3 = 0;
301	}
302	/* XXX only on last descriptor? */
303	OS_MEMZERO(ads->u.tx.status, sizeof(ads->u.tx.status));
304	return AH_TRUE;
305}
306
307#if 0
308
309HAL_BOOL
310ar5416ChainTxDesc(struct ath_hal *ah, struct ath_desc *ds,
311	u_int pktLen,
312	u_int hdrLen,
313	HAL_PKT_TYPE type,
314	u_int keyIx,
315	HAL_CIPHER cipher,
316	uint8_t delims,
317	u_int segLen,
318	HAL_BOOL firstSeg,
319	HAL_BOOL lastSeg)
320{
321	struct ar5416_desc *ads = AR5416DESC(ds);
322	uint32_t *ds_txstatus = AR5416_DS_TXSTATUS(ah,ads);
323
324	int isaggr = 0;
325
326	(void) hdrLen;
327	(void) ah;
328
329	HALASSERT((segLen &~ AR_BufLen) == 0);
330
331	HALASSERT(isValidPktType(type));
332	if (type == HAL_PKT_TYPE_AMPDU) {
333		type = HAL_PKT_TYPE_NORMAL;
334		isaggr = 1;
335	}
336
337	if (!firstSeg) {
338		ath_hal_memzero(ds->ds_hw, AR5416_DESC_TX_CTL_SZ);
339	}
340
341	ads->ds_ctl0 = (pktLen & AR_FrameLen);
342	ads->ds_ctl1 = (type << AR_FrameType_S)
343			| (isaggr ? (AR_IsAggr | AR_MoreAggr) : 0);
344	ads->ds_ctl2 = 0;
345	ads->ds_ctl3 = 0;
346	if (keyIx != HAL_TXKEYIX_INVALID) {
347		/* XXX validate key index */
348		ads->ds_ctl1 |= SM(keyIx, AR_DestIdx);
349		ads->ds_ctl0 |= AR_DestIdxValid;
350	}
351
352	ads->ds_ctl6 = SM(keyType[cipher], AR_EncrType);
353	if (isaggr) {
354		ads->ds_ctl6 |= SM(delims, AR_PadDelim);
355	}
356
357	if (firstSeg) {
358		ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
359	} else if (lastSeg) {           /* !firstSeg && lastSeg */
360		ads->ds_ctl0 = 0;
361		ads->ds_ctl1 |= segLen;
362	} else {                        /* !firstSeg && !lastSeg */
363		/*
364		 * Intermediate descriptor in a multi-descriptor frame.
365		 */
366		ads->ds_ctl0 = 0;
367		ads->ds_ctl1 |= segLen | AR_TxMore;
368	}
369	ds_txstatus[0] = ds_txstatus[1] = 0;
370	ds_txstatus[9] &= ~AR_TxDone;
371
372	return AH_TRUE;
373}
374
375HAL_BOOL
376ar5416SetupFirstTxDesc(struct ath_hal *ah, struct ath_desc *ds,
377	u_int aggrLen, u_int flags, u_int txPower,
378	u_int txRate0, u_int txTries0, u_int antMode,
379	u_int rtsctsRate, u_int rtsctsDuration)
380{
381#define RTSCTS  (HAL_TXDESC_RTSENA|HAL_TXDESC_CTSENA)
382	struct ar5416_desc *ads = AR5416DESC(ds);
383	struct ath_hal_5212 *ahp = AH5212(ah);
384
385	HALASSERT(txTries0 != 0);
386	HALASSERT(isValidTxRate(txRate0));
387	HALASSERT((flags & RTSCTS) != RTSCTS);
388	/* XXX validate antMode */
389
390	txPower = (txPower + ahp->ah_txPowerIndexOffset );
391	if(txPower > 63)  txPower=63;
392
393	ads->ds_ctl0 |= (txPower << AR_XmitPower_S)
394		| (flags & HAL_TXDESC_VEOL ? AR_VEOL : 0)
395		| (flags & HAL_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
396		| (flags & HAL_TXDESC_INTREQ ? AR_TxIntrReq : 0);
397	ads->ds_ctl1 |= (flags & HAL_TXDESC_NOACK ? AR_NoAck : 0);
398	ads->ds_ctl2 |= SM(txTries0, AR_XmitDataTries0);
399	ads->ds_ctl3 |= (txRate0 << AR_XmitRate0_S);
400	ads->ds_ctl7 = SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel0)
401		| SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel1)
402		| SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel2)
403		| SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel3);
404
405	/* NB: no V1 WAR */
406	ads->ds_ctl8 = 0;
407	ads->ds_ctl9 = (txPower << 24);
408	ads->ds_ctl10 = (txPower << 24);
409	ads->ds_ctl11 = (txPower << 24);
410
411	ads->ds_ctl6 &= ~(0xffff);
412	ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
413
414	if (flags & RTSCTS) {
415		/* XXX validate rtsctsDuration */
416		ads->ds_ctl0 |= (flags & HAL_TXDESC_CTSENA ? AR_CTSEnable : 0)
417			| (flags & HAL_TXDESC_RTSENA ? AR_RTSEnable : 0);
418		ads->ds_ctl2 |= SM(rtsctsDuration, AR_BurstDur);
419	}
420
421	return AH_TRUE;
422#undef RTSCTS
423}
424
425HAL_BOOL
426ar5416SetupLastTxDesc(struct ath_hal *ah, struct ath_desc *ds,
427		const struct ath_desc *ds0)
428{
429	struct ar5416_desc *ads = AR5416DESC(ds);
430
431	ads->ds_ctl1 &= ~AR_MoreAggr;
432	ads->ds_ctl6 &= ~AR_PadDelim;
433
434	/* hack to copy rate info to last desc for later processing */
435#ifdef AH_NEED_DESC_SWAP
436	ads->ds_ctl2 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl2);
437	ads->ds_ctl3 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl3);
438#else
439	ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
440	ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
441#endif
442
443	return AH_TRUE;
444}
445#endif /* 0 */
446
447#ifdef AH_NEED_DESC_SWAP
448/* Swap transmit descriptor */
449static __inline void
450ar5416SwapTxDesc(struct ath_desc *ds)
451{
452	ds->ds_data = __bswap32(ds->ds_data);
453	ds->ds_ctl0 = __bswap32(ds->ds_ctl0);
454	ds->ds_ctl1 = __bswap32(ds->ds_ctl1);
455	ds->ds_hw[0] = __bswap32(ds->ds_hw[0]);
456	ds->ds_hw[1] = __bswap32(ds->ds_hw[1]);
457	ds->ds_hw[2] = __bswap32(ds->ds_hw[2]);
458	ds->ds_hw[3] = __bswap32(ds->ds_hw[3]);
459}
460#endif
461
462/*
463 * Processing of HW TX descriptor.
464 */
465HAL_STATUS
466ar5416ProcTxDesc(struct ath_hal *ah,
467	struct ath_desc *ds, struct ath_tx_status *ts)
468{
469	struct ar5416_desc *ads = AR5416DESC(ds);
470	uint32_t *ds_txstatus = AR5416_DS_TXSTATUS(ah,ads);
471
472#ifdef AH_NEED_DESC_SWAP
473	if ((ds_txstatus[9] & __bswap32(AR_TxDone)) == 0)
474		return HAL_EINPROGRESS;
475	ar5416SwapTxDesc(ds);
476#else
477	if ((ds_txstatus[9] & AR_TxDone) == 0)
478		return HAL_EINPROGRESS;
479#endif
480
481	/* Update software copies of the HW status */
482	ts->ts_seqnum = MS(ds_txstatus[9], AR_SeqNum);
483	ts->ts_tstamp = AR_SendTimestamp(ds_txstatus);
484
485	ts->ts_status = 0;
486	if (ds_txstatus[1] & AR_ExcessiveRetries)
487		ts->ts_status |= HAL_TXERR_XRETRY;
488	if (ds_txstatus[1] & AR_Filtered)
489		ts->ts_status |= HAL_TXERR_FILT;
490	if (ds_txstatus[1] & AR_FIFOUnderrun)
491		ts->ts_status |= HAL_TXERR_FIFO;
492	if (ds_txstatus[9] & AR_TxOpExceeded)
493		ts->ts_status |= HAL_TXERR_XTXOP;
494	if (ds_txstatus[1] & AR_TxTimerExpired)
495		ts->ts_status |= HAL_TXERR_TIMER_EXPIRED;
496
497	ts->ts_flags  = 0;
498	if (ds_txstatus[0] & AR_TxBaStatus) {
499		ts->ts_flags |= HAL_TX_BA;
500		ts->ts_ba_low = AR_BaBitmapLow(ds_txstatus);
501		ts->ts_ba_high = AR_BaBitmapHigh(ds_txstatus);
502	}
503	if (ds->ds_ctl1 & AR_IsAggr)
504		ts->ts_flags |= HAL_TX_AGGR;
505	if (ds_txstatus[1] & AR_DescCfgErr)
506		ts->ts_flags |= HAL_TX_DESC_CFG_ERR;
507	if (ds_txstatus[1] & AR_TxDataUnderrun)
508		ts->ts_flags |= HAL_TX_DATA_UNDERRUN;
509	if (ds_txstatus[1] & AR_TxDelimUnderrun)
510		ts->ts_flags |= HAL_TX_DELIM_UNDERRUN;
511
512	/*
513	 * Extract the transmit rate used and mark the rate as
514	 * ``alternate'' if it wasn't the series 0 rate.
515	 */
516	ts->ts_finaltsi =  MS(ds_txstatus[9], AR_FinalTxIdx);
517	switch (ts->ts_finaltsi) {
518	case 0:
519		ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate0);
520		break;
521	case 1:
522		ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate1);
523		break;
524	case 2:
525		ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate2);
526		break;
527	case 3:
528		ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate3);
529		break;
530	}
531
532	ts->ts_rssi = MS(ds_txstatus[5], AR_TxRSSICombined);
533	ts->ts_rssi_ctl[0] = MS(ds_txstatus[0], AR_TxRSSIAnt00);
534	ts->ts_rssi_ctl[1] = MS(ds_txstatus[0], AR_TxRSSIAnt01);
535	ts->ts_rssi_ctl[2] = MS(ds_txstatus[0], AR_TxRSSIAnt02);
536	ts->ts_rssi_ext[0] = MS(ds_txstatus[5], AR_TxRSSIAnt10);
537	ts->ts_rssi_ext[1] = MS(ds_txstatus[5], AR_TxRSSIAnt11);
538	ts->ts_rssi_ext[2] = MS(ds_txstatus[5], AR_TxRSSIAnt12);
539	ts->ts_evm0 = AR_TxEVM0(ds_txstatus);
540	ts->ts_evm1 = AR_TxEVM1(ds_txstatus);
541	ts->ts_evm2 = AR_TxEVM2(ds_txstatus);
542
543	ts->ts_shortretry = MS(ds_txstatus[1], AR_RTSFailCnt);
544	ts->ts_longretry = MS(ds_txstatus[1], AR_DataFailCnt);
545	/*
546	 * The retry count has the number of un-acked tries for the
547	 * final series used.  When doing multi-rate retry we must
548	 * fixup the retry count by adding in the try counts for
549	 * each series that was fully-processed.  Beware that this
550	 * takes values from the try counts in the final descriptor.
551	 * These are not required by the hardware.  We assume they
552	 * are placed there by the driver as otherwise we have no
553	 * access and the driver can't do the calculation because it
554	 * doesn't know the descriptor format.
555	 */
556	switch (ts->ts_finaltsi) {
557	case 3: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries2);
558	case 2: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries1);
559	case 1: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries0);
560	}
561
562	/*
563	 * These fields are not used. Zero these to preserve compatability
564	 * with existing drivers.
565	 */
566	ts->ts_virtcol = MS(ads->ds_ctl1, AR_VirtRetryCnt);
567	ts->ts_antenna = 0; /* We don't switch antennas on Owl*/
568
569	/* handle tx trigger level changes internally */
570	if ((ts->ts_status & HAL_TXERR_FIFO) ||
571	    (ts->ts_flags & (HAL_TX_DATA_UNDERRUN | HAL_TX_DELIM_UNDERRUN)))
572		ar5212UpdateTxTrigLevel(ah, AH_TRUE);
573
574	return HAL_OK;
575}
576
577#if 0
578HAL_BOOL
579ar5416SetGlobalTxTimeout(struct ath_hal *ah, u_int tu)
580{
581	struct ath_hal_5416 *ahp = AH5416(ah);
582
583	if (tu > 0xFFFF) {
584		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad global tx timeout %u\n",
585		    __func__, tu);
586		/* restore default handling */
587		ahp->ah_globaltxtimeout = (u_int) -1;
588		return AH_FALSE;
589	}
590	OS_REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
591	ahp->ah_globaltxtimeout = tu;
592	return AH_TRUE;
593}
594
595u_int
596ar5416GetGlobalTxTimeout(struct ath_hal *ah)
597{
598	return MS(OS_REG_READ(ah, AR_GTXTO), AR_GTXTO_TIMEOUT_LIMIT);
599}
600
601void
602ar5416Set11nRateScenario(struct ath_hal *ah, struct ath_desc *ds,
603        u_int durUpdateEn, u_int rtsctsRate,
604	HAL_11N_RATE_SERIES series[], u_int nseries)
605{
606	struct ar5416_desc *ads = AR5416DESC(ds);
607
608	HALASSERT(nseries == 4);
609	(void)nseries;
610
611
612	ads->ds_ctl2 = set11nTries(series, 0)
613		     | set11nTries(series, 1)
614		     | set11nTries(series, 2)
615		     | set11nTries(series, 3)
616		     | (durUpdateEn ? AR_DurUpdateEn : 0);
617
618	ads->ds_ctl3 = set11nRate(series, 0)
619		     | set11nRate(series, 1)
620		     | set11nRate(series, 2)
621		     | set11nRate(series, 3);
622
623	ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
624		     | set11nPktDurRTSCTS(series, 1);
625
626	ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
627		     | set11nPktDurRTSCTS(series, 3);
628
629	ads->ds_ctl7 = set11nRateFlags(series, 0)
630		     | set11nRateFlags(series, 1)
631		     | set11nRateFlags(series, 2)
632		     | set11nRateFlags(series, 3)
633		     | SM(rtsctsRate, AR_RTSCTSRate);
634
635	/*
636	 * Enable RTSCTS if any of the series is flagged for RTSCTS,
637	 * but only if CTS is not enabled.
638	 */
639	/*
640	 * FIXME : the entire RTS/CTS handling should be moved to this
641	 * function (by passing the global RTS/CTS flags to this function).
642	 * currently it is split between this function and the
643	 * setupFiirstDescriptor. with this current implementation there
644	 * is an implicit assumption that setupFirstDescriptor is called
645	 * before this function.
646	 */
647	if (((series[0].RateFlags & HAL_RATESERIES_RTS_CTS) ||
648	     (series[1].RateFlags & HAL_RATESERIES_RTS_CTS) ||
649	     (series[2].RateFlags & HAL_RATESERIES_RTS_CTS) ||
650	     (series[3].RateFlags & HAL_RATESERIES_RTS_CTS) )  &&
651	    (ads->ds_ctl0 & AR_CTSEnable) == 0) {
652		ads->ds_ctl0 |= AR_RTSEnable;
653		ads->ds_ctl0 &= ~AR_CTSEnable;
654	}
655}
656
657void
658ar5416Set11nAggrMiddle(struct ath_hal *ah, struct ath_desc *ds, u_int numDelims)
659{
660	struct ar5416_desc *ads = AR5416DESC(ds);
661	uint32_t *ds_txstatus = AR5416_DS_TXSTATUS(ah,ads);
662
663	ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
664
665	ads->ds_ctl6 &= ~AR_PadDelim;
666	ads->ds_ctl6 |= SM(numDelims, AR_PadDelim);
667	ads->ds_ctl6 &= ~AR_AggrLen;
668
669	/*
670	 * Clear the TxDone status here, may need to change
671	 * func name to reflect this
672	 */
673	ds_txstatus[9] &= ~AR_TxDone;
674}
675
676void
677ar5416Clr11nAggr(struct ath_hal *ah, struct ath_desc *ds)
678{
679	struct ar5416_desc *ads = AR5416DESC(ds);
680
681	ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
682	ads->ds_ctl6 &= ~AR_PadDelim;
683	ads->ds_ctl6 &= ~AR_AggrLen;
684}
685
686void
687ar5416Set11nBurstDuration(struct ath_hal *ah, struct ath_desc *ds,
688                                                  u_int burstDuration)
689{
690	struct ar5416_desc *ads = AR5416DESC(ds);
691
692	ads->ds_ctl2 &= ~AR_BurstDur;
693	ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
694}
695#endif
696
697/*
698 * Retrieve the rate table from the given TX completion descriptor
699 */
700HAL_BOOL
701ar5416GetTxCompletionRates(struct ath_hal *ah, const struct ath_desc *ds0, int *rates, int *tries)
702{
703	const struct ar5416_desc *ads = AR5416DESC_CONST(ds0);
704
705	rates[0] = MS(ads->ds_ctl3, AR_XmitRate0);
706	rates[1] = MS(ads->ds_ctl3, AR_XmitRate1);
707	rates[2] = MS(ads->ds_ctl3, AR_XmitRate2);
708	rates[3] = MS(ads->ds_ctl3, AR_XmitRate3);
709
710	tries[0] = MS(ads->ds_ctl2, AR_XmitDataTries0);
711	tries[1] = MS(ads->ds_ctl2, AR_XmitDataTries1);
712	tries[2] = MS(ads->ds_ctl2, AR_XmitDataTries2);
713	tries[3] = MS(ads->ds_ctl2, AR_XmitDataTries3);
714
715	return AH_TRUE;
716}
717
718