1 /* 2 * Copyright (c) 2012-2014 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 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 <linux/interrupt.h> 18 19 #include "wil6210.h" 20 #include "trace.h" 21 22 /** 23 * Theory of operation: 24 * 25 * There is ISR pseudo-cause register, 26 * dma_rgf->DMA_RGF.PSEUDO_CAUSE.PSEUDO_CAUSE 27 * Its bits represents OR'ed bits from 3 real ISR registers: 28 * TX, RX, and MISC. 29 * 30 * Registers may be configured to either "write 1 to clear" or 31 * "clear on read" mode 32 * 33 * When handling interrupt, one have to mask/unmask interrupts for the 34 * real ISR registers, or hardware may malfunction. 35 * 36 */ 37 38 #define WIL6210_IRQ_DISABLE (0xFFFFFFFFUL) 39 #define WIL6210_IMC_RX (BIT_DMA_EP_RX_ICR_RX_DONE | \ 40 BIT_DMA_EP_RX_ICR_RX_HTRSH) 41 #define WIL6210_IMC_TX (BIT_DMA_EP_TX_ICR_TX_DONE | \ 42 BIT_DMA_EP_TX_ICR_TX_DONE_N(0)) 43 #define WIL6210_IMC_MISC (ISR_MISC_FW_READY | \ 44 ISR_MISC_MBOX_EVT | \ 45 ISR_MISC_FW_ERROR) 46 47 #define WIL6210_IRQ_PSEUDO_MASK (u32)(~(BIT_DMA_PSEUDO_CAUSE_RX | \ 48 BIT_DMA_PSEUDO_CAUSE_TX | \ 49 BIT_DMA_PSEUDO_CAUSE_MISC)) 50 51 #if defined(CONFIG_WIL6210_ISR_COR) 52 /* configure to Clear-On-Read mode */ 53 #define WIL_ICR_ICC_VALUE (0xFFFFFFFFUL) 54 55 static inline void wil_icr_clear(u32 x, void __iomem *addr) 56 { 57 } 58 #else /* defined(CONFIG_WIL6210_ISR_COR) */ 59 /* configure to Write-1-to-Clear mode */ 60 #define WIL_ICR_ICC_VALUE (0UL) 61 62 static inline void wil_icr_clear(u32 x, void __iomem *addr) 63 { 64 iowrite32(x, addr); 65 } 66 #endif /* defined(CONFIG_WIL6210_ISR_COR) */ 67 68 static inline u32 wil_ioread32_and_clear(void __iomem *addr) 69 { 70 u32 x = ioread32(addr); 71 72 wil_icr_clear(x, addr); 73 74 return x; 75 } 76 77 static void wil6210_mask_irq_tx(struct wil6210_priv *wil) 78 { 79 iowrite32(WIL6210_IRQ_DISABLE, wil->csr + 80 HOSTADDR(RGF_DMA_EP_TX_ICR) + 81 offsetof(struct RGF_ICR, IMS)); 82 } 83 84 static void wil6210_mask_irq_rx(struct wil6210_priv *wil) 85 { 86 iowrite32(WIL6210_IRQ_DISABLE, wil->csr + 87 HOSTADDR(RGF_DMA_EP_RX_ICR) + 88 offsetof(struct RGF_ICR, IMS)); 89 } 90 91 static void wil6210_mask_irq_misc(struct wil6210_priv *wil) 92 { 93 iowrite32(WIL6210_IRQ_DISABLE, wil->csr + 94 HOSTADDR(RGF_DMA_EP_MISC_ICR) + 95 offsetof(struct RGF_ICR, IMS)); 96 } 97 98 static void wil6210_mask_irq_pseudo(struct wil6210_priv *wil) 99 { 100 wil_dbg_irq(wil, "%s()\n", __func__); 101 102 iowrite32(WIL6210_IRQ_DISABLE, wil->csr + 103 HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW)); 104 105 clear_bit(wil_status_irqen, &wil->status); 106 } 107 108 void wil6210_unmask_irq_tx(struct wil6210_priv *wil) 109 { 110 iowrite32(WIL6210_IMC_TX, wil->csr + 111 HOSTADDR(RGF_DMA_EP_TX_ICR) + 112 offsetof(struct RGF_ICR, IMC)); 113 } 114 115 void wil6210_unmask_irq_rx(struct wil6210_priv *wil) 116 { 117 iowrite32(WIL6210_IMC_RX, wil->csr + 118 HOSTADDR(RGF_DMA_EP_RX_ICR) + 119 offsetof(struct RGF_ICR, IMC)); 120 } 121 122 static void wil6210_unmask_irq_misc(struct wil6210_priv *wil) 123 { 124 iowrite32(WIL6210_IMC_MISC, wil->csr + 125 HOSTADDR(RGF_DMA_EP_MISC_ICR) + 126 offsetof(struct RGF_ICR, IMC)); 127 } 128 129 static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil) 130 { 131 wil_dbg_irq(wil, "%s()\n", __func__); 132 133 set_bit(wil_status_irqen, &wil->status); 134 135 iowrite32(WIL6210_IRQ_PSEUDO_MASK, wil->csr + 136 HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW)); 137 } 138 139 void wil_mask_irq(struct wil6210_priv *wil) 140 { 141 wil_dbg_irq(wil, "%s()\n", __func__); 142 143 wil6210_mask_irq_tx(wil); 144 wil6210_mask_irq_rx(wil); 145 wil6210_mask_irq_misc(wil); 146 wil6210_mask_irq_pseudo(wil); 147 } 148 149 void wil_unmask_irq(struct wil6210_priv *wil) 150 { 151 wil_dbg_irq(wil, "%s()\n", __func__); 152 153 iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_RX_ICR) + 154 offsetof(struct RGF_ICR, ICC)); 155 iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_TX_ICR) + 156 offsetof(struct RGF_ICR, ICC)); 157 iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) + 158 offsetof(struct RGF_ICR, ICC)); 159 160 /* interrupt moderation parameters */ 161 wil_set_itr_trsh(wil); 162 163 wil6210_unmask_irq_pseudo(wil); 164 wil6210_unmask_irq_tx(wil); 165 wil6210_unmask_irq_rx(wil); 166 wil6210_unmask_irq_misc(wil); 167 } 168 169 static irqreturn_t wil6210_irq_rx(int irq, void *cookie) 170 { 171 struct wil6210_priv *wil = cookie; 172 u32 isr = wil_ioread32_and_clear(wil->csr + 173 HOSTADDR(RGF_DMA_EP_RX_ICR) + 174 offsetof(struct RGF_ICR, ICR)); 175 bool need_unmask = true; 176 177 trace_wil6210_irq_rx(isr); 178 wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr); 179 180 if (!isr) { 181 wil_err(wil, "spurious IRQ: RX\n"); 182 return IRQ_NONE; 183 } 184 185 wil6210_mask_irq_rx(wil); 186 187 /* RX_DONE and RX_HTRSH interrupts are the same if interrupt 188 * moderation is not used. Interrupt moderation may cause RX 189 * buffer overflow while RX_DONE is delayed. The required 190 * action is always the same - should empty the accumulated 191 * packets from the RX ring. 192 */ 193 if (isr & (BIT_DMA_EP_RX_ICR_RX_DONE | BIT_DMA_EP_RX_ICR_RX_HTRSH)) { 194 wil_dbg_irq(wil, "RX done\n"); 195 196 if (isr & BIT_DMA_EP_RX_ICR_RX_HTRSH) 197 wil_err_ratelimited(wil, "Received \"Rx buffer is in risk " 198 "of overflow\" interrupt\n"); 199 200 isr &= ~(BIT_DMA_EP_RX_ICR_RX_DONE | BIT_DMA_EP_RX_ICR_RX_HTRSH); 201 if (test_bit(wil_status_reset_done, &wil->status)) { 202 if (test_bit(wil_status_napi_en, &wil->status)) { 203 wil_dbg_txrx(wil, "NAPI(Rx) schedule\n"); 204 need_unmask = false; 205 napi_schedule(&wil->napi_rx); 206 } else { 207 wil_err(wil, "Got Rx interrupt while " 208 "stopping interface\n"); 209 } 210 } else { 211 wil_err(wil, "Got Rx interrupt while in reset\n"); 212 } 213 } 214 215 if (isr) 216 wil_err(wil, "un-handled RX ISR bits 0x%08x\n", isr); 217 218 /* Rx IRQ will be enabled when NAPI processing finished */ 219 220 atomic_inc(&wil->isr_count_rx); 221 222 if (unlikely(need_unmask)) 223 wil6210_unmask_irq_rx(wil); 224 225 return IRQ_HANDLED; 226 } 227 228 static irqreturn_t wil6210_irq_tx(int irq, void *cookie) 229 { 230 struct wil6210_priv *wil = cookie; 231 u32 isr = wil_ioread32_and_clear(wil->csr + 232 HOSTADDR(RGF_DMA_EP_TX_ICR) + 233 offsetof(struct RGF_ICR, ICR)); 234 bool need_unmask = true; 235 236 trace_wil6210_irq_tx(isr); 237 wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr); 238 239 if (!isr) { 240 wil_err(wil, "spurious IRQ: TX\n"); 241 return IRQ_NONE; 242 } 243 244 wil6210_mask_irq_tx(wil); 245 246 if (isr & BIT_DMA_EP_TX_ICR_TX_DONE) { 247 wil_dbg_irq(wil, "TX done\n"); 248 isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE; 249 /* clear also all VRING interrupts */ 250 isr &= ~(BIT(25) - 1UL); 251 if (test_bit(wil_status_reset_done, &wil->status)) { 252 wil_dbg_txrx(wil, "NAPI(Tx) schedule\n"); 253 need_unmask = false; 254 napi_schedule(&wil->napi_tx); 255 } else { 256 wil_err(wil, "Got Tx interrupt while in reset\n"); 257 } 258 } 259 260 if (isr) 261 wil_err(wil, "un-handled TX ISR bits 0x%08x\n", isr); 262 263 /* Tx IRQ will be enabled when NAPI processing finished */ 264 265 atomic_inc(&wil->isr_count_tx); 266 267 if (unlikely(need_unmask)) 268 wil6210_unmask_irq_tx(wil); 269 270 return IRQ_HANDLED; 271 } 272 273 static void wil_notify_fw_error(struct wil6210_priv *wil) 274 { 275 struct device *dev = &wil_to_ndev(wil)->dev; 276 char *envp[3] = { 277 [0] = "SOURCE=wil6210", 278 [1] = "EVENT=FW_ERROR", 279 [2] = NULL, 280 }; 281 wil_err(wil, "Notify about firmware error\n"); 282 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); 283 } 284 285 static void wil_cache_mbox_regs(struct wil6210_priv *wil) 286 { 287 /* make shadow copy of registers that should not change on run time */ 288 wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX, 289 sizeof(struct wil6210_mbox_ctl)); 290 wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx); 291 wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx); 292 } 293 294 static irqreturn_t wil6210_irq_misc(int irq, void *cookie) 295 { 296 struct wil6210_priv *wil = cookie; 297 u32 isr = wil_ioread32_and_clear(wil->csr + 298 HOSTADDR(RGF_DMA_EP_MISC_ICR) + 299 offsetof(struct RGF_ICR, ICR)); 300 301 trace_wil6210_irq_misc(isr); 302 wil_dbg_irq(wil, "ISR MISC 0x%08x\n", isr); 303 304 if (!isr) { 305 wil_err(wil, "spurious IRQ: MISC\n"); 306 return IRQ_NONE; 307 } 308 309 wil6210_mask_irq_misc(wil); 310 311 if (isr & ISR_MISC_FW_ERROR) { 312 wil_err(wil, "Firmware error detected\n"); 313 clear_bit(wil_status_fwready, &wil->status); 314 /* 315 * do not clear @isr here - we do 2-nd part in thread 316 * there, user space get notified, and it should be done 317 * in non-atomic context 318 */ 319 } 320 321 if (isr & ISR_MISC_FW_READY) { 322 wil_dbg_irq(wil, "IRQ: FW ready\n"); 323 wil_cache_mbox_regs(wil); 324 set_bit(wil_status_reset_done, &wil->status); 325 /** 326 * Actual FW ready indicated by the 327 * WMI_FW_READY_EVENTID 328 */ 329 isr &= ~ISR_MISC_FW_READY; 330 } 331 332 wil->isr_misc = isr; 333 334 if (isr) { 335 return IRQ_WAKE_THREAD; 336 } else { 337 wil6210_unmask_irq_misc(wil); 338 return IRQ_HANDLED; 339 } 340 } 341 342 static irqreturn_t wil6210_irq_misc_thread(int irq, void *cookie) 343 { 344 struct wil6210_priv *wil = cookie; 345 u32 isr = wil->isr_misc; 346 347 trace_wil6210_irq_misc_thread(isr); 348 wil_dbg_irq(wil, "Thread ISR MISC 0x%08x\n", isr); 349 350 if (isr & ISR_MISC_FW_ERROR) { 351 wil_notify_fw_error(wil); 352 isr &= ~ISR_MISC_FW_ERROR; 353 wil_fw_error_recovery(wil); 354 } 355 356 if (isr & ISR_MISC_MBOX_EVT) { 357 wil_dbg_irq(wil, "MBOX event\n"); 358 wmi_recv_cmd(wil); 359 isr &= ~ISR_MISC_MBOX_EVT; 360 } 361 362 if (isr) 363 wil_dbg_irq(wil, "un-handled MISC ISR bits 0x%08x\n", isr); 364 365 wil->isr_misc = 0; 366 367 wil6210_unmask_irq_misc(wil); 368 369 return IRQ_HANDLED; 370 } 371 372 /** 373 * thread IRQ handler 374 */ 375 static irqreturn_t wil6210_thread_irq(int irq, void *cookie) 376 { 377 struct wil6210_priv *wil = cookie; 378 379 wil_dbg_irq(wil, "Thread IRQ\n"); 380 /* Discover real IRQ cause */ 381 if (wil->isr_misc) 382 wil6210_irq_misc_thread(irq, cookie); 383 384 wil6210_unmask_irq_pseudo(wil); 385 386 return IRQ_HANDLED; 387 } 388 389 /* DEBUG 390 * There is subtle bug in hardware that causes IRQ to raise when it should be 391 * masked. It is quite rare and hard to debug. 392 * 393 * Catch irq issue if it happens and print all I can. 394 */ 395 static int wil6210_debug_irq_mask(struct wil6210_priv *wil, u32 pseudo_cause) 396 { 397 if (!test_bit(wil_status_irqen, &wil->status)) { 398 u32 icm_rx = wil_ioread32_and_clear(wil->csr + 399 HOSTADDR(RGF_DMA_EP_RX_ICR) + 400 offsetof(struct RGF_ICR, ICM)); 401 u32 icr_rx = wil_ioread32_and_clear(wil->csr + 402 HOSTADDR(RGF_DMA_EP_RX_ICR) + 403 offsetof(struct RGF_ICR, ICR)); 404 u32 imv_rx = ioread32(wil->csr + 405 HOSTADDR(RGF_DMA_EP_RX_ICR) + 406 offsetof(struct RGF_ICR, IMV)); 407 u32 icm_tx = wil_ioread32_and_clear(wil->csr + 408 HOSTADDR(RGF_DMA_EP_TX_ICR) + 409 offsetof(struct RGF_ICR, ICM)); 410 u32 icr_tx = wil_ioread32_and_clear(wil->csr + 411 HOSTADDR(RGF_DMA_EP_TX_ICR) + 412 offsetof(struct RGF_ICR, ICR)); 413 u32 imv_tx = ioread32(wil->csr + 414 HOSTADDR(RGF_DMA_EP_TX_ICR) + 415 offsetof(struct RGF_ICR, IMV)); 416 u32 icm_misc = wil_ioread32_and_clear(wil->csr + 417 HOSTADDR(RGF_DMA_EP_MISC_ICR) + 418 offsetof(struct RGF_ICR, ICM)); 419 u32 icr_misc = wil_ioread32_and_clear(wil->csr + 420 HOSTADDR(RGF_DMA_EP_MISC_ICR) + 421 offsetof(struct RGF_ICR, ICR)); 422 u32 imv_misc = ioread32(wil->csr + 423 HOSTADDR(RGF_DMA_EP_MISC_ICR) + 424 offsetof(struct RGF_ICR, IMV)); 425 wil_err(wil, "IRQ when it should be masked: pseudo 0x%08x\n" 426 "Rx icm:icr:imv 0x%08x 0x%08x 0x%08x\n" 427 "Tx icm:icr:imv 0x%08x 0x%08x 0x%08x\n" 428 "Misc icm:icr:imv 0x%08x 0x%08x 0x%08x\n", 429 pseudo_cause, 430 icm_rx, icr_rx, imv_rx, 431 icm_tx, icr_tx, imv_tx, 432 icm_misc, icr_misc, imv_misc); 433 434 return -EINVAL; 435 } 436 437 return 0; 438 } 439 440 static irqreturn_t wil6210_hardirq(int irq, void *cookie) 441 { 442 irqreturn_t rc = IRQ_HANDLED; 443 struct wil6210_priv *wil = cookie; 444 u32 pseudo_cause = ioread32(wil->csr + HOSTADDR(RGF_DMA_PSEUDO_CAUSE)); 445 446 /** 447 * pseudo_cause is Clear-On-Read, no need to ACK 448 */ 449 if ((pseudo_cause == 0) || ((pseudo_cause & 0xff) == 0xff)) 450 return IRQ_NONE; 451 452 /* FIXME: IRQ mask debug */ 453 if (wil6210_debug_irq_mask(wil, pseudo_cause)) 454 return IRQ_NONE; 455 456 trace_wil6210_irq_pseudo(pseudo_cause); 457 wil_dbg_irq(wil, "Pseudo IRQ 0x%08x\n", pseudo_cause); 458 459 wil6210_mask_irq_pseudo(wil); 460 461 /* Discover real IRQ cause 462 * There are 2 possible phases for every IRQ: 463 * - hard IRQ handler called right here 464 * - threaded handler called later 465 * 466 * Hard IRQ handler reads and clears ISR. 467 * 468 * If threaded handler requested, hard IRQ handler 469 * returns IRQ_WAKE_THREAD and saves ISR register value 470 * for the threaded handler use. 471 * 472 * voting for wake thread - need at least 1 vote 473 */ 474 if ((pseudo_cause & BIT_DMA_PSEUDO_CAUSE_RX) && 475 (wil6210_irq_rx(irq, cookie) == IRQ_WAKE_THREAD)) 476 rc = IRQ_WAKE_THREAD; 477 478 if ((pseudo_cause & BIT_DMA_PSEUDO_CAUSE_TX) && 479 (wil6210_irq_tx(irq, cookie) == IRQ_WAKE_THREAD)) 480 rc = IRQ_WAKE_THREAD; 481 482 if ((pseudo_cause & BIT_DMA_PSEUDO_CAUSE_MISC) && 483 (wil6210_irq_misc(irq, cookie) == IRQ_WAKE_THREAD)) 484 rc = IRQ_WAKE_THREAD; 485 486 /* if thread is requested, it will unmask IRQ */ 487 if (rc != IRQ_WAKE_THREAD) 488 wil6210_unmask_irq_pseudo(wil); 489 490 return rc; 491 } 492 493 static int wil6210_request_3msi(struct wil6210_priv *wil, int irq) 494 { 495 int rc; 496 /* 497 * IRQ's are in the following order: 498 * - Tx 499 * - Rx 500 * - Misc 501 */ 502 503 rc = request_irq(irq, wil6210_irq_tx, IRQF_SHARED, 504 WIL_NAME"_tx", wil); 505 if (rc) 506 return rc; 507 508 rc = request_irq(irq + 1, wil6210_irq_rx, IRQF_SHARED, 509 WIL_NAME"_rx", wil); 510 if (rc) 511 goto free0; 512 513 rc = request_threaded_irq(irq + 2, wil6210_irq_misc, 514 wil6210_irq_misc_thread, 515 IRQF_SHARED, WIL_NAME"_misc", wil); 516 if (rc) 517 goto free1; 518 519 return 0; 520 /* error branch */ 521 free1: 522 free_irq(irq + 1, wil); 523 free0: 524 free_irq(irq, wil); 525 526 return rc; 527 } 528 529 /* can't use wil_ioread32_and_clear because ICC value is not set yet */ 530 static inline void wil_clear32(void __iomem *addr) 531 { 532 u32 x = ioread32(addr); 533 534 iowrite32(x, addr); 535 } 536 537 void wil6210_clear_irq(struct wil6210_priv *wil) 538 { 539 wil_clear32(wil->csr + HOSTADDR(RGF_DMA_EP_RX_ICR) + 540 offsetof(struct RGF_ICR, ICR)); 541 wil_clear32(wil->csr + HOSTADDR(RGF_DMA_EP_TX_ICR) + 542 offsetof(struct RGF_ICR, ICR)); 543 wil_clear32(wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) + 544 offsetof(struct RGF_ICR, ICR)); 545 wmb(); /* make sure write completed */ 546 } 547 548 int wil6210_init_irq(struct wil6210_priv *wil, int irq) 549 { 550 int rc; 551 552 wil_dbg_misc(wil, "%s() n_msi=%d\n", __func__, wil->n_msi); 553 554 if (wil->n_msi == 3) 555 rc = wil6210_request_3msi(wil, irq); 556 else 557 rc = request_threaded_irq(irq, wil6210_hardirq, 558 wil6210_thread_irq, 559 wil->n_msi ? 0 : IRQF_SHARED, 560 WIL_NAME, wil); 561 return rc; 562 } 563 564 void wil6210_fini_irq(struct wil6210_priv *wil, int irq) 565 { 566 wil_dbg_misc(wil, "%s()\n", __func__); 567 568 wil_mask_irq(wil); 569 free_irq(irq, wil); 570 if (wil->n_msi == 3) { 571 free_irq(irq + 1, wil); 572 free_irq(irq + 2, wil); 573 } 574 } 575