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