1 /*
2  * Copyright (c) 2002-2008 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  * $Id: ar5416_xmit.c,v 1.1.1.1 2008/12/11 04:46:50 alc Exp $
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  */
33 HAL_BOOL
ar5416StopTxDma(struct ath_hal * ah,u_int q)34 ar5416StopTxDma(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 
155 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 keyIx,u_int antMode,u_int flags,u_int rtsctsRate,u_int rtsctsDuration,u_int compicvLen,u_int compivLen,u_int comp)156 ar5416SetupTxDesc(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 
237 HAL_BOOL
ar5416SetupXTxDesc(struct ath_hal * ah,struct ath_desc * ds,u_int txRate1,u_int txTries1,u_int txRate2,u_int txTries2,u_int txRate3,u_int txTries3)238 ar5416SetupXTxDesc(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 
263 HAL_BOOL
ar5416FillTxDesc(struct ath_hal * ah,struct ath_desc * ds,u_int segLen,HAL_BOOL firstSeg,HAL_BOOL lastSeg,const struct ath_desc * ds0)264 ar5416FillTxDesc(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 
309 HAL_BOOL
310 ar5416ChainTxDesc(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 
375 HAL_BOOL
376 ar5416SetupFirstTxDesc(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 
425 HAL_BOOL
426 ar5416SetupLastTxDesc(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 */
449 static __inline void
ar5416SwapTxDesc(struct ath_desc * ds)450 ar5416SwapTxDesc(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  */
465 HAL_STATUS
ar5416ProcTxDesc(struct ath_hal * ah,struct ath_desc * ds,struct ath_tx_status * ts)466 ar5416ProcTxDesc(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 			HAL_TXSTAT_ALTRATE;
524 		break;
525 	case 2:
526 		ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate2) |
527 			HAL_TXSTAT_ALTRATE;
528 		break;
529 	case 3:
530 		ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate3) |
531 			HAL_TXSTAT_ALTRATE;
532 		break;
533 	}
534 
535 	ts->ts_rssi = MS(ds_txstatus[5], AR_TxRSSICombined);
536 	ts->ts_rssi_ctl[0] = MS(ds_txstatus[0], AR_TxRSSIAnt00);
537 	ts->ts_rssi_ctl[1] = MS(ds_txstatus[0], AR_TxRSSIAnt01);
538 	ts->ts_rssi_ctl[2] = MS(ds_txstatus[0], AR_TxRSSIAnt02);
539 	ts->ts_rssi_ext[0] = MS(ds_txstatus[5], AR_TxRSSIAnt10);
540 	ts->ts_rssi_ext[1] = MS(ds_txstatus[5], AR_TxRSSIAnt11);
541 	ts->ts_rssi_ext[2] = MS(ds_txstatus[5], AR_TxRSSIAnt12);
542 	ts->ts_evm0 = AR_TxEVM0(ds_txstatus);
543 	ts->ts_evm1 = AR_TxEVM1(ds_txstatus);
544 	ts->ts_evm2 = AR_TxEVM2(ds_txstatus);
545 
546 	ts->ts_shortretry = MS(ds_txstatus[1], AR_RTSFailCnt);
547 	ts->ts_longretry = MS(ds_txstatus[1], AR_DataFailCnt);
548 	/*
549 	 * The retry count has the number of un-acked tries for the
550 	 * final series used.  When doing multi-rate retry we must
551 	 * fixup the retry count by adding in the try counts for
552 	 * each series that was fully-processed.  Beware that this
553 	 * takes values from the try counts in the final descriptor.
554 	 * These are not required by the hardware.  We assume they
555 	 * are placed there by the driver as otherwise we have no
556 	 * access and the driver can't do the calculation because it
557 	 * doesn't know the descriptor format.
558 	 */
559 	switch (ts->ts_finaltsi) {
560 	case 3: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries2);
561 	case 2: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries1);
562 	case 1: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries0);
563 	}
564 
565 	/*
566 	 * These fields are not used. Zero these to preserve compatability
567 	 * with existing drivers.
568 	 */
569 	ts->ts_virtcol = MS(ads->ds_ctl1, AR_VirtRetryCnt);
570 	ts->ts_antenna = 0; /* We don't switch antennas on Owl*/
571 
572 	/* handle tx trigger level changes internally */
573 	if ((ts->ts_status & HAL_TXERR_FIFO) ||
574 	    (ts->ts_flags & (HAL_TX_DATA_UNDERRUN | HAL_TX_DELIM_UNDERRUN)))
575 		ar5212UpdateTxTrigLevel(ah, AH_TRUE);
576 
577 	return HAL_OK;
578 }
579 
580 #if 0
581 HAL_BOOL
582 ar5416SetGlobalTxTimeout(struct ath_hal *ah, u_int tu)
583 {
584 	struct ath_hal_5416 *ahp = AH5416(ah);
585 
586 	if (tu > 0xFFFF) {
587 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad global tx timeout %u\n",
588 		    __func__, tu);
589 		/* restore default handling */
590 		ahp->ah_globaltxtimeout = (u_int) -1;
591 		return AH_FALSE;
592 	}
593 	OS_REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
594 	ahp->ah_globaltxtimeout = tu;
595 	return AH_TRUE;
596 }
597 
598 u_int
599 ar5416GetGlobalTxTimeout(struct ath_hal *ah)
600 {
601 	return MS(OS_REG_READ(ah, AR_GTXTO), AR_GTXTO_TIMEOUT_LIMIT);
602 }
603 
604 void
605 ar5416Set11nRateScenario(struct ath_hal *ah, struct ath_desc *ds,
606         u_int durUpdateEn, u_int rtsctsRate,
607 	HAL_11N_RATE_SERIES series[], u_int nseries)
608 {
609 	struct ar5416_desc *ads = AR5416DESC(ds);
610 
611 	HALASSERT(nseries == 4);
612 	(void)nseries;
613 
614 
615 	ads->ds_ctl2 = set11nTries(series, 0)
616 		     | set11nTries(series, 1)
617 		     | set11nTries(series, 2)
618 		     | set11nTries(series, 3)
619 		     | (durUpdateEn ? AR_DurUpdateEn : 0);
620 
621 	ads->ds_ctl3 = set11nRate(series, 0)
622 		     | set11nRate(series, 1)
623 		     | set11nRate(series, 2)
624 		     | set11nRate(series, 3);
625 
626 	ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
627 		     | set11nPktDurRTSCTS(series, 1);
628 
629 	ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
630 		     | set11nPktDurRTSCTS(series, 3);
631 
632 	ads->ds_ctl7 = set11nRateFlags(series, 0)
633 		     | set11nRateFlags(series, 1)
634 		     | set11nRateFlags(series, 2)
635 		     | set11nRateFlags(series, 3)
636 		     | SM(rtsctsRate, AR_RTSCTSRate);
637 
638 	/*
639 	 * Enable RTSCTS if any of the series is flagged for RTSCTS,
640 	 * but only if CTS is not enabled.
641 	 */
642 	/*
643 	 * FIXME : the entire RTS/CTS handling should be moved to this
644 	 * function (by passing the global RTS/CTS flags to this function).
645 	 * currently it is split between this function and the
646 	 * setupFiirstDescriptor. with this current implementation there
647 	 * is an implicit assumption that setupFirstDescriptor is called
648 	 * before this function.
649 	 */
650 	if (((series[0].RateFlags & HAL_RATESERIES_RTS_CTS) ||
651 	     (series[1].RateFlags & HAL_RATESERIES_RTS_CTS) ||
652 	     (series[2].RateFlags & HAL_RATESERIES_RTS_CTS) ||
653 	     (series[3].RateFlags & HAL_RATESERIES_RTS_CTS) )  &&
654 	    (ads->ds_ctl0 & AR_CTSEnable) == 0) {
655 		ads->ds_ctl0 |= AR_RTSEnable;
656 		ads->ds_ctl0 &= ~AR_CTSEnable;
657 	}
658 }
659 
660 void
661 ar5416Set11nAggrMiddle(struct ath_hal *ah, struct ath_desc *ds, u_int numDelims)
662 {
663 	struct ar5416_desc *ads = AR5416DESC(ds);
664 	uint32_t *ds_txstatus = AR5416_DS_TXSTATUS(ah,ads);
665 
666 	ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
667 
668 	ads->ds_ctl6 &= ~AR_PadDelim;
669 	ads->ds_ctl6 |= SM(numDelims, AR_PadDelim);
670 	ads->ds_ctl6 &= ~AR_AggrLen;
671 
672 	/*
673 	 * Clear the TxDone status here, may need to change
674 	 * func name to reflect this
675 	 */
676 	ds_txstatus[9] &= ~AR_TxDone;
677 }
678 
679 void
680 ar5416Clr11nAggr(struct ath_hal *ah, struct ath_desc *ds)
681 {
682 	struct ar5416_desc *ads = AR5416DESC(ds);
683 
684 	ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
685 	ads->ds_ctl6 &= ~AR_PadDelim;
686 	ads->ds_ctl6 &= ~AR_AggrLen;
687 }
688 
689 void
690 ar5416Set11nBurstDuration(struct ath_hal *ah, struct ath_desc *ds,
691                                                   u_int burstDuration)
692 {
693 	struct ar5416_desc *ads = AR5416DESC(ds);
694 
695 	ads->ds_ctl2 &= ~AR_BurstDur;
696 	ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
697 }
698 #endif
699