2 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
3 * Copyright (c) 2002-2008 Atheros Communications, Inc.
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.
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.
17 * $Id: ar5416_xmit.c,v 1.1.1.1 2008/12/11 04:46:50 alc Exp $
23 #include "ah_internal.h"
25 #include "ar5416/ar5416.h"
26 #include "ar5416/ar5416reg.h"
27 #include "ar5416/ar5416phy.h"
28 #include "ar5416/ar5416desc.h"
31 * Stop transmit on the specified queue
34 ar5416StopTxDma(struct ath_hal
*ah
, u_int q
)
36 #define STOP_DMA_TIMEOUT 4000 /* us */
37 #define STOP_DMA_ITER 100 /* us */
40 HALASSERT(q
< AH_PRIVATE(ah
)->ah_caps
.halTotalQueues
);
42 HALASSERT(AH5212(ah
)->ah_txq
[q
].tqi_type
!= HAL_TX_QUEUE_INACTIVE
);
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)
48 OS_DELAY(STOP_DMA_ITER
);
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
));
66 /* ar5416 and up can kill packets at the PCU level */
67 if (ar5212NumTxPending(ah
, q
)) {
70 HALDEBUG(ah
, HAL_DEBUG_TXQUEUE
,
71 "%s: Num of pending TX Frames %d on Q %d\n",
72 __func__
, ar5212NumTxPending(ah
, q
), q
);
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
);
84 if ((OS_REG_READ(ah
, AR_TSF_L32
)>>10) == (tsfLow
>>10))
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 */
93 OS_REG_SET_BIT(ah
, AR_DIAG_SW
, AR_DIAG_CHAN_IDLE
);
95 /* Allow the quiet mechanism to do its work */
97 OS_REG_CLR_BIT(ah
, AR_TIMER_MODE
, AR_TIMER_MODE_QUIET
);
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)
103 OS_DELAY(STOP_DMA_ITER
);
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);
110 OS_REG_CLR_BIT(ah
, AR_DIAG_SW
, AR_DIAG_CHAN_IDLE
);
113 OS_REG_WRITE(ah
, AR_Q_TXD
, 0);
116 #undef STOP_DMA_TIMEOUT
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)
124 #define set11nTries(_series, _index) \
125 (SM((_series)[_index].Tries, AR_XmitDataTries##_index))
127 #define set11nRate(_series, _index) \
128 (SM((_series)[_index].Rate, AR_XmitRate##_index))
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))
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)
141 * Descriptor Access Functions
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)
156 ar5416SetupTxDesc(struct ath_hal
*ah
, struct ath_desc
*ds
,
161 u_int txRate0
, u_int txTries0
,
166 u_int rtsctsDuration
,
171 #define RTSCTS (HAL_TXDESC_RTSENA|HAL_TXDESC_CTSENA)
172 struct ar5416_desc
*ads
= AR5416DESC(ds
);
173 struct ath_hal_5416
*ahp
= AH5416(ah
);
177 HALASSERT(txTries0
!= 0);
178 HALASSERT(isValidPktType(type
));
179 HALASSERT(isValidTxRate(txRate0
));
180 HALASSERT((flags
& RTSCTS
) != RTSCTS
);
181 /* XXX validate antMode */
183 txPower
= (txPower
+ AH5212(ah
)->ah_txPowerIndexOffset
);
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)
193 ads
->ds_ctl1
= (type
<< AR_FrameType_S
)
194 | (flags
& HAL_TXDESC_NOACK
? AR_NoAck
: 0)
196 ads
->ds_ctl2
= SM(txTries0
, AR_XmitDataTries0
)
197 | (flags
& HAL_TXDESC_DURENA
? AR_DurUpdateEn
: 0)
199 ads
->ds_ctl3
= (txRate0
<< AR_XmitRate0_S
)
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
)
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
);
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
);
226 /* XXX validate rtsctsDuration */
227 ads
->ds_ctl0
|= (flags
& HAL_TXDESC_CTSENA
? AR_CTSEnable
: 0)
228 | (flags
& HAL_TXDESC_RTSENA
? AR_RTSEnable
: 0)
230 ads
->ds_ctl2
|= SM(rtsctsDuration
, AR_BurstDur
);
231 ads
->ds_ctl7
|= (rtsctsRate
<< AR_RTSCTSRate_S
);
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
)
243 struct ar5416_desc
*ads
= AR5416DESC(ds
);
246 HALASSERT(isValidTxRate(txRate1
));
247 ads
->ds_ctl2
|= SM(txTries1
, AR_XmitDataTries1
);
248 ads
->ds_ctl3
|= (txRate1
<< AR_XmitRate1_S
);
251 HALASSERT(isValidTxRate(txRate2
));
252 ads
->ds_ctl2
|= SM(txTries2
, AR_XmitDataTries2
);
253 ads
->ds_ctl3
|= (txRate2
<< AR_XmitRate2_S
);
256 HALASSERT(isValidTxRate(txRate3
));
257 ads
->ds_ctl2
|= SM(txTries3
, AR_XmitDataTries3
);
258 ads
->ds_ctl3
|= (txRate3
<< AR_XmitRate3_S
);
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
)
268 struct ar5416_desc
*ads
= AR5416DESC(ds
);
270 HALASSERT((segLen
&~ AR_BufLen
) == 0);
274 * First descriptor, don't clobber xmit control data
275 * setup by ar5212SetupTxDesc.
277 ads
->ds_ctl1
|= segLen
| (lastSeg
? 0 : AR_TxMore
);
278 } else if (lastSeg
) { /* !firstSeg && lastSeg */
280 * Last descriptor in a multi-descriptor frame,
281 * copy the multi-rate transmit parameters from
282 * the first frame for processing on completion.
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
);
290 ads
->ds_ctl2
= AR5416DESC_CONST(ds0
)->ds_ctl2
;
291 ads
->ds_ctl3
= AR5416DESC_CONST(ds0
)->ds_ctl3
;
293 } else { /* !firstSeg && !lastSeg */
295 * Intermediate descriptor in a multi-descriptor frame.
298 ads
->ds_ctl1
= segLen
| AR_TxMore
;
302 /* XXX only on last descriptor? */
303 OS_MEMZERO(ads
->u
.tx
.status
, sizeof(ads
->u
.tx
.status
));
310 ar5416ChainTxDesc(struct ath_hal
*ah
, struct ath_desc
*ds
,
321 struct ar5416_desc
*ads
= AR5416DESC(ds
);
322 uint32_t *ds_txstatus
= AR5416_DS_TXSTATUS(ah
,ads
);
329 HALASSERT((segLen
&~ AR_BufLen
) == 0);
331 HALASSERT(isValidPktType(type
));
332 if (type
== HAL_PKT_TYPE_AMPDU
) {
333 type
= HAL_PKT_TYPE_NORMAL
;
338 ath_hal_memzero(ds
->ds_hw
, AR5416_DESC_TX_CTL_SZ
);
341 ads
->ds_ctl0
= (pktLen
& AR_FrameLen
);
342 ads
->ds_ctl1
= (type
<< AR_FrameType_S
)
343 | (isaggr
? (AR_IsAggr
| AR_MoreAggr
) : 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
;
352 ads
->ds_ctl6
= SM(keyType
[cipher
], AR_EncrType
);
354 ads
->ds_ctl6
|= SM(delims
, AR_PadDelim
);
358 ads
->ds_ctl1
|= segLen
| (lastSeg
? 0 : AR_TxMore
);
359 } else if (lastSeg
) { /* !firstSeg && lastSeg */
361 ads
->ds_ctl1
|= segLen
;
362 } else { /* !firstSeg && !lastSeg */
364 * Intermediate descriptor in a multi-descriptor frame.
367 ads
->ds_ctl1
|= segLen
| AR_TxMore
;
369 ds_txstatus
[0] = ds_txstatus
[1] = 0;
370 ds_txstatus
[9] &= ~AR_TxDone
;
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
)
381 #define RTSCTS (HAL_TXDESC_RTSENA|HAL_TXDESC_CTSENA)
382 struct ar5416_desc
*ads
= AR5416DESC(ds
);
383 struct ath_hal_5212
*ahp
= AH5212(ah
);
385 HALASSERT(txTries0
!= 0);
386 HALASSERT(isValidTxRate(txRate0
));
387 HALASSERT((flags
& RTSCTS
) != RTSCTS
);
388 /* XXX validate antMode */
390 txPower
= (txPower
+ ahp
->ah_txPowerIndexOffset
);
391 if(txPower
> 63) txPower
=63;
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
);
407 ads
->ds_ctl9
= (txPower
<< 24);
408 ads
->ds_ctl10
= (txPower
<< 24);
409 ads
->ds_ctl11
= (txPower
<< 24);
411 ads
->ds_ctl6
&= ~(0xffff);
412 ads
->ds_ctl6
|= SM(aggrLen
, AR_AggrLen
);
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
);
426 ar5416SetupLastTxDesc(struct ath_hal
*ah
, struct ath_desc
*ds
,
427 const struct ath_desc
*ds0
)
429 struct ar5416_desc
*ads
= AR5416DESC(ds
);
431 ads
->ds_ctl1
&= ~AR_MoreAggr
;
432 ads
->ds_ctl6
&= ~AR_PadDelim
;
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
);
439 ads
->ds_ctl2
= AR5416DESC_CONST(ds0
)->ds_ctl2
;
440 ads
->ds_ctl3
= AR5416DESC_CONST(ds0
)->ds_ctl3
;
447 #ifdef AH_NEED_DESC_SWAP
448 /* Swap transmit descriptor */
450 ar5416SwapTxDesc(struct ath_desc
*ds
)
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]);
463 * Processing of HW TX descriptor.
466 ar5416ProcTxDesc(struct ath_hal
*ah
,
467 struct ath_desc
*ds
, struct ath_tx_status
*ts
)
469 struct ar5416_desc
*ads
= AR5416DESC(ds
);
470 uint32_t *ds_txstatus
= AR5416_DS_TXSTATUS(ah
,ads
);
472 #ifdef AH_NEED_DESC_SWAP
473 if ((ds_txstatus
[9] & __bswap32(AR_TxDone
)) == 0)
474 return HAL_EINPROGRESS
;
475 ar5416SwapTxDesc(ds
);
477 if ((ds_txstatus
[9] & AR_TxDone
) == 0)
478 return HAL_EINPROGRESS
;
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
);
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
;
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
);
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
;
513 * Extract the transmit rate used and mark the rate as
514 * ``alternate'' if it wasn't the series 0 rate.
516 ts
->ts_finaltsi
= MS(ds_txstatus
[9], AR_FinalTxIdx
);
517 switch (ts
->ts_finaltsi
) {
519 ts
->ts_rate
= MS(ads
->ds_ctl3
, AR_XmitRate0
);
522 ts
->ts_rate
= MS(ads
->ds_ctl3
, AR_XmitRate1
) |
526 ts
->ts_rate
= MS(ads
->ds_ctl3
, AR_XmitRate2
) |
530 ts
->ts_rate
= MS(ads
->ds_ctl3
, AR_XmitRate3
) |
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
);
546 ts
->ts_shortretry
= MS(ds_txstatus
[1], AR_RTSFailCnt
);
547 ts
->ts_longretry
= MS(ds_txstatus
[1], AR_DataFailCnt
);
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.
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
);
566 * These fields are not used. Zero these to preserve compatability
567 * with existing drivers.
569 ts
->ts_virtcol
= MS(ads
->ds_ctl1
, AR_VirtRetryCnt
);
570 ts
->ts_antenna
= 0; /* We don't switch antennas on Owl*/
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
);
582 ar5416SetGlobalTxTimeout(struct ath_hal
*ah
, u_int tu
)
584 struct ath_hal_5416
*ahp
= AH5416(ah
);
587 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: bad global tx timeout %u\n",
589 /* restore default handling */
590 ahp
->ah_globaltxtimeout
= (u_int
) -1;
593 OS_REG_RMW_FIELD(ah
, AR_GTXTO
, AR_GTXTO_TIMEOUT_LIMIT
, tu
);
594 ahp
->ah_globaltxtimeout
= tu
;
599 ar5416GetGlobalTxTimeout(struct ath_hal
*ah
)
601 return MS(OS_REG_READ(ah
, AR_GTXTO
), AR_GTXTO_TIMEOUT_LIMIT
);
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
)
609 struct ar5416_desc
*ads
= AR5416DESC(ds
);
611 HALASSERT(nseries
== 4);
615 ads
->ds_ctl2
= set11nTries(series
, 0)
616 | set11nTries(series
, 1)
617 | set11nTries(series
, 2)
618 | set11nTries(series
, 3)
619 | (durUpdateEn
? AR_DurUpdateEn
: 0);
621 ads
->ds_ctl3
= set11nRate(series
, 0)
622 | set11nRate(series
, 1)
623 | set11nRate(series
, 2)
624 | set11nRate(series
, 3);
626 ads
->ds_ctl4
= set11nPktDurRTSCTS(series
, 0)
627 | set11nPktDurRTSCTS(series
, 1);
629 ads
->ds_ctl5
= set11nPktDurRTSCTS(series
, 2)
630 | set11nPktDurRTSCTS(series
, 3);
632 ads
->ds_ctl7
= set11nRateFlags(series
, 0)
633 | set11nRateFlags(series
, 1)
634 | set11nRateFlags(series
, 2)
635 | set11nRateFlags(series
, 3)
636 | SM(rtsctsRate
, AR_RTSCTSRate
);
639 * Enable RTSCTS if any of the series is flagged for RTSCTS,
640 * but only if CTS is not enabled.
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.
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
;
661 ar5416Set11nAggrMiddle(struct ath_hal
*ah
, struct ath_desc
*ds
, u_int numDelims
)
663 struct ar5416_desc
*ads
= AR5416DESC(ds
);
664 uint32_t *ds_txstatus
= AR5416_DS_TXSTATUS(ah
,ads
);
666 ads
->ds_ctl1
|= (AR_IsAggr
| AR_MoreAggr
);
668 ads
->ds_ctl6
&= ~AR_PadDelim
;
669 ads
->ds_ctl6
|= SM(numDelims
, AR_PadDelim
);
670 ads
->ds_ctl6
&= ~AR_AggrLen
;
673 * Clear the TxDone status here, may need to change
674 * func name to reflect this
676 ds_txstatus
[9] &= ~AR_TxDone
;
680 ar5416Clr11nAggr(struct ath_hal
*ah
, struct ath_desc
*ds
)
682 struct ar5416_desc
*ads
= AR5416DESC(ds
);
684 ads
->ds_ctl1
&= (~AR_IsAggr
& ~AR_MoreAggr
);
685 ads
->ds_ctl6
&= ~AR_PadDelim
;
686 ads
->ds_ctl6
&= ~AR_AggrLen
;
690 ar5416Set11nBurstDuration(struct ath_hal
*ah
, struct ath_desc
*ds
,
693 struct ar5416_desc
*ads
= AR5416DESC(ds
);
695 ads
->ds_ctl2
&= ~AR_BurstDur
;
696 ads
->ds_ctl2
|= SM(burstDuration
, AR_BurstDur
);