1 /* 2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> 3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> 4 * 5 * Permission to use, copy, modify, and 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 */ 18 19 /********************************************\ 20 Queue Control Unit, DCF Control Unit Functions 21 \********************************************/ 22 23 #include "ath5k.h" 24 #include "reg.h" 25 #include "debug.h" 26 27 /** 28 * DOC: Queue Control Unit (QCU)/DCF Control Unit (DCU) functions 29 * 30 * Here we setup parameters for the 12 available TX queues. Note that 31 * on the various registers we can usually only map the first 10 of them so 32 * basically we have 10 queues to play with. Each queue has a matching 33 * QCU that controls when the queue will get triggered and multiple QCUs 34 * can be mapped to a single DCU that controls the various DFS parameters 35 * for the various queues. In our setup we have a 1:1 mapping between QCUs 36 * and DCUs allowing us to have different DFS settings for each queue. 37 * 38 * When a frame goes into a TX queue, QCU decides when it'll trigger a 39 * transmission based on various criteria (such as how many data we have inside 40 * it's buffer or -if it's a beacon queue- if it's time to fire up the queue 41 * based on TSF etc), DCU adds backoff, IFSes etc and then a scheduler 42 * (arbitrator) decides the priority of each QCU based on it's configuration 43 * (e.g. beacons are always transmitted when they leave DCU bypassing all other 44 * frames from other queues waiting to be transmitted). After a frame leaves 45 * the DCU it goes to PCU for further processing and then to PHY for 46 * the actual transmission. 47 */ 48 49 50 /******************\ 51 * Helper functions * 52 \******************/ 53 54 /** 55 * ath5k_hw_num_tx_pending() - Get number of pending frames for a given queue 56 * @ah: The &struct ath5k_hw 57 * @queue: The hw queue number 58 */ 59 u32 60 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue) 61 { 62 u32 pending; 63 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); 64 65 /* Return if queue is declared inactive */ 66 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) 67 return false; 68 69 /* XXX: How about AR5K_CFG_TXCNT ? */ 70 if (ah->ah_version == AR5K_AR5210) 71 return false; 72 73 pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue)); 74 pending &= AR5K_QCU_STS_FRMPENDCNT; 75 76 /* It's possible to have no frames pending even if TXE 77 * is set. To indicate that q has not stopped return 78 * true */ 79 if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue)) 80 return true; 81 82 return pending; 83 } 84 85 /** 86 * ath5k_hw_release_tx_queue() - Set a transmit queue inactive 87 * @ah: The &struct ath5k_hw 88 * @queue: The hw queue number 89 */ 90 void 91 ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue) 92 { 93 if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num)) 94 return; 95 96 /* This queue will be skipped in further operations */ 97 ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE; 98 /*For SIMR setup*/ 99 AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue); 100 } 101 102 /** 103 * ath5k_cw_validate() - Make sure the given cw is valid 104 * @cw_req: The contention window value to check 105 * 106 * Make sure cw is a power of 2 minus 1 and smaller than 1024 107 */ 108 static u16 109 ath5k_cw_validate(u16 cw_req) 110 { 111 u32 cw = 1; 112 cw_req = min(cw_req, (u16)1023); 113 114 while (cw < cw_req) 115 cw = (cw << 1) | 1; 116 117 return cw; 118 } 119 120 /** 121 * ath5k_hw_get_tx_queueprops() - Get properties for a transmit queue 122 * @ah: The &struct ath5k_hw 123 * @queue: The hw queue number 124 * @queue_info: The &struct ath5k_txq_info to fill 125 */ 126 int 127 ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, 128 struct ath5k_txq_info *queue_info) 129 { 130 memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info)); 131 return 0; 132 } 133 134 /** 135 * ath5k_hw_set_tx_queueprops() - Set properties for a transmit queue 136 * @ah: The &struct ath5k_hw 137 * @queue: The hw queue number 138 * @qinfo: The &struct ath5k_txq_info to use 139 * 140 * Returns 0 on success or -EIO if queue is inactive 141 */ 142 int 143 ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, 144 const struct ath5k_txq_info *qinfo) 145 { 146 struct ath5k_txq_info *qi; 147 148 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); 149 150 qi = &ah->ah_txq[queue]; 151 152 if (qi->tqi_type == AR5K_TX_QUEUE_INACTIVE) 153 return -EIO; 154 155 /* copy and validate values */ 156 qi->tqi_type = qinfo->tqi_type; 157 qi->tqi_subtype = qinfo->tqi_subtype; 158 qi->tqi_flags = qinfo->tqi_flags; 159 /* 160 * According to the docs: Although the AIFS field is 8 bit wide, 161 * the maximum supported value is 0xFC. Setting it higher than that 162 * will cause the DCU to hang. 163 */ 164 qi->tqi_aifs = min(qinfo->tqi_aifs, (u8)0xFC); 165 qi->tqi_cw_min = ath5k_cw_validate(qinfo->tqi_cw_min); 166 qi->tqi_cw_max = ath5k_cw_validate(qinfo->tqi_cw_max); 167 qi->tqi_cbr_period = qinfo->tqi_cbr_period; 168 qi->tqi_cbr_overflow_limit = qinfo->tqi_cbr_overflow_limit; 169 qi->tqi_burst_time = qinfo->tqi_burst_time; 170 qi->tqi_ready_time = qinfo->tqi_ready_time; 171 172 /*XXX: Is this supported on 5210 ?*/ 173 /*XXX: Is this correct for AR5K_WME_AC_VI,VO ???*/ 174 if ((qinfo->tqi_type == AR5K_TX_QUEUE_DATA && 175 ((qinfo->tqi_subtype == AR5K_WME_AC_VI) || 176 (qinfo->tqi_subtype == AR5K_WME_AC_VO))) || 177 qinfo->tqi_type == AR5K_TX_QUEUE_UAPSD) 178 qi->tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS; 179 180 return 0; 181 } 182 183 /** 184 * ath5k_hw_setup_tx_queue() - Initialize a transmit queue 185 * @ah: The &struct ath5k_hw 186 * @queue_type: One of enum ath5k_tx_queue 187 * @queue_info: The &struct ath5k_txq_info to use 188 * 189 * Returns 0 on success, -EINVAL on invalid arguments 190 */ 191 int 192 ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, 193 struct ath5k_txq_info *queue_info) 194 { 195 unsigned int queue; 196 int ret; 197 198 /* 199 * Get queue by type 200 */ 201 /* 5210 only has 2 queues */ 202 if (ah->ah_capabilities.cap_queues.q_tx_num == 2) { 203 switch (queue_type) { 204 case AR5K_TX_QUEUE_DATA: 205 queue = AR5K_TX_QUEUE_ID_NOQCU_DATA; 206 break; 207 case AR5K_TX_QUEUE_BEACON: 208 case AR5K_TX_QUEUE_CAB: 209 queue = AR5K_TX_QUEUE_ID_NOQCU_BEACON; 210 break; 211 default: 212 return -EINVAL; 213 } 214 } else { 215 switch (queue_type) { 216 case AR5K_TX_QUEUE_DATA: 217 for (queue = AR5K_TX_QUEUE_ID_DATA_MIN; 218 ah->ah_txq[queue].tqi_type != 219 AR5K_TX_QUEUE_INACTIVE; queue++) { 220 221 if (queue > AR5K_TX_QUEUE_ID_DATA_MAX) 222 return -EINVAL; 223 } 224 break; 225 case AR5K_TX_QUEUE_UAPSD: 226 queue = AR5K_TX_QUEUE_ID_UAPSD; 227 break; 228 case AR5K_TX_QUEUE_BEACON: 229 queue = AR5K_TX_QUEUE_ID_BEACON; 230 break; 231 case AR5K_TX_QUEUE_CAB: 232 queue = AR5K_TX_QUEUE_ID_CAB; 233 break; 234 default: 235 return -EINVAL; 236 } 237 } 238 239 /* 240 * Setup internal queue structure 241 */ 242 memset(&ah->ah_txq[queue], 0, sizeof(struct ath5k_txq_info)); 243 ah->ah_txq[queue].tqi_type = queue_type; 244 245 if (queue_info != NULL) { 246 queue_info->tqi_type = queue_type; 247 ret = ath5k_hw_set_tx_queueprops(ah, queue, queue_info); 248 if (ret) 249 return ret; 250 } 251 252 /* 253 * We use ah_txq_status to hold a temp value for 254 * the Secondary interrupt mask registers on 5211+ 255 * check out ath5k_hw_reset_tx_queue 256 */ 257 AR5K_Q_ENABLE_BITS(ah->ah_txq_status, queue); 258 259 return queue; 260 } 261 262 263 /*******************************\ 264 * Single QCU/DCU initialization * 265 \*******************************/ 266 267 /** 268 * ath5k_hw_set_tx_retry_limits() - Set tx retry limits on DCU 269 * @ah: The &struct ath5k_hw 270 * @queue: The hw queue number 271 * 272 * This function is used when initializing a queue, to set 273 * retry limits based on ah->ah_retry_* and the chipset used. 274 */ 275 void 276 ath5k_hw_set_tx_retry_limits(struct ath5k_hw *ah, 277 unsigned int queue) 278 { 279 /* Single data queue on AR5210 */ 280 if (ah->ah_version == AR5K_AR5210) { 281 struct ath5k_txq_info *tq = &ah->ah_txq[queue]; 282 283 if (queue > 0) 284 return; 285 286 ath5k_hw_reg_write(ah, 287 (tq->tqi_cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S) 288 | AR5K_REG_SM(ah->ah_retry_long, 289 AR5K_NODCU_RETRY_LMT_SLG_RETRY) 290 | AR5K_REG_SM(ah->ah_retry_short, 291 AR5K_NODCU_RETRY_LMT_SSH_RETRY) 292 | AR5K_REG_SM(ah->ah_retry_long, 293 AR5K_NODCU_RETRY_LMT_LG_RETRY) 294 | AR5K_REG_SM(ah->ah_retry_short, 295 AR5K_NODCU_RETRY_LMT_SH_RETRY), 296 AR5K_NODCU_RETRY_LMT); 297 /* DCU on AR5211+ */ 298 } else { 299 ath5k_hw_reg_write(ah, 300 AR5K_REG_SM(ah->ah_retry_long, 301 AR5K_DCU_RETRY_LMT_RTS) 302 | AR5K_REG_SM(ah->ah_retry_long, 303 AR5K_DCU_RETRY_LMT_STA_RTS) 304 | AR5K_REG_SM(max(ah->ah_retry_long, ah->ah_retry_short), 305 AR5K_DCU_RETRY_LMT_STA_DATA), 306 AR5K_QUEUE_DFS_RETRY_LIMIT(queue)); 307 } 308 } 309 310 /** 311 * ath5k_hw_reset_tx_queue() - Initialize a single hw queue 312 * @ah: The &struct ath5k_hw 313 * @queue: The hw queue number 314 * 315 * Set DFS properties for the given transmit queue on DCU 316 * and configures all queue-specific parameters. 317 */ 318 int 319 ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) 320 { 321 struct ath5k_txq_info *tq = &ah->ah_txq[queue]; 322 323 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); 324 325 tq = &ah->ah_txq[queue]; 326 327 /* Skip if queue inactive or if we are on AR5210 328 * that doesn't have QCU/DCU */ 329 if ((ah->ah_version == AR5K_AR5210) || 330 (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE)) 331 return 0; 332 333 /* 334 * Set contention window (cw_min/cw_max) 335 * and arbitrated interframe space (aifs)... 336 */ 337 ath5k_hw_reg_write(ah, 338 AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) | 339 AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) | 340 AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS), 341 AR5K_QUEUE_DFS_LOCAL_IFS(queue)); 342 343 /* 344 * Set tx retry limits for this queue 345 */ 346 ath5k_hw_set_tx_retry_limits(ah, queue); 347 348 349 /* 350 * Set misc registers 351 */ 352 353 /* Enable DCU to wait for next fragment from QCU */ 354 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), 355 AR5K_DCU_MISC_FRAG_WAIT); 356 357 /* On Maui and Spirit use the global seqnum on DCU */ 358 if (ah->ah_mac_version < AR5K_SREV_AR5211) 359 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), 360 AR5K_DCU_MISC_SEQNUM_CTL); 361 362 /* Constant bit rate period */ 363 if (tq->tqi_cbr_period) { 364 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period, 365 AR5K_QCU_CBRCFG_INTVAL) | 366 AR5K_REG_SM(tq->tqi_cbr_overflow_limit, 367 AR5K_QCU_CBRCFG_ORN_THRES), 368 AR5K_QUEUE_CBRCFG(queue)); 369 370 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), 371 AR5K_QCU_MISC_FRSHED_CBR); 372 373 if (tq->tqi_cbr_overflow_limit) 374 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), 375 AR5K_QCU_MISC_CBR_THRES_ENABLE); 376 } 377 378 /* Ready time interval */ 379 if (tq->tqi_ready_time && (tq->tqi_type != AR5K_TX_QUEUE_CAB)) 380 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time, 381 AR5K_QCU_RDYTIMECFG_INTVAL) | 382 AR5K_QCU_RDYTIMECFG_ENABLE, 383 AR5K_QUEUE_RDYTIMECFG(queue)); 384 385 if (tq->tqi_burst_time) { 386 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time, 387 AR5K_DCU_CHAN_TIME_DUR) | 388 AR5K_DCU_CHAN_TIME_ENABLE, 389 AR5K_QUEUE_DFS_CHANNEL_TIME(queue)); 390 391 if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE) 392 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), 393 AR5K_QCU_MISC_RDY_VEOL_POLICY); 394 } 395 396 /* Enable/disable Post frame backoff */ 397 if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE) 398 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS, 399 AR5K_QUEUE_DFS_MISC(queue)); 400 401 /* Enable/disable fragmentation burst backoff */ 402 if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) 403 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG, 404 AR5K_QUEUE_DFS_MISC(queue)); 405 406 /* 407 * Set registers by queue type 408 */ 409 switch (tq->tqi_type) { 410 case AR5K_TX_QUEUE_BEACON: 411 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), 412 AR5K_QCU_MISC_FRSHED_DBA_GT | 413 AR5K_QCU_MISC_CBREXP_BCN_DIS | 414 AR5K_QCU_MISC_BCN_ENABLE); 415 416 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), 417 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL << 418 AR5K_DCU_MISC_ARBLOCK_CTL_S) | 419 AR5K_DCU_MISC_ARBLOCK_IGNORE | 420 AR5K_DCU_MISC_POST_FR_BKOFF_DIS | 421 AR5K_DCU_MISC_BCN_ENABLE); 422 break; 423 424 case AR5K_TX_QUEUE_CAB: 425 /* XXX: use BCN_SENT_GT, if we can figure out how */ 426 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), 427 AR5K_QCU_MISC_FRSHED_DBA_GT | 428 AR5K_QCU_MISC_CBREXP_DIS | 429 AR5K_QCU_MISC_CBREXP_BCN_DIS); 430 431 ath5k_hw_reg_write(ah, ((tq->tqi_ready_time - 432 (AR5K_TUNE_SW_BEACON_RESP - 433 AR5K_TUNE_DMA_BEACON_RESP) - 434 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) | 435 AR5K_QCU_RDYTIMECFG_ENABLE, 436 AR5K_QUEUE_RDYTIMECFG(queue)); 437 438 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), 439 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL << 440 AR5K_DCU_MISC_ARBLOCK_CTL_S)); 441 break; 442 443 case AR5K_TX_QUEUE_UAPSD: 444 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), 445 AR5K_QCU_MISC_CBREXP_DIS); 446 break; 447 448 case AR5K_TX_QUEUE_DATA: 449 default: 450 break; 451 } 452 453 /* TODO: Handle frame compression */ 454 455 /* 456 * Enable interrupts for this tx queue 457 * in the secondary interrupt mask registers 458 */ 459 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE) 460 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue); 461 462 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE) 463 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue); 464 465 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE) 466 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue); 467 468 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE) 469 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue); 470 471 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE) 472 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue); 473 474 if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE) 475 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue); 476 477 if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE) 478 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue); 479 480 if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE) 481 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue); 482 483 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE) 484 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue); 485 486 /* Update secondary interrupt mask registers */ 487 488 /* Filter out inactive queues */ 489 ah->ah_txq_imr_txok &= ah->ah_txq_status; 490 ah->ah_txq_imr_txerr &= ah->ah_txq_status; 491 ah->ah_txq_imr_txurn &= ah->ah_txq_status; 492 ah->ah_txq_imr_txdesc &= ah->ah_txq_status; 493 ah->ah_txq_imr_txeol &= ah->ah_txq_status; 494 ah->ah_txq_imr_cbrorn &= ah->ah_txq_status; 495 ah->ah_txq_imr_cbrurn &= ah->ah_txq_status; 496 ah->ah_txq_imr_qtrig &= ah->ah_txq_status; 497 ah->ah_txq_imr_nofrm &= ah->ah_txq_status; 498 499 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok, 500 AR5K_SIMR0_QCU_TXOK) | 501 AR5K_REG_SM(ah->ah_txq_imr_txdesc, 502 AR5K_SIMR0_QCU_TXDESC), 503 AR5K_SIMR0); 504 505 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr, 506 AR5K_SIMR1_QCU_TXERR) | 507 AR5K_REG_SM(ah->ah_txq_imr_txeol, 508 AR5K_SIMR1_QCU_TXEOL), 509 AR5K_SIMR1); 510 511 /* Update SIMR2 but don't overwrite rest simr2 settings */ 512 AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN); 513 AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2, 514 AR5K_REG_SM(ah->ah_txq_imr_txurn, 515 AR5K_SIMR2_QCU_TXURN)); 516 517 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn, 518 AR5K_SIMR3_QCBRORN) | 519 AR5K_REG_SM(ah->ah_txq_imr_cbrurn, 520 AR5K_SIMR3_QCBRURN), 521 AR5K_SIMR3); 522 523 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig, 524 AR5K_SIMR4_QTRIG), AR5K_SIMR4); 525 526 /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */ 527 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm, 528 AR5K_TXNOFRM_QCU), AR5K_TXNOFRM); 529 530 /* No queue has TXNOFRM enabled, disable the interrupt 531 * by setting AR5K_TXNOFRM to zero */ 532 if (ah->ah_txq_imr_nofrm == 0) 533 ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM); 534 535 /* Set QCU mask for this DCU to save power */ 536 AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue); 537 538 return 0; 539 } 540 541 542 /**************************\ 543 * Global QCU/DCU functions * 544 \**************************/ 545 546 /** 547 * ath5k_hw_set_ifs_intervals() - Set global inter-frame spaces on DCU 548 * @ah: The &struct ath5k_hw 549 * @slot_time: Slot time in us 550 * 551 * Sets the global IFS intervals on DCU (also works on AR5210) for 552 * the given slot time and the current bwmode. 553 */ 554 int ath5k_hw_set_ifs_intervals(struct ath5k_hw *ah, unsigned int slot_time) 555 { 556 struct ieee80211_channel *channel = ah->ah_current_channel; 557 struct ieee80211_rate *rate; 558 u32 ack_tx_time, eifs, eifs_clock, sifs, sifs_clock; 559 u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time); 560 561 if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX) 562 return -EINVAL; 563 564 sifs = ath5k_hw_get_default_sifs(ah); 565 sifs_clock = ath5k_hw_htoclock(ah, sifs - 2); 566 567 /* EIFS 568 * Txtime of ack at lowest rate + SIFS + DIFS 569 * (DIFS = SIFS + 2 * Slot time) 570 * 571 * Note: HAL has some predefined values for EIFS 572 * Turbo: (37 + 2 * 6) 573 * Default: (74 + 2 * 9) 574 * Half: (149 + 2 * 13) 575 * Quarter: (298 + 2 * 21) 576 * 577 * (74 + 2 * 6) for AR5210 default and turbo ! 578 * 579 * According to the formula we have 580 * ack_tx_time = 25 for turbo and 581 * ack_tx_time = 42.5 * clock multiplier 582 * for default/half/quarter. 583 * 584 * This can't be right, 42 is what we would get 585 * from ath5k_hw_get_frame_dur_for_bwmode or 586 * ieee80211_generic_frame_duration for zero frame 587 * length and without SIFS ! 588 * 589 * Also we have different lowest rate for 802.11a 590 */ 591 if (channel->band == IEEE80211_BAND_5GHZ) 592 rate = &ah->sbands[IEEE80211_BAND_5GHZ].bitrates[0]; 593 else 594 rate = &ah->sbands[IEEE80211_BAND_2GHZ].bitrates[0]; 595 596 ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false); 597 598 /* ack_tx_time includes an SIFS already */ 599 eifs = ack_tx_time + sifs + 2 * slot_time; 600 eifs_clock = ath5k_hw_htoclock(ah, eifs); 601 602 /* Set IFS settings on AR5210 */ 603 if (ah->ah_version == AR5K_AR5210) { 604 u32 pifs, pifs_clock, difs, difs_clock; 605 606 /* Set slot time */ 607 ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME); 608 609 /* Set EIFS */ 610 eifs_clock = AR5K_REG_SM(eifs_clock, AR5K_IFS1_EIFS); 611 612 /* PIFS = Slot time + SIFS */ 613 pifs = slot_time + sifs; 614 pifs_clock = ath5k_hw_htoclock(ah, pifs); 615 pifs_clock = AR5K_REG_SM(pifs_clock, AR5K_IFS1_PIFS); 616 617 /* DIFS = SIFS + 2 * Slot time */ 618 difs = sifs + 2 * slot_time; 619 difs_clock = ath5k_hw_htoclock(ah, difs); 620 621 /* Set SIFS/DIFS */ 622 ath5k_hw_reg_write(ah, (difs_clock << 623 AR5K_IFS0_DIFS_S) | sifs_clock, 624 AR5K_IFS0); 625 626 /* Set PIFS/EIFS and preserve AR5K_INIT_CARR_SENSE_EN */ 627 ath5k_hw_reg_write(ah, pifs_clock | eifs_clock | 628 (AR5K_INIT_CARR_SENSE_EN << AR5K_IFS1_CS_EN_S), 629 AR5K_IFS1); 630 631 return 0; 632 } 633 634 /* Set IFS slot time */ 635 ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT); 636 637 /* Set EIFS interval */ 638 ath5k_hw_reg_write(ah, eifs_clock, AR5K_DCU_GBL_IFS_EIFS); 639 640 /* Set SIFS interval in usecs */ 641 AR5K_REG_WRITE_BITS(ah, AR5K_DCU_GBL_IFS_MISC, 642 AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC, 643 sifs); 644 645 /* Set SIFS interval in clock cycles */ 646 ath5k_hw_reg_write(ah, sifs_clock, AR5K_DCU_GBL_IFS_SIFS); 647 648 return 0; 649 } 650 651 652 /** 653 * ath5k_hw_init_queues() - Initialize tx queues 654 * @ah: The &struct ath5k_hw 655 * 656 * Initializes all tx queues based on information on 657 * ah->ah_txq* set by the driver 658 */ 659 int 660 ath5k_hw_init_queues(struct ath5k_hw *ah) 661 { 662 int i, ret; 663 664 /* TODO: HW Compression support for data queues */ 665 /* TODO: Burst prefetch for data queues */ 666 667 /* 668 * Reset queues and start beacon timers at the end of the reset routine 669 * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping 670 * Note: If we want we can assign multiple qcus on one dcu. 671 */ 672 if (ah->ah_version != AR5K_AR5210) 673 for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) { 674 ret = ath5k_hw_reset_tx_queue(ah, i); 675 if (ret) { 676 ATH5K_ERR(ah, 677 "failed to reset TX queue #%d\n", i); 678 return ret; 679 } 680 } 681 else 682 /* No QCU/DCU on AR5210, just set tx 683 * retry limits. We set IFS parameters 684 * on ath5k_hw_set_ifs_intervals */ 685 ath5k_hw_set_tx_retry_limits(ah, 0); 686 687 /* Set the turbo flag when operating on 40MHz */ 688 if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) 689 AR5K_REG_ENABLE_BITS(ah, AR5K_DCU_GBL_IFS_MISC, 690 AR5K_DCU_GBL_IFS_MISC_TURBO_MODE); 691 692 /* If we didn't set IFS timings through 693 * ath5k_hw_set_coverage_class make sure 694 * we set them here */ 695 if (!ah->ah_coverage_class) { 696 unsigned int slot_time = ath5k_hw_get_default_slottime(ah); 697 ath5k_hw_set_ifs_intervals(ah, slot_time); 698 } 699 700 return 0; 701 } 702