netmap: d_poll -> d_kqfilter
[dragonfly.git] / sys / dev / netif / ath / hal / ath_hal / ar5416 / ar5416_xmit.c
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 194135 2009-06-13 23:36:54Z sam $
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
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
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
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
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
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
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                 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
578 HAL_BOOL
579 ar5416SetGlobalTxTimeout(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
595 u_int
596 ar5416GetGlobalTxTimeout(struct ath_hal *ah)
597 {
598         return MS(OS_REG_READ(ah, AR_GTXTO), AR_GTXTO_TIMEOUT_LIMIT);
599 }
600
601 void
602 ar5416Set11nRateScenario(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
657 void
658 ar5416Set11nAggrMiddle(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
676 void
677 ar5416Clr11nAggr(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
686 void
687 ar5416Set11nBurstDuration(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