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