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