1 // SPDX-License-Identifier: ISC 2 /* 3 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. 4 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. 5 */ 6 7 #include <linux/interrupt.h> 8 9 #include "wil6210.h" 10 #include "trace.h" 11 12 /** 13 * Theory of operation: 14 * 15 * There is ISR pseudo-cause register, 16 * dma_rgf->DMA_RGF.PSEUDO_CAUSE.PSEUDO_CAUSE 17 * Its bits represents OR'ed bits from 3 real ISR registers: 18 * TX, RX, and MISC. 19 * 20 * Registers may be configured to either "write 1 to clear" or 21 * "clear on read" mode 22 * 23 * When handling interrupt, one have to mask/unmask interrupts for the 24 * real ISR registers, or hardware may malfunction. 25 * 26 */ 27 28 #define WIL6210_IRQ_DISABLE (0xFFFFFFFFUL) 29 #define WIL6210_IRQ_DISABLE_NO_HALP (0xF7FFFFFFUL) 30 #define WIL6210_IMC_RX (BIT_DMA_EP_RX_ICR_RX_DONE | \ 31 BIT_DMA_EP_RX_ICR_RX_HTRSH) 32 #define WIL6210_IMC_RX_NO_RX_HTRSH (WIL6210_IMC_RX & \ 33 (~(BIT_DMA_EP_RX_ICR_RX_HTRSH))) 34 #define WIL6210_IMC_TX (BIT_DMA_EP_TX_ICR_TX_DONE | \ 35 BIT_DMA_EP_TX_ICR_TX_DONE_N(0)) 36 #define WIL6210_IMC_TX_EDMA BIT_TX_STATUS_IRQ 37 #define WIL6210_IMC_RX_EDMA BIT_RX_STATUS_IRQ 38 #define WIL6210_IMC_MISC_NO_HALP (ISR_MISC_FW_READY | \ 39 ISR_MISC_MBOX_EVT | \ 40 ISR_MISC_FW_ERROR) 41 #define WIL6210_IMC_MISC (WIL6210_IMC_MISC_NO_HALP | \ 42 BIT_DMA_EP_MISC_ICR_HALP) 43 #define WIL6210_IRQ_PSEUDO_MASK (u32)(~(BIT_DMA_PSEUDO_CAUSE_RX | \ 44 BIT_DMA_PSEUDO_CAUSE_TX | \ 45 BIT_DMA_PSEUDO_CAUSE_MISC)) 46 47 #if defined(CONFIG_WIL6210_ISR_COR) 48 /* configure to Clear-On-Read mode */ 49 #define WIL_ICR_ICC_VALUE (0xFFFFFFFFUL) 50 #define WIL_ICR_ICC_MISC_VALUE (0xF7FFFFFFUL) 51 52 static inline void wil_icr_clear(u32 x, void __iomem *addr) 53 { 54 } 55 #else /* defined(CONFIG_WIL6210_ISR_COR) */ 56 /* configure to Write-1-to-Clear mode */ 57 #define WIL_ICR_ICC_VALUE (0UL) 58 #define WIL_ICR_ICC_MISC_VALUE (0UL) 59 60 static inline void wil_icr_clear(u32 x, void __iomem *addr) 61 { 62 writel(x, addr); 63 } 64 #endif /* defined(CONFIG_WIL6210_ISR_COR) */ 65 66 static inline u32 wil_ioread32_and_clear(void __iomem *addr) 67 { 68 u32 x = readl(addr); 69 70 wil_icr_clear(x, addr); 71 72 return x; 73 } 74 75 static void wil6210_mask_irq_tx(struct wil6210_priv *wil) 76 { 77 wil_w(wil, RGF_DMA_EP_TX_ICR + offsetof(struct RGF_ICR, IMS), 78 WIL6210_IRQ_DISABLE); 79 } 80 81 static void wil6210_mask_irq_tx_edma(struct wil6210_priv *wil) 82 { 83 wil_w(wil, RGF_INT_GEN_TX_ICR + offsetof(struct RGF_ICR, IMS), 84 WIL6210_IRQ_DISABLE); 85 } 86 87 static void wil6210_mask_irq_rx(struct wil6210_priv *wil) 88 { 89 wil_w(wil, RGF_DMA_EP_RX_ICR + offsetof(struct RGF_ICR, IMS), 90 WIL6210_IRQ_DISABLE); 91 } 92 93 static void wil6210_mask_irq_rx_edma(struct wil6210_priv *wil) 94 { 95 wil_w(wil, RGF_INT_GEN_RX_ICR + offsetof(struct RGF_ICR, IMS), 96 WIL6210_IRQ_DISABLE); 97 } 98 99 static void wil6210_mask_irq_misc(struct wil6210_priv *wil, bool mask_halp) 100 { 101 wil_dbg_irq(wil, "mask_irq_misc: mask_halp(%s)\n", 102 mask_halp ? "true" : "false"); 103 104 wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, IMS), 105 mask_halp ? WIL6210_IRQ_DISABLE : WIL6210_IRQ_DISABLE_NO_HALP); 106 } 107 108 void wil6210_mask_halp(struct wil6210_priv *wil) 109 { 110 wil_dbg_irq(wil, "mask_halp\n"); 111 112 wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, IMS), 113 BIT_DMA_EP_MISC_ICR_HALP); 114 } 115 116 static void wil6210_mask_irq_pseudo(struct wil6210_priv *wil) 117 { 118 wil_dbg_irq(wil, "mask_irq_pseudo\n"); 119 120 wil_w(wil, RGF_DMA_PSEUDO_CAUSE_MASK_SW, WIL6210_IRQ_DISABLE); 121 122 clear_bit(wil_status_irqen, wil->status); 123 } 124 125 void wil6210_unmask_irq_tx(struct wil6210_priv *wil) 126 { 127 wil_w(wil, RGF_DMA_EP_TX_ICR + offsetof(struct RGF_ICR, IMC), 128 WIL6210_IMC_TX); 129 } 130 131 void wil6210_unmask_irq_tx_edma(struct wil6210_priv *wil) 132 { 133 wil_w(wil, RGF_INT_GEN_TX_ICR + offsetof(struct RGF_ICR, IMC), 134 WIL6210_IMC_TX_EDMA); 135 } 136 137 void wil6210_unmask_irq_rx(struct wil6210_priv *wil) 138 { 139 bool unmask_rx_htrsh = atomic_read(&wil->connected_vifs) > 0; 140 141 wil_w(wil, RGF_DMA_EP_RX_ICR + offsetof(struct RGF_ICR, IMC), 142 unmask_rx_htrsh ? WIL6210_IMC_RX : WIL6210_IMC_RX_NO_RX_HTRSH); 143 } 144 145 void wil6210_unmask_irq_rx_edma(struct wil6210_priv *wil) 146 { 147 wil_w(wil, RGF_INT_GEN_RX_ICR + offsetof(struct RGF_ICR, IMC), 148 WIL6210_IMC_RX_EDMA); 149 } 150 151 static void wil6210_unmask_irq_misc(struct wil6210_priv *wil, bool unmask_halp) 152 { 153 wil_dbg_irq(wil, "unmask_irq_misc: unmask_halp(%s)\n", 154 unmask_halp ? "true" : "false"); 155 156 wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, IMC), 157 unmask_halp ? WIL6210_IMC_MISC : WIL6210_IMC_MISC_NO_HALP); 158 } 159 160 static void wil6210_unmask_halp(struct wil6210_priv *wil) 161 { 162 wil_dbg_irq(wil, "unmask_halp\n"); 163 164 wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, IMC), 165 BIT_DMA_EP_MISC_ICR_HALP); 166 } 167 168 static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil) 169 { 170 wil_dbg_irq(wil, "unmask_irq_pseudo\n"); 171 172 set_bit(wil_status_irqen, wil->status); 173 174 wil_w(wil, RGF_DMA_PSEUDO_CAUSE_MASK_SW, WIL6210_IRQ_PSEUDO_MASK); 175 } 176 177 void wil_mask_irq(struct wil6210_priv *wil) 178 { 179 wil_dbg_irq(wil, "mask_irq\n"); 180 181 wil6210_mask_irq_tx(wil); 182 wil6210_mask_irq_tx_edma(wil); 183 wil6210_mask_irq_rx(wil); 184 wil6210_mask_irq_rx_edma(wil); 185 wil6210_mask_irq_misc(wil, true); 186 wil6210_mask_irq_pseudo(wil); 187 } 188 189 void wil_unmask_irq(struct wil6210_priv *wil) 190 { 191 wil_dbg_irq(wil, "unmask_irq\n"); 192 193 wil_w(wil, RGF_DMA_EP_RX_ICR + offsetof(struct RGF_ICR, ICC), 194 WIL_ICR_ICC_VALUE); 195 wil_w(wil, RGF_DMA_EP_TX_ICR + offsetof(struct RGF_ICR, ICC), 196 WIL_ICR_ICC_VALUE); 197 wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, ICC), 198 WIL_ICR_ICC_MISC_VALUE); 199 wil_w(wil, RGF_INT_GEN_TX_ICR + offsetof(struct RGF_ICR, ICC), 200 WIL_ICR_ICC_VALUE); 201 wil_w(wil, RGF_INT_GEN_RX_ICR + offsetof(struct RGF_ICR, ICC), 202 WIL_ICR_ICC_VALUE); 203 204 wil6210_unmask_irq_pseudo(wil); 205 if (wil->use_enhanced_dma_hw) { 206 wil6210_unmask_irq_tx_edma(wil); 207 wil6210_unmask_irq_rx_edma(wil); 208 } else { 209 wil6210_unmask_irq_tx(wil); 210 wil6210_unmask_irq_rx(wil); 211 } 212 wil6210_unmask_irq_misc(wil, true); 213 } 214 215 void wil_configure_interrupt_moderation_edma(struct wil6210_priv *wil) 216 { 217 u32 moderation; 218 219 wil_s(wil, RGF_INT_GEN_IDLE_TIME_LIMIT, WIL_EDMA_IDLE_TIME_LIMIT_USEC); 220 221 wil_s(wil, RGF_INT_GEN_TIME_UNIT_LIMIT, WIL_EDMA_TIME_UNIT_CLK_CYCLES); 222 223 /* Update RX and TX moderation */ 224 moderation = wil->rx_max_burst_duration | 225 (WIL_EDMA_AGG_WATERMARK << WIL_EDMA_AGG_WATERMARK_POS); 226 wil_w(wil, RGF_INT_CTRL_INT_GEN_CFG_0, moderation); 227 wil_w(wil, RGF_INT_CTRL_INT_GEN_CFG_1, moderation); 228 229 /* Treat special events as regular 230 * (set bit 0 to 0x1 and clear bits 1-8) 231 */ 232 wil_c(wil, RGF_INT_COUNT_ON_SPECIAL_EVT, 0x1FE); 233 wil_s(wil, RGF_INT_COUNT_ON_SPECIAL_EVT, 0x1); 234 } 235 236 void wil_configure_interrupt_moderation(struct wil6210_priv *wil) 237 { 238 struct wireless_dev *wdev = wil->main_ndev->ieee80211_ptr; 239 240 wil_dbg_irq(wil, "configure_interrupt_moderation\n"); 241 242 /* disable interrupt moderation for monitor 243 * to get better timestamp precision 244 */ 245 if (wdev->iftype == NL80211_IFTYPE_MONITOR) 246 return; 247 248 /* Disable and clear tx counter before (re)configuration */ 249 wil_w(wil, RGF_DMA_ITR_TX_CNT_CTL, BIT_DMA_ITR_TX_CNT_CTL_CLR); 250 wil_w(wil, RGF_DMA_ITR_TX_CNT_TRSH, wil->tx_max_burst_duration); 251 wil_info(wil, "set ITR_TX_CNT_TRSH = %d usec\n", 252 wil->tx_max_burst_duration); 253 /* Configure TX max burst duration timer to use usec units */ 254 wil_w(wil, RGF_DMA_ITR_TX_CNT_CTL, 255 BIT_DMA_ITR_TX_CNT_CTL_EN | BIT_DMA_ITR_TX_CNT_CTL_EXT_TIC_SEL); 256 257 /* Disable and clear tx idle counter before (re)configuration */ 258 wil_w(wil, RGF_DMA_ITR_TX_IDL_CNT_CTL, BIT_DMA_ITR_TX_IDL_CNT_CTL_CLR); 259 wil_w(wil, RGF_DMA_ITR_TX_IDL_CNT_TRSH, wil->tx_interframe_timeout); 260 wil_info(wil, "set ITR_TX_IDL_CNT_TRSH = %d usec\n", 261 wil->tx_interframe_timeout); 262 /* Configure TX max burst duration timer to use usec units */ 263 wil_w(wil, RGF_DMA_ITR_TX_IDL_CNT_CTL, BIT_DMA_ITR_TX_IDL_CNT_CTL_EN | 264 BIT_DMA_ITR_TX_IDL_CNT_CTL_EXT_TIC_SEL); 265 266 /* Disable and clear rx counter before (re)configuration */ 267 wil_w(wil, RGF_DMA_ITR_RX_CNT_CTL, BIT_DMA_ITR_RX_CNT_CTL_CLR); 268 wil_w(wil, RGF_DMA_ITR_RX_CNT_TRSH, wil->rx_max_burst_duration); 269 wil_info(wil, "set ITR_RX_CNT_TRSH = %d usec\n", 270 wil->rx_max_burst_duration); 271 /* Configure TX max burst duration timer to use usec units */ 272 wil_w(wil, RGF_DMA_ITR_RX_CNT_CTL, 273 BIT_DMA_ITR_RX_CNT_CTL_EN | BIT_DMA_ITR_RX_CNT_CTL_EXT_TIC_SEL); 274 275 /* Disable and clear rx idle counter before (re)configuration */ 276 wil_w(wil, RGF_DMA_ITR_RX_IDL_CNT_CTL, BIT_DMA_ITR_RX_IDL_CNT_CTL_CLR); 277 wil_w(wil, RGF_DMA_ITR_RX_IDL_CNT_TRSH, wil->rx_interframe_timeout); 278 wil_info(wil, "set ITR_RX_IDL_CNT_TRSH = %d usec\n", 279 wil->rx_interframe_timeout); 280 /* Configure TX max burst duration timer to use usec units */ 281 wil_w(wil, RGF_DMA_ITR_RX_IDL_CNT_CTL, BIT_DMA_ITR_RX_IDL_CNT_CTL_EN | 282 BIT_DMA_ITR_RX_IDL_CNT_CTL_EXT_TIC_SEL); 283 } 284 285 static irqreturn_t wil6210_irq_rx(int irq, void *cookie) 286 { 287 struct wil6210_priv *wil = cookie; 288 u32 isr; 289 bool need_unmask = true; 290 291 wil6210_mask_irq_rx(wil); 292 293 isr = wil_ioread32_and_clear(wil->csr + 294 HOSTADDR(RGF_DMA_EP_RX_ICR) + 295 offsetof(struct RGF_ICR, ICR)); 296 297 trace_wil6210_irq_rx(isr); 298 wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr); 299 300 if (unlikely(!isr)) { 301 wil_err_ratelimited(wil, "spurious IRQ: RX\n"); 302 wil6210_unmask_irq_rx(wil); 303 return IRQ_NONE; 304 } 305 306 /* RX_DONE and RX_HTRSH interrupts are the same if interrupt 307 * moderation is not used. Interrupt moderation may cause RX 308 * buffer overflow while RX_DONE is delayed. The required 309 * action is always the same - should empty the accumulated 310 * packets from the RX ring. 311 */ 312 if (likely(isr & (BIT_DMA_EP_RX_ICR_RX_DONE | 313 BIT_DMA_EP_RX_ICR_RX_HTRSH))) { 314 wil_dbg_irq(wil, "RX done / RX_HTRSH received, ISR (0x%x)\n", 315 isr); 316 317 isr &= ~(BIT_DMA_EP_RX_ICR_RX_DONE | 318 BIT_DMA_EP_RX_ICR_RX_HTRSH); 319 if (likely(test_bit(wil_status_fwready, wil->status))) { 320 if (likely(test_bit(wil_status_napi_en, wil->status))) { 321 wil_dbg_txrx(wil, "NAPI(Rx) schedule\n"); 322 need_unmask = false; 323 napi_schedule(&wil->napi_rx); 324 } else { 325 wil_err_ratelimited( 326 wil, 327 "Got Rx interrupt while stopping interface\n"); 328 } 329 } else { 330 wil_err_ratelimited(wil, "Got Rx interrupt while in reset\n"); 331 } 332 } 333 334 if (unlikely(isr)) 335 wil_err(wil, "un-handled RX ISR bits 0x%08x\n", isr); 336 337 /* Rx IRQ will be enabled when NAPI processing finished */ 338 339 atomic_inc(&wil->isr_count_rx); 340 341 if (unlikely(need_unmask)) 342 wil6210_unmask_irq_rx(wil); 343 344 return IRQ_HANDLED; 345 } 346 347 static irqreturn_t wil6210_irq_rx_edma(int irq, void *cookie) 348 { 349 struct wil6210_priv *wil = cookie; 350 u32 isr; 351 bool need_unmask = true; 352 353 wil6210_mask_irq_rx_edma(wil); 354 355 isr = wil_ioread32_and_clear(wil->csr + 356 HOSTADDR(RGF_INT_GEN_RX_ICR) + 357 offsetof(struct RGF_ICR, ICR)); 358 359 trace_wil6210_irq_rx(isr); 360 wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr); 361 362 if (unlikely(!isr)) { 363 wil_err(wil, "spurious IRQ: RX\n"); 364 wil6210_unmask_irq_rx_edma(wil); 365 return IRQ_NONE; 366 } 367 368 if (likely(isr & BIT_RX_STATUS_IRQ)) { 369 wil_dbg_irq(wil, "RX status ring\n"); 370 isr &= ~BIT_RX_STATUS_IRQ; 371 if (likely(test_bit(wil_status_fwready, wil->status))) { 372 if (likely(test_bit(wil_status_napi_en, wil->status))) { 373 wil_dbg_txrx(wil, "NAPI(Rx) schedule\n"); 374 need_unmask = false; 375 napi_schedule(&wil->napi_rx); 376 } else { 377 wil_err(wil, 378 "Got Rx interrupt while stopping interface\n"); 379 } 380 } else { 381 wil_err(wil, "Got Rx interrupt while in reset\n"); 382 } 383 } 384 385 if (unlikely(isr)) 386 wil_err(wil, "un-handled RX ISR bits 0x%08x\n", isr); 387 388 /* Rx IRQ will be enabled when NAPI processing finished */ 389 390 atomic_inc(&wil->isr_count_rx); 391 392 if (unlikely(need_unmask)) 393 wil6210_unmask_irq_rx_edma(wil); 394 395 return IRQ_HANDLED; 396 } 397 398 static irqreturn_t wil6210_irq_tx_edma(int irq, void *cookie) 399 { 400 struct wil6210_priv *wil = cookie; 401 u32 isr; 402 bool need_unmask = true; 403 404 wil6210_mask_irq_tx_edma(wil); 405 406 isr = wil_ioread32_and_clear(wil->csr + 407 HOSTADDR(RGF_INT_GEN_TX_ICR) + 408 offsetof(struct RGF_ICR, ICR)); 409 410 trace_wil6210_irq_tx(isr); 411 wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr); 412 413 if (unlikely(!isr)) { 414 wil_err(wil, "spurious IRQ: TX\n"); 415 wil6210_unmask_irq_tx_edma(wil); 416 return IRQ_NONE; 417 } 418 419 if (likely(isr & BIT_TX_STATUS_IRQ)) { 420 wil_dbg_irq(wil, "TX status ring\n"); 421 isr &= ~BIT_TX_STATUS_IRQ; 422 if (likely(test_bit(wil_status_fwready, wil->status))) { 423 wil_dbg_txrx(wil, "NAPI(Tx) schedule\n"); 424 need_unmask = false; 425 napi_schedule(&wil->napi_tx); 426 } else { 427 wil_err(wil, "Got Tx status ring IRQ while in reset\n"); 428 } 429 } 430 431 if (unlikely(isr)) 432 wil_err(wil, "un-handled TX ISR bits 0x%08x\n", isr); 433 434 /* Tx IRQ will be enabled when NAPI processing finished */ 435 436 atomic_inc(&wil->isr_count_tx); 437 438 if (unlikely(need_unmask)) 439 wil6210_unmask_irq_tx_edma(wil); 440 441 return IRQ_HANDLED; 442 } 443 444 static irqreturn_t wil6210_irq_tx(int irq, void *cookie) 445 { 446 struct wil6210_priv *wil = cookie; 447 u32 isr; 448 bool need_unmask = true; 449 450 wil6210_mask_irq_tx(wil); 451 452 isr = wil_ioread32_and_clear(wil->csr + 453 HOSTADDR(RGF_DMA_EP_TX_ICR) + 454 offsetof(struct RGF_ICR, ICR)); 455 456 trace_wil6210_irq_tx(isr); 457 wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr); 458 459 if (unlikely(!isr)) { 460 wil_err_ratelimited(wil, "spurious IRQ: TX\n"); 461 wil6210_unmask_irq_tx(wil); 462 return IRQ_NONE; 463 } 464 465 if (likely(isr & BIT_DMA_EP_TX_ICR_TX_DONE)) { 466 wil_dbg_irq(wil, "TX done\n"); 467 isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE; 468 /* clear also all VRING interrupts */ 469 isr &= ~(BIT(25) - 1UL); 470 if (likely(test_bit(wil_status_fwready, wil->status))) { 471 wil_dbg_txrx(wil, "NAPI(Tx) schedule\n"); 472 need_unmask = false; 473 napi_schedule(&wil->napi_tx); 474 } else { 475 wil_err_ratelimited(wil, "Got Tx interrupt while in reset\n"); 476 } 477 } 478 479 if (unlikely(isr)) 480 wil_err_ratelimited(wil, "un-handled TX ISR bits 0x%08x\n", 481 isr); 482 483 /* Tx IRQ will be enabled when NAPI processing finished */ 484 485 atomic_inc(&wil->isr_count_tx); 486 487 if (unlikely(need_unmask)) 488 wil6210_unmask_irq_tx(wil); 489 490 return IRQ_HANDLED; 491 } 492 493 static void wil_notify_fw_error(struct wil6210_priv *wil) 494 { 495 struct device *dev = &wil->main_ndev->dev; 496 char *envp[3] = { 497 [0] = "SOURCE=wil6210", 498 [1] = "EVENT=FW_ERROR", 499 [2] = NULL, 500 }; 501 wil_err(wil, "Notify about firmware error\n"); 502 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); 503 } 504 505 static void wil_cache_mbox_regs(struct wil6210_priv *wil) 506 { 507 /* make shadow copy of registers that should not change on run time */ 508 wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX, 509 sizeof(struct wil6210_mbox_ctl)); 510 wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx); 511 wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx); 512 } 513 514 static bool wil_validate_mbox_regs(struct wil6210_priv *wil) 515 { 516 size_t min_size = sizeof(struct wil6210_mbox_hdr) + 517 sizeof(struct wmi_cmd_hdr); 518 519 if (wil->mbox_ctl.rx.entry_size < min_size) { 520 wil_err(wil, "rx mbox entry too small (%d)\n", 521 wil->mbox_ctl.rx.entry_size); 522 return false; 523 } 524 if (wil->mbox_ctl.tx.entry_size < min_size) { 525 wil_err(wil, "tx mbox entry too small (%d)\n", 526 wil->mbox_ctl.tx.entry_size); 527 return false; 528 } 529 530 return true; 531 } 532 533 static irqreturn_t wil6210_irq_misc(int irq, void *cookie) 534 { 535 struct wil6210_priv *wil = cookie; 536 u32 isr; 537 538 wil6210_mask_irq_misc(wil, false); 539 540 isr = wil_ioread32_and_clear(wil->csr + 541 HOSTADDR(RGF_DMA_EP_MISC_ICR) + 542 offsetof(struct RGF_ICR, ICR)); 543 544 trace_wil6210_irq_misc(isr); 545 wil_dbg_irq(wil, "ISR MISC 0x%08x\n", isr); 546 547 if (!isr) { 548 wil_err(wil, "spurious IRQ: MISC\n"); 549 wil6210_unmask_irq_misc(wil, false); 550 return IRQ_NONE; 551 } 552 553 if (isr & ISR_MISC_FW_ERROR) { 554 u32 fw_assert_code = wil_r(wil, wil->rgf_fw_assert_code_addr); 555 u32 ucode_assert_code = 556 wil_r(wil, wil->rgf_ucode_assert_code_addr); 557 558 wil_err(wil, 559 "Firmware error detected, assert codes FW 0x%08x, UCODE 0x%08x\n", 560 fw_assert_code, ucode_assert_code); 561 clear_bit(wil_status_fwready, wil->status); 562 /* 563 * do not clear @isr here - we do 2-nd part in thread 564 * there, user space get notified, and it should be done 565 * in non-atomic context 566 */ 567 } 568 569 if (isr & ISR_MISC_FW_READY) { 570 wil_dbg_irq(wil, "IRQ: FW ready\n"); 571 wil_cache_mbox_regs(wil); 572 if (wil_validate_mbox_regs(wil)) 573 set_bit(wil_status_mbox_ready, wil->status); 574 /** 575 * Actual FW ready indicated by the 576 * WMI_FW_READY_EVENTID 577 */ 578 isr &= ~ISR_MISC_FW_READY; 579 } 580 581 if (isr & BIT_DMA_EP_MISC_ICR_HALP) { 582 isr &= ~BIT_DMA_EP_MISC_ICR_HALP; 583 if (wil->halp.handle_icr) { 584 /* no need to handle HALP ICRs until next vote */ 585 wil->halp.handle_icr = false; 586 wil_dbg_irq(wil, "irq_misc: HALP IRQ invoked\n"); 587 wil6210_mask_irq_misc(wil, true); 588 complete(&wil->halp.comp); 589 } 590 } 591 592 wil->isr_misc = isr; 593 594 if (isr) { 595 return IRQ_WAKE_THREAD; 596 } else { 597 wil6210_unmask_irq_misc(wil, false); 598 return IRQ_HANDLED; 599 } 600 } 601 602 static irqreturn_t wil6210_irq_misc_thread(int irq, void *cookie) 603 { 604 struct wil6210_priv *wil = cookie; 605 u32 isr = wil->isr_misc; 606 607 trace_wil6210_irq_misc_thread(isr); 608 wil_dbg_irq(wil, "Thread ISR MISC 0x%08x\n", isr); 609 610 if (isr & ISR_MISC_FW_ERROR) { 611 wil->recovery_state = fw_recovery_pending; 612 wil_fw_core_dump(wil); 613 wil_notify_fw_error(wil); 614 isr &= ~ISR_MISC_FW_ERROR; 615 if (wil->platform_ops.notify) { 616 wil_err(wil, "notify platform driver about FW crash"); 617 wil->platform_ops.notify(wil->platform_handle, 618 WIL_PLATFORM_EVT_FW_CRASH); 619 } else { 620 wil_fw_error_recovery(wil); 621 } 622 } 623 if (isr & ISR_MISC_MBOX_EVT) { 624 wil_dbg_irq(wil, "MBOX event\n"); 625 wmi_recv_cmd(wil); 626 isr &= ~ISR_MISC_MBOX_EVT; 627 } 628 629 if (isr) 630 wil_dbg_irq(wil, "un-handled MISC ISR bits 0x%08x\n", isr); 631 632 wil->isr_misc = 0; 633 634 wil6210_unmask_irq_misc(wil, false); 635 636 /* in non-triple MSI case, this is done inside wil6210_thread_irq 637 * because it has to be done after unmasking the pseudo. 638 */ 639 if (wil->n_msi == 3 && wil->suspend_resp_rcvd) { 640 wil_dbg_irq(wil, "set suspend_resp_comp to true\n"); 641 wil->suspend_resp_comp = true; 642 wake_up_interruptible(&wil->wq); 643 } 644 645 return IRQ_HANDLED; 646 } 647 648 /** 649 * thread IRQ handler 650 */ 651 static irqreturn_t wil6210_thread_irq(int irq, void *cookie) 652 { 653 struct wil6210_priv *wil = cookie; 654 655 wil_dbg_irq(wil, "Thread IRQ\n"); 656 /* Discover real IRQ cause */ 657 if (wil->isr_misc) 658 wil6210_irq_misc_thread(irq, cookie); 659 660 wil6210_unmask_irq_pseudo(wil); 661 662 if (wil->suspend_resp_rcvd) { 663 wil_dbg_irq(wil, "set suspend_resp_comp to true\n"); 664 wil->suspend_resp_comp = true; 665 wake_up_interruptible(&wil->wq); 666 } 667 668 return IRQ_HANDLED; 669 } 670 671 /* DEBUG 672 * There is subtle bug in hardware that causes IRQ to raise when it should be 673 * masked. It is quite rare and hard to debug. 674 * 675 * Catch irq issue if it happens and print all I can. 676 */ 677 static int wil6210_debug_irq_mask(struct wil6210_priv *wil, u32 pseudo_cause) 678 { 679 u32 icm_rx, icr_rx, imv_rx; 680 u32 icm_tx, icr_tx, imv_tx; 681 u32 icm_misc, icr_misc, imv_misc; 682 683 if (!test_bit(wil_status_irqen, wil->status)) { 684 if (wil->use_enhanced_dma_hw) { 685 icm_rx = wil_ioread32_and_clear(wil->csr + 686 HOSTADDR(RGF_INT_GEN_RX_ICR) + 687 offsetof(struct RGF_ICR, ICM)); 688 icr_rx = wil_ioread32_and_clear(wil->csr + 689 HOSTADDR(RGF_INT_GEN_RX_ICR) + 690 offsetof(struct RGF_ICR, ICR)); 691 imv_rx = wil_r(wil, RGF_INT_GEN_RX_ICR + 692 offsetof(struct RGF_ICR, IMV)); 693 icm_tx = wil_ioread32_and_clear(wil->csr + 694 HOSTADDR(RGF_INT_GEN_TX_ICR) + 695 offsetof(struct RGF_ICR, ICM)); 696 icr_tx = wil_ioread32_and_clear(wil->csr + 697 HOSTADDR(RGF_INT_GEN_TX_ICR) + 698 offsetof(struct RGF_ICR, ICR)); 699 imv_tx = wil_r(wil, RGF_INT_GEN_TX_ICR + 700 offsetof(struct RGF_ICR, IMV)); 701 } else { 702 icm_rx = wil_ioread32_and_clear(wil->csr + 703 HOSTADDR(RGF_DMA_EP_RX_ICR) + 704 offsetof(struct RGF_ICR, ICM)); 705 icr_rx = wil_ioread32_and_clear(wil->csr + 706 HOSTADDR(RGF_DMA_EP_RX_ICR) + 707 offsetof(struct RGF_ICR, ICR)); 708 imv_rx = wil_r(wil, RGF_DMA_EP_RX_ICR + 709 offsetof(struct RGF_ICR, IMV)); 710 icm_tx = wil_ioread32_and_clear(wil->csr + 711 HOSTADDR(RGF_DMA_EP_TX_ICR) + 712 offsetof(struct RGF_ICR, ICM)); 713 icr_tx = wil_ioread32_and_clear(wil->csr + 714 HOSTADDR(RGF_DMA_EP_TX_ICR) + 715 offsetof(struct RGF_ICR, ICR)); 716 imv_tx = wil_r(wil, RGF_DMA_EP_TX_ICR + 717 offsetof(struct RGF_ICR, IMV)); 718 } 719 icm_misc = wil_ioread32_and_clear(wil->csr + 720 HOSTADDR(RGF_DMA_EP_MISC_ICR) + 721 offsetof(struct RGF_ICR, ICM)); 722 icr_misc = wil_ioread32_and_clear(wil->csr + 723 HOSTADDR(RGF_DMA_EP_MISC_ICR) + 724 offsetof(struct RGF_ICR, ICR)); 725 imv_misc = wil_r(wil, RGF_DMA_EP_MISC_ICR + 726 offsetof(struct RGF_ICR, IMV)); 727 728 /* HALP interrupt can be unmasked when misc interrupts are 729 * masked 730 */ 731 if (icr_misc & BIT_DMA_EP_MISC_ICR_HALP) 732 return 0; 733 734 wil_err(wil, "IRQ when it should be masked: pseudo 0x%08x\n" 735 "Rx icm:icr:imv 0x%08x 0x%08x 0x%08x\n" 736 "Tx icm:icr:imv 0x%08x 0x%08x 0x%08x\n" 737 "Misc icm:icr:imv 0x%08x 0x%08x 0x%08x\n", 738 pseudo_cause, 739 icm_rx, icr_rx, imv_rx, 740 icm_tx, icr_tx, imv_tx, 741 icm_misc, icr_misc, imv_misc); 742 743 return -EINVAL; 744 } 745 746 return 0; 747 } 748 749 static irqreturn_t wil6210_hardirq(int irq, void *cookie) 750 { 751 irqreturn_t rc = IRQ_HANDLED; 752 struct wil6210_priv *wil = cookie; 753 u32 pseudo_cause = wil_r(wil, RGF_DMA_PSEUDO_CAUSE); 754 755 /** 756 * pseudo_cause is Clear-On-Read, no need to ACK 757 */ 758 if (unlikely((pseudo_cause == 0) || ((pseudo_cause & 0xff) == 0xff))) 759 return IRQ_NONE; 760 761 /* IRQ mask debug */ 762 if (unlikely(wil6210_debug_irq_mask(wil, pseudo_cause))) 763 return IRQ_NONE; 764 765 trace_wil6210_irq_pseudo(pseudo_cause); 766 wil_dbg_irq(wil, "Pseudo IRQ 0x%08x\n", pseudo_cause); 767 768 wil6210_mask_irq_pseudo(wil); 769 770 /* Discover real IRQ cause 771 * There are 2 possible phases for every IRQ: 772 * - hard IRQ handler called right here 773 * - threaded handler called later 774 * 775 * Hard IRQ handler reads and clears ISR. 776 * 777 * If threaded handler requested, hard IRQ handler 778 * returns IRQ_WAKE_THREAD and saves ISR register value 779 * for the threaded handler use. 780 * 781 * voting for wake thread - need at least 1 vote 782 */ 783 if ((pseudo_cause & BIT_DMA_PSEUDO_CAUSE_RX) && 784 (wil->txrx_ops.irq_rx(irq, cookie) == IRQ_WAKE_THREAD)) 785 rc = IRQ_WAKE_THREAD; 786 787 if ((pseudo_cause & BIT_DMA_PSEUDO_CAUSE_TX) && 788 (wil->txrx_ops.irq_tx(irq, cookie) == IRQ_WAKE_THREAD)) 789 rc = IRQ_WAKE_THREAD; 790 791 if ((pseudo_cause & BIT_DMA_PSEUDO_CAUSE_MISC) && 792 (wil6210_irq_misc(irq, cookie) == IRQ_WAKE_THREAD)) 793 rc = IRQ_WAKE_THREAD; 794 795 /* if thread is requested, it will unmask IRQ */ 796 if (rc != IRQ_WAKE_THREAD) 797 wil6210_unmask_irq_pseudo(wil); 798 799 return rc; 800 } 801 802 static int wil6210_request_3msi(struct wil6210_priv *wil, int irq) 803 { 804 int rc; 805 806 /* IRQ's are in the following order: 807 * - Tx 808 * - Rx 809 * - Misc 810 */ 811 rc = request_irq(irq, wil->txrx_ops.irq_tx, IRQF_SHARED, 812 WIL_NAME "_tx", wil); 813 if (rc) 814 return rc; 815 816 rc = request_irq(irq + 1, wil->txrx_ops.irq_rx, IRQF_SHARED, 817 WIL_NAME "_rx", wil); 818 if (rc) 819 goto free0; 820 821 rc = request_threaded_irq(irq + 2, wil6210_irq_misc, 822 wil6210_irq_misc_thread, 823 IRQF_SHARED, WIL_NAME "_misc", wil); 824 if (rc) 825 goto free1; 826 827 return 0; 828 free1: 829 free_irq(irq + 1, wil); 830 free0: 831 free_irq(irq, wil); 832 833 return rc; 834 } 835 836 /* can't use wil_ioread32_and_clear because ICC value is not set yet */ 837 static inline void wil_clear32(void __iomem *addr) 838 { 839 u32 x = readl(addr); 840 841 writel(x, addr); 842 } 843 844 void wil6210_clear_irq(struct wil6210_priv *wil) 845 { 846 wil_clear32(wil->csr + HOSTADDR(RGF_DMA_EP_RX_ICR) + 847 offsetof(struct RGF_ICR, ICR)); 848 wil_clear32(wil->csr + HOSTADDR(RGF_DMA_EP_TX_ICR) + 849 offsetof(struct RGF_ICR, ICR)); 850 wil_clear32(wil->csr + HOSTADDR(RGF_INT_GEN_RX_ICR) + 851 offsetof(struct RGF_ICR, ICR)); 852 wil_clear32(wil->csr + HOSTADDR(RGF_INT_GEN_TX_ICR) + 853 offsetof(struct RGF_ICR, ICR)); 854 wil_clear32(wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) + 855 offsetof(struct RGF_ICR, ICR)); 856 wmb(); /* make sure write completed */ 857 } 858 859 void wil6210_set_halp(struct wil6210_priv *wil) 860 { 861 wil_dbg_irq(wil, "set_halp\n"); 862 863 wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, ICS), 864 BIT_DMA_EP_MISC_ICR_HALP); 865 } 866 867 void wil6210_clear_halp(struct wil6210_priv *wil) 868 { 869 wil_dbg_irq(wil, "clear_halp\n"); 870 871 wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, ICR), 872 BIT_DMA_EP_MISC_ICR_HALP); 873 wil6210_unmask_halp(wil); 874 } 875 876 int wil6210_init_irq(struct wil6210_priv *wil, int irq) 877 { 878 int rc; 879 880 wil_dbg_misc(wil, "init_irq: %s, n_msi=%d\n", 881 wil->n_msi ? "MSI" : "INTx", wil->n_msi); 882 883 if (wil->use_enhanced_dma_hw) { 884 wil->txrx_ops.irq_tx = wil6210_irq_tx_edma; 885 wil->txrx_ops.irq_rx = wil6210_irq_rx_edma; 886 } else { 887 wil->txrx_ops.irq_tx = wil6210_irq_tx; 888 wil->txrx_ops.irq_rx = wil6210_irq_rx; 889 } 890 891 if (wil->n_msi == 3) 892 rc = wil6210_request_3msi(wil, irq); 893 else 894 rc = request_threaded_irq(irq, wil6210_hardirq, 895 wil6210_thread_irq, 896 wil->n_msi ? 0 : IRQF_SHARED, 897 WIL_NAME, wil); 898 return rc; 899 } 900 901 void wil6210_fini_irq(struct wil6210_priv *wil, int irq) 902 { 903 wil_dbg_misc(wil, "fini_irq:\n"); 904 905 wil_mask_irq(wil); 906 free_irq(irq, wil); 907 if (wil->n_msi == 3) { 908 free_irq(irq + 1, wil); 909 free_irq(irq + 2, wil); 910 } 911 } 912