ar5416_xmit.c revision 218067
1/* 2 * Copyright (c) 2002-2009 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 * $FreeBSD: head/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c 218067 2011-01-29 12:30:13Z adrian $ 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 */ 33HAL_BOOL 34ar5416StopTxDma(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 155HAL_BOOL 156ar5416SetupTxDesc(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 234 if (AR_SREV_KITE(ah)) { 235 ads->ds_ctl8 = 0; 236 ads->ds_ctl9 = 0; 237 ads->ds_ctl10 = 0; 238 ads->ds_ctl11 = 0; 239 } 240 return AH_TRUE; 241#undef RTSCTS 242} 243 244HAL_BOOL 245ar5416SetupXTxDesc(struct ath_hal *ah, struct ath_desc *ds, 246 u_int txRate1, u_int txTries1, 247 u_int txRate2, u_int txTries2, 248 u_int txRate3, u_int txTries3) 249{ 250 struct ar5416_desc *ads = AR5416DESC(ds); 251 252 if (txTries1) { 253 HALASSERT(isValidTxRate(txRate1)); 254 ads->ds_ctl2 |= SM(txTries1, AR_XmitDataTries1); 255 ads->ds_ctl3 |= (txRate1 << AR_XmitRate1_S); 256 } 257 if (txTries2) { 258 HALASSERT(isValidTxRate(txRate2)); 259 ads->ds_ctl2 |= SM(txTries2, AR_XmitDataTries2); 260 ads->ds_ctl3 |= (txRate2 << AR_XmitRate2_S); 261 } 262 if (txTries3) { 263 HALASSERT(isValidTxRate(txRate3)); 264 ads->ds_ctl2 |= SM(txTries3, AR_XmitDataTries3); 265 ads->ds_ctl3 |= (txRate3 << AR_XmitRate3_S); 266 } 267 return AH_TRUE; 268} 269 270HAL_BOOL 271ar5416FillTxDesc(struct ath_hal *ah, struct ath_desc *ds, 272 u_int segLen, HAL_BOOL firstSeg, HAL_BOOL lastSeg, 273 const struct ath_desc *ds0) 274{ 275 struct ar5416_desc *ads = AR5416DESC(ds); 276 277 HALASSERT((segLen &~ AR_BufLen) == 0); 278 279 if (firstSeg) { 280 /* 281 * First descriptor, don't clobber xmit control data 282 * setup by ar5212SetupTxDesc. 283 */ 284 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore); 285 } else if (lastSeg) { /* !firstSeg && lastSeg */ 286 /* 287 * Last descriptor in a multi-descriptor frame, 288 * copy the multi-rate transmit parameters from 289 * the first frame for processing on completion. 290 */ 291 ads->ds_ctl0 = 0; 292 ads->ds_ctl1 = segLen; 293#ifdef AH_NEED_DESC_SWAP 294 ads->ds_ctl2 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl2); 295 ads->ds_ctl3 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl3); 296#else 297 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2; 298 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3; 299#endif 300 } else { /* !firstSeg && !lastSeg */ 301 /* 302 * Intermediate descriptor in a multi-descriptor frame. 303 */ 304 ads->ds_ctl0 = 0; 305 ads->ds_ctl1 = segLen | AR_TxMore; 306 ads->ds_ctl2 = 0; 307 ads->ds_ctl3 = 0; 308 } 309 /* XXX only on last descriptor? */ 310 OS_MEMZERO(ads->u.tx.status, sizeof(ads->u.tx.status)); 311 return AH_TRUE; 312} 313 314HAL_BOOL 315ar5416ChainTxDesc(struct ath_hal *ah, struct ath_desc *ds, 316 u_int pktLen, 317 u_int hdrLen, 318 HAL_PKT_TYPE type, 319 u_int keyIx, 320 HAL_CIPHER cipher, 321 uint8_t delims, 322 u_int segLen, 323 HAL_BOOL firstSeg, 324 HAL_BOOL lastSeg) 325{ 326 struct ar5416_desc *ads = AR5416DESC(ds); 327 uint32_t *ds_txstatus = AR5416_DS_TXSTATUS(ah,ads); 328 struct ath_hal_5416 *ahp = AH5416(ah); 329 330 int isaggr = 0; 331 332 (void) hdrLen; 333 (void) ah; 334 335 HALASSERT((segLen &~ AR_BufLen) == 0); 336 337 HALASSERT(isValidPktType(type)); 338 if (type == HAL_PKT_TYPE_AMPDU) { 339 type = HAL_PKT_TYPE_NORMAL; 340 isaggr = 1; 341 } 342 343 if (!firstSeg) { 344 OS_MEMZERO(ds->ds_hw, AR5416_DESC_TX_CTL_SZ); 345 } 346 347 ads->ds_ctl0 = (pktLen & AR_FrameLen); 348 ads->ds_ctl1 = (type << AR_FrameType_S) 349 | (isaggr ? (AR_IsAggr | AR_MoreAggr) : 0); 350 ads->ds_ctl2 = 0; 351 ads->ds_ctl3 = 0; 352 if (keyIx != HAL_TXKEYIX_INVALID) { 353 /* XXX validate key index */ 354 ads->ds_ctl1 |= SM(keyIx, AR_DestIdx); 355 ads->ds_ctl0 |= AR_DestIdxValid; 356 } 357 358 ads->ds_ctl6 = SM(ahp->ah_keytype[cipher], AR_EncrType); 359 if (isaggr) { 360 ads->ds_ctl6 |= SM(delims, AR_PadDelim); 361 } 362 363 if (firstSeg) { 364 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore); 365 } else if (lastSeg) { /* !firstSeg && lastSeg */ 366 ads->ds_ctl0 = 0; 367 ads->ds_ctl1 |= segLen; 368 } else { /* !firstSeg && !lastSeg */ 369 /* 370 * Intermediate descriptor in a multi-descriptor frame. 371 */ 372 ads->ds_ctl0 = 0; 373 ads->ds_ctl1 |= segLen | AR_TxMore; 374 } 375 ds_txstatus[0] = ds_txstatus[1] = 0; 376 ds_txstatus[9] &= ~AR_TxDone; 377 378 return AH_TRUE; 379} 380 381HAL_BOOL 382ar5416SetupFirstTxDesc(struct ath_hal *ah, struct ath_desc *ds, 383 u_int aggrLen, u_int flags, u_int txPower, 384 u_int txRate0, u_int txTries0, u_int antMode, 385 u_int rtsctsRate, u_int rtsctsDuration) 386{ 387#define RTSCTS (HAL_TXDESC_RTSENA|HAL_TXDESC_CTSENA) 388 struct ar5416_desc *ads = AR5416DESC(ds); 389 struct ath_hal_5212 *ahp = AH5212(ah); 390 391 HALASSERT(txTries0 != 0); 392 HALASSERT(isValidTxRate(txRate0)); 393 HALASSERT((flags & RTSCTS) != RTSCTS); 394 /* XXX validate antMode */ 395 396 txPower = (txPower + ahp->ah_txPowerIndexOffset ); 397 if(txPower > 63) txPower=63; 398 399 ads->ds_ctl0 |= (txPower << AR_XmitPower_S) 400 | (flags & HAL_TXDESC_VEOL ? AR_VEOL : 0) 401 | (flags & HAL_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) 402 | (flags & HAL_TXDESC_INTREQ ? AR_TxIntrReq : 0); 403 ads->ds_ctl1 |= (flags & HAL_TXDESC_NOACK ? AR_NoAck : 0); 404 ads->ds_ctl2 |= SM(txTries0, AR_XmitDataTries0); 405 ads->ds_ctl3 |= (txRate0 << AR_XmitRate0_S); 406 ads->ds_ctl7 = SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel0) 407 | SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel1) 408 | SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel2) 409 | SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel3); 410 411 /* NB: no V1 WAR */ 412 ads->ds_ctl8 = 0; 413 ads->ds_ctl9 = (txPower << 24); 414 ads->ds_ctl10 = (txPower << 24); 415 ads->ds_ctl11 = (txPower << 24); 416 417 ads->ds_ctl6 &= ~(0xffff); 418 ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen); 419 420 if (flags & RTSCTS) { 421 /* XXX validate rtsctsDuration */ 422 ads->ds_ctl0 |= (flags & HAL_TXDESC_CTSENA ? AR_CTSEnable : 0) 423 | (flags & HAL_TXDESC_RTSENA ? AR_RTSEnable : 0); 424 ads->ds_ctl2 |= SM(rtsctsDuration, AR_BurstDur); 425 } 426 427 if (AR_SREV_KITE(ah)) { 428 ads->ds_ctl8 = 0; 429 ads->ds_ctl9 = 0; 430 ads->ds_ctl10 = 0; 431 ads->ds_ctl11 = 0; 432 } 433 434 return AH_TRUE; 435#undef RTSCTS 436} 437 438HAL_BOOL 439ar5416SetupLastTxDesc(struct ath_hal *ah, struct ath_desc *ds, 440 const struct ath_desc *ds0) 441{ 442 struct ar5416_desc *ads = AR5416DESC(ds); 443 444 ads->ds_ctl1 &= ~AR_MoreAggr; 445 ads->ds_ctl6 &= ~AR_PadDelim; 446 447 /* hack to copy rate info to last desc for later processing */ 448#ifdef AH_NEED_DESC_SWAP 449 ads->ds_ctl2 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl2); 450 ads->ds_ctl3 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl3); 451#else 452 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2; 453 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3; 454#endif 455 456 return AH_TRUE; 457} 458 459#ifdef AH_NEED_DESC_SWAP 460/* Swap transmit descriptor */ 461static __inline void 462ar5416SwapTxDesc(struct ath_desc *ds) 463{ 464 ds->ds_data = __bswap32(ds->ds_data); 465 ds->ds_ctl0 = __bswap32(ds->ds_ctl0); 466 ds->ds_ctl1 = __bswap32(ds->ds_ctl1); 467 ds->ds_hw[0] = __bswap32(ds->ds_hw[0]); 468 ds->ds_hw[1] = __bswap32(ds->ds_hw[1]); 469 ds->ds_hw[2] = __bswap32(ds->ds_hw[2]); 470 ds->ds_hw[3] = __bswap32(ds->ds_hw[3]); 471} 472#endif 473 474/* 475 * Processing of HW TX descriptor. 476 */ 477HAL_STATUS 478ar5416ProcTxDesc(struct ath_hal *ah, 479 struct ath_desc *ds, struct ath_tx_status *ts) 480{ 481 struct ar5416_desc *ads = AR5416DESC(ds); 482 uint32_t *ds_txstatus = AR5416_DS_TXSTATUS(ah,ads); 483 484#ifdef AH_NEED_DESC_SWAP 485 if ((ds_txstatus[9] & __bswap32(AR_TxDone)) == 0) 486 return HAL_EINPROGRESS; 487 ar5416SwapTxDesc(ds); 488#else 489 if ((ds_txstatus[9] & AR_TxDone) == 0) 490 return HAL_EINPROGRESS; 491#endif 492 493 /* Update software copies of the HW status */ 494 ts->ts_seqnum = MS(ds_txstatus[9], AR_SeqNum); 495 ts->ts_tstamp = AR_SendTimestamp(ds_txstatus); 496 497 ts->ts_status = 0; 498 if (ds_txstatus[1] & AR_ExcessiveRetries) 499 ts->ts_status |= HAL_TXERR_XRETRY; 500 if (ds_txstatus[1] & AR_Filtered) 501 ts->ts_status |= HAL_TXERR_FILT; 502 if (ds_txstatus[1] & AR_FIFOUnderrun) 503 ts->ts_status |= HAL_TXERR_FIFO; 504 if (ds_txstatus[9] & AR_TxOpExceeded) 505 ts->ts_status |= HAL_TXERR_XTXOP; 506 if (ds_txstatus[1] & AR_TxTimerExpired) 507 ts->ts_status |= HAL_TXERR_TIMER_EXPIRED; 508 509 ts->ts_flags = 0; 510 if (ds_txstatus[0] & AR_TxBaStatus) { 511 ts->ts_flags |= HAL_TX_BA; 512 ts->ts_ba_low = AR_BaBitmapLow(ds_txstatus); 513 ts->ts_ba_high = AR_BaBitmapHigh(ds_txstatus); 514 } 515 if (ds->ds_ctl1 & AR_IsAggr) 516 ts->ts_flags |= HAL_TX_AGGR; 517 if (ds_txstatus[1] & AR_DescCfgErr) 518 ts->ts_flags |= HAL_TX_DESC_CFG_ERR; 519 if (ds_txstatus[1] & AR_TxDataUnderrun) 520 ts->ts_flags |= HAL_TX_DATA_UNDERRUN; 521 if (ds_txstatus[1] & AR_TxDelimUnderrun) 522 ts->ts_flags |= HAL_TX_DELIM_UNDERRUN; 523 524 /* 525 * Extract the transmit rate used and mark the rate as 526 * ``alternate'' if it wasn't the series 0 rate. 527 */ 528 ts->ts_finaltsi = MS(ds_txstatus[9], AR_FinalTxIdx); 529 switch (ts->ts_finaltsi) { 530 case 0: 531 ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate0); 532 break; 533 case 1: 534 ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate1); 535 break; 536 case 2: 537 ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate2); 538 break; 539 case 3: 540 ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate3); 541 break; 542 } 543 544 ts->ts_rssi = MS(ds_txstatus[5], AR_TxRSSICombined); 545 ts->ts_rssi_ctl[0] = MS(ds_txstatus[0], AR_TxRSSIAnt00); 546 ts->ts_rssi_ctl[1] = MS(ds_txstatus[0], AR_TxRSSIAnt01); 547 ts->ts_rssi_ctl[2] = MS(ds_txstatus[0], AR_TxRSSIAnt02); 548 ts->ts_rssi_ext[0] = MS(ds_txstatus[5], AR_TxRSSIAnt10); 549 ts->ts_rssi_ext[1] = MS(ds_txstatus[5], AR_TxRSSIAnt11); 550 ts->ts_rssi_ext[2] = MS(ds_txstatus[5], AR_TxRSSIAnt12); 551 ts->ts_evm0 = AR_TxEVM0(ds_txstatus); 552 ts->ts_evm1 = AR_TxEVM1(ds_txstatus); 553 ts->ts_evm2 = AR_TxEVM2(ds_txstatus); 554 555 ts->ts_shortretry = MS(ds_txstatus[1], AR_RTSFailCnt); 556 ts->ts_longretry = MS(ds_txstatus[1], AR_DataFailCnt); 557 /* 558 * The retry count has the number of un-acked tries for the 559 * final series used. When doing multi-rate retry we must 560 * fixup the retry count by adding in the try counts for 561 * each series that was fully-processed. Beware that this 562 * takes values from the try counts in the final descriptor. 563 * These are not required by the hardware. We assume they 564 * are placed there by the driver as otherwise we have no 565 * access and the driver can't do the calculation because it 566 * doesn't know the descriptor format. 567 */ 568 switch (ts->ts_finaltsi) { 569 case 3: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries2); 570 case 2: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries1); 571 case 1: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries0); 572 } 573 574 /* 575 * These fields are not used. Zero these to preserve compatability 576 * with existing drivers. 577 */ 578 ts->ts_virtcol = MS(ads->ds_ctl1, AR_VirtRetryCnt); 579 ts->ts_antenna = 0; /* We don't switch antennas on Owl*/ 580 581 /* handle tx trigger level changes internally */ 582 if ((ts->ts_status & HAL_TXERR_FIFO) || 583 (ts->ts_flags & (HAL_TX_DATA_UNDERRUN | HAL_TX_DELIM_UNDERRUN))) 584 ar5212UpdateTxTrigLevel(ah, AH_TRUE); 585 586 return HAL_OK; 587} 588 589HAL_BOOL 590ar5416SetGlobalTxTimeout(struct ath_hal *ah, u_int tu) 591{ 592 struct ath_hal_5416 *ahp = AH5416(ah); 593 594 if (tu > 0xFFFF) { 595 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad global tx timeout %u\n", 596 __func__, tu); 597 /* restore default handling */ 598 ahp->ah_globaltxtimeout = (u_int) -1; 599 return AH_FALSE; 600 } 601 OS_REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu); 602 ahp->ah_globaltxtimeout = tu; 603 return AH_TRUE; 604} 605 606u_int 607ar5416GetGlobalTxTimeout(struct ath_hal *ah) 608{ 609 return MS(OS_REG_READ(ah, AR_GTXTO), AR_GTXTO_TIMEOUT_LIMIT); 610} 611 612void 613ar5416Set11nRateScenario(struct ath_hal *ah, struct ath_desc *ds, 614 u_int durUpdateEn, u_int rtsctsRate, 615 HAL_11N_RATE_SERIES series[], u_int nseries, u_int flags) 616{ 617 struct ar5416_desc *ads = AR5416DESC(ds); 618 uint32_t ds_ctl0; 619 620 HALASSERT(nseries == 4); 621 (void)nseries; 622 623 /* 624 * Only one of RTS and CTS enable must be set. 625 * If a frame has both set, just do RTS protection - 626 * that's enough to satisfy legacy protection. 627 */ 628 if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) { 629 ds_ctl0 = ads->ds_ctl0; 630 631 if (flags & HAL_TXDESC_RTSENA) { 632 ds_ctl0 &= ~AR_CTSEnable; 633 ds_ctl0 |= AR_RTSEnable; 634 } else { 635 ds_ctl0 &= ~AR_RTSEnable; 636 ds_ctl0 |= AR_CTSEnable; 637 } 638 639 ads->ds_ctl0 = ds_ctl0; 640 } else { 641 ads->ds_ctl0 = 642 (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable)); 643 } 644 645 646 ads->ds_ctl2 = set11nTries(series, 0) 647 | set11nTries(series, 1) 648 | set11nTries(series, 2) 649 | set11nTries(series, 3) 650 | (durUpdateEn ? AR_DurUpdateEn : 0); 651 652 ads->ds_ctl3 = set11nRate(series, 0) 653 | set11nRate(series, 1) 654 | set11nRate(series, 2) 655 | set11nRate(series, 3); 656 657 ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0) 658 | set11nPktDurRTSCTS(series, 1); 659 660 ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2) 661 | set11nPktDurRTSCTS(series, 3); 662 663 ads->ds_ctl7 = set11nRateFlags(series, 0) 664 | set11nRateFlags(series, 1) 665 | set11nRateFlags(series, 2) 666 | set11nRateFlags(series, 3) 667 | SM(rtsctsRate, AR_RTSCTSRate); 668} 669 670void 671ar5416Set11nAggrMiddle(struct ath_hal *ah, struct ath_desc *ds, u_int numDelims) 672{ 673 struct ar5416_desc *ads = AR5416DESC(ds); 674 uint32_t *ds_txstatus = AR5416_DS_TXSTATUS(ah,ads); 675 676 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr); 677 678 ads->ds_ctl6 &= ~AR_PadDelim; 679 ads->ds_ctl6 |= SM(numDelims, AR_PadDelim); 680 ads->ds_ctl6 &= ~AR_AggrLen; 681 682 /* 683 * Clear the TxDone status here, may need to change 684 * func name to reflect this 685 */ 686 ds_txstatus[9] &= ~AR_TxDone; 687} 688 689void 690ar5416Clr11nAggr(struct ath_hal *ah, struct ath_desc *ds) 691{ 692 struct ar5416_desc *ads = AR5416DESC(ds); 693 694 ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr); 695 ads->ds_ctl6 &= ~AR_PadDelim; 696 ads->ds_ctl6 &= ~AR_AggrLen; 697} 698 699void 700ar5416Set11nBurstDuration(struct ath_hal *ah, struct ath_desc *ds, 701 u_int burstDuration) 702{ 703 struct ar5416_desc *ads = AR5416DESC(ds); 704 705 ads->ds_ctl2 &= ~AR_BurstDur; 706 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur); 707} 708 709/* 710 * Retrieve the rate table from the given TX completion descriptor 711 */ 712HAL_BOOL 713ar5416GetTxCompletionRates(struct ath_hal *ah, const struct ath_desc *ds0, int *rates, int *tries) 714{ 715 const struct ar5416_desc *ads = AR5416DESC_CONST(ds0); 716 717 rates[0] = MS(ads->ds_ctl3, AR_XmitRate0); 718 rates[1] = MS(ads->ds_ctl3, AR_XmitRate1); 719 rates[2] = MS(ads->ds_ctl3, AR_XmitRate2); 720 rates[3] = MS(ads->ds_ctl3, AR_XmitRate3); 721 722 tries[0] = MS(ads->ds_ctl2, AR_XmitDataTries0); 723 tries[1] = MS(ads->ds_ctl2, AR_XmitDataTries1); 724 tries[2] = MS(ads->ds_ctl2, AR_XmitDataTries2); 725 tries[3] = MS(ads->ds_ctl2, AR_XmitDataTries3); 726 727 return AH_TRUE; 728} 729 730