ar9300_xmit_ds.c revision 250003
1/* 2 * Copyright (c) 2013 Qualcomm Atheros, Inc. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17#include "opt_ah.h" 18 19#ifdef AH_SUPPORT_AR9300 20 21#include "ah.h" 22#include "ah_desc.h" 23#include "ah_internal.h" 24 25#include "ar9300/ar9300desc.h" 26#include "ar9300/ar9300.h" 27#include "ar9300/ar9300reg.h" 28#include "ar9300/ar9300phy.h" 29#include "ah_devid.h" 30 31#if AH_BYTE_ORDER == AH_BIG_ENDIAN 32static void ar9300_swap_tx_desc(void *ds); 33#endif 34 35void 36ar9300_tx_req_intr_desc(struct ath_hal *ah, void *ds) 37{ 38 HALDEBUG(ah, HAL_DEBUG_INTERRUPT, 39 "%s:Desc Interrupt not supported\n", __func__); 40} 41 42static inline u_int16_t 43ar9300_calc_ptr_chk_sum(struct ar9300_txc *ads) 44{ 45 u_int checksum; 46 u_int16_t ptrchecksum; 47 48 /* checksum = __bswap32(ads->ds_info) + ads->ds_link */ 49 checksum = ads->ds_info + ads->ds_link 50 + ads->ds_data0 + ads->ds_ctl3 51 + ads->ds_data1 + ads->ds_ctl5 52 + ads->ds_data2 + ads->ds_ctl7 53 + ads->ds_data3 + ads->ds_ctl9; 54 55 ptrchecksum = ((checksum & 0xffff) + (checksum >> 16)) & AR_tx_ptr_chk_sum; 56 return ptrchecksum; 57} 58 59 60HAL_BOOL 61ar9300_fill_tx_desc( 62 struct ath_hal *ah, 63 void *ds, 64 dma_addr_t *buf_addr, 65 u_int32_t *seg_len, 66 u_int desc_id, 67 u_int qcu, 68 HAL_KEY_TYPE key_type, 69 HAL_BOOL first_seg, 70 HAL_BOOL last_seg, 71 const void *ds0) 72{ 73 struct ar9300_txc *ads = AR9300TXC(ds); 74 75 /* Fill TXC info field */ 76 ads->ds_info = TXC_INFO(qcu); 77 78 /* Set the buffer addresses */ 79 ads->ds_data0 = buf_addr[0]; 80 ads->ds_data1 = buf_addr[1]; 81 ads->ds_data2 = buf_addr[2]; 82 ads->ds_data3 = buf_addr[3]; 83 84 /* Set the buffer lengths */ 85 ads->ds_ctl3 = (seg_len[0] << AR_buf_len_S) & AR_buf_len; 86 ads->ds_ctl5 = (seg_len[1] << AR_buf_len_S) & AR_buf_len; 87 ads->ds_ctl7 = (seg_len[2] << AR_buf_len_S) & AR_buf_len; 88 ads->ds_ctl9 = (seg_len[3] << AR_buf_len_S) & AR_buf_len; 89 90 /* Fill in pointer checksum and descriptor id */ 91 ads->ds_ctl10 = (desc_id << AR_tx_desc_id_S) | ar9300_calc_ptr_chk_sum(ads); 92 93 if (first_seg) { 94 /* 95 * First descriptor, don't clobber xmit control data 96 * setup by ar9300_set_11n_tx_desc. 97 * 98 * Note: AR_encr_type is already setup in the first descriptor by 99 * set_11n_tx_desc(). 100 */ 101 ads->ds_ctl12 |= (last_seg ? 0 : AR_tx_more); 102 } else if (last_seg) { /* !first_seg && last_seg */ 103 /* 104 * Last descriptor in a multi-descriptor frame, 105 * copy the multi-rate transmit parameters from 106 * the first frame for processing on completion. 107 */ 108 ads->ds_ctl11 = 0; 109 ads->ds_ctl12 = 0; 110#ifdef AH_NEED_DESC_SWAP 111 ads->ds_ctl13 = __bswap32(AR9300TXC_CONST(ds0)->ds_ctl13); 112 ads->ds_ctl14 = __bswap32(AR9300TXC_CONST(ds0)->ds_ctl14); 113 ads->ds_ctl17 = __bswap32(SM(key_type, AR_encr_type)); 114#else 115 ads->ds_ctl13 = AR9300TXC_CONST(ds0)->ds_ctl13; 116 ads->ds_ctl14 = AR9300TXC_CONST(ds0)->ds_ctl14; 117 ads->ds_ctl17 = SM(key_type, AR_encr_type); 118#endif 119 } else { /* !first_seg && !last_seg */ 120 /* 121 * XXX Intermediate descriptor in a multi-descriptor frame. 122 */ 123 ads->ds_ctl11 = 0; 124 ads->ds_ctl12 = AR_tx_more; 125 ads->ds_ctl13 = 0; 126 ads->ds_ctl14 = 0; 127 ads->ds_ctl17 = SM(key_type, AR_encr_type); 128 } 129 130 return AH_TRUE; 131} 132 133void 134ar9300_set_desc_link(struct ath_hal *ah, void *ds, u_int32_t link) 135{ 136 struct ar9300_txc *ads = AR9300TXC(ds); 137 138 ads->ds_link = link; 139 140 /* TODO - checksum is calculated twice for subframes 141 * Once in filldesc and again when linked. Need to fix. 142 */ 143 /* Fill in pointer checksum. Preserve descriptor id */ 144 ads->ds_ctl10 &= ~AR_tx_ptr_chk_sum; 145 ads->ds_ctl10 |= ar9300_calc_ptr_chk_sum(ads); 146} 147 148void 149ar9300_get_desc_link_ptr(struct ath_hal *ah, void *ds, u_int32_t **link) 150{ 151 struct ar9300_txc *ads = AR9300TXC(ds); 152 153 *link = &ads->ds_link; 154} 155 156void 157ar9300_clear_tx_desc_status(struct ath_hal *ah, void *ds) 158{ 159 struct ar9300_txs *ads = AR9300TXS(ds); 160 ads->status1 = ads->status2 = 0; 161 ads->status3 = ads->status4 = 0; 162 ads->status5 = ads->status6 = 0; 163 ads->status7 = ads->status8 = 0; 164} 165 166#ifdef ATH_SWRETRY 167void 168ar9300_clear_dest_mask(struct ath_hal *ah, void *ds) 169{ 170 struct ar9300_txc *ads = AR9300TXC(ds); 171 ads->ds_ctl11 |= AR_clr_dest_mask; 172} 173#endif 174 175#if AH_BYTE_ORDER == AH_BIG_ENDIAN 176/* XXX what words need swapping */ 177/* Swap transmit descriptor */ 178static __inline void 179ar9300_swap_tx_desc(void *dsp) 180{ 181 struct ar9300_txs *ds = (struct ar9300_txs *)dsp; 182 183 ds->ds_info = __bswap32(ds->ds_info); 184 ds->status1 = __bswap32(ds->status1); 185 ds->status2 = __bswap32(ds->status2); 186 ds->status3 = __bswap32(ds->status3); 187 ds->status4 = __bswap32(ds->status4); 188 ds->status5 = __bswap32(ds->status5); 189 ds->status6 = __bswap32(ds->status6); 190 ds->status7 = __bswap32(ds->status7); 191 ds->status8 = __bswap32(ds->status8); 192} 193#endif 194 195 196/* 197 * Extract the transmit rate code. 198 */ 199void 200ar9300_get_tx_rate_code(struct ath_hal *ah, void *ds, struct ath_tx_status *ts) 201{ 202 struct ar9300_txc *ads = AR9300TXC(ds); 203 204 switch (ts->ts_rateindex) { 205 case 0: 206 ts->ts_ratecode = MS(ads->ds_ctl14, AR_xmit_rate0); 207 break; 208 case 1: 209 ts->ts_ratecode = MS(ads->ds_ctl14, AR_xmit_rate1); 210 break; 211 case 2: 212 ts->ts_ratecode = MS(ads->ds_ctl14, AR_xmit_rate2); 213 break; 214 case 3: 215 ts->ts_ratecode = MS(ads->ds_ctl14, AR_xmit_rate3); 216 break; 217 } 218 219 ar9300_set_selfgenrate_limit(ah, ts->ts_ratecode); 220} 221 222/* 223 * Get TX Status descriptor contents. 224 */ 225void 226ar9300_get_raw_tx_desc(struct ath_hal *ah, u_int32_t *txstatus) 227{ 228 struct ath_hal_9300 *ahp = AH9300(ah); 229 struct ar9300_txs *ads; 230 231 ads = &ahp->ts_ring[ahp->ts_tail]; 232 233 OS_MEMCPY(txstatus, ads, sizeof(struct ar9300_txs)); 234} 235 236/* 237 * Processing of HW TX descriptor. 238 */ 239HAL_STATUS 240ar9300_proc_tx_desc(struct ath_hal *ah, void *txstatus) 241{ 242 struct ath_hal_9300 *ahp = AH9300(ah); 243 struct ar9300_txs *ads; 244 struct ath_tx_status *ts = (struct ath_tx_status *)txstatus; 245 u_int32_t dsinfo; 246 247 ads = &ahp->ts_ring[ahp->ts_tail]; 248 249 if ((ads->status8 & AR_tx_done) == 0) { 250 return HAL_EINPROGRESS; 251 } 252 /* Increment the tail to point to the next status element. */ 253 ahp->ts_tail = (ahp->ts_tail + 1) & (ahp->ts_size-1); 254 255 /* 256 ** For big endian systems, ds_info is not swapped as the other 257 ** registers are. Ensure we use the bswap32 version (which is 258 ** defined to "nothing" in little endian systems 259 */ 260 261 /* 262 * Sanity check 263 */ 264 265#if 0 266 ath_hal_printf(ah, 267 "CHH: ds_info 0x%x status1: 0x%x status8: 0x%x\n", 268 ads->ds_info, ads->status1, ads->status8); 269#endif 270 271 dsinfo = ads->ds_info; 272 273 if ((MS(dsinfo, AR_desc_id) != ATHEROS_VENDOR_ID) || 274 (MS(dsinfo, AR_tx_rx_desc) != 1)) 275 { 276 HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, "%s: Tx Descriptor error %x\n", 277 __func__, dsinfo); 278 HALASSERT(0); 279 /* Zero out the status for reuse */ 280 OS_MEMZERO(ads, sizeof(struct ar9300_txs)); 281 return HAL_EIO; 282 } 283 284 /* Update software copies of the HW status */ 285 ts->queue_id = MS(dsinfo, AR_tx_qcu_num); 286 ts->desc_id = MS(ads->status1, AR_tx_desc_id); 287 ts->ts_seqnum = MS(ads->status8, AR_seq_num); 288 ts->ts_tstamp = ads->status4; 289 ts->ts_status = 0; 290 ts->ts_flags = 0; 291 292 if (ads->status3 & AR_excessive_retries) { 293 ts->ts_status |= HAL_TXERR_XRETRY; 294 } 295 if (ads->status3 & AR_filtered) { 296 ts->ts_status |= HAL_TXERR_FILT; 297 } 298 if (ads->status3 & AR_fifounderrun) { 299 ts->ts_status |= HAL_TXERR_FIFO; 300 ar9300_update_tx_trig_level(ah, AH_TRUE); 301 } 302 if (ads->status8 & AR_tx_op_exceeded) { 303 ts->ts_status |= HAL_TXERR_XTXOP; 304 } 305 if (ads->status3 & AR_tx_timer_expired) { 306 ts->ts_status |= HAL_TXERR_TIMER_EXPIRED; 307 } 308 if (ads->status3 & AR_desc_cfg_err) { 309 ts->ts_flags |= HAL_TX_DESC_CFG_ERR; 310 } 311 if (ads->status3 & AR_tx_data_underrun) { 312 ts->ts_flags |= HAL_TX_DATA_UNDERRUN; 313 ar9300_update_tx_trig_level(ah, AH_TRUE); 314 } 315 if (ads->status3 & AR_tx_delim_underrun) { 316 ts->ts_flags |= HAL_TX_DELIM_UNDERRUN; 317 ar9300_update_tx_trig_level(ah, AH_TRUE); 318 } 319 if (ads->status2 & AR_tx_ba_status) { 320 ts->ts_flags |= HAL_TX_BA; 321 ts->ba_low = ads->status5; 322 ts->ba_high = ads->status6; 323 } 324 325 /* 326 * Extract the transmit rate. 327 */ 328 ts->ts_rateindex = MS(ads->status8, AR_final_tx_idx); 329 330 ts->ts_rssi = MS(ads->status7, AR_tx_rssi_combined); 331 ts->ts_rssi_ctl0 = MS(ads->status2, AR_tx_rssi_ant00); 332 ts->ts_rssi_ctl1 = MS(ads->status2, AR_tx_rssi_ant01); 333 ts->ts_rssi_ctl2 = MS(ads->status2, AR_tx_rssi_ant02); 334 ts->ts_rssi_ext0 = MS(ads->status7, AR_tx_rssi_ant10); 335 ts->ts_rssi_ext1 = MS(ads->status7, AR_tx_rssi_ant11); 336 ts->ts_rssi_ext2 = MS(ads->status7, AR_tx_rssi_ant12); 337 ts->ts_shortretry = MS(ads->status3, AR_rts_fail_cnt); 338 ts->ts_longretry = MS(ads->status3, AR_data_fail_cnt); 339 ts->ts_virtcol = MS(ads->status3, AR_virt_retry_cnt); 340 ts->ts_antenna = 0; 341 342 /* extract TID from block ack */ 343 ts->tid = MS(ads->status8, AR_tx_tid); 344 345 /* Zero out the status for reuse */ 346 OS_MEMZERO(ads, sizeof(struct ar9300_txs)); 347 348 return HAL_OK; 349} 350 351/* 352 * Calculate air time of a transmit packet 353 * if comp_wastedt is 1, calculate air time only for failed subframes 354 * this is required for VOW_DCS ( dynamic channel selection ) 355 */ 356u_int32_t 357ar9300_calc_tx_airtime(struct ath_hal *ah, void *ds, struct ath_tx_status *ts, 358 HAL_BOOL comp_wastedt, u_int8_t nbad, u_int8_t nframes ) 359{ 360 struct ar9300_txc *ads = AR9300TXC(ds); 361 int finalindex_tries; 362 u_int32_t airtime, lastrate_dur; 363 364 365 /* 366 * Number of attempts made on the final index 367 * Note: If no BA was recv, then the data_fail_cnt is the number of tries 368 * made on the final index. If BA was recv, then add 1 to account for the 369 * successful attempt. 370 */ 371 if ( !comp_wastedt ){ 372 finalindex_tries = ts->ts_longretry + (ts->ts_flags & HAL_TX_BA)? 1 : 0; 373 } else { 374 finalindex_tries = ts->ts_longretry ; 375 } 376 377 /* 378 * Calculate time of transmit on air for packet including retries 379 * at different rates. 380 */ 381 switch (ts->ts_rateindex) { 382 case 0: 383 lastrate_dur = MS(ads->ds_ctl15, AR_packet_dur0); 384 airtime = (lastrate_dur * finalindex_tries); 385 break; 386 case 1: 387 lastrate_dur = MS(ads->ds_ctl15, AR_packet_dur1); 388 airtime = (lastrate_dur * finalindex_tries) + 389 (MS(ads->ds_ctl13, AR_xmit_data_tries0) * 390 MS(ads->ds_ctl15, AR_packet_dur0)); 391 break; 392 case 2: 393 lastrate_dur = MS(ads->ds_ctl16, AR_packet_dur2); 394 airtime = (lastrate_dur * finalindex_tries) + 395 (MS(ads->ds_ctl13, AR_xmit_data_tries1) * 396 MS(ads->ds_ctl15, AR_packet_dur1)) + 397 (MS(ads->ds_ctl13, AR_xmit_data_tries0) * 398 MS(ads->ds_ctl15, AR_packet_dur0)); 399 break; 400 case 3: 401 lastrate_dur = MS(ads->ds_ctl16, AR_packet_dur3); 402 airtime = (lastrate_dur * finalindex_tries) + 403 (MS(ads->ds_ctl13, AR_xmit_data_tries2) * 404 MS(ads->ds_ctl16, AR_packet_dur2)) + 405 (MS(ads->ds_ctl13, AR_xmit_data_tries1) * 406 MS(ads->ds_ctl15, AR_packet_dur1)) + 407 (MS(ads->ds_ctl13, AR_xmit_data_tries0) * 408 MS(ads->ds_ctl15, AR_packet_dur0)); 409 break; 410 default: 411 HALASSERT(0); 412 return 0; 413 } 414 415 if ( comp_wastedt && (ts->ts_flags & HAL_TX_BA)){ 416 airtime += nbad?((lastrate_dur*nbad) / nframes):0; 417 } 418 return airtime; 419 420} 421 422#ifdef AH_PRIVATE_DIAG 423void 424ar9300__cont_tx_mode(struct ath_hal *ah, void *ds, int mode) 425{ 426#if 0 427 static int qnum = 0; 428 int i; 429 unsigned int qbits, val, val1, val2; 430 int prefetch; 431 struct ar9300_txs *ads = AR9300TXS(ds); 432 433 if (mode == 10) { 434 return; 435 } 436 437 if (mode == 7) { /* print status from the cont tx desc */ 438 if (ads) { 439 val1 = ads->ds_txstatus1; 440 val2 = ads->ds_txstatus2; 441 HALDEBUG(ah, HAL_DEBUG_TXDESC, "s0(%x) s1(%x)\n", 442 (unsigned)val1, (unsigned)val2); 443 } 444 HALDEBUG(ah, HAL_DEBUG_TXDESC, "txe(%x) txd(%x)\n", 445 OS_REG_READ(ah, AR_Q_TXE), 446 OS_REG_READ(ah, AR_Q_TXD) 447 ); 448 for (i = 0; i < HAL_NUM_TX_QUEUES; i++) { 449 val = OS_REG_READ(ah, AR_QTXDP(i)); 450 val2 = OS_REG_READ(ah, AR_QSTS(i)) & AR_Q_STS_PEND_FR_CNT; 451 HALDEBUG(ah, HAL_DEBUG_TXDESC, "[%d] %x %d\n", i, val, val2); 452 } 453 return; 454 } 455 if (mode == 8) { /* set TXE for qnum */ 456 OS_REG_WRITE(ah, AR_Q_TXE, 1 << qnum); 457 return; 458 } 459 if (mode == 9) { 460 prefetch = (int)ds; 461 return; 462 } 463 464 if (mode >= 1) { /* initiate cont tx operation */ 465 /* Disable AGC to A2 */ 466 qnum = (int) ds; 467 468 OS_REG_WRITE(ah, AR_PHY_TEST, 469 (OS_REG_READ(ah, AR_PHY_TEST) | PHY_AGC_CLR) ); 470 471 OS_REG_WRITE(ah, 0x9864, OS_REG_READ(ah, 0x9864) | 0x7f000); 472 OS_REG_WRITE(ah, 0x9924, OS_REG_READ(ah, 0x9924) | 0x7f00fe); 473 OS_REG_WRITE(ah, AR_DIAG_SW, 474 (OS_REG_READ(ah, AR_DIAG_SW) | 475 (AR_DIAG_FORCE_RX_CLEAR + AR_DIAG_IGNORE_VIRT_CS)) ); 476 477 478 OS_REG_WRITE(ah, AR_CR, AR_CR_RXD); /* set receive disable */ 479 480 if (mode == 3 || mode == 4) { 481 int txcfg; 482 483 if (mode == 3) { 484 OS_REG_WRITE(ah, AR_DLCL_IFS(qnum), 0); 485 OS_REG_WRITE(ah, AR_DRETRY_LIMIT(qnum), 0xffffffff); 486 OS_REG_WRITE(ah, AR_D_GBL_IFS_SIFS, 100); 487 OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS, 100); 488 OS_REG_WRITE(ah, AR_TIME_OUT, 2); 489 OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, 100); 490 } 491 492 OS_REG_WRITE(ah, AR_DRETRY_LIMIT(qnum), 0xffffffff); 493 /* enable prefetch on qnum */ 494 OS_REG_WRITE(ah, AR_D_FPCTL, 0x10 | qnum); 495 txcfg = 5 | (6 << AR_FTRIG_S); 496 OS_REG_WRITE(ah, AR_TXCFG, txcfg); 497 498 OS_REG_WRITE(ah, AR_QMISC(qnum), /* set QCU modes */ 499 AR_Q_MISC_DCU_EARLY_TERM_REQ 500 + AR_Q_MISC_FSP_ASAP 501 + AR_Q_MISC_CBR_INCR_DIS1 502 + AR_Q_MISC_CBR_INCR_DIS0 503 ); 504 505 /* stop tx dma all all except qnum */ 506 qbits = 0x3ff; 507 qbits &= ~(1 << qnum); 508 for (i = 0; i < 10; i++) { 509 if (i == qnum) { 510 continue; 511 } 512 OS_REG_WRITE(ah, AR_Q_TXD, 1 << i); 513 } 514 515 OS_REG_WRITE(ah, AR_Q_TXD, qbits); 516 517 /* clear and freeze MIB counters */ 518 OS_REG_WRITE(ah, AR_MIBC, AR_MIBC_CMC); 519 OS_REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC); 520 521 OS_REG_WRITE(ah, AR_DMISC(qnum), 522 (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << 523 AR_D_MISC_ARB_LOCKOUT_CNTRL_S) 524 + (AR_D_MISC_ARB_LOCKOUT_IGNORE) 525 + (AR_D_MISC_POST_FR_BKOFF_DIS) 526 + (AR_D_MISC_VIR_COL_HANDLING_IGNORE << 527 AR_D_MISC_VIR_COL_HANDLING_S)); 528 529 for (i = 0; i < HAL_NUM_TX_QUEUES + 2; i++) { /* disconnect QCUs */ 530 if (i == qnum) { 531 continue; 532 } 533 OS_REG_WRITE(ah, AR_DQCUMASK(i), 0); 534 } 535 } 536 } 537 if (mode == 0) { 538 OS_REG_WRITE(ah, AR_PHY_TEST, 539 (OS_REG_READ(ah, AR_PHY_TEST) & ~PHY_AGC_CLR)); 540 OS_REG_WRITE(ah, AR_DIAG_SW, 541 (OS_REG_READ(ah, AR_DIAG_SW) & 542 ~(AR_DIAG_FORCE_RX_CLEAR + AR_DIAG_IGNORE_VIRT_CS))); 543 } 544#endif 545} 546#endif 547 548void 549ar9300_set_paprd_tx_desc(struct ath_hal *ah, void *ds, int chain_num) 550{ 551 struct ar9300_txc *ads = AR9300TXC(ds); 552 553 ads->ds_ctl12 |= SM((1 << chain_num), AR_paprd_chain_mask); 554} 555HAL_STATUS 556ar9300_is_tx_done(struct ath_hal *ah) 557{ 558 struct ath_hal_9300 *ahp = AH9300(ah); 559 struct ar9300_txs *ads; 560 561 ads = &ahp->ts_ring[ahp->ts_tail]; 562 563 if (ads->status8 & AR_tx_done) { 564 return HAL_OK; 565 } 566 return HAL_EINPROGRESS; 567} 568 569void 570ar9300_set_11n_tx_desc( 571 struct ath_hal *ah, 572 void *ds, 573 u_int pkt_len, 574 HAL_PKT_TYPE type, 575 u_int tx_power, 576 u_int key_ix, 577 HAL_KEY_TYPE key_type, 578 u_int flags) 579{ 580 struct ar9300_txc *ads = AR9300TXC(ds); 581 struct ath_hal_9300 *ahp = AH9300(ah); 582 583 HALASSERT(is_valid_pkt_type(type)); 584 HALASSERT(is_valid_key_type(key_type)); 585 586 tx_power += ahp->ah_tx_power_index_offset; 587 if (tx_power > 63) { 588 tx_power = 63; 589 } 590 ads->ds_ctl11 = 591 (pkt_len & AR_frame_len) 592 | (flags & HAL_TXDESC_VMF ? AR_virt_more_frag : 0) 593 | SM(tx_power, AR_xmit_power0) 594 | (flags & HAL_TXDESC_VEOL ? AR_veol : 0) 595 | (flags & HAL_TXDESC_CLRDMASK ? AR_clr_dest_mask : 0) 596 | (key_ix != HAL_TXKEYIX_INVALID ? AR_dest_idx_valid : 0) 597 | (flags & HAL_TXDESC_LOWRXCHAIN ? AR_low_rx_chain : 0); 598 599 ads->ds_ctl12 = 600 (key_ix != HAL_TXKEYIX_INVALID ? SM(key_ix, AR_dest_idx) : 0) 601 | SM(type, AR_frame_type) 602 | (flags & HAL_TXDESC_NOACK ? AR_no_ack : 0) 603 | (flags & HAL_TXDESC_EXT_ONLY ? AR_ext_only : 0) 604 | (flags & HAL_TXDESC_EXT_AND_CTL ? AR_ext_and_ctl : 0); 605 606 ads->ds_ctl17 = 607 SM(key_type, AR_encr_type) | (flags & HAL_TXDESC_LDPC ? AR_ldpc : 0); 608 609 ads->ds_ctl18 = 0; 610 ads->ds_ctl19 = AR_not_sounding; /* set not sounding for normal frame */ 611 612 613 /* 614 * Clear Ness1/2/3 (Number of Extension Spatial Streams) fields. 615 * Ness0 is cleared in ctl19. See EV66059 (BB panic). 616 */ 617 ads->ds_ctl20 = 0; 618 ads->ds_ctl21 = 0; 619 ads->ds_ctl22 = 0; 620} 621 622void ar9300_set_rx_chainmask(struct ath_hal *ah, int rxchainmask) 623{ 624 OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rxchainmask); 625} 626 627void ar9300_update_loc_ctl_reg(struct ath_hal *ah, int pos_bit) 628{ 629 u_int32_t reg_val; 630 reg_val = OS_REG_READ(ah, AR_LOC_CTL_REG); 631 if (pos_bit) { 632 if (!(reg_val & AR_LOC_CTL_REG_FS)) { 633 /* set fast timestamp bit in the regiter */ 634 OS_REG_WRITE(ah, AR_LOC_CTL_REG, (reg_val | AR_LOC_CTL_REG_FS)); 635 OS_REG_WRITE(ah, AR_LOC_TIMER_REG, 0); 636 } 637 } 638 else { 639 OS_REG_WRITE(ah, AR_LOC_CTL_REG, (reg_val & ~AR_LOC_CTL_REG_FS)); 640 } 641} 642 643#if 0 644#define HT_RC_2_MCS(_rc) ((_rc) & 0x0f) 645static const u_int8_t ba_duration_delta[] = { 646 24, /* 0: BPSK */ 647 12, /* 1: QPSK 1/2 */ 648 12, /* 2: QPSK 3/4 */ 649 4, /* 3: 16-QAM 1/2 */ 650 4, /* 4: 16-QAM 3/4 */ 651 4, /* 5: 64-QAM 2/3 */ 652 4, /* 6: 64-QAM 3/4 */ 653 4, /* 7: 64-QAM 5/6 */ 654 24, /* 8: BPSK */ 655 12, /* 9: QPSK 1/2 */ 656 12, /* 10: QPSK 3/4 */ 657 4, /* 11: 16-QAM 1/2 */ 658 4, /* 12: 16-QAM 3/4 */ 659 4, /* 13: 64-QAM 2/3 */ 660 4, /* 14: 64-QAM 3/4 */ 661 4, /* 15: 64-QAM 5/6 */ 662}; 663#endif 664 665 666static u_int8_t 667ar9300_get_tx_mode(u_int rate_flags) 668{ 669 670 /* Check whether STBC is enabled if TxBF is not enabled */ 671 if (rate_flags & HAL_RATESERIES_STBC){ 672 return AR9300_STBC_MODE; 673 } 674 return AR9300_DEF_MODE; 675} 676void 677ar9300_set_11n_rate_scenario( 678 struct ath_hal *ah, 679 void *ds, 680 void *lastds, 681 u_int dur_update_en, 682 u_int rts_cts_rate, 683 u_int rts_cts_duration, 684 HAL_11N_RATE_SERIES series[], 685 u_int nseries, 686 u_int flags, 687 u_int32_t smart_antenna) 688{ 689 struct ath_hal_private *ap = AH_PRIVATE(ah); 690 struct ar9300_txc *ads = AR9300TXC(ds); 691 struct ar9300_txc *last_ads = AR9300TXC(lastds); 692 u_int32_t ds_ctl11; 693 u_int8_t ant, cal_pkt = 0; 694 u_int mode, tx_mode = AR9300_DEF_MODE; 695 696 HALASSERT(nseries == 4); 697 (void)nseries; 698 (void)rts_cts_duration; /* use H/W to calculate RTSCTSDuration */ 699 700 ds_ctl11 = ads->ds_ctl11; 701 /* 702 * Rate control settings override 703 */ 704 if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) { 705 if (flags & HAL_TXDESC_RTSENA) { 706 ds_ctl11 &= ~AR_cts_enable; 707 ds_ctl11 |= AR_rts_enable; 708 } else { 709 ds_ctl11 &= ~AR_rts_enable; 710 ds_ctl11 |= AR_cts_enable; 711 } 712 } else { 713 ds_ctl11 = (ds_ctl11 & ~(AR_rts_enable | AR_cts_enable)); 714 } 715 716 mode = ath_hal_get_curmode(ah, ap->ah_curchan); 717 cal_pkt = (ads->ds_ctl12 & AR_paprd_chain_mask)?1:0; 718 719 if (ap->ah_config.ath_hal_desc_tpc ) { 720 int16_t txpower; 721 722 if (!cal_pkt) { 723 /* Series 0 TxPower */ 724 tx_mode = ar9300_get_tx_mode(series[0].RateFlags); 725 txpower = ar9300_get_rate_txpower(ah, mode, series[0].rate_index, 726 series[0].ch_sel, tx_mode); 727 } else { 728 txpower = AH9300(ah)->paprd_training_power; 729 } 730 ds_ctl11 &= ~AR_xmit_power0; 731 ds_ctl11 |= 732 set_11n_tx_power(0, AH_MIN(txpower, series[0].tx_power_cap)); 733 } 734 735 ads->ds_ctl11 = ds_ctl11; 736 737 738 ads->ds_ctl13 = set_11n_tries(series, 0) 739 | set_11n_tries(series, 1) 740 | set_11n_tries(series, 2) 741 | set_11n_tries(series, 3) 742 | (dur_update_en ? AR_dur_update_ena : 0) 743 | SM(0, AR_burst_dur); 744 745 ads->ds_ctl14 = set_11n_rate(series, 0) 746 | set_11n_rate(series, 1) 747 | set_11n_rate(series, 2) 748 | set_11n_rate(series, 3); 749 750 ads->ds_ctl15 = set_11n_pkt_dur_rts_cts(series, 0) 751 | set_11n_pkt_dur_rts_cts(series, 1); 752 753 ads->ds_ctl16 = set_11n_pkt_dur_rts_cts(series, 2) 754 | set_11n_pkt_dur_rts_cts(series, 3); 755 756 ads->ds_ctl18 = set_11n_rate_flags(series, 0) 757 | set_11n_rate_flags(series, 1) 758 | set_11n_rate_flags(series, 2) 759 | set_11n_rate_flags(series, 3) 760 | SM(rts_cts_rate, AR_rts_cts_rate); 761 /* set not sounding for normal frame */ 762 ads->ds_ctl19 = AR_not_sounding; 763 764 if (ap->ah_config.ath_hal_desc_tpc) { 765 int16_t txpower; 766 767 if (!cal_pkt) { 768 /* Series 1 TxPower */ 769 tx_mode = ar9300_get_tx_mode(series[1].RateFlags); 770 txpower = ar9300_get_rate_txpower( 771 ah, mode, series[1].rate_index, series[1].ch_sel, tx_mode); 772 } else { 773 txpower = AH9300(ah)->paprd_training_power; 774 } 775 ads->ds_ctl20 |= 776 set_11n_tx_power(1, AH_MIN(txpower, series[1].tx_power_cap)); 777 778 779 /* Series 2 TxPower */ 780 if (!cal_pkt) { 781 tx_mode = ar9300_get_tx_mode(series[2].RateFlags); 782 txpower = ar9300_get_rate_txpower( 783 ah, mode, series[2].rate_index, series[2].ch_sel, tx_mode); 784 } else { 785 txpower = AH9300(ah)->paprd_training_power; 786 } 787 ads->ds_ctl21 |= 788 set_11n_tx_power(2, AH_MIN(txpower, series[2].tx_power_cap)); 789 790 /* Series 3 TxPower */ 791 if (!cal_pkt) { 792 tx_mode = ar9300_get_tx_mode(series[3].RateFlags); 793 txpower = ar9300_get_rate_txpower( 794 ah, mode, series[3].rate_index, series[3].ch_sel, tx_mode); 795 } else { 796 txpower = AH9300(ah)->paprd_training_power; 797 } 798 ads->ds_ctl22 |= 799 set_11n_tx_power(3, AH_MIN(txpower, series[3].tx_power_cap)); 800 } 801 802 if (smart_antenna != 0xffffffff) 803 { 804 /* TX DESC dword 19 to 23 are used for smart antenna configuaration 805 * ctl19 for rate series 0 ... ctrl22 for series 3 806 * bits[2:0] used to configure smart anntenna 807 */ 808 ant = (smart_antenna&0x000000ff); 809 ads->ds_ctl19 |= ant; /* rateseries 0 */ 810 811 ant = (smart_antenna&0x0000ff00) >> 8; 812 ads->ds_ctl20 |= ant; /* rateseries 1 */ 813 814 ant = (smart_antenna&0x00ff0000) >> 16; 815 ads->ds_ctl21 |= ant; /* rateseries 2 */ 816 817 ant = (smart_antenna&0xff000000) >> 24; 818 ads->ds_ctl22 |= ant; /* rateseries 3 */ 819 } 820 821#ifdef AH_NEED_DESC_SWAP 822 last_ads->ds_ctl13 = __bswap32(ads->ds_ctl13); 823 last_ads->ds_ctl14 = __bswap32(ads->ds_ctl14); 824#else 825 last_ads->ds_ctl13 = ads->ds_ctl13; 826 last_ads->ds_ctl14 = ads->ds_ctl14; 827#endif 828} 829 830void 831ar9300_set_11n_aggr_first(struct ath_hal *ah, void *ds, u_int aggr_len) 832{ 833 struct ar9300_txc *ads = AR9300TXC(ds); 834 835 ads->ds_ctl12 |= (AR_is_aggr | AR_more_aggr); 836 837 ads->ds_ctl17 &= ~AR_aggr_len; 838 ads->ds_ctl17 |= SM(aggr_len, AR_aggr_len); 839} 840 841void 842ar9300_set_11n_aggr_middle(struct ath_hal *ah, void *ds, u_int num_delims) 843{ 844 struct ar9300_txc *ads = AR9300TXC(ds); 845 unsigned int ctl17; 846 847 ads->ds_ctl12 |= (AR_is_aggr | AR_more_aggr); 848 849 /* 850 * We use a stack variable to manipulate ctl6 to reduce uncached 851 * read modify, modfiy, write. 852 */ 853 ctl17 = ads->ds_ctl17; 854 ctl17 &= ~AR_pad_delim; 855 ctl17 |= SM(num_delims, AR_pad_delim); 856 ads->ds_ctl17 = ctl17; 857} 858 859void 860ar9300_set_11n_aggr_last(struct ath_hal *ah, void *ds) 861{ 862 struct ar9300_txc *ads = AR9300TXC(ds); 863 864 ads->ds_ctl12 |= AR_is_aggr; 865 ads->ds_ctl12 &= ~AR_more_aggr; 866 ads->ds_ctl17 &= ~AR_pad_delim; 867} 868 869void 870ar9300_clr_11n_aggr(struct ath_hal *ah, void *ds) 871{ 872 struct ar9300_txc *ads = AR9300TXC(ds); 873 874 ads->ds_ctl12 &= (~AR_is_aggr & ~AR_more_aggr); 875} 876 877void 878ar9300_set_11n_burst_duration(struct ath_hal *ah, void *ds, 879 u_int burst_duration) 880{ 881 struct ar9300_txc *ads = AR9300TXC(ds); 882 883 ads->ds_ctl13 &= ~AR_burst_dur; 884 ads->ds_ctl13 |= SM(burst_duration, AR_burst_dur); 885} 886 887void 888ar9300_set_11n_rifs_burst_middle(struct ath_hal *ah, void *ds) 889{ 890 struct ar9300_txc *ads = AR9300TXC(ds); 891 892 ads->ds_ctl12 |= AR_more_rifs | AR_no_ack; 893} 894 895void 896ar9300_set_11n_rifs_burst_last(struct ath_hal *ah, void *ds) 897{ 898 struct ar9300_txc *ads = AR9300TXC(ds); 899 900 ads->ds_ctl12 &= (~AR_more_aggr & ~AR_more_rifs); 901} 902 903void 904ar9300_clr_11n_rifs_burst(struct ath_hal *ah, void *ds) 905{ 906 struct ar9300_txc *ads = AR9300TXC(ds); 907 908 ads->ds_ctl12 &= (~AR_more_rifs & ~AR_no_ack); 909} 910 911void 912ar9300_set_11n_aggr_rifs_burst(struct ath_hal *ah, void *ds) 913{ 914 struct ar9300_txc *ads = AR9300TXC(ds); 915 916 ads->ds_ctl12 |= AR_no_ack; 917 ads->ds_ctl12 &= ~AR_more_rifs; 918} 919 920void 921ar9300_set_11n_virtual_more_frag(struct ath_hal *ah, void *ds, 922 u_int vmf) 923{ 924 struct ar9300_txc *ads = AR9300TXC(ds); 925 926 if (vmf) { 927 ads->ds_ctl11 |= AR_virt_more_frag; 928 } else { 929 ads->ds_ctl11 &= ~AR_virt_more_frag; 930 } 931} 932 933void 934ar9300_get_desc_info(struct ath_hal *ah, HAL_DESC_INFO *desc_info) 935{ 936 desc_info->txctl_numwords = TXCTL_NUMWORDS(ah); 937 desc_info->txctl_offset = TXCTL_OFFSET(ah); 938 desc_info->txstatus_numwords = TXSTATUS_NUMWORDS(ah); 939 desc_info->txstatus_offset = TXSTATUS_OFFSET(ah); 940 941 desc_info->rxctl_numwords = RXCTL_NUMWORDS(ah); 942 desc_info->rxctl_offset = RXCTL_OFFSET(ah); 943 desc_info->rxstatus_numwords = RXSTATUS_NUMWORDS(ah); 944 desc_info->rxstatus_offset = RXSTATUS_OFFSET(ah); 945} 946 947#endif /* AH_SUPPORT_AR9300 */ 948