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