Home | History | Annotate | Line # | Download | only in ar5416
      1 /*
      2  * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
      3  * Copyright (c) 2002-2008 Atheros Communications, Inc.
      4  *
      5  * Permission to use, copy, modify, and/or distribute this software for any
      6  * purpose with or without fee is hereby granted, provided that the above
      7  * copyright notice and this permission notice appear in all copies.
      8  *
      9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     16  *
     17  * $Id: ar5416_xmit.c,v 1.1.1.1 2008/12/11 04:46:50 alc Exp $
     18  */
     19 #include "opt_ah.h"
     20 
     21 #include "ah.h"
     22 #include "ah_desc.h"
     23 #include "ah_internal.h"
     24 
     25 #include "ar5416/ar5416.h"
     26 #include "ar5416/ar5416reg.h"
     27 #include "ar5416/ar5416phy.h"
     28 #include "ar5416/ar5416desc.h"
     29 
     30 /*
     31  * Stop transmit on the specified queue
     32  */
     33 HAL_BOOL
     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 			HAL_TXSTAT_ALTRATE;
    524 		break;
    525 	case 2:
    526 		ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate2) |
    527 			HAL_TXSTAT_ALTRATE;
    528 		break;
    529 	case 3:
    530 		ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate3) |
    531 			HAL_TXSTAT_ALTRATE;
    532 		break;
    533 	}
    534 
    535 	ts->ts_rssi = MS(ds_txstatus[5], AR_TxRSSICombined);
    536 	ts->ts_rssi_ctl[0] = MS(ds_txstatus[0], AR_TxRSSIAnt00);
    537 	ts->ts_rssi_ctl[1] = MS(ds_txstatus[0], AR_TxRSSIAnt01);
    538 	ts->ts_rssi_ctl[2] = MS(ds_txstatus[0], AR_TxRSSIAnt02);
    539 	ts->ts_rssi_ext[0] = MS(ds_txstatus[5], AR_TxRSSIAnt10);
    540 	ts->ts_rssi_ext[1] = MS(ds_txstatus[5], AR_TxRSSIAnt11);
    541 	ts->ts_rssi_ext[2] = MS(ds_txstatus[5], AR_TxRSSIAnt12);
    542 	ts->ts_evm0 = AR_TxEVM0(ds_txstatus);
    543 	ts->ts_evm1 = AR_TxEVM1(ds_txstatus);
    544 	ts->ts_evm2 = AR_TxEVM2(ds_txstatus);
    545 
    546 	ts->ts_shortretry = MS(ds_txstatus[1], AR_RTSFailCnt);
    547 	ts->ts_longretry = MS(ds_txstatus[1], AR_DataFailCnt);
    548 	/*
    549 	 * The retry count has the number of un-acked tries for the
    550 	 * final series used.  When doing multi-rate retry we must
    551 	 * fixup the retry count by adding in the try counts for
    552 	 * each series that was fully-processed.  Beware that this
    553 	 * takes values from the try counts in the final descriptor.
    554 	 * These are not required by the hardware.  We assume they
    555 	 * are placed there by the driver as otherwise we have no
    556 	 * access and the driver can't do the calculation because it
    557 	 * doesn't know the descriptor format.
    558 	 */
    559 	switch (ts->ts_finaltsi) {
    560 	case 3: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries2);
    561 	case 2: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries1);
    562 	case 1: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries0);
    563 	}
    564 
    565 	/*
    566 	 * These fields are not used. Zero these to preserve compatability
    567 	 * with existing drivers.
    568 	 */
    569 	ts->ts_virtcol = MS(ads->ds_ctl1, AR_VirtRetryCnt);
    570 	ts->ts_antenna = 0; /* We don't switch antennas on Owl*/
    571 
    572 	/* handle tx trigger level changes internally */
    573 	if ((ts->ts_status & HAL_TXERR_FIFO) ||
    574 	    (ts->ts_flags & (HAL_TX_DATA_UNDERRUN | HAL_TX_DELIM_UNDERRUN)))
    575 		ar5212UpdateTxTrigLevel(ah, AH_TRUE);
    576 
    577 	return HAL_OK;
    578 }
    579 
    580 #if 0
    581 HAL_BOOL
    582 ar5416SetGlobalTxTimeout(struct ath_hal *ah, u_int tu)
    583 {
    584 	struct ath_hal_5416 *ahp = AH5416(ah);
    585 
    586 	if (tu > 0xFFFF) {
    587 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad global tx timeout %u\n",
    588 		    __func__, tu);
    589 		/* restore default handling */
    590 		ahp->ah_globaltxtimeout = (u_int) -1;
    591 		return AH_FALSE;
    592 	}
    593 	OS_REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
    594 	ahp->ah_globaltxtimeout = tu;
    595 	return AH_TRUE;
    596 }
    597 
    598 u_int
    599 ar5416GetGlobalTxTimeout(struct ath_hal *ah)
    600 {
    601 	return MS(OS_REG_READ(ah, AR_GTXTO), AR_GTXTO_TIMEOUT_LIMIT);
    602 }
    603 
    604 void
    605 ar5416Set11nRateScenario(struct ath_hal *ah, struct ath_desc *ds,
    606         u_int durUpdateEn, u_int rtsctsRate,
    607 	HAL_11N_RATE_SERIES series[], u_int nseries)
    608 {
    609 	struct ar5416_desc *ads = AR5416DESC(ds);
    610 
    611 	HALASSERT(nseries == 4);
    612 	(void)nseries;
    613 
    614 
    615 	ads->ds_ctl2 = set11nTries(series, 0)
    616 		     | set11nTries(series, 1)
    617 		     | set11nTries(series, 2)
    618 		     | set11nTries(series, 3)
    619 		     | (durUpdateEn ? AR_DurUpdateEn : 0);
    620 
    621 	ads->ds_ctl3 = set11nRate(series, 0)
    622 		     | set11nRate(series, 1)
    623 		     | set11nRate(series, 2)
    624 		     | set11nRate(series, 3);
    625 
    626 	ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
    627 		     | set11nPktDurRTSCTS(series, 1);
    628 
    629 	ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
    630 		     | set11nPktDurRTSCTS(series, 3);
    631 
    632 	ads->ds_ctl7 = set11nRateFlags(series, 0)
    633 		     | set11nRateFlags(series, 1)
    634 		     | set11nRateFlags(series, 2)
    635 		     | set11nRateFlags(series, 3)
    636 		     | SM(rtsctsRate, AR_RTSCTSRate);
    637 
    638 	/*
    639 	 * Enable RTSCTS if any of the series is flagged for RTSCTS,
    640 	 * but only if CTS is not enabled.
    641 	 */
    642 	/*
    643 	 * FIXME : the entire RTS/CTS handling should be moved to this
    644 	 * function (by passing the global RTS/CTS flags to this function).
    645 	 * currently it is split between this function and the
    646 	 * setupFiirstDescriptor. with this current implementation there
    647 	 * is an implicit assumption that setupFirstDescriptor is called
    648 	 * before this function.
    649 	 */
    650 	if (((series[0].RateFlags & HAL_RATESERIES_RTS_CTS) ||
    651 	     (series[1].RateFlags & HAL_RATESERIES_RTS_CTS) ||
    652 	     (series[2].RateFlags & HAL_RATESERIES_RTS_CTS) ||
    653 	     (series[3].RateFlags & HAL_RATESERIES_RTS_CTS) )  &&
    654 	    (ads->ds_ctl0 & AR_CTSEnable) == 0) {
    655 		ads->ds_ctl0 |= AR_RTSEnable;
    656 		ads->ds_ctl0 &= ~AR_CTSEnable;
    657 	}
    658 }
    659 
    660 void
    661 ar5416Set11nAggrMiddle(struct ath_hal *ah, struct ath_desc *ds, u_int numDelims)
    662 {
    663 	struct ar5416_desc *ads = AR5416DESC(ds);
    664 	uint32_t *ds_txstatus = AR5416_DS_TXSTATUS(ah,ads);
    665 
    666 	ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
    667 
    668 	ads->ds_ctl6 &= ~AR_PadDelim;
    669 	ads->ds_ctl6 |= SM(numDelims, AR_PadDelim);
    670 	ads->ds_ctl6 &= ~AR_AggrLen;
    671 
    672 	/*
    673 	 * Clear the TxDone status here, may need to change
    674 	 * func name to reflect this
    675 	 */
    676 	ds_txstatus[9] &= ~AR_TxDone;
    677 }
    678 
    679 void
    680 ar5416Clr11nAggr(struct ath_hal *ah, struct ath_desc *ds)
    681 {
    682 	struct ar5416_desc *ads = AR5416DESC(ds);
    683 
    684 	ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
    685 	ads->ds_ctl6 &= ~AR_PadDelim;
    686 	ads->ds_ctl6 &= ~AR_AggrLen;
    687 }
    688 
    689 void
    690 ar5416Set11nBurstDuration(struct ath_hal *ah, struct ath_desc *ds,
    691                                                   u_int burstDuration)
    692 {
    693 	struct ar5416_desc *ads = AR5416DESC(ds);
    694 
    695 	ads->ds_ctl2 &= ~AR_BurstDur;
    696 	ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
    697 }
    698 #endif
    699