ar5416_xmit.c revision 218170
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 218170 2011-02-01 15:26:30Z 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)|(1<<0x01)|(1<<0x02)|(1<<0x03)|\
153	 (1<<0x04)|(1<<0x05)|(1<<0x06)|(1<<0x07)|(1<<0x00))
154/* NB: accept HT rates */
155#define	isValidTxRate(_r)	((1<<((_r) & 0x7f)) & VALID_TX_RATES)
156
157HAL_BOOL
158ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds,
159	u_int pktLen,
160	u_int hdrLen,
161	HAL_PKT_TYPE type,
162	u_int txPower,
163	u_int txRate0, u_int txTries0,
164	u_int keyIx,
165	u_int antMode,
166	u_int flags,
167	u_int rtsctsRate,
168	u_int rtsctsDuration,
169	u_int compicvLen,
170	u_int compivLen,
171	u_int comp)
172{
173#define	RTSCTS	(HAL_TXDESC_RTSENA|HAL_TXDESC_CTSENA)
174	struct ar5416_desc *ads = AR5416DESC(ds);
175	struct ath_hal_5416 *ahp = AH5416(ah);
176
177	(void) hdrLen;
178
179	HALASSERT(txTries0 != 0);
180	HALASSERT(isValidPktType(type));
181	HALASSERT(isValidTxRate(txRate0));
182	HALASSERT((flags & RTSCTS) != RTSCTS);
183	/* XXX validate antMode */
184
185        txPower = (txPower + AH5212(ah)->ah_txPowerIndexOffset);
186        if (txPower > 63)
187		txPower = 63;
188
189	ads->ds_ctl0 = (pktLen & AR_FrameLen)
190		     | (txPower << AR_XmitPower_S)
191		     | (flags & HAL_TXDESC_VEOL ? AR_VEOL : 0)
192		     | (flags & HAL_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
193		     | (flags & HAL_TXDESC_INTREQ ? AR_TxIntrReq : 0)
194		     ;
195	ads->ds_ctl1 = (type << AR_FrameType_S)
196		     | (flags & HAL_TXDESC_NOACK ? AR_NoAck : 0)
197                     ;
198	ads->ds_ctl2 = SM(txTries0, AR_XmitDataTries0)
199		     | (flags & HAL_TXDESC_DURENA ? AR_DurUpdateEn : 0)
200		     ;
201	ads->ds_ctl3 = (txRate0 << AR_XmitRate0_S)
202		     ;
203	ads->ds_ctl4 = 0;
204	ads->ds_ctl5 = 0;
205	ads->ds_ctl6 = 0;
206	ads->ds_ctl7 = SM(ahp->ah_tx_chainmask, AR_ChainSel0)
207		     | SM(ahp->ah_tx_chainmask, AR_ChainSel1)
208		     | SM(ahp->ah_tx_chainmask, AR_ChainSel2)
209		     | SM(ahp->ah_tx_chainmask, AR_ChainSel3)
210		     ;
211	ads->ds_ctl8 = 0;
212	ads->ds_ctl9 = (txPower << 24);		/* XXX? */
213	ads->ds_ctl10 = (txPower << 24);	/* XXX? */
214	ads->ds_ctl11 = (txPower << 24);	/* XXX? */
215	if (keyIx != HAL_TXKEYIX_INVALID) {
216		/* XXX validate key index */
217		ads->ds_ctl1 |= SM(keyIx, AR_DestIdx);
218		ads->ds_ctl0 |= AR_DestIdxValid;
219		ads->ds_ctl6 |= SM(ahp->ah_keytype[keyIx], AR_EncrType);
220	}
221	if (flags & RTSCTS) {
222		if (!isValidTxRate(rtsctsRate)) {
223			HALDEBUG(ah, HAL_DEBUG_ANY,
224			    "%s: invalid rts/cts rate 0x%x\n",
225			    __func__, rtsctsRate);
226			return AH_FALSE;
227		}
228		/* XXX validate rtsctsDuration */
229		ads->ds_ctl0 |= (flags & HAL_TXDESC_CTSENA ? AR_CTSEnable : 0)
230			     | (flags & HAL_TXDESC_RTSENA ? AR_RTSEnable : 0)
231			     ;
232		ads->ds_ctl7 |= (rtsctsRate << AR_RTSCTSRate_S);
233	}
234
235	if (AR_SREV_KITE(ah)) {
236		ads->ds_ctl8 = 0;
237		ads->ds_ctl9 = 0;
238		ads->ds_ctl10 = 0;
239		ads->ds_ctl11 = 0;
240	}
241	return AH_TRUE;
242#undef RTSCTS
243}
244
245HAL_BOOL
246ar5416SetupXTxDesc(struct ath_hal *ah, struct ath_desc *ds,
247	u_int txRate1, u_int txTries1,
248	u_int txRate2, u_int txTries2,
249	u_int txRate3, u_int txTries3)
250{
251	struct ar5416_desc *ads = AR5416DESC(ds);
252
253	if (txTries1) {
254		HALASSERT(isValidTxRate(txRate1));
255		ads->ds_ctl2 |= SM(txTries1, AR_XmitDataTries1);
256		ads->ds_ctl3 |= (txRate1 << AR_XmitRate1_S);
257	}
258	if (txTries2) {
259		HALASSERT(isValidTxRate(txRate2));
260		ads->ds_ctl2 |= SM(txTries2, AR_XmitDataTries2);
261		ads->ds_ctl3 |= (txRate2 << AR_XmitRate2_S);
262	}
263	if (txTries3) {
264		HALASSERT(isValidTxRate(txRate3));
265		ads->ds_ctl2 |= SM(txTries3, AR_XmitDataTries3);
266		ads->ds_ctl3 |= (txRate3 << AR_XmitRate3_S);
267	}
268	return AH_TRUE;
269}
270
271HAL_BOOL
272ar5416FillTxDesc(struct ath_hal *ah, struct ath_desc *ds,
273	u_int segLen, HAL_BOOL firstSeg, HAL_BOOL lastSeg,
274	const struct ath_desc *ds0)
275{
276	struct ar5416_desc *ads = AR5416DESC(ds);
277
278	HALASSERT((segLen &~ AR_BufLen) == 0);
279
280	if (firstSeg) {
281		/*
282		 * First descriptor, don't clobber xmit control data
283		 * setup by ar5212SetupTxDesc.
284		 */
285		ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
286	} else if (lastSeg) {		/* !firstSeg && lastSeg */
287		/*
288		 * Last descriptor in a multi-descriptor frame,
289		 * copy the multi-rate transmit parameters from
290		 * the first frame for processing on completion.
291		 */
292		ads->ds_ctl0 = 0;
293		ads->ds_ctl1 = segLen;
294#ifdef AH_NEED_DESC_SWAP
295		ads->ds_ctl2 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl2);
296		ads->ds_ctl3 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl3);
297#else
298		ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
299		ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
300#endif
301	} else {			/* !firstSeg && !lastSeg */
302		/*
303		 * Intermediate descriptor in a multi-descriptor frame.
304		 */
305		ads->ds_ctl0 = 0;
306		ads->ds_ctl1 = segLen | AR_TxMore;
307		ads->ds_ctl2 = 0;
308		ads->ds_ctl3 = 0;
309	}
310	/* XXX only on last descriptor? */
311	OS_MEMZERO(ads->u.tx.status, sizeof(ads->u.tx.status));
312	return AH_TRUE;
313}
314
315HAL_BOOL
316ar5416ChainTxDesc(struct ath_hal *ah, struct ath_desc *ds,
317	u_int pktLen,
318	u_int hdrLen,
319	HAL_PKT_TYPE type,
320	u_int keyIx,
321	HAL_CIPHER cipher,
322	uint8_t delims,
323	u_int segLen,
324	HAL_BOOL firstSeg,
325	HAL_BOOL lastSeg)
326{
327	struct ar5416_desc *ads = AR5416DESC(ds);
328	uint32_t *ds_txstatus = AR5416_DS_TXSTATUS(ah,ads);
329	struct ath_hal_5416 *ahp = AH5416(ah);
330
331	int isaggr = 0;
332
333	(void) hdrLen;
334	(void) ah;
335
336	HALASSERT((segLen &~ AR_BufLen) == 0);
337
338	HALASSERT(isValidPktType(type));
339	if (type == HAL_PKT_TYPE_AMPDU) {
340		type = HAL_PKT_TYPE_NORMAL;
341		isaggr = 1;
342	}
343
344	if (!firstSeg) {
345		OS_MEMZERO(ds->ds_hw, AR5416_DESC_TX_CTL_SZ);
346	}
347
348	ads->ds_ctl0 = (pktLen & AR_FrameLen);
349	ads->ds_ctl1 = (type << AR_FrameType_S)
350			| (isaggr ? (AR_IsAggr | AR_MoreAggr) : 0);
351	ads->ds_ctl2 = 0;
352	ads->ds_ctl3 = 0;
353	if (keyIx != HAL_TXKEYIX_INVALID) {
354		/* XXX validate key index */
355		ads->ds_ctl1 |= SM(keyIx, AR_DestIdx);
356		ads->ds_ctl0 |= AR_DestIdxValid;
357	}
358
359	ads->ds_ctl6 = SM(ahp->ah_keytype[cipher], AR_EncrType);
360	if (isaggr) {
361		ads->ds_ctl6 |= SM(delims, AR_PadDelim);
362	}
363
364	if (firstSeg) {
365		ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
366	} else if (lastSeg) {           /* !firstSeg && lastSeg */
367		ads->ds_ctl0 = 0;
368		ads->ds_ctl1 |= segLen;
369	} else {                        /* !firstSeg && !lastSeg */
370		/*
371		 * Intermediate descriptor in a multi-descriptor frame.
372		 */
373		ads->ds_ctl0 = 0;
374		ads->ds_ctl1 |= segLen | AR_TxMore;
375	}
376	ds_txstatus[0] = ds_txstatus[1] = 0;
377	ds_txstatus[9] &= ~AR_TxDone;
378
379	return AH_TRUE;
380}
381
382HAL_BOOL
383ar5416SetupFirstTxDesc(struct ath_hal *ah, struct ath_desc *ds,
384	u_int aggrLen, u_int flags, u_int txPower,
385	u_int txRate0, u_int txTries0, u_int antMode,
386	u_int rtsctsRate, u_int rtsctsDuration)
387{
388#define RTSCTS  (HAL_TXDESC_RTSENA|HAL_TXDESC_CTSENA)
389	struct ar5416_desc *ads = AR5416DESC(ds);
390	struct ath_hal_5212 *ahp = AH5212(ah);
391
392	HALASSERT(txTries0 != 0);
393	HALASSERT(isValidTxRate(txRate0));
394	HALASSERT((flags & RTSCTS) != RTSCTS);
395	/* XXX validate antMode */
396
397	txPower = (txPower + ahp->ah_txPowerIndexOffset );
398	if(txPower > 63)  txPower=63;
399
400	ads->ds_ctl0 |= (txPower << AR_XmitPower_S)
401		| (flags & HAL_TXDESC_VEOL ? AR_VEOL : 0)
402		| (flags & HAL_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
403		| (flags & HAL_TXDESC_INTREQ ? AR_TxIntrReq : 0);
404	ads->ds_ctl1 |= (flags & HAL_TXDESC_NOACK ? AR_NoAck : 0);
405	ads->ds_ctl2 |= SM(txTries0, AR_XmitDataTries0);
406	ads->ds_ctl3 |= (txRate0 << AR_XmitRate0_S);
407	ads->ds_ctl7 = SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel0)
408		| SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel1)
409		| SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel2)
410		| SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel3);
411
412	/* NB: no V1 WAR */
413	ads->ds_ctl8 = 0;
414	ads->ds_ctl9 = (txPower << 24);
415	ads->ds_ctl10 = (txPower << 24);
416	ads->ds_ctl11 = (txPower << 24);
417
418	ads->ds_ctl6 &= ~(0xffff);
419	ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
420
421	if (flags & RTSCTS) {
422		/* XXX validate rtsctsDuration */
423		ads->ds_ctl0 |= (flags & HAL_TXDESC_CTSENA ? AR_CTSEnable : 0)
424			| (flags & HAL_TXDESC_RTSENA ? AR_RTSEnable : 0);
425	}
426
427	if (AR_SREV_KITE(ah)) {
428		ads->ds_ctl8 = 0;
429		ads->ds_ctl9 = 0;
430		ads->ds_ctl10 = 0;
431		ads->ds_ctl11 = 0;
432	}
433
434	return AH_TRUE;
435#undef RTSCTS
436}
437
438HAL_BOOL
439ar5416SetupLastTxDesc(struct ath_hal *ah, struct ath_desc *ds,
440		const struct ath_desc *ds0)
441{
442	struct ar5416_desc *ads = AR5416DESC(ds);
443
444	ads->ds_ctl1 &= ~AR_MoreAggr;
445	ads->ds_ctl6 &= ~AR_PadDelim;
446
447	/* hack to copy rate info to last desc for later processing */
448#ifdef AH_NEED_DESC_SWAP
449	ads->ds_ctl2 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl2);
450	ads->ds_ctl3 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl3);
451#else
452	ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
453	ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
454#endif
455
456	return AH_TRUE;
457}
458
459#ifdef AH_NEED_DESC_SWAP
460/* Swap transmit descriptor */
461static __inline void
462ar5416SwapTxDesc(struct ath_desc *ds)
463{
464	ds->ds_data = __bswap32(ds->ds_data);
465	ds->ds_ctl0 = __bswap32(ds->ds_ctl0);
466	ds->ds_ctl1 = __bswap32(ds->ds_ctl1);
467	ds->ds_hw[0] = __bswap32(ds->ds_hw[0]);
468	ds->ds_hw[1] = __bswap32(ds->ds_hw[1]);
469	ds->ds_hw[2] = __bswap32(ds->ds_hw[2]);
470	ds->ds_hw[3] = __bswap32(ds->ds_hw[3]);
471}
472#endif
473
474/*
475 * Processing of HW TX descriptor.
476 */
477HAL_STATUS
478ar5416ProcTxDesc(struct ath_hal *ah,
479	struct ath_desc *ds, struct ath_tx_status *ts)
480{
481	struct ar5416_desc *ads = AR5416DESC(ds);
482	uint32_t *ds_txstatus = AR5416_DS_TXSTATUS(ah,ads);
483
484#ifdef AH_NEED_DESC_SWAP
485	if ((ds_txstatus[9] & __bswap32(AR_TxDone)) == 0)
486		return HAL_EINPROGRESS;
487	ar5416SwapTxDesc(ds);
488#else
489	if ((ds_txstatus[9] & AR_TxDone) == 0)
490		return HAL_EINPROGRESS;
491#endif
492
493	/* Update software copies of the HW status */
494	ts->ts_seqnum = MS(ds_txstatus[9], AR_SeqNum);
495	ts->ts_tstamp = AR_SendTimestamp(ds_txstatus);
496
497	ts->ts_status = 0;
498	if (ds_txstatus[1] & AR_ExcessiveRetries)
499		ts->ts_status |= HAL_TXERR_XRETRY;
500	if (ds_txstatus[1] & AR_Filtered)
501		ts->ts_status |= HAL_TXERR_FILT;
502	if (ds_txstatus[1] & AR_FIFOUnderrun)
503		ts->ts_status |= HAL_TXERR_FIFO;
504	if (ds_txstatus[9] & AR_TxOpExceeded)
505		ts->ts_status |= HAL_TXERR_XTXOP;
506	if (ds_txstatus[1] & AR_TxTimerExpired)
507		ts->ts_status |= HAL_TXERR_TIMER_EXPIRED;
508
509	ts->ts_flags  = 0;
510	if (ds_txstatus[0] & AR_TxBaStatus) {
511		ts->ts_flags |= HAL_TX_BA;
512		ts->ts_ba_low = AR_BaBitmapLow(ds_txstatus);
513		ts->ts_ba_high = AR_BaBitmapHigh(ds_txstatus);
514	}
515	if (ds->ds_ctl1 & AR_IsAggr)
516		ts->ts_flags |= HAL_TX_AGGR;
517	if (ds_txstatus[1] & AR_DescCfgErr)
518		ts->ts_flags |= HAL_TX_DESC_CFG_ERR;
519	if (ds_txstatus[1] & AR_TxDataUnderrun)
520		ts->ts_flags |= HAL_TX_DATA_UNDERRUN;
521	if (ds_txstatus[1] & AR_TxDelimUnderrun)
522		ts->ts_flags |= HAL_TX_DELIM_UNDERRUN;
523
524	/*
525	 * Extract the transmit rate used and mark the rate as
526	 * ``alternate'' if it wasn't the series 0 rate.
527	 */
528	ts->ts_finaltsi =  MS(ds_txstatus[9], AR_FinalTxIdx);
529	switch (ts->ts_finaltsi) {
530	case 0:
531		ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate0);
532		break;
533	case 1:
534		ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate1);
535		break;
536	case 2:
537		ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate2);
538		break;
539	case 3:
540		ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate3);
541		break;
542	}
543
544	ts->ts_rssi = MS(ds_txstatus[5], AR_TxRSSICombined);
545	ts->ts_rssi_ctl[0] = MS(ds_txstatus[0], AR_TxRSSIAnt00);
546	ts->ts_rssi_ctl[1] = MS(ds_txstatus[0], AR_TxRSSIAnt01);
547	ts->ts_rssi_ctl[2] = MS(ds_txstatus[0], AR_TxRSSIAnt02);
548	ts->ts_rssi_ext[0] = MS(ds_txstatus[5], AR_TxRSSIAnt10);
549	ts->ts_rssi_ext[1] = MS(ds_txstatus[5], AR_TxRSSIAnt11);
550	ts->ts_rssi_ext[2] = MS(ds_txstatus[5], AR_TxRSSIAnt12);
551	ts->ts_evm0 = AR_TxEVM0(ds_txstatus);
552	ts->ts_evm1 = AR_TxEVM1(ds_txstatus);
553	ts->ts_evm2 = AR_TxEVM2(ds_txstatus);
554
555	ts->ts_shortretry = MS(ds_txstatus[1], AR_RTSFailCnt);
556	ts->ts_longretry = MS(ds_txstatus[1], AR_DataFailCnt);
557	/*
558	 * The retry count has the number of un-acked tries for the
559	 * final series used.  When doing multi-rate retry we must
560	 * fixup the retry count by adding in the try counts for
561	 * each series that was fully-processed.  Beware that this
562	 * takes values from the try counts in the final descriptor.
563	 * These are not required by the hardware.  We assume they
564	 * are placed there by the driver as otherwise we have no
565	 * access and the driver can't do the calculation because it
566	 * doesn't know the descriptor format.
567	 */
568	switch (ts->ts_finaltsi) {
569	case 3: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries2);
570	case 2: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries1);
571	case 1: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries0);
572	}
573
574	/*
575	 * These fields are not used. Zero these to preserve compatability
576	 * with existing drivers.
577	 */
578	ts->ts_virtcol = MS(ads->ds_ctl1, AR_VirtRetryCnt);
579	ts->ts_antenna = 0; /* We don't switch antennas on Owl*/
580
581	/* handle tx trigger level changes internally */
582	if ((ts->ts_status & HAL_TXERR_FIFO) ||
583	    (ts->ts_flags & (HAL_TX_DATA_UNDERRUN | HAL_TX_DELIM_UNDERRUN)))
584		ar5212UpdateTxTrigLevel(ah, AH_TRUE);
585
586	return HAL_OK;
587}
588
589HAL_BOOL
590ar5416SetGlobalTxTimeout(struct ath_hal *ah, u_int tu)
591{
592	struct ath_hal_5416 *ahp = AH5416(ah);
593
594	if (tu > 0xFFFF) {
595		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad global tx timeout %u\n",
596		    __func__, tu);
597		/* restore default handling */
598		ahp->ah_globaltxtimeout = (u_int) -1;
599		return AH_FALSE;
600	}
601	OS_REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
602	ahp->ah_globaltxtimeout = tu;
603	return AH_TRUE;
604}
605
606u_int
607ar5416GetGlobalTxTimeout(struct ath_hal *ah)
608{
609	return MS(OS_REG_READ(ah, AR_GTXTO), AR_GTXTO_TIMEOUT_LIMIT);
610}
611
612void
613ar5416Set11nRateScenario(struct ath_hal *ah, struct ath_desc *ds,
614        u_int durUpdateEn, u_int rtsctsRate,
615	HAL_11N_RATE_SERIES series[], u_int nseries, u_int flags)
616{
617	struct ar5416_desc *ads = AR5416DESC(ds);
618	uint32_t ds_ctl0;
619
620	HALASSERT(nseries == 4);
621	(void)nseries;
622
623	/*
624	 * Only one of RTS and CTS enable must be set.
625	 * If a frame has both set, just do RTS protection -
626	 * that's enough to satisfy legacy protection.
627	 */
628	if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) {
629		ds_ctl0 = ads->ds_ctl0;
630
631		if (flags & HAL_TXDESC_RTSENA) {
632			ds_ctl0 &= ~AR_CTSEnable;
633			ds_ctl0 |= AR_RTSEnable;
634		} else {
635			ds_ctl0 &= ~AR_RTSEnable;
636			ds_ctl0 |= AR_CTSEnable;
637		}
638
639		ads->ds_ctl0 = ds_ctl0;
640	} else {
641		ads->ds_ctl0 =
642		    (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
643	}
644
645
646	ads->ds_ctl2 = set11nTries(series, 0)
647		     | set11nTries(series, 1)
648		     | set11nTries(series, 2)
649		     | set11nTries(series, 3)
650		     | (durUpdateEn ? AR_DurUpdateEn : 0);
651
652	ads->ds_ctl3 = set11nRate(series, 0)
653		     | set11nRate(series, 1)
654		     | set11nRate(series, 2)
655		     | set11nRate(series, 3);
656
657	ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
658		     | set11nPktDurRTSCTS(series, 1);
659
660	ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
661		     | set11nPktDurRTSCTS(series, 3);
662
663	ads->ds_ctl7 = set11nRateFlags(series, 0)
664		     | set11nRateFlags(series, 1)
665		     | set11nRateFlags(series, 2)
666		     | set11nRateFlags(series, 3)
667		     | SM(rtsctsRate, AR_RTSCTSRate);
668}
669
670void
671ar5416Set11nAggrMiddle(struct ath_hal *ah, struct ath_desc *ds, u_int numDelims)
672{
673	struct ar5416_desc *ads = AR5416DESC(ds);
674	uint32_t *ds_txstatus = AR5416_DS_TXSTATUS(ah,ads);
675
676	ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
677
678	ads->ds_ctl6 &= ~AR_PadDelim;
679	ads->ds_ctl6 |= SM(numDelims, AR_PadDelim);
680	ads->ds_ctl6 &= ~AR_AggrLen;
681
682	/*
683	 * Clear the TxDone status here, may need to change
684	 * func name to reflect this
685	 */
686	ds_txstatus[9] &= ~AR_TxDone;
687}
688
689void
690ar5416Clr11nAggr(struct ath_hal *ah, struct ath_desc *ds)
691{
692	struct ar5416_desc *ads = AR5416DESC(ds);
693
694	ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
695	ads->ds_ctl6 &= ~AR_PadDelim;
696	ads->ds_ctl6 &= ~AR_AggrLen;
697}
698
699void
700ar5416Set11nBurstDuration(struct ath_hal *ah, struct ath_desc *ds,
701                                                  u_int burstDuration)
702{
703	struct ar5416_desc *ads = AR5416DESC(ds);
704
705	ads->ds_ctl2 &= ~AR_BurstDur;
706	ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
707}
708
709/*
710 * Retrieve the rate table from the given TX completion descriptor
711 */
712HAL_BOOL
713ar5416GetTxCompletionRates(struct ath_hal *ah, const struct ath_desc *ds0, int *rates, int *tries)
714{
715	const struct ar5416_desc *ads = AR5416DESC_CONST(ds0);
716
717	rates[0] = MS(ads->ds_ctl3, AR_XmitRate0);
718	rates[1] = MS(ads->ds_ctl3, AR_XmitRate1);
719	rates[2] = MS(ads->ds_ctl3, AR_XmitRate2);
720	rates[3] = MS(ads->ds_ctl3, AR_XmitRate3);
721
722	tries[0] = MS(ads->ds_ctl2, AR_XmitDataTries0);
723	tries[1] = MS(ads->ds_ctl2, AR_XmitDataTries1);
724	tries[2] = MS(ads->ds_ctl2, AR_XmitDataTries2);
725	tries[3] = MS(ads->ds_ctl2, AR_XmitDataTries3);
726
727	return AH_TRUE;
728}
729
730