1 /* 2 * Copyright (c) 2008-2009 Atheros Communications 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 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include "hw.h" 18 19 static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah, 20 struct ath9k_tx_queue_info *qi) 21 { 22 ath_print(ath9k_hw_common(ah), ATH_DBG_INTERRUPT, 23 "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n", 24 ah->txok_interrupt_mask, ah->txerr_interrupt_mask, 25 ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask, 26 ah->txurn_interrupt_mask); 27 28 ENABLE_REGWRITE_BUFFER(ah); 29 30 REG_WRITE(ah, AR_IMR_S0, 31 SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK) 32 | SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC)); 33 REG_WRITE(ah, AR_IMR_S1, 34 SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR) 35 | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL)); 36 37 ah->imrs2_reg &= ~AR_IMR_S2_QCU_TXURN; 38 ah->imrs2_reg |= (ah->txurn_interrupt_mask & AR_IMR_S2_QCU_TXURN); 39 REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg); 40 41 REGWRITE_BUFFER_FLUSH(ah); 42 DISABLE_REGWRITE_BUFFER(ah); 43 } 44 45 u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q) 46 { 47 return REG_READ(ah, AR_QTXDP(q)); 48 } 49 EXPORT_SYMBOL(ath9k_hw_gettxbuf); 50 51 void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp) 52 { 53 REG_WRITE(ah, AR_QTXDP(q), txdp); 54 } 55 EXPORT_SYMBOL(ath9k_hw_puttxbuf); 56 57 void ath9k_hw_txstart(struct ath_hw *ah, u32 q) 58 { 59 ath_print(ath9k_hw_common(ah), ATH_DBG_QUEUE, 60 "Enable TXE on queue: %u\n", q); 61 REG_WRITE(ah, AR_Q_TXE, 1 << q); 62 } 63 EXPORT_SYMBOL(ath9k_hw_txstart); 64 65 void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds) 66 { 67 struct ar5416_desc *ads = AR5416DESC(ds); 68 69 ads->ds_txstatus0 = ads->ds_txstatus1 = 0; 70 ads->ds_txstatus2 = ads->ds_txstatus3 = 0; 71 ads->ds_txstatus4 = ads->ds_txstatus5 = 0; 72 ads->ds_txstatus6 = ads->ds_txstatus7 = 0; 73 ads->ds_txstatus8 = ads->ds_txstatus9 = 0; 74 } 75 EXPORT_SYMBOL(ath9k_hw_cleartxdesc); 76 77 u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q) 78 { 79 u32 npend; 80 81 npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT; 82 if (npend == 0) { 83 84 if (REG_READ(ah, AR_Q_TXE) & (1 << q)) 85 npend = 1; 86 } 87 88 return npend; 89 } 90 EXPORT_SYMBOL(ath9k_hw_numtxpending); 91 92 /** 93 * ath9k_hw_updatetxtriglevel - adjusts the frame trigger level 94 * 95 * @ah: atheros hardware struct 96 * @bIncTrigLevel: whether or not the frame trigger level should be updated 97 * 98 * The frame trigger level specifies the minimum number of bytes, 99 * in units of 64 bytes, that must be DMA'ed into the PCU TX FIFO 100 * before the PCU will initiate sending the frame on the air. This can 101 * mean we initiate transmit before a full frame is on the PCU TX FIFO. 102 * Resets to 0x1 (meaning 64 bytes or a full frame, whichever occurs 103 * first) 104 * 105 * Caution must be taken to ensure to set the frame trigger level based 106 * on the DMA request size. For example if the DMA request size is set to 107 * 128 bytes the trigger level cannot exceed 6 * 64 = 384. This is because 108 * there need to be enough space in the tx FIFO for the requested transfer 109 * size. Hence the tx FIFO will stop with 512 - 128 = 384 bytes. If we set 110 * the threshold to a value beyond 6, then the transmit will hang. 111 * 112 * Current dual stream devices have a PCU TX FIFO size of 8 KB. 113 * Current single stream devices have a PCU TX FIFO size of 4 KB, however, 114 * there is a hardware issue which forces us to use 2 KB instead so the 115 * frame trigger level must not exceed 2 KB for these chipsets. 116 */ 117 bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel) 118 { 119 u32 txcfg, curLevel, newLevel; 120 enum ath9k_int omask; 121 122 if (ah->tx_trig_level >= ah->config.max_txtrig_level) 123 return false; 124 125 omask = ath9k_hw_set_interrupts(ah, ah->imask & ~ATH9K_INT_GLOBAL); 126 127 txcfg = REG_READ(ah, AR_TXCFG); 128 curLevel = MS(txcfg, AR_FTRIG); 129 newLevel = curLevel; 130 if (bIncTrigLevel) { 131 if (curLevel < ah->config.max_txtrig_level) 132 newLevel++; 133 } else if (curLevel > MIN_TX_FIFO_THRESHOLD) 134 newLevel--; 135 if (newLevel != curLevel) 136 REG_WRITE(ah, AR_TXCFG, 137 (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG)); 138 139 ath9k_hw_set_interrupts(ah, omask); 140 141 ah->tx_trig_level = newLevel; 142 143 return newLevel != curLevel; 144 } 145 EXPORT_SYMBOL(ath9k_hw_updatetxtriglevel); 146 147 bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q) 148 { 149 #define ATH9K_TX_STOP_DMA_TIMEOUT 4000 /* usec */ 150 #define ATH9K_TIME_QUANTUM 100 /* usec */ 151 struct ath_common *common = ath9k_hw_common(ah); 152 struct ath9k_hw_capabilities *pCap = &ah->caps; 153 struct ath9k_tx_queue_info *qi; 154 u32 tsfLow, j, wait; 155 u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM; 156 157 if (q >= pCap->total_queues) { 158 ath_print(common, ATH_DBG_QUEUE, "Stopping TX DMA, " 159 "invalid queue: %u\n", q); 160 return false; 161 } 162 163 qi = &ah->txq[q]; 164 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 165 ath_print(common, ATH_DBG_QUEUE, "Stopping TX DMA, " 166 "inactive queue: %u\n", q); 167 return false; 168 } 169 170 REG_WRITE(ah, AR_Q_TXD, 1 << q); 171 172 for (wait = wait_time; wait != 0; wait--) { 173 if (ath9k_hw_numtxpending(ah, q) == 0) 174 break; 175 udelay(ATH9K_TIME_QUANTUM); 176 } 177 178 if (ath9k_hw_numtxpending(ah, q)) { 179 ath_print(common, ATH_DBG_QUEUE, 180 "%s: Num of pending TX Frames %d on Q %d\n", 181 __func__, ath9k_hw_numtxpending(ah, q), q); 182 183 for (j = 0; j < 2; j++) { 184 tsfLow = REG_READ(ah, AR_TSF_L32); 185 REG_WRITE(ah, AR_QUIET2, 186 SM(10, AR_QUIET2_QUIET_DUR)); 187 REG_WRITE(ah, AR_QUIET_PERIOD, 100); 188 REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10); 189 REG_SET_BIT(ah, AR_TIMER_MODE, 190 AR_QUIET_TIMER_EN); 191 192 if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10)) 193 break; 194 195 ath_print(common, ATH_DBG_QUEUE, 196 "TSF has moved while trying to set " 197 "quiet time TSF: 0x%08x\n", tsfLow); 198 } 199 200 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); 201 202 udelay(200); 203 REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN); 204 205 wait = wait_time; 206 while (ath9k_hw_numtxpending(ah, q)) { 207 if ((--wait) == 0) { 208 ath_print(common, ATH_DBG_FATAL, 209 "Failed to stop TX DMA in 100 " 210 "msec after killing last frame\n"); 211 break; 212 } 213 udelay(ATH9K_TIME_QUANTUM); 214 } 215 216 REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); 217 } 218 219 REG_WRITE(ah, AR_Q_TXD, 0); 220 return wait != 0; 221 222 #undef ATH9K_TX_STOP_DMA_TIMEOUT 223 #undef ATH9K_TIME_QUANTUM 224 } 225 EXPORT_SYMBOL(ath9k_hw_stoptxdma); 226 227 void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs) 228 { 229 *txqs &= ah->intr_txqs; 230 ah->intr_txqs &= ~(*txqs); 231 } 232 EXPORT_SYMBOL(ath9k_hw_gettxintrtxqs); 233 234 bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, 235 const struct ath9k_tx_queue_info *qinfo) 236 { 237 u32 cw; 238 struct ath_common *common = ath9k_hw_common(ah); 239 struct ath9k_hw_capabilities *pCap = &ah->caps; 240 struct ath9k_tx_queue_info *qi; 241 242 if (q >= pCap->total_queues) { 243 ath_print(common, ATH_DBG_QUEUE, "Set TXQ properties, " 244 "invalid queue: %u\n", q); 245 return false; 246 } 247 248 qi = &ah->txq[q]; 249 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 250 ath_print(common, ATH_DBG_QUEUE, "Set TXQ properties, " 251 "inactive queue: %u\n", q); 252 return false; 253 } 254 255 ath_print(common, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q); 256 257 qi->tqi_ver = qinfo->tqi_ver; 258 qi->tqi_subtype = qinfo->tqi_subtype; 259 qi->tqi_qflags = qinfo->tqi_qflags; 260 qi->tqi_priority = qinfo->tqi_priority; 261 if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT) 262 qi->tqi_aifs = min(qinfo->tqi_aifs, 255U); 263 else 264 qi->tqi_aifs = INIT_AIFS; 265 if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) { 266 cw = min(qinfo->tqi_cwmin, 1024U); 267 qi->tqi_cwmin = 1; 268 while (qi->tqi_cwmin < cw) 269 qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1; 270 } else 271 qi->tqi_cwmin = qinfo->tqi_cwmin; 272 if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) { 273 cw = min(qinfo->tqi_cwmax, 1024U); 274 qi->tqi_cwmax = 1; 275 while (qi->tqi_cwmax < cw) 276 qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1; 277 } else 278 qi->tqi_cwmax = INIT_CWMAX; 279 280 if (qinfo->tqi_shretry != 0) 281 qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U); 282 else 283 qi->tqi_shretry = INIT_SH_RETRY; 284 if (qinfo->tqi_lgretry != 0) 285 qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U); 286 else 287 qi->tqi_lgretry = INIT_LG_RETRY; 288 qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod; 289 qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit; 290 qi->tqi_burstTime = qinfo->tqi_burstTime; 291 qi->tqi_readyTime = qinfo->tqi_readyTime; 292 293 switch (qinfo->tqi_subtype) { 294 case ATH9K_WME_UPSD: 295 if (qi->tqi_type == ATH9K_TX_QUEUE_DATA) 296 qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS; 297 break; 298 default: 299 break; 300 } 301 302 return true; 303 } 304 EXPORT_SYMBOL(ath9k_hw_set_txq_props); 305 306 bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q, 307 struct ath9k_tx_queue_info *qinfo) 308 { 309 struct ath_common *common = ath9k_hw_common(ah); 310 struct ath9k_hw_capabilities *pCap = &ah->caps; 311 struct ath9k_tx_queue_info *qi; 312 313 if (q >= pCap->total_queues) { 314 ath_print(common, ATH_DBG_QUEUE, "Get TXQ properties, " 315 "invalid queue: %u\n", q); 316 return false; 317 } 318 319 qi = &ah->txq[q]; 320 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 321 ath_print(common, ATH_DBG_QUEUE, "Get TXQ properties, " 322 "inactive queue: %u\n", q); 323 return false; 324 } 325 326 qinfo->tqi_qflags = qi->tqi_qflags; 327 qinfo->tqi_ver = qi->tqi_ver; 328 qinfo->tqi_subtype = qi->tqi_subtype; 329 qinfo->tqi_qflags = qi->tqi_qflags; 330 qinfo->tqi_priority = qi->tqi_priority; 331 qinfo->tqi_aifs = qi->tqi_aifs; 332 qinfo->tqi_cwmin = qi->tqi_cwmin; 333 qinfo->tqi_cwmax = qi->tqi_cwmax; 334 qinfo->tqi_shretry = qi->tqi_shretry; 335 qinfo->tqi_lgretry = qi->tqi_lgretry; 336 qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod; 337 qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit; 338 qinfo->tqi_burstTime = qi->tqi_burstTime; 339 qinfo->tqi_readyTime = qi->tqi_readyTime; 340 341 return true; 342 } 343 EXPORT_SYMBOL(ath9k_hw_get_txq_props); 344 345 int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type, 346 const struct ath9k_tx_queue_info *qinfo) 347 { 348 struct ath_common *common = ath9k_hw_common(ah); 349 struct ath9k_tx_queue_info *qi; 350 struct ath9k_hw_capabilities *pCap = &ah->caps; 351 int q; 352 353 switch (type) { 354 case ATH9K_TX_QUEUE_BEACON: 355 q = pCap->total_queues - 1; 356 break; 357 case ATH9K_TX_QUEUE_CAB: 358 q = pCap->total_queues - 2; 359 break; 360 case ATH9K_TX_QUEUE_PSPOLL: 361 q = 1; 362 break; 363 case ATH9K_TX_QUEUE_UAPSD: 364 q = pCap->total_queues - 3; 365 break; 366 case ATH9K_TX_QUEUE_DATA: 367 for (q = 0; q < pCap->total_queues; q++) 368 if (ah->txq[q].tqi_type == 369 ATH9K_TX_QUEUE_INACTIVE) 370 break; 371 if (q == pCap->total_queues) { 372 ath_print(common, ATH_DBG_FATAL, 373 "No available TX queue\n"); 374 return -1; 375 } 376 break; 377 default: 378 ath_print(common, ATH_DBG_FATAL, 379 "Invalid TX queue type: %u\n", type); 380 return -1; 381 } 382 383 ath_print(common, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q); 384 385 qi = &ah->txq[q]; 386 if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) { 387 ath_print(common, ATH_DBG_FATAL, 388 "TX queue: %u already active\n", q); 389 return -1; 390 } 391 memset(qi, 0, sizeof(struct ath9k_tx_queue_info)); 392 qi->tqi_type = type; 393 if (qinfo == NULL) { 394 qi->tqi_qflags = 395 TXQ_FLAG_TXOKINT_ENABLE 396 | TXQ_FLAG_TXERRINT_ENABLE 397 | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE; 398 qi->tqi_aifs = INIT_AIFS; 399 qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT; 400 qi->tqi_cwmax = INIT_CWMAX; 401 qi->tqi_shretry = INIT_SH_RETRY; 402 qi->tqi_lgretry = INIT_LG_RETRY; 403 qi->tqi_physCompBuf = 0; 404 } else { 405 qi->tqi_physCompBuf = qinfo->tqi_physCompBuf; 406 (void) ath9k_hw_set_txq_props(ah, q, qinfo); 407 } 408 409 return q; 410 } 411 EXPORT_SYMBOL(ath9k_hw_setuptxqueue); 412 413 bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q) 414 { 415 struct ath9k_hw_capabilities *pCap = &ah->caps; 416 struct ath_common *common = ath9k_hw_common(ah); 417 struct ath9k_tx_queue_info *qi; 418 419 if (q >= pCap->total_queues) { 420 ath_print(common, ATH_DBG_QUEUE, "Release TXQ, " 421 "invalid queue: %u\n", q); 422 return false; 423 } 424 qi = &ah->txq[q]; 425 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 426 ath_print(common, ATH_DBG_QUEUE, "Release TXQ, " 427 "inactive queue: %u\n", q); 428 return false; 429 } 430 431 ath_print(common, ATH_DBG_QUEUE, "Release TX queue: %u\n", q); 432 433 qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE; 434 ah->txok_interrupt_mask &= ~(1 << q); 435 ah->txerr_interrupt_mask &= ~(1 << q); 436 ah->txdesc_interrupt_mask &= ~(1 << q); 437 ah->txeol_interrupt_mask &= ~(1 << q); 438 ah->txurn_interrupt_mask &= ~(1 << q); 439 ath9k_hw_set_txq_interrupts(ah, qi); 440 441 return true; 442 } 443 EXPORT_SYMBOL(ath9k_hw_releasetxqueue); 444 445 bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) 446 { 447 struct ath9k_hw_capabilities *pCap = &ah->caps; 448 struct ath_common *common = ath9k_hw_common(ah); 449 struct ath9k_channel *chan = ah->curchan; 450 struct ath9k_tx_queue_info *qi; 451 u32 cwMin, chanCwMin, value; 452 453 if (q >= pCap->total_queues) { 454 ath_print(common, ATH_DBG_QUEUE, "Reset TXQ, " 455 "invalid queue: %u\n", q); 456 return false; 457 } 458 459 qi = &ah->txq[q]; 460 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { 461 ath_print(common, ATH_DBG_QUEUE, "Reset TXQ, " 462 "inactive queue: %u\n", q); 463 return true; 464 } 465 466 ath_print(common, ATH_DBG_QUEUE, "Reset TX queue: %u\n", q); 467 468 if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) { 469 if (chan && IS_CHAN_B(chan)) 470 chanCwMin = INIT_CWMIN_11B; 471 else 472 chanCwMin = INIT_CWMIN; 473 474 for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1); 475 } else 476 cwMin = qi->tqi_cwmin; 477 478 ENABLE_REGWRITE_BUFFER(ah); 479 480 REG_WRITE(ah, AR_DLCL_IFS(q), 481 SM(cwMin, AR_D_LCL_IFS_CWMIN) | 482 SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) | 483 SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS)); 484 485 REG_WRITE(ah, AR_DRETRY_LIMIT(q), 486 SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH) | 487 SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG) | 488 SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)); 489 490 REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ); 491 REG_WRITE(ah, AR_DMISC(q), 492 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2); 493 494 REGWRITE_BUFFER_FLUSH(ah); 495 496 if (qi->tqi_cbrPeriod) { 497 REG_WRITE(ah, AR_QCBRCFG(q), 498 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) | 499 SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH)); 500 REG_WRITE(ah, AR_QMISC(q), 501 REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_FSP_CBR | 502 (qi->tqi_cbrOverflowLimit ? 503 AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0)); 504 } 505 if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) { 506 REG_WRITE(ah, AR_QRDYTIMECFG(q), 507 SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) | 508 AR_Q_RDYTIMECFG_EN); 509 } 510 511 REGWRITE_BUFFER_FLUSH(ah); 512 513 REG_WRITE(ah, AR_DCHNTIME(q), 514 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) | 515 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0)); 516 517 if (qi->tqi_burstTime 518 && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) { 519 REG_WRITE(ah, AR_QMISC(q), 520 REG_READ(ah, AR_QMISC(q)) | 521 AR_Q_MISC_RDYTIME_EXP_POLICY); 522 523 } 524 525 if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) { 526 REG_WRITE(ah, AR_DMISC(q), 527 REG_READ(ah, AR_DMISC(q)) | 528 AR_D_MISC_POST_FR_BKOFF_DIS); 529 } 530 531 REGWRITE_BUFFER_FLUSH(ah); 532 DISABLE_REGWRITE_BUFFER(ah); 533 534 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) { 535 REG_WRITE(ah, AR_DMISC(q), 536 REG_READ(ah, AR_DMISC(q)) | 537 AR_D_MISC_FRAG_BKOFF_EN); 538 } 539 switch (qi->tqi_type) { 540 case ATH9K_TX_QUEUE_BEACON: 541 ENABLE_REGWRITE_BUFFER(ah); 542 543 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) 544 | AR_Q_MISC_FSP_DBA_GATED 545 | AR_Q_MISC_BEACON_USE 546 | AR_Q_MISC_CBR_INCR_DIS1); 547 548 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) 549 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << 550 AR_D_MISC_ARB_LOCKOUT_CNTRL_S) 551 | AR_D_MISC_BEACON_USE 552 | AR_D_MISC_POST_FR_BKOFF_DIS); 553 554 REGWRITE_BUFFER_FLUSH(ah); 555 DISABLE_REGWRITE_BUFFER(ah); 556 557 /* cwmin and cwmax should be 0 for beacon queue */ 558 if (AR_SREV_9300_20_OR_LATER(ah)) { 559 REG_WRITE(ah, AR_DLCL_IFS(q), SM(0, AR_D_LCL_IFS_CWMIN) 560 | SM(0, AR_D_LCL_IFS_CWMAX) 561 | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS)); 562 } 563 break; 564 case ATH9K_TX_QUEUE_CAB: 565 ENABLE_REGWRITE_BUFFER(ah); 566 567 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) 568 | AR_Q_MISC_FSP_DBA_GATED 569 | AR_Q_MISC_CBR_INCR_DIS1 570 | AR_Q_MISC_CBR_INCR_DIS0); 571 value = (qi->tqi_readyTime - 572 (ah->config.sw_beacon_response_time - 573 ah->config.dma_beacon_response_time) - 574 ah->config.additional_swba_backoff) * 1024; 575 REG_WRITE(ah, AR_QRDYTIMECFG(q), 576 value | AR_Q_RDYTIMECFG_EN); 577 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) 578 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << 579 AR_D_MISC_ARB_LOCKOUT_CNTRL_S)); 580 581 REGWRITE_BUFFER_FLUSH(ah); 582 DISABLE_REGWRITE_BUFFER(ah); 583 584 break; 585 case ATH9K_TX_QUEUE_PSPOLL: 586 REG_WRITE(ah, AR_QMISC(q), 587 REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1); 588 break; 589 case ATH9K_TX_QUEUE_UAPSD: 590 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) | 591 AR_D_MISC_POST_FR_BKOFF_DIS); 592 break; 593 default: 594 break; 595 } 596 597 if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) { 598 REG_WRITE(ah, AR_DMISC(q), 599 REG_READ(ah, AR_DMISC(q)) | 600 SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL, 601 AR_D_MISC_ARB_LOCKOUT_CNTRL) | 602 AR_D_MISC_POST_FR_BKOFF_DIS); 603 } 604 605 if (AR_SREV_9300_20_OR_LATER(ah)) 606 REG_WRITE(ah, AR_Q_DESC_CRCCHK, AR_Q_DESC_CRCCHK_EN); 607 608 if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE) 609 ah->txok_interrupt_mask |= 1 << q; 610 else 611 ah->txok_interrupt_mask &= ~(1 << q); 612 if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE) 613 ah->txerr_interrupt_mask |= 1 << q; 614 else 615 ah->txerr_interrupt_mask &= ~(1 << q); 616 if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE) 617 ah->txdesc_interrupt_mask |= 1 << q; 618 else 619 ah->txdesc_interrupt_mask &= ~(1 << q); 620 if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE) 621 ah->txeol_interrupt_mask |= 1 << q; 622 else 623 ah->txeol_interrupt_mask &= ~(1 << q); 624 if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE) 625 ah->txurn_interrupt_mask |= 1 << q; 626 else 627 ah->txurn_interrupt_mask &= ~(1 << q); 628 ath9k_hw_set_txq_interrupts(ah, qi); 629 630 return true; 631 } 632 EXPORT_SYMBOL(ath9k_hw_resettxqueue); 633 634 int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, 635 struct ath_rx_status *rs, u64 tsf) 636 { 637 struct ar5416_desc ads; 638 struct ar5416_desc *adsp = AR5416DESC(ds); 639 u32 phyerr; 640 641 if ((adsp->ds_rxstatus8 & AR_RxDone) == 0) 642 return -EINPROGRESS; 643 644 ads.u.rx = adsp->u.rx; 645 646 rs->rs_status = 0; 647 rs->rs_flags = 0; 648 649 rs->rs_datalen = ads.ds_rxstatus1 & AR_DataLen; 650 rs->rs_tstamp = ads.AR_RcvTimestamp; 651 652 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) { 653 rs->rs_rssi = ATH9K_RSSI_BAD; 654 rs->rs_rssi_ctl0 = ATH9K_RSSI_BAD; 655 rs->rs_rssi_ctl1 = ATH9K_RSSI_BAD; 656 rs->rs_rssi_ctl2 = ATH9K_RSSI_BAD; 657 rs->rs_rssi_ext0 = ATH9K_RSSI_BAD; 658 rs->rs_rssi_ext1 = ATH9K_RSSI_BAD; 659 rs->rs_rssi_ext2 = ATH9K_RSSI_BAD; 660 } else { 661 rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined); 662 rs->rs_rssi_ctl0 = MS(ads.ds_rxstatus0, 663 AR_RxRSSIAnt00); 664 rs->rs_rssi_ctl1 = MS(ads.ds_rxstatus0, 665 AR_RxRSSIAnt01); 666 rs->rs_rssi_ctl2 = MS(ads.ds_rxstatus0, 667 AR_RxRSSIAnt02); 668 rs->rs_rssi_ext0 = MS(ads.ds_rxstatus4, 669 AR_RxRSSIAnt10); 670 rs->rs_rssi_ext1 = MS(ads.ds_rxstatus4, 671 AR_RxRSSIAnt11); 672 rs->rs_rssi_ext2 = MS(ads.ds_rxstatus4, 673 AR_RxRSSIAnt12); 674 } 675 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid) 676 rs->rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx); 677 else 678 rs->rs_keyix = ATH9K_RXKEYIX_INVALID; 679 680 rs->rs_rate = RXSTATUS_RATE(ah, (&ads)); 681 rs->rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0; 682 683 rs->rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0; 684 rs->rs_moreaggr = 685 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0; 686 rs->rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna); 687 rs->rs_flags = 688 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0; 689 rs->rs_flags |= 690 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0; 691 692 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr) 693 rs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE; 694 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) 695 rs->rs_flags |= ATH9K_RX_DELIM_CRC_POST; 696 if (ads.ds_rxstatus8 & AR_DecryptBusyErr) 697 rs->rs_flags |= ATH9K_RX_DECRYPT_BUSY; 698 699 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) { 700 if (ads.ds_rxstatus8 & AR_CRCErr) 701 rs->rs_status |= ATH9K_RXERR_CRC; 702 else if (ads.ds_rxstatus8 & AR_PHYErr) { 703 rs->rs_status |= ATH9K_RXERR_PHY; 704 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode); 705 rs->rs_phyerr = phyerr; 706 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) 707 rs->rs_status |= ATH9K_RXERR_DECRYPT; 708 else if (ads.ds_rxstatus8 & AR_MichaelErr) 709 rs->rs_status |= ATH9K_RXERR_MIC; 710 } 711 712 return 0; 713 } 714 EXPORT_SYMBOL(ath9k_hw_rxprocdesc); 715 716 /* 717 * This can stop or re-enables RX. 718 * 719 * If bool is set this will kill any frame which is currently being 720 * transferred between the MAC and baseband and also prevent any new 721 * frames from getting started. 722 */ 723 bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set) 724 { 725 u32 reg; 726 727 if (set) { 728 REG_SET_BIT(ah, AR_DIAG_SW, 729 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 730 731 if (!ath9k_hw_wait(ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 732 0, AH_WAIT_TIMEOUT)) { 733 REG_CLR_BIT(ah, AR_DIAG_SW, 734 (AR_DIAG_RX_DIS | 735 AR_DIAG_RX_ABORT)); 736 737 reg = REG_READ(ah, AR_OBS_BUS_1); 738 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, 739 "RX failed to go idle in 10 ms RXSM=0x%x\n", 740 reg); 741 742 return false; 743 } 744 } else { 745 REG_CLR_BIT(ah, AR_DIAG_SW, 746 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 747 } 748 749 return true; 750 } 751 EXPORT_SYMBOL(ath9k_hw_setrxabort); 752 753 void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp) 754 { 755 REG_WRITE(ah, AR_RXDP, rxdp); 756 } 757 EXPORT_SYMBOL(ath9k_hw_putrxbuf); 758 759 void ath9k_hw_startpcureceive(struct ath_hw *ah) 760 { 761 ath9k_enable_mib_counters(ah); 762 763 ath9k_ani_reset(ah); 764 765 REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 766 } 767 EXPORT_SYMBOL(ath9k_hw_startpcureceive); 768 769 void ath9k_hw_stoppcurecv(struct ath_hw *ah) 770 { 771 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); 772 773 ath9k_hw_disable_mib_counters(ah); 774 } 775 EXPORT_SYMBOL(ath9k_hw_stoppcurecv); 776 777 void ath9k_hw_abortpcurecv(struct ath_hw *ah) 778 { 779 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS); 780 781 ath9k_hw_disable_mib_counters(ah); 782 } 783 EXPORT_SYMBOL(ath9k_hw_abortpcurecv); 784 785 bool ath9k_hw_stopdmarecv(struct ath_hw *ah) 786 { 787 #define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */ 788 #define AH_RX_TIME_QUANTUM 100 /* usec */ 789 struct ath_common *common = ath9k_hw_common(ah); 790 int i; 791 792 REG_WRITE(ah, AR_CR, AR_CR_RXD); 793 794 /* Wait for rx enable bit to go low */ 795 for (i = AH_RX_STOP_DMA_TIMEOUT / AH_TIME_QUANTUM; i != 0; i--) { 796 if ((REG_READ(ah, AR_CR) & AR_CR_RXE) == 0) 797 break; 798 udelay(AH_TIME_QUANTUM); 799 } 800 801 if (i == 0) { 802 ath_print(common, ATH_DBG_FATAL, 803 "DMA failed to stop in %d ms " 804 "AR_CR=0x%08x AR_DIAG_SW=0x%08x\n", 805 AH_RX_STOP_DMA_TIMEOUT / 1000, 806 REG_READ(ah, AR_CR), 807 REG_READ(ah, AR_DIAG_SW)); 808 return false; 809 } else { 810 return true; 811 } 812 813 #undef AH_RX_TIME_QUANTUM 814 #undef AH_RX_STOP_DMA_TIMEOUT 815 } 816 EXPORT_SYMBOL(ath9k_hw_stopdmarecv); 817 818 int ath9k_hw_beaconq_setup(struct ath_hw *ah) 819 { 820 struct ath9k_tx_queue_info qi; 821 822 memset(&qi, 0, sizeof(qi)); 823 qi.tqi_aifs = 1; 824 qi.tqi_cwmin = 0; 825 qi.tqi_cwmax = 0; 826 /* NB: don't enable any interrupts */ 827 return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi); 828 } 829 EXPORT_SYMBOL(ath9k_hw_beaconq_setup); 830 831 bool ath9k_hw_intrpend(struct ath_hw *ah) 832 { 833 u32 host_isr; 834 835 if (AR_SREV_9100(ah)) 836 return true; 837 838 host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE); 839 if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS)) 840 return true; 841 842 host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE); 843 if ((host_isr & AR_INTR_SYNC_DEFAULT) 844 && (host_isr != AR_INTR_SPURIOUS)) 845 return true; 846 847 return false; 848 } 849 EXPORT_SYMBOL(ath9k_hw_intrpend); 850 851 enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, 852 enum ath9k_int ints) 853 { 854 enum ath9k_int omask = ah->imask; 855 u32 mask, mask2; 856 struct ath9k_hw_capabilities *pCap = &ah->caps; 857 struct ath_common *common = ath9k_hw_common(ah); 858 859 ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); 860 861 if (omask & ATH9K_INT_GLOBAL) { 862 ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n"); 863 REG_WRITE(ah, AR_IER, AR_IER_DISABLE); 864 (void) REG_READ(ah, AR_IER); 865 if (!AR_SREV_9100(ah)) { 866 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0); 867 (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE); 868 869 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0); 870 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE); 871 } 872 } 873 874 /* TODO: global int Ref count */ 875 mask = ints & ATH9K_INT_COMMON; 876 mask2 = 0; 877 878 if (ints & ATH9K_INT_TX) { 879 if (ah->config.tx_intr_mitigation) 880 mask |= AR_IMR_TXMINTR | AR_IMR_TXINTM; 881 else { 882 if (ah->txok_interrupt_mask) 883 mask |= AR_IMR_TXOK; 884 if (ah->txdesc_interrupt_mask) 885 mask |= AR_IMR_TXDESC; 886 } 887 if (ah->txerr_interrupt_mask) 888 mask |= AR_IMR_TXERR; 889 if (ah->txeol_interrupt_mask) 890 mask |= AR_IMR_TXEOL; 891 } 892 if (ints & ATH9K_INT_RX) { 893 if (AR_SREV_9300_20_OR_LATER(ah)) { 894 mask |= AR_IMR_RXERR | AR_IMR_RXOK_HP; 895 if (ah->config.rx_intr_mitigation) { 896 mask &= ~AR_IMR_RXOK_LP; 897 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM; 898 } else { 899 mask |= AR_IMR_RXOK_LP; 900 } 901 } else { 902 if (ah->config.rx_intr_mitigation) 903 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM; 904 else 905 mask |= AR_IMR_RXOK | AR_IMR_RXDESC; 906 } 907 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) 908 mask |= AR_IMR_GENTMR; 909 } 910 911 if (ints & (ATH9K_INT_BMISC)) { 912 mask |= AR_IMR_BCNMISC; 913 if (ints & ATH9K_INT_TIM) 914 mask2 |= AR_IMR_S2_TIM; 915 if (ints & ATH9K_INT_DTIM) 916 mask2 |= AR_IMR_S2_DTIM; 917 if (ints & ATH9K_INT_DTIMSYNC) 918 mask2 |= AR_IMR_S2_DTIMSYNC; 919 if (ints & ATH9K_INT_CABEND) 920 mask2 |= AR_IMR_S2_CABEND; 921 if (ints & ATH9K_INT_TSFOOR) 922 mask2 |= AR_IMR_S2_TSFOOR; 923 } 924 925 if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) { 926 mask |= AR_IMR_BCNMISC; 927 if (ints & ATH9K_INT_GTT) 928 mask2 |= AR_IMR_S2_GTT; 929 if (ints & ATH9K_INT_CST) 930 mask2 |= AR_IMR_S2_CST; 931 } 932 933 ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask); 934 REG_WRITE(ah, AR_IMR, mask); 935 ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC | 936 AR_IMR_S2_CABEND | AR_IMR_S2_CABTO | 937 AR_IMR_S2_TSFOOR | AR_IMR_S2_GTT | AR_IMR_S2_CST); 938 ah->imrs2_reg |= mask2; 939 REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg); 940 941 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { 942 if (ints & ATH9K_INT_TIM_TIMER) 943 REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER); 944 else 945 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER); 946 } 947 948 if (ints & ATH9K_INT_GLOBAL) { 949 ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n"); 950 REG_WRITE(ah, AR_IER, AR_IER_ENABLE); 951 if (!AR_SREV_9100(ah)) { 952 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 953 AR_INTR_MAC_IRQ); 954 REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ); 955 956 957 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 958 AR_INTR_SYNC_DEFAULT); 959 REG_WRITE(ah, AR_INTR_SYNC_MASK, 960 AR_INTR_SYNC_DEFAULT); 961 } 962 ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n", 963 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); 964 } 965 966 return omask; 967 } 968 EXPORT_SYMBOL(ath9k_hw_set_interrupts); 969