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 #include "ah.h" 20 #include "ah_internal.h" 21 22 #include "ar9300/ar9300.h" 23 #include "ar9300/ar9300reg.h" 24 #include "ar9300/ar9300phy.h" 25 26 /* 27 * Checks to see if an interrupt is pending on our NIC 28 * 29 * Returns: TRUE if an interrupt is pending 30 * FALSE if not 31 */ 32 HAL_BOOL 33 ar9300_is_interrupt_pending(struct ath_hal *ah) 34 { 35 u_int32_t sync_en_def = AR9300_INTR_SYNC_DEFAULT; 36 u_int32_t host_isr; 37 38 /* 39 * Some platforms trigger our ISR before applying power to 40 * the card, so make sure. 41 */ 42 host_isr = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_CAUSE)); 43 if ((host_isr & AR_INTR_ASYNC_USED) && (host_isr != AR_INTR_SPURIOUS)) { 44 return AH_TRUE; 45 } 46 47 host_isr = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE)); 48 if (AR_SREV_POSEIDON(ah)) { 49 sync_en_def = AR9300_INTR_SYNC_DEF_NO_HOST1_PERR; 50 } 51 else if (AR_SREV_WASP(ah)) { 52 sync_en_def = AR9340_INTR_SYNC_DEFAULT; 53 } 54 55 if ((host_isr & (sync_en_def | AR_INTR_SYNC_MASK_GPIO)) && 56 (host_isr != AR_INTR_SPURIOUS)) { 57 return AH_TRUE; 58 } 59 60 return AH_FALSE; 61 } 62 63 /* 64 * Reads the Interrupt Status Register value from the NIC, thus deasserting 65 * the interrupt line, and returns both the masked and unmasked mapped ISR 66 * values. The value returned is mapped to abstract the hw-specific bit 67 * locations in the Interrupt Status Register. 68 * 69 * Returns: A hardware-abstracted bitmap of all non-masked-out 70 * interrupts pending, as well as an unmasked value 71 */ 72 #define MAP_ISR_S2_HAL_CST 6 /* Carrier sense timeout */ 73 #define MAP_ISR_S2_HAL_GTT 6 /* Global transmit timeout */ 74 #define MAP_ISR_S2_HAL_TIM 3 /* TIM */ 75 #define MAP_ISR_S2_HAL_CABEND 0 /* CABEND */ 76 #define MAP_ISR_S2_HAL_DTIMSYNC 7 /* DTIMSYNC */ 77 #define MAP_ISR_S2_HAL_DTIM 7 /* DTIM */ 78 #define MAP_ISR_S2_HAL_TSFOOR 4 /* Rx TSF out of range */ 79 #define MAP_ISR_S2_HAL_BBPANIC 6 /* Panic watchdog IRQ from BB */ 80 HAL_BOOL 81 ar9300_get_pending_interrupts( 82 struct ath_hal *ah, 83 HAL_INT *masked, 84 HAL_INT_TYPE type, 85 u_int8_t msi, 86 HAL_BOOL nortc) 87 { 88 struct ath_hal_9300 *ahp = AH9300(ah); 89 HAL_BOOL ret_val = AH_TRUE; 90 u_int32_t isr = 0; 91 u_int32_t mask2 = 0; 92 u_int32_t sync_cause = 0; 93 u_int32_t async_cause; 94 u_int32_t msi_pend_addr_mask = 0; 95 u_int32_t sync_en_def = AR9300_INTR_SYNC_DEFAULT; 96 HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps; 97 98 *masked = 0; 99 100 if (!nortc) { 101 if (HAL_INT_MSI == type) { 102 if (msi == HAL_MSIVEC_RXHP) { 103 OS_REG_WRITE(ah, AR_ISR, AR_ISR_HP_RXOK); 104 *masked = HAL_INT_RXHP; 105 goto end; 106 } else if (msi == HAL_MSIVEC_RXLP) { 107 OS_REG_WRITE(ah, AR_ISR, 108 (AR_ISR_LP_RXOK | AR_ISR_RXMINTR | AR_ISR_RXINTM)); 109 *masked = HAL_INT_RXLP; 110 goto end; 111 } else if (msi == HAL_MSIVEC_TX) { 112 OS_REG_WRITE(ah, AR_ISR, AR_ISR_TXOK); 113 *masked = HAL_INT_TX; 114 goto end; 115 } else if (msi == HAL_MSIVEC_MISC) { 116 /* 117 * For the misc MSI event fall through and determine the cause. 118 */ 119 } 120 } 121 } 122 123 /* Make sure mac interrupt is pending in async interrupt cause register */ 124 async_cause = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_CAUSE)); 125 if (async_cause & AR_INTR_ASYNC_USED) { 126 /* 127 * RTC may not be on since it runs on a slow 32khz clock 128 * so check its status to be sure 129 */ 130 if (!nortc && 131 (OS_REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) == 132 AR_RTC_STATUS_ON) 133 { 134 isr = OS_REG_READ(ah, AR_ISR); 135 } 136 } 137 138 if (AR_SREV_POSEIDON(ah)) { 139 sync_en_def = AR9300_INTR_SYNC_DEF_NO_HOST1_PERR; 140 } 141 else if (AR_SREV_WASP(ah)) { 142 sync_en_def = AR9340_INTR_SYNC_DEFAULT; 143 } 144 145 /* Store away the async and sync cause registers */ 146 /* XXX Do this before the filtering done below */ 147 #ifdef AH_INTERRUPT_DEBUGGING 148 ah->ah_intrstate[0] = OS_REG_READ(ah, AR_ISR); 149 ah->ah_intrstate[1] = OS_REG_READ(ah, AR_ISR_S0); 150 ah->ah_intrstate[2] = OS_REG_READ(ah, AR_ISR_S1); 151 ah->ah_intrstate[3] = OS_REG_READ(ah, AR_ISR_S2); 152 ah->ah_intrstate[4] = OS_REG_READ(ah, AR_ISR_S3); 153 ah->ah_intrstate[5] = OS_REG_READ(ah, AR_ISR_S4); 154 ah->ah_intrstate[6] = OS_REG_READ(ah, AR_ISR_S5); 155 156 /* XXX double reading? */ 157 ah->ah_syncstate = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE)); 158 #endif 159 160 sync_cause = 161 OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE)) & 162 (sync_en_def | AR_INTR_SYNC_MASK_GPIO); 163 164 if (!isr && !sync_cause && !async_cause) { 165 ret_val = AH_FALSE; 166 goto end; 167 } 168 169 HALDEBUG(ah, HAL_DEBUG_INTERRUPT, 170 "%s: isr=0x%x, sync_cause=0x%x, async_cause=0x%x\n", 171 __func__, 172 isr, 173 sync_cause, 174 async_cause); 175 176 if (isr) { 177 if (isr & AR_ISR_BCNMISC) { 178 u_int32_t isr2; 179 isr2 = OS_REG_READ(ah, AR_ISR_S2); 180 181 /* Translate ISR bits to HAL values */ 182 mask2 |= ((isr2 & AR_ISR_S2_TIM) >> MAP_ISR_S2_HAL_TIM); 183 mask2 |= ((isr2 & AR_ISR_S2_DTIM) >> MAP_ISR_S2_HAL_DTIM); 184 mask2 |= ((isr2 & AR_ISR_S2_DTIMSYNC) >> MAP_ISR_S2_HAL_DTIMSYNC); 185 mask2 |= ((isr2 & AR_ISR_S2_CABEND) >> MAP_ISR_S2_HAL_CABEND); 186 mask2 |= ((isr2 & AR_ISR_S2_GTT) << MAP_ISR_S2_HAL_GTT); 187 mask2 |= ((isr2 & AR_ISR_S2_CST) << MAP_ISR_S2_HAL_CST); 188 mask2 |= ((isr2 & AR_ISR_S2_TSFOOR) >> MAP_ISR_S2_HAL_TSFOOR); 189 mask2 |= ((isr2 & AR_ISR_S2_BBPANIC) >> MAP_ISR_S2_HAL_BBPANIC); 190 191 if (!p_cap->halIsrRacSupport) { 192 /* 193 * EV61133 (missing interrupts due to ISR_RAC): 194 * If not using ISR_RAC, clear interrupts by writing to ISR_S2. 195 * This avoids a race condition where a new BCNMISC interrupt 196 * could come in between reading the ISR and clearing the 197 * interrupt via the primary ISR. We therefore clear the 198 * interrupt via the secondary, which avoids this race. 199 */ 200 OS_REG_WRITE(ah, AR_ISR_S2, isr2); 201 isr &= ~AR_ISR_BCNMISC; 202 } 203 } 204 205 /* Use AR_ISR_RAC only if chip supports it. 206 * See EV61133 (missing interrupts due to ISR_RAC) 207 */ 208 if (p_cap->halIsrRacSupport) { 209 isr = OS_REG_READ(ah, AR_ISR_RAC); 210 } 211 if (isr == 0xffffffff) { 212 *masked = 0; 213 ret_val = AH_FALSE; 214 goto end; 215 } 216 217 *masked = isr & HAL_INT_COMMON; 218 219 /* 220 * When interrupt mitigation is switched on, we fake a normal RX or TX 221 * interrupt when we received a mitigated interrupt. This way, the upper 222 * layer do not need to know about feature. 223 */ 224 if (ahp->ah_intr_mitigation_rx) { 225 /* Only Rx interrupt mitigation. No Tx intr. mitigation. */ 226 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) { 227 *masked |= HAL_INT_RXLP; 228 } 229 } 230 if (ahp->ah_intr_mitigation_tx) { 231 if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM)) { 232 *masked |= HAL_INT_TX; 233 } 234 } 235 236 if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR)) { 237 *masked |= HAL_INT_RXLP; 238 } 239 if (isr & AR_ISR_HP_RXOK) { 240 *masked |= HAL_INT_RXHP; 241 } 242 if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) { 243 *masked |= HAL_INT_TX; 244 245 if (!p_cap->halIsrRacSupport) { 246 u_int32_t s0, s1; 247 /* 248 * EV61133 (missing interrupts due to ISR_RAC): 249 * If not using ISR_RAC, clear interrupts by writing to 250 * ISR_S0/S1. 251 * This avoids a race condition where a new interrupt 252 * could come in between reading the ISR and clearing the 253 * interrupt via the primary ISR. We therefore clear the 254 * interrupt via the secondary, which avoids this race. 255 */ 256 s0 = OS_REG_READ(ah, AR_ISR_S0); 257 OS_REG_WRITE(ah, AR_ISR_S0, s0); 258 s1 = OS_REG_READ(ah, AR_ISR_S1); 259 OS_REG_WRITE(ah, AR_ISR_S1, s1); 260 261 isr &= ~(AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL); 262 } 263 } 264 265 /* 266 * Do not treat receive overflows as fatal for owl. 267 */ 268 if (isr & AR_ISR_RXORN) { 269 #if __PKT_SERIOUS_ERRORS__ 270 HALDEBUG(ah, HAL_DEBUG_INTERRUPT, 271 "%s: receive FIFO overrun interrupt\n", __func__); 272 #endif 273 } 274 275 #if 0 276 /* XXX Verify if this is fixed for Osprey */ 277 if (!p_cap->halAutoSleepSupport) { 278 u_int32_t isr5 = OS_REG_READ(ah, AR_ISR_S5_S); 279 if (isr5 & AR_ISR_S5_TIM_TIMER) { 280 *masked |= HAL_INT_TIM_TIMER; 281 } 282 } 283 #endif 284 if (isr & AR_ISR_GENTMR) { 285 u_int32_t s5; 286 287 if (p_cap->halIsrRacSupport) { 288 /* Use secondary shadow registers if using ISR_RAC */ 289 s5 = OS_REG_READ(ah, AR_ISR_S5_S); 290 } else { 291 s5 = OS_REG_READ(ah, AR_ISR_S5); 292 } 293 if (isr & AR_ISR_GENTMR) { 294 295 HALDEBUG(ah, HAL_DEBUG_INTERRUPT, 296 "%s: GENTIMER, ISR_RAC=0x%x ISR_S2_S=0x%x\n", __func__, 297 isr, s5); 298 ahp->ah_intr_gen_timer_trigger = 299 MS(s5, AR_ISR_S5_GENTIMER_TRIG); 300 ahp->ah_intr_gen_timer_thresh = 301 MS(s5, AR_ISR_S5_GENTIMER_THRESH); 302 if (ahp->ah_intr_gen_timer_trigger) { 303 *masked |= HAL_INT_GENTIMER; 304 } 305 } 306 if (!p_cap->halIsrRacSupport) { 307 /* 308 * EV61133 (missing interrupts due to ISR_RAC): 309 * If not using ISR_RAC, clear interrupts by writing to ISR_S5. 310 * This avoids a race condition where a new interrupt 311 * could come in between reading the ISR and clearing the 312 * interrupt via the primary ISR. We therefore clear the 313 * interrupt via the secondary, which avoids this race. 314 */ 315 OS_REG_WRITE(ah, AR_ISR_S5, s5); 316 isr &= ~AR_ISR_GENTMR; 317 } 318 } 319 320 *masked |= mask2; 321 322 if (!p_cap->halIsrRacSupport) { 323 /* 324 * EV61133 (missing interrupts due to ISR_RAC): 325 * If not using ISR_RAC, clear the interrupts we've read by 326 * writing back ones in these locations to the primary ISR 327 * (except for interrupts that have a secondary isr register - 328 * see above). 329 */ 330 OS_REG_WRITE(ah, AR_ISR, isr); 331 332 /* Flush prior write */ 333 (void) OS_REG_READ(ah, AR_ISR); 334 } 335 336 #ifdef AH_SUPPORT_AR9300 337 if (*masked & HAL_INT_BBPANIC) { 338 ar9300_handle_bb_panic(ah); 339 } 340 #endif 341 } 342 343 if (async_cause) { 344 if (nortc) { 345 OS_REG_WRITE(ah, 346 AR_HOSTIF_REG(ah, AR_INTR_ASYNC_CAUSE_CLR), async_cause); 347 /* Flush prior write */ 348 (void) OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_CAUSE_CLR)); 349 } else { 350 #ifdef ATH_GPIO_USE_ASYNC_CAUSE 351 if (async_cause & AR_INTR_ASYNC_CAUSE_GPIO) { 352 ahp->ah_gpio_cause = (async_cause & AR_INTR_ASYNC_CAUSE_GPIO) >> 353 AR_INTR_ASYNC_ENABLE_GPIO_S; 354 *masked |= HAL_INT_GPIO; 355 } 356 #endif 357 } 358 359 #if ATH_SUPPORT_MCI 360 if ((async_cause & AR_INTR_ASYNC_CAUSE_MCI) && 361 p_cap->halMciSupport) 362 { 363 u_int32_t int_raw, int_rx_msg; 364 365 int_rx_msg = OS_REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW); 366 int_raw = OS_REG_READ(ah, AR_MCI_INTERRUPT_RAW); 367 368 if ((int_raw == 0xdeadbeef) || (int_rx_msg == 0xdeadbeef)) 369 { 370 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 371 "(MCI) Get 0xdeadbeef during MCI int processing" 372 "new int_raw=0x%08x, new rx_msg_raw=0x%08x, " 373 "int_raw=0x%08x, rx_msg_raw=0x%08x\n", 374 int_raw, int_rx_msg, ahp->ah_mci_int_raw, 375 ahp->ah_mci_int_rx_msg); 376 } 377 else { 378 if (ahp->ah_mci_int_raw || ahp->ah_mci_int_rx_msg) { 379 ahp->ah_mci_int_rx_msg |= int_rx_msg; 380 ahp->ah_mci_int_raw |= int_raw; 381 } 382 else { 383 ahp->ah_mci_int_rx_msg = int_rx_msg; 384 ahp->ah_mci_int_raw = int_raw; 385 } 386 387 *masked |= HAL_INT_MCI; 388 ahp->ah_mci_rx_status = OS_REG_READ(ah, AR_MCI_RX_STATUS); 389 if (int_rx_msg & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO) { 390 ahp->ah_mci_cont_status = 391 OS_REG_READ(ah, AR_MCI_CONT_STATUS); 392 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 393 "(MCI) cont_status=0x%08x\n", ahp->ah_mci_cont_status); 394 } 395 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, 396 int_rx_msg); 397 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, int_raw); 398 399 HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s:AR_INTR_SYNC_MCI\n", __func__); 400 } 401 } 402 #endif 403 } 404 405 if (sync_cause) { 406 int host1_fatal, host1_perr, radm_cpl_timeout, local_timeout; 407 408 host1_fatal = AR_SREV_WASP(ah) ? 409 AR9340_INTR_SYNC_HOST1_FATAL : AR9300_INTR_SYNC_HOST1_FATAL; 410 host1_perr = AR_SREV_WASP(ah) ? 411 AR9340_INTR_SYNC_HOST1_PERR : AR9300_INTR_SYNC_HOST1_PERR; 412 radm_cpl_timeout = AR_SREV_WASP(ah) ? 413 0x0 : AR9300_INTR_SYNC_RADM_CPL_TIMEOUT; 414 local_timeout = AR_SREV_WASP(ah) ? 415 AR9340_INTR_SYNC_LOCAL_TIMEOUT : AR9300_INTR_SYNC_LOCAL_TIMEOUT; 416 417 if (sync_cause & host1_fatal) { 418 #if __PKT_SERIOUS_ERRORS__ 419 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, 420 "%s: received PCI FATAL interrupt\n", __func__); 421 #endif 422 *masked |= HAL_INT_FATAL; /* Set FATAL INT flag here;*/ 423 } 424 if (sync_cause & host1_perr) { 425 #if __PKT_SERIOUS_ERRORS__ 426 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, 427 "%s: received PCI PERR interrupt\n", __func__); 428 #endif 429 } 430 431 if (sync_cause & radm_cpl_timeout) { 432 HALDEBUG(ah, HAL_DEBUG_INTERRUPT, 433 "%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n", 434 __func__); 435 436 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), AR_RC_HOSTIF); 437 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), 0); 438 *masked |= HAL_INT_FATAL; 439 } 440 if (sync_cause & local_timeout) { 441 HALDEBUG(ah, HAL_DEBUG_INTERRUPT, 442 "%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n", 443 __func__); 444 } 445 446 #ifndef ATH_GPIO_USE_ASYNC_CAUSE 447 if (sync_cause & AR_INTR_SYNC_MASK_GPIO) { 448 ahp->ah_gpio_cause = (sync_cause & AR_INTR_SYNC_MASK_GPIO) >> 449 AR_INTR_SYNC_ENABLE_GPIO_S; 450 *masked |= HAL_INT_GPIO; 451 HALDEBUG(ah, HAL_DEBUG_INTERRUPT, 452 "%s: AR_INTR_SYNC_GPIO\n", __func__); 453 } 454 #endif 455 456 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE_CLR), sync_cause); 457 /* Flush prior write */ 458 (void) OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE_CLR)); 459 } 460 461 end: 462 if (HAL_INT_MSI == type) { 463 /* 464 * WAR for Bug EV#75887 465 * In normal case, SW read HOST_INTF_PCIE_MSI (0x40A4) and write 466 * into ah_msi_reg. Then use value of ah_msi_reg to set bit#25 467 * when want to enable HW write the cfg_msi_pending. 468 * Sometimes, driver get MSI interrupt before read 0x40a4 and 469 * ah_msi_reg is initialization value (0x0). 470 * We don't know why "MSI interrupt earlier than driver read" now... 471 */ 472 if (!ahp->ah_msi_reg) { 473 ahp->ah_msi_reg = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_PCIE_MSI)); 474 } 475 if (AR_SREV_POSEIDON(ah)) { 476 msi_pend_addr_mask = AR_PCIE_MSI_HW_INT_PENDING_ADDR_MSI_64; 477 } else { 478 msi_pend_addr_mask = AR_PCIE_MSI_HW_INT_PENDING_ADDR; 479 } 480 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_PCIE_MSI), 481 ((ahp->ah_msi_reg | AR_PCIE_MSI_ENABLE) & msi_pend_addr_mask)); 482 483 } 484 485 return ret_val; 486 } 487 488 HAL_INT 489 ar9300_get_interrupts(struct ath_hal *ah) 490 { 491 return AH9300(ah)->ah_mask_reg; 492 } 493 494 /* 495 * Atomically enables NIC interrupts. Interrupts are passed in 496 * via the enumerated bitmask in ints. 497 */ 498 HAL_INT 499 ar9300_set_interrupts(struct ath_hal *ah, HAL_INT ints, HAL_BOOL nortc) 500 { 501 struct ath_hal_9300 *ahp = AH9300(ah); 502 u_int32_t omask = ahp->ah_mask_reg; 503 u_int32_t mask, mask2, msi_mask = 0; 504 u_int32_t msi_pend_addr_mask = 0; 505 u_int32_t sync_en_def = AR9300_INTR_SYNC_DEFAULT; 506 HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps; 507 508 HALDEBUG(ah, HAL_DEBUG_INTERRUPT, 509 "%s: 0x%x => 0x%x\n", __func__, omask, ints); 510 511 if (omask & HAL_INT_GLOBAL) { 512 HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: disable IER\n", __func__); 513 514 if (ah->ah_config.ath_hal_enable_msi) { 515 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_ENABLE), 0); 516 /* flush write to HW */ 517 (void)OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_ENABLE)); 518 } 519 520 if (!nortc) { 521 OS_REG_WRITE(ah, AR_IER, AR_IER_DISABLE); 522 (void) OS_REG_READ(ah, AR_IER); /* flush write to HW */ 523 } 524 525 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), 0); 526 /* flush write to HW */ 527 (void) OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE)); 528 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_ENABLE), 0); 529 /* flush write to HW */ 530 (void) OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_ENABLE)); 531 } 532 533 if (!nortc) { 534 /* reference count for global IER */ 535 if (ints & HAL_INT_GLOBAL) { 536 #ifdef AH_DEBUG 537 HALDEBUG(ah, HAL_DEBUG_INTERRUPT, 538 "%s: Request HAL_INT_GLOBAL ENABLED\n", __func__); 539 #if 0 540 if (OS_ATOMIC_READ(&ahp->ah_ier_ref_count) == 0) { 541 HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, 542 "%s: WARNING: ah_ier_ref_count is 0 " 543 "and attempting to enable IER\n", 544 __func__); 545 } 546 #endif 547 #endif 548 #if 0 549 if (OS_ATOMIC_READ(&ahp->ah_ier_ref_count) > 0) { 550 OS_ATOMIC_DEC(&ahp->ah_ier_ref_count); 551 } 552 #endif 553 } else { 554 HALDEBUG(ah, HAL_DEBUG_INTERRUPT, 555 "%s: Request HAL_INT_GLOBAL DISABLED\n", __func__); 556 OS_ATOMIC_INC(&ahp->ah_ier_ref_count); 557 } 558 HALDEBUG(ah, HAL_DEBUG_INTERRUPT, 559 "%s: ah_ier_ref_count = %d\n", __func__, ahp->ah_ier_ref_count); 560 561 mask = ints & HAL_INT_COMMON; 562 mask2 = 0; 563 msi_mask = 0; 564 565 if (ints & HAL_INT_TX) { 566 if (ahp->ah_intr_mitigation_tx) { 567 mask |= AR_IMR_TXMINTR | AR_IMR_TXINTM; 568 } else if (ahp->ah_tx_ok_interrupt_mask) { 569 mask |= AR_IMR_TXOK; 570 } 571 msi_mask |= AR_INTR_PRIO_TX; 572 if (ahp->ah_tx_err_interrupt_mask) { 573 mask |= AR_IMR_TXERR; 574 } 575 if (ahp->ah_tx_eol_interrupt_mask) { 576 mask |= AR_IMR_TXEOL; 577 } 578 } 579 if (ints & HAL_INT_RX) { 580 mask |= AR_IMR_RXERR | AR_IMR_RXOK_HP; 581 if (ahp->ah_intr_mitigation_rx) { 582 mask &= ~(AR_IMR_RXOK_LP); 583 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM; 584 } else { 585 mask |= AR_IMR_RXOK_LP; 586 } 587 msi_mask |= AR_INTR_PRIO_RXLP | AR_INTR_PRIO_RXHP; 588 if (! p_cap->halAutoSleepSupport) { 589 mask |= AR_IMR_GENTMR; 590 } 591 } 592 593 if (ints & (HAL_INT_BMISC)) { 594 mask |= AR_IMR_BCNMISC; 595 if (ints & HAL_INT_TIM) { 596 mask2 |= AR_IMR_S2_TIM; 597 } 598 if (ints & HAL_INT_DTIM) { 599 mask2 |= AR_IMR_S2_DTIM; 600 } 601 if (ints & HAL_INT_DTIMSYNC) { 602 mask2 |= AR_IMR_S2_DTIMSYNC; 603 } 604 if (ints & HAL_INT_CABEND) { 605 mask2 |= (AR_IMR_S2_CABEND); 606 } 607 if (ints & HAL_INT_TSFOOR) { 608 mask2 |= AR_IMR_S2_TSFOOR; 609 } 610 } 611 612 if (ints & (HAL_INT_GTT | HAL_INT_CST)) { 613 mask |= AR_IMR_BCNMISC; 614 if (ints & HAL_INT_GTT) { 615 mask2 |= AR_IMR_S2_GTT; 616 } 617 if (ints & HAL_INT_CST) { 618 mask2 |= AR_IMR_S2_CST; 619 } 620 } 621 622 if (ints & HAL_INT_BBPANIC) { 623 /* EV92527 - MAC secondary interrupt must enable AR_IMR_BCNMISC */ 624 mask |= AR_IMR_BCNMISC; 625 mask2 |= AR_IMR_S2_BBPANIC; 626 } 627 628 if (ints & HAL_INT_GENTIMER) { 629 HALDEBUG(ah, HAL_DEBUG_INTERRUPT, 630 "%s: enabling gen timer\n", __func__); 631 mask |= AR_IMR_GENTMR; 632 } 633 634 /* Write the new IMR and store off our SW copy. */ 635 HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: new IMR 0x%x\n", __func__, mask); 636 OS_REG_WRITE(ah, AR_IMR, mask); 637 ahp->ah_mask2Reg &= ~(AR_IMR_S2_TIM | 638 AR_IMR_S2_DTIM | 639 AR_IMR_S2_DTIMSYNC | 640 AR_IMR_S2_CABEND | 641 AR_IMR_S2_CABTO | 642 AR_IMR_S2_TSFOOR | 643 AR_IMR_S2_GTT | 644 AR_IMR_S2_CST | 645 AR_IMR_S2_BBPANIC); 646 ahp->ah_mask2Reg |= mask2; 647 OS_REG_WRITE(ah, AR_IMR_S2, ahp->ah_mask2Reg ); 648 ahp->ah_mask_reg = ints; 649 650 if (! p_cap->halAutoSleepSupport) { 651 if (ints & HAL_INT_TIM_TIMER) { 652 OS_REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER); 653 } 654 else { 655 OS_REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER); 656 } 657 } 658 } 659 660 /* Re-enable interrupts if they were enabled before. */ 661 #if HAL_INTR_REFCOUNT_DISABLE 662 if ((ints & HAL_INT_GLOBAL)) { 663 #else 664 if ((ints & HAL_INT_GLOBAL) && (OS_ATOMIC_READ(&ahp->ah_ier_ref_count) == 0)) { 665 #endif 666 HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: enable IER\n", __func__); 667 668 if (!nortc) { 669 OS_REG_WRITE(ah, AR_IER, AR_IER_ENABLE); 670 } 671 672 mask = AR_INTR_MAC_IRQ; 673 #ifdef ATH_GPIO_USE_ASYNC_CAUSE 674 if (ints & HAL_INT_GPIO) { 675 if (ahp->ah_gpio_mask) { 676 mask |= SM(ahp->ah_gpio_mask, AR_INTR_ASYNC_MASK_GPIO); 677 } 678 } 679 #endif 680 681 #if ATH_SUPPORT_MCI 682 if (ints & HAL_INT_MCI) { 683 mask |= AR_INTR_ASYNC_MASK_MCI; 684 } 685 #endif 686 687 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_ENABLE), mask); 688 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_MASK), mask); 689 690 if (ah->ah_config.ath_hal_enable_msi) { 691 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_ENABLE), 692 msi_mask); 693 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_MASK), 694 msi_mask); 695 if (AR_SREV_POSEIDON(ah)) { 696 msi_pend_addr_mask = AR_PCIE_MSI_HW_INT_PENDING_ADDR_MSI_64; 697 } else { 698 msi_pend_addr_mask = AR_PCIE_MSI_HW_INT_PENDING_ADDR; 699 } 700 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_PCIE_MSI), 701 ((ahp->ah_msi_reg | AR_PCIE_MSI_ENABLE) & msi_pend_addr_mask)); 702 } 703 704 /* 705 * debug - enable to see all synchronous interrupts status 706 * Enable synchronous GPIO interrupts as well, since some async 707 * GPIO interrupts don't wake the chip up. 708 */ 709 mask = 0; 710 #ifndef ATH_GPIO_USE_ASYNC_CAUSE 711 if (ints & HAL_INT_GPIO) { 712 mask |= SM(ahp->ah_gpio_mask, AR_INTR_SYNC_MASK_GPIO); 713 } 714 #endif 715 if (AR_SREV_POSEIDON(ah)) { 716 sync_en_def = AR9300_INTR_SYNC_DEF_NO_HOST1_PERR; 717 } 718 else if (AR_SREV_WASP(ah)) { 719 sync_en_def = AR9340_INTR_SYNC_DEFAULT; 720 } 721 722 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), 723 (sync_en_def | mask)); 724 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_MASK), 725 (sync_en_def | mask)); 726 727 HALDEBUG(ah, HAL_DEBUG_INTERRUPT, 728 "AR_IMR 0x%x IER 0x%x\n", 729 OS_REG_READ(ah, AR_IMR), OS_REG_READ(ah, AR_IER)); 730 } 731 732 return omask; 733 } 734 735 void 736 ar9300_set_intr_mitigation_timer( 737 struct ath_hal* ah, 738 HAL_INT_MITIGATION reg, 739 u_int32_t value) 740 { 741 #ifdef AR5416_INT_MITIGATION 742 switch (reg) { 743 case HAL_INT_THRESHOLD: 744 OS_REG_WRITE(ah, AR_MIRT, 0); 745 break; 746 case HAL_INT_RX_LASTPKT: 747 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, value); 748 break; 749 case HAL_INT_RX_FIRSTPKT: 750 OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, value); 751 break; 752 case HAL_INT_TX_LASTPKT: 753 OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, value); 754 break; 755 case HAL_INT_TX_FIRSTPKT: 756 OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, value); 757 break; 758 default: 759 break; 760 } 761 #endif 762 } 763 764 u_int32_t 765 ar9300_get_intr_mitigation_timer(struct ath_hal* ah, HAL_INT_MITIGATION reg) 766 { 767 u_int32_t val = 0; 768 #ifdef AR5416_INT_MITIGATION 769 switch (reg) { 770 case HAL_INT_THRESHOLD: 771 val = OS_REG_READ(ah, AR_MIRT); 772 break; 773 case HAL_INT_RX_LASTPKT: 774 val = OS_REG_READ(ah, AR_RIMT) & 0xFFFF; 775 break; 776 case HAL_INT_RX_FIRSTPKT: 777 val = OS_REG_READ(ah, AR_RIMT) >> 16; 778 break; 779 case HAL_INT_TX_LASTPKT: 780 val = OS_REG_READ(ah, AR_TIMT) & 0xFFFF; 781 break; 782 case HAL_INT_TX_FIRSTPKT: 783 val = OS_REG_READ(ah, AR_TIMT) >> 16; 784 break; 785 default: 786 break; 787 } 788 #endif 789 return val; 790 } 791