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