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.
21 #ifdef AH_SUPPORT_AR5416
25 #include "ah_internal.h"
27 #include "ar5416/ar5416.h"
28 #include "ar5416/ar5416reg.h"
29 #include "ar5416/ar5416phy.h"
30 #include "ar5416/ar5416desc.h"
33 * Stop transmit on the specified queue
36 ar5416StopTxDma(struct ath_hal
*ah
, u_int q
)
38 #define STOP_DMA_TIMEOUT 4000 /* us */
39 #define STOP_DMA_ITER 100 /* us */
42 HALASSERT(q
< AH_PRIVATE(ah
)->ah_caps
.halTotalQueues
);
44 HALASSERT(AH5212(ah
)->ah_txq
[q
].tqi_type
!= HAL_TX_QUEUE_INACTIVE
);
46 OS_REG_WRITE(ah
, AR_Q_TXD
, 1 << q
);
47 for (i
= STOP_DMA_TIMEOUT
/STOP_DMA_ITER
; i
!= 0; i
--) {
48 if (ar5212NumTxPending(ah
, q
) == 0)
50 OS_DELAY(STOP_DMA_ITER
);
54 HALDEBUG(ah
, HAL_DEBUG_ANY
,
55 "%s: queue %u DMA did not stop in 400 msec\n", __func__
, q
);
56 HALDEBUG(ah
, HAL_DEBUG_ANY
,
57 "%s: QSTS 0x%x Q_TXE 0x%x Q_TXD 0x%x Q_CBR 0x%x\n", __func__
,
58 OS_REG_READ(ah
, AR_QSTS(q
)), OS_REG_READ(ah
, AR_Q_TXE
),
59 OS_REG_READ(ah
, AR_Q_TXD
), OS_REG_READ(ah
, AR_QCBRCFG(q
)));
60 HALDEBUG(ah
, HAL_DEBUG_ANY
,
61 "%s: Q_MISC 0x%x Q_RDYTIMECFG 0x%x Q_RDYTIMESHDN 0x%x\n",
62 __func__
, OS_REG_READ(ah
, AR_QMISC(q
)),
63 OS_REG_READ(ah
, AR_QRDYTIMECFG(q
)),
64 OS_REG_READ(ah
, AR_Q_RDYTIMESHDN
));
68 /* ar5416 and up can kill packets at the PCU level */
69 if (ar5212NumTxPending(ah
, q
)) {
72 HALDEBUG(ah
, HAL_DEBUG_TXQUEUE
,
73 "%s: Num of pending TX Frames %d on Q %d\n",
74 __func__
, ar5212NumTxPending(ah
, q
), q
);
76 /* Kill last PCU Tx Frame */
77 /* TODO - save off and restore current values of Q1/Q2? */
78 for (j
= 0; j
< 2; j
++) {
79 uint32_t tsfLow
= OS_REG_READ(ah
, AR_TSF_L32
);
80 OS_REG_WRITE(ah
, AR_QUIET2
,
81 SM(10, AR_QUIET2_QUIET_DUR
));
82 OS_REG_WRITE(ah
, AR_QUIET_PERIOD
, 100);
83 OS_REG_WRITE(ah
, AR_NEXT_QUIET
, tsfLow
>> 10);
84 OS_REG_SET_BIT(ah
, AR_TIMER_MODE
, AR_TIMER_MODE_QUIET
);
86 if ((OS_REG_READ(ah
, AR_TSF_L32
)>>10) == (tsfLow
>>10))
89 HALDEBUG(ah
, HAL_DEBUG_ANY
,
90 "%s: TSF moved while trying to set quiet time "
91 "TSF: 0x%08x\n", __func__
, tsfLow
);
92 HALASSERT(j
< 1); /* TSF shouldn't count twice or reg access is taking forever */
95 OS_REG_SET_BIT(ah
, AR_DIAG_SW
, AR_DIAG_CHAN_IDLE
);
97 /* Allow the quiet mechanism to do its work */
99 OS_REG_CLR_BIT(ah
, AR_TIMER_MODE
, AR_TIMER_MODE_QUIET
);
101 /* Verify the transmit q is empty */
102 for (i
= STOP_DMA_TIMEOUT
/STOP_DMA_ITER
; i
!= 0; i
--) {
103 if (ar5212NumTxPending(ah
, q
) == 0)
105 OS_DELAY(STOP_DMA_ITER
);
108 HALDEBUG(ah
, HAL_DEBUG_ANY
,
109 "%s: Failed to stop Tx DMA in %d msec after killing"
110 " last frame\n", __func__
, STOP_DMA_TIMEOUT
/ 1000);
112 OS_REG_CLR_BIT(ah
, AR_DIAG_SW
, AR_DIAG_CHAN_IDLE
);
115 OS_REG_WRITE(ah
, AR_Q_TXD
, 0);
118 #undef STOP_DMA_TIMEOUT
121 #define VALID_KEY_TYPES \
122 ((1 << HAL_KEY_TYPE_CLEAR) | (1 << HAL_KEY_TYPE_WEP)|\
123 (1 << HAL_KEY_TYPE_AES) | (1 << HAL_KEY_TYPE_TKIP))
124 #define isValidKeyType(_t) ((1 << (_t)) & VALID_KEY_TYPES)
126 #define set11nTries(_series, _index) \
127 (SM((_series)[_index].Tries, AR_XmitDataTries##_index))
129 #define set11nRate(_series, _index) \
130 (SM((_series)[_index].Rate, AR_XmitRate##_index))
132 #define set11nPktDurRTSCTS(_series, _index) \
133 (SM((_series)[_index].PktDuration, AR_PacketDur##_index) |\
134 ((_series)[_index].RateFlags & HAL_RATESERIES_RTS_CTS ?\
135 AR_RTSCTSQual##_index : 0))
137 #define set11nRateFlags(_series, _index) \
138 ((_series)[_index].RateFlags & HAL_RATESERIES_2040 ? AR_2040_##_index : 0) \
139 |((_series)[_index].RateFlags & HAL_RATESERIES_HALFGI ? AR_GI##_index : 0) \
140 |SM((_series)[_index].ChSel, AR_ChainSel##_index)
143 * Descriptor Access Functions
146 #define VALID_PKT_TYPES \
147 ((1<<HAL_PKT_TYPE_NORMAL)|(1<<HAL_PKT_TYPE_ATIM)|\
148 (1<<HAL_PKT_TYPE_PSPOLL)|(1<<HAL_PKT_TYPE_PROBE_RESP)|\
149 (1<<HAL_PKT_TYPE_BEACON)|(1<<HAL_PKT_TYPE_AMPDU))
150 #define isValidPktType(_t) ((1<<(_t)) & VALID_PKT_TYPES)
151 #define VALID_TX_RATES \
152 ((1<<0x0b)|(1<<0x0f)|(1<<0x0a)|(1<<0x0e)|(1<<0x09)|(1<<0x0d)|\
153 (1<<0x08)|(1<<0x0c)|(1<<0x1b)|(1<<0x1a)|(1<<0x1e)|(1<<0x19)|\
154 (1<<0x1d)|(1<<0x18)|(1<<0x1c))
155 #define isValidTxRate(_r) ((1<<(_r)) & VALID_TX_RATES)
158 ar5416SetupTxDesc(struct ath_hal
*ah
, struct ath_desc
*ds
,
163 u_int txRate0
, u_int txTries0
,
168 u_int rtsctsDuration
,
173 #define RTSCTS (HAL_TXDESC_RTSENA|HAL_TXDESC_CTSENA)
174 struct ar5416_desc
*ads
= AR5416DESC(ds
);
175 struct ath_hal_5416
*ahp
= AH5416(ah
);
179 HALASSERT(txTries0
!= 0);
180 HALASSERT(isValidPktType(type
));
181 HALASSERT(isValidTxRate(txRate0
));
182 HALASSERT((flags
& RTSCTS
) != RTSCTS
);
183 /* XXX validate antMode */
185 txPower
= (txPower
+ AH5212(ah
)->ah_txPowerIndexOffset
);
189 ads
->ds_ctl0
= (pktLen
& AR_FrameLen
)
190 | (txPower
<< AR_XmitPower_S
)
191 | (flags
& HAL_TXDESC_VEOL
? AR_VEOL
: 0)
192 | (flags
& HAL_TXDESC_CLRDMASK
? AR_ClrDestMask
: 0)
193 | (flags
& HAL_TXDESC_INTREQ
? AR_TxIntrReq
: 0)
195 ads
->ds_ctl1
= (type
<< AR_FrameType_S
)
196 | (flags
& HAL_TXDESC_NOACK
? AR_NoAck
: 0)
198 ads
->ds_ctl2
= SM(txTries0
, AR_XmitDataTries0
)
199 | (flags
& HAL_TXDESC_DURENA
? AR_DurUpdateEn
: 0)
201 ads
->ds_ctl3
= (txRate0
<< AR_XmitRate0_S
)
206 ads
->ds_ctl7
= SM(ahp
->ah_tx_chainmask
, AR_ChainSel0
)
207 | SM(ahp
->ah_tx_chainmask
, AR_ChainSel1
)
208 | SM(ahp
->ah_tx_chainmask
, AR_ChainSel2
)
209 | SM(ahp
->ah_tx_chainmask
, AR_ChainSel3
)
212 ads
->ds_ctl9
= (txPower
<< 24); /* XXX? */
213 ads
->ds_ctl10
= (txPower
<< 24); /* XXX? */
214 ads
->ds_ctl11
= (txPower
<< 24); /* XXX? */
215 if (keyIx
!= HAL_TXKEYIX_INVALID
) {
216 /* XXX validate key index */
217 ads
->ds_ctl1
|= SM(keyIx
, AR_DestIdx
);
218 ads
->ds_ctl0
|= AR_DestIdxValid
;
219 ads
->ds_ctl6
|= SM(ahp
->ah_keytype
[keyIx
], AR_EncrType
);
221 if (flags
& RTSCTS
) {
222 if (!isValidTxRate(rtsctsRate
)) {
223 HALDEBUG(ah
, HAL_DEBUG_ANY
,
224 "%s: invalid rts/cts rate 0x%x\n",
225 __func__
, rtsctsRate
);
228 /* XXX validate rtsctsDuration */
229 ads
->ds_ctl0
|= (flags
& HAL_TXDESC_CTSENA
? AR_CTSEnable
: 0)
230 | (flags
& HAL_TXDESC_RTSENA
? AR_RTSEnable
: 0)
232 ads
->ds_ctl2
|= SM(rtsctsDuration
, AR_BurstDur
);
233 ads
->ds_ctl7
|= (rtsctsRate
<< AR_RTSCTSRate_S
);
240 ar5416SetupXTxDesc(struct ath_hal
*ah
, struct ath_desc
*ds
,
241 u_int txRate1
, u_int txTries1
,
242 u_int txRate2
, u_int txTries2
,
243 u_int txRate3
, u_int txTries3
)
245 struct ar5416_desc
*ads
= AR5416DESC(ds
);
248 HALASSERT(isValidTxRate(txRate1
));
249 ads
->ds_ctl2
|= SM(txTries1
, AR_XmitDataTries1
);
250 ads
->ds_ctl3
|= (txRate1
<< AR_XmitRate1_S
);
253 HALASSERT(isValidTxRate(txRate2
));
254 ads
->ds_ctl2
|= SM(txTries2
, AR_XmitDataTries2
);
255 ads
->ds_ctl3
|= (txRate2
<< AR_XmitRate2_S
);
258 HALASSERT(isValidTxRate(txRate3
));
259 ads
->ds_ctl2
|= SM(txTries3
, AR_XmitDataTries3
);
260 ads
->ds_ctl3
|= (txRate3
<< AR_XmitRate3_S
);
266 ar5416FillTxDesc(struct ath_hal
*ah
, struct ath_desc
*ds
,
267 u_int segLen
, HAL_BOOL firstSeg
, HAL_BOOL lastSeg
,
268 const struct ath_desc
*ds0
)
270 struct ar5416_desc
*ads
= AR5416DESC(ds
);
272 HALASSERT((segLen
&~ AR_BufLen
) == 0);
276 * First descriptor, don't clobber xmit control data
277 * setup by ar5212SetupTxDesc.
279 ads
->ds_ctl1
|= segLen
| (lastSeg
? 0 : AR_TxMore
);
280 } else if (lastSeg
) { /* !firstSeg && lastSeg */
282 * Last descriptor in a multi-descriptor frame,
283 * copy the multi-rate transmit parameters from
284 * the first frame for processing on completion.
287 ads
->ds_ctl1
= segLen
;
288 #ifdef AH_NEED_DESC_SWAP
289 ads
->ds_ctl2
= __bswap32(AR5416DESC_CONST(ds0
)->ds_ctl2
);
290 ads
->ds_ctl3
= __bswap32(AR5416DESC_CONST(ds0
)->ds_ctl3
);
292 ads
->ds_ctl2
= AR5416DESC_CONST(ds0
)->ds_ctl2
;
293 ads
->ds_ctl3
= AR5416DESC_CONST(ds0
)->ds_ctl3
;
295 } else { /* !firstSeg && !lastSeg */
297 * Intermediate descriptor in a multi-descriptor frame.
300 ads
->ds_ctl1
= segLen
| AR_TxMore
;
304 /* XXX only on last descriptor? */
305 OS_MEMZERO(ads
->u
.tx
.status
, sizeof(ads
->u
.tx
.status
));
312 ar5416ChainTxDesc(struct ath_hal
*ah
, struct ath_desc
*ds
,
323 struct ar5416_desc
*ads
= AR5416DESC(ds
);
324 uint32_t *ds_txstatus
= AR5416_DS_TXSTATUS(ah
,ads
);
331 HALASSERT((segLen
&~ AR_BufLen
) == 0);
333 HALASSERT(isValidPktType(type
));
334 if (type
== HAL_PKT_TYPE_AMPDU
) {
335 type
= HAL_PKT_TYPE_NORMAL
;
340 ath_hal_memzero(ds
->ds_hw
, AR5416_DESC_TX_CTL_SZ
);
343 ads
->ds_ctl0
= (pktLen
& AR_FrameLen
);
344 ads
->ds_ctl1
= (type
<< AR_FrameType_S
)
345 | (isaggr
? (AR_IsAggr
| AR_MoreAggr
) : 0);
348 if (keyIx
!= HAL_TXKEYIX_INVALID
) {
349 /* XXX validate key index */
350 ads
->ds_ctl1
|= SM(keyIx
, AR_DestIdx
);
351 ads
->ds_ctl0
|= AR_DestIdxValid
;
354 ads
->ds_ctl6
= SM(keyType
[cipher
], AR_EncrType
);
356 ads
->ds_ctl6
|= SM(delims
, AR_PadDelim
);
360 ads
->ds_ctl1
|= segLen
| (lastSeg
? 0 : AR_TxMore
);
361 } else if (lastSeg
) { /* !firstSeg && lastSeg */
363 ads
->ds_ctl1
|= segLen
;
364 } else { /* !firstSeg && !lastSeg */
366 * Intermediate descriptor in a multi-descriptor frame.
369 ads
->ds_ctl1
|= segLen
| AR_TxMore
;
371 ds_txstatus
[0] = ds_txstatus
[1] = 0;
372 ds_txstatus
[9] &= ~AR_TxDone
;
378 ar5416SetupFirstTxDesc(struct ath_hal
*ah
, struct ath_desc
*ds
,
379 u_int aggrLen
, u_int flags
, u_int txPower
,
380 u_int txRate0
, u_int txTries0
, u_int antMode
,
381 u_int rtsctsRate
, u_int rtsctsDuration
)
383 #define RTSCTS (HAL_TXDESC_RTSENA|HAL_TXDESC_CTSENA)
384 struct ar5416_desc
*ads
= AR5416DESC(ds
);
385 struct ath_hal_5212
*ahp
= AH5212(ah
);
387 HALASSERT(txTries0
!= 0);
388 HALASSERT(isValidTxRate(txRate0
));
389 HALASSERT((flags
& RTSCTS
) != RTSCTS
);
390 /* XXX validate antMode */
392 txPower
= (txPower
+ ahp
->ah_txPowerIndexOffset
);
393 if(txPower
> 63) txPower
=63;
395 ads
->ds_ctl0
|= (txPower
<< AR_XmitPower_S
)
396 | (flags
& HAL_TXDESC_VEOL
? AR_VEOL
: 0)
397 | (flags
& HAL_TXDESC_CLRDMASK
? AR_ClrDestMask
: 0)
398 | (flags
& HAL_TXDESC_INTREQ
? AR_TxIntrReq
: 0);
399 ads
->ds_ctl1
|= (flags
& HAL_TXDESC_NOACK
? AR_NoAck
: 0);
400 ads
->ds_ctl2
|= SM(txTries0
, AR_XmitDataTries0
);
401 ads
->ds_ctl3
|= (txRate0
<< AR_XmitRate0_S
);
402 ads
->ds_ctl7
= SM(AH5416(ah
)->ah_tx_chainmask
, AR_ChainSel0
)
403 | SM(AH5416(ah
)->ah_tx_chainmask
, AR_ChainSel1
)
404 | SM(AH5416(ah
)->ah_tx_chainmask
, AR_ChainSel2
)
405 | SM(AH5416(ah
)->ah_tx_chainmask
, AR_ChainSel3
);
409 ads
->ds_ctl9
= (txPower
<< 24);
410 ads
->ds_ctl10
= (txPower
<< 24);
411 ads
->ds_ctl11
= (txPower
<< 24);
413 ads
->ds_ctl6
&= ~(0xffff);
414 ads
->ds_ctl6
|= SM(aggrLen
, AR_AggrLen
);
416 if (flags
& RTSCTS
) {
417 /* XXX validate rtsctsDuration */
418 ads
->ds_ctl0
|= (flags
& HAL_TXDESC_CTSENA
? AR_CTSEnable
: 0)
419 | (flags
& HAL_TXDESC_RTSENA
? AR_RTSEnable
: 0);
420 ads
->ds_ctl2
|= SM(rtsctsDuration
, AR_BurstDur
);
428 ar5416SetupLastTxDesc(struct ath_hal
*ah
, struct ath_desc
*ds
,
429 const struct ath_desc
*ds0
)
431 struct ar5416_desc
*ads
= AR5416DESC(ds
);
433 ads
->ds_ctl1
&= ~AR_MoreAggr
;
434 ads
->ds_ctl6
&= ~AR_PadDelim
;
436 /* hack to copy rate info to last desc for later processing */
437 #ifdef AH_NEED_DESC_SWAP
438 ads
->ds_ctl2
= __bswap32(AR5416DESC_CONST(ds0
)->ds_ctl2
);
439 ads
->ds_ctl3
= __bswap32(AR5416DESC_CONST(ds0
)->ds_ctl3
);
441 ads
->ds_ctl2
= AR5416DESC_CONST(ds0
)->ds_ctl2
;
442 ads
->ds_ctl3
= AR5416DESC_CONST(ds0
)->ds_ctl3
;
449 #ifdef AH_NEED_DESC_SWAP
450 /* Swap transmit descriptor */
452 ar5416SwapTxDesc(struct ath_desc
*ds
)
454 ds
->ds_data
= __bswap32(ds
->ds_data
);
455 ds
->ds_ctl0
= __bswap32(ds
->ds_ctl0
);
456 ds
->ds_ctl1
= __bswap32(ds
->ds_ctl1
);
457 ds
->ds_hw
[0] = __bswap32(ds
->ds_hw
[0]);
458 ds
->ds_hw
[1] = __bswap32(ds
->ds_hw
[1]);
459 ds
->ds_hw
[2] = __bswap32(ds
->ds_hw
[2]);
460 ds
->ds_hw
[3] = __bswap32(ds
->ds_hw
[3]);
465 * Processing of HW TX descriptor.
468 ar5416ProcTxDesc(struct ath_hal
*ah
,
469 struct ath_desc
*ds
, struct ath_tx_status
*ts
)
471 struct ar5416_desc
*ads
= AR5416DESC(ds
);
472 uint32_t *ds_txstatus
= AR5416_DS_TXSTATUS(ah
,ads
);
474 #ifdef AH_NEED_DESC_SWAP
475 if ((ds_txstatus
[9] & __bswap32(AR_TxDone
)) == 0)
476 return HAL_EINPROGRESS
;
477 ar5416SwapTxDesc(ds
);
479 if ((ds_txstatus
[9] & AR_TxDone
) == 0)
480 return HAL_EINPROGRESS
;
483 /* Update software copies of the HW status */
484 ts
->ts_seqnum
= MS(ds_txstatus
[9], AR_SeqNum
);
485 ts
->ts_tstamp
= AR_SendTimestamp(ds_txstatus
);
488 if (ds_txstatus
[1] & AR_ExcessiveRetries
)
489 ts
->ts_status
|= HAL_TXERR_XRETRY
;
490 if (ds_txstatus
[1] & AR_Filtered
)
491 ts
->ts_status
|= HAL_TXERR_FILT
;
492 if (ds_txstatus
[1] & AR_FIFOUnderrun
)
493 ts
->ts_status
|= HAL_TXERR_FIFO
;
494 if (ds_txstatus
[9] & AR_TxOpExceeded
)
495 ts
->ts_status
|= HAL_TXERR_XTXOP
;
496 if (ds_txstatus
[1] & AR_TxTimerExpired
)
497 ts
->ts_status
|= HAL_TXERR_TIMER_EXPIRED
;
500 if (ds_txstatus
[0] & AR_TxBaStatus
) {
501 ts
->ts_flags
|= HAL_TX_BA
;
502 ts
->ts_ba_low
= AR_BaBitmapLow(ds_txstatus
);
503 ts
->ts_ba_high
= AR_BaBitmapHigh(ds_txstatus
);
505 if (ds
->ds_ctl1
& AR_IsAggr
)
506 ts
->ts_flags
|= HAL_TX_AGGR
;
507 if (ds_txstatus
[1] & AR_DescCfgErr
)
508 ts
->ts_flags
|= HAL_TX_DESC_CFG_ERR
;
509 if (ds_txstatus
[1] & AR_TxDataUnderrun
)
510 ts
->ts_flags
|= HAL_TX_DATA_UNDERRUN
;
511 if (ds_txstatus
[1] & AR_TxDelimUnderrun
)
512 ts
->ts_flags
|= HAL_TX_DELIM_UNDERRUN
;
515 * Extract the transmit rate used and mark the rate as
516 * ``alternate'' if it wasn't the series 0 rate.
518 ts
->ts_finaltsi
= MS(ds_txstatus
[9], AR_FinalTxIdx
);
519 switch (ts
->ts_finaltsi
) {
521 ts
->ts_rate
= MS(ads
->ds_ctl3
, AR_XmitRate0
);
524 ts
->ts_rate
= MS(ads
->ds_ctl3
, AR_XmitRate1
) |
528 ts
->ts_rate
= MS(ads
->ds_ctl3
, AR_XmitRate2
) |
532 ts
->ts_rate
= MS(ads
->ds_ctl3
, AR_XmitRate3
) |
537 ts
->ts_rssi
= MS(ds_txstatus
[5], AR_TxRSSICombined
);
538 ts
->ts_rssi_ctl
[0] = MS(ds_txstatus
[0], AR_TxRSSIAnt00
);
539 ts
->ts_rssi_ctl
[1] = MS(ds_txstatus
[0], AR_TxRSSIAnt01
);
540 ts
->ts_rssi_ctl
[2] = MS(ds_txstatus
[0], AR_TxRSSIAnt02
);
541 ts
->ts_rssi_ext
[0] = MS(ds_txstatus
[5], AR_TxRSSIAnt10
);
542 ts
->ts_rssi_ext
[1] = MS(ds_txstatus
[5], AR_TxRSSIAnt11
);
543 ts
->ts_rssi_ext
[2] = MS(ds_txstatus
[5], AR_TxRSSIAnt12
);
544 ts
->ts_evm0
= AR_TxEVM0(ds_txstatus
);
545 ts
->ts_evm1
= AR_TxEVM1(ds_txstatus
);
546 ts
->ts_evm2
= AR_TxEVM2(ds_txstatus
);
548 ts
->ts_shortretry
= MS(ds_txstatus
[1], AR_RTSFailCnt
);
549 ts
->ts_longretry
= MS(ds_txstatus
[1], AR_DataFailCnt
);
551 * The retry count has the number of un-acked tries for the
552 * final series used. When doing multi-rate retry we must
553 * fixup the retry count by adding in the try counts for
554 * each series that was fully-processed. Beware that this
555 * takes values from the try counts in the final descriptor.
556 * These are not required by the hardware. We assume they
557 * are placed there by the driver as otherwise we have no
558 * access and the driver can't do the calculation because it
559 * doesn't know the descriptor format.
561 switch (ts
->ts_finaltsi
) {
562 case 3: ts
->ts_longretry
+= MS(ads
->ds_ctl2
, AR_XmitDataTries2
);
563 case 2: ts
->ts_longretry
+= MS(ads
->ds_ctl2
, AR_XmitDataTries1
);
564 case 1: ts
->ts_longretry
+= MS(ads
->ds_ctl2
, AR_XmitDataTries0
);
568 * These fields are not used. Zero these to preserve compatability
569 * with existing drivers.
571 ts
->ts_virtcol
= MS(ads
->ds_ctl1
, AR_VirtRetryCnt
);
572 ts
->ts_antenna
= 0; /* We don't switch antennas on Owl*/
574 /* handle tx trigger level changes internally */
575 if ((ts
->ts_status
& HAL_TXERR_FIFO
) ||
576 (ts
->ts_flags
& (HAL_TX_DATA_UNDERRUN
| HAL_TX_DELIM_UNDERRUN
)))
577 ar5212UpdateTxTrigLevel(ah
, AH_TRUE
);
584 ar5416SetGlobalTxTimeout(struct ath_hal
*ah
, u_int tu
)
586 struct ath_hal_5416
*ahp
= AH5416(ah
);
589 HALDEBUG(ah
, HAL_DEBUG_ANY
, "%s: bad global tx timeout %u\n",
591 /* restore default handling */
592 ahp
->ah_globaltxtimeout
= (u_int
) -1;
595 OS_REG_RMW_FIELD(ah
, AR_GTXTO
, AR_GTXTO_TIMEOUT_LIMIT
, tu
);
596 ahp
->ah_globaltxtimeout
= tu
;
601 ar5416GetGlobalTxTimeout(struct ath_hal
*ah
)
603 return MS(OS_REG_READ(ah
, AR_GTXTO
), AR_GTXTO_TIMEOUT_LIMIT
);
607 ar5416Set11nRateScenario(struct ath_hal
*ah
, struct ath_desc
*ds
,
608 u_int durUpdateEn
, u_int rtsctsRate
,
609 HAL_11N_RATE_SERIES series
[], u_int nseries
)
611 struct ar5416_desc
*ads
= AR5416DESC(ds
);
613 HALASSERT(nseries
== 4);
617 ads
->ds_ctl2
= set11nTries(series
, 0)
618 | set11nTries(series
, 1)
619 | set11nTries(series
, 2)
620 | set11nTries(series
, 3)
621 | (durUpdateEn
? AR_DurUpdateEn
: 0);
623 ads
->ds_ctl3
= set11nRate(series
, 0)
624 | set11nRate(series
, 1)
625 | set11nRate(series
, 2)
626 | set11nRate(series
, 3);
628 ads
->ds_ctl4
= set11nPktDurRTSCTS(series
, 0)
629 | set11nPktDurRTSCTS(series
, 1);
631 ads
->ds_ctl5
= set11nPktDurRTSCTS(series
, 2)
632 | set11nPktDurRTSCTS(series
, 3);
634 ads
->ds_ctl7
= set11nRateFlags(series
, 0)
635 | set11nRateFlags(series
, 1)
636 | set11nRateFlags(series
, 2)
637 | set11nRateFlags(series
, 3)
638 | SM(rtsctsRate
, AR_RTSCTSRate
);
641 * Enable RTSCTS if any of the series is flagged for RTSCTS,
642 * but only if CTS is not enabled.
645 * FIXME : the entire RTS/CTS handling should be moved to this
646 * function (by passing the global RTS/CTS flags to this function).
647 * currently it is split between this function and the
648 * setupFiirstDescriptor. with this current implementation there
649 * is an implicit assumption that setupFirstDescriptor is called
650 * before this function.
652 if (((series
[0].RateFlags
& HAL_RATESERIES_RTS_CTS
) ||
653 (series
[1].RateFlags
& HAL_RATESERIES_RTS_CTS
) ||
654 (series
[2].RateFlags
& HAL_RATESERIES_RTS_CTS
) ||
655 (series
[3].RateFlags
& HAL_RATESERIES_RTS_CTS
) ) &&
656 (ads
->ds_ctl0
& AR_CTSEnable
) == 0) {
657 ads
->ds_ctl0
|= AR_RTSEnable
;
658 ads
->ds_ctl0
&= ~AR_CTSEnable
;
663 ar5416Set11nAggrMiddle(struct ath_hal
*ah
, struct ath_desc
*ds
, u_int numDelims
)
665 struct ar5416_desc
*ads
= AR5416DESC(ds
);
666 uint32_t *ds_txstatus
= AR5416_DS_TXSTATUS(ah
,ads
);
668 ads
->ds_ctl1
|= (AR_IsAggr
| AR_MoreAggr
);
670 ads
->ds_ctl6
&= ~AR_PadDelim
;
671 ads
->ds_ctl6
|= SM(numDelims
, AR_PadDelim
);
672 ads
->ds_ctl6
&= ~AR_AggrLen
;
675 * Clear the TxDone status here, may need to change
676 * func name to reflect this
678 ds_txstatus
[9] &= ~AR_TxDone
;
682 ar5416Clr11nAggr(struct ath_hal
*ah
, struct ath_desc
*ds
)
684 struct ar5416_desc
*ads
= AR5416DESC(ds
);
686 ads
->ds_ctl1
&= (~AR_IsAggr
& ~AR_MoreAggr
);
687 ads
->ds_ctl6
&= ~AR_PadDelim
;
688 ads
->ds_ctl6
&= ~AR_AggrLen
;
692 ar5416Set11nBurstDuration(struct ath_hal
*ah
, struct ath_desc
*ds
,
695 struct ar5416_desc
*ads
= AR5416DESC(ds
);
697 ads
->ds_ctl2
&= ~AR_BurstDur
;
698 ads
->ds_ctl2
|= SM(burstDuration
, AR_BurstDur
);
701 #endif /* AH_SUPPORT_AR5416 */