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 /* thread IRQ handler */ 649 static irqreturn_t wil6210_thread_irq(int irq, void *cookie) 650 { 651 struct wil6210_priv *wil = cookie; 652 653 wil_dbg_irq(wil, "Thread IRQ\n"); 654 /* Discover real IRQ cause */ 655 if (wil->isr_misc) 656 wil6210_irq_misc_thread(irq, cookie); 657 658 wil6210_unmask_irq_pseudo(wil); 659 660 if (wil->suspend_resp_rcvd) { 661 wil_dbg_irq(wil, "set suspend_resp_comp to true\n"); 662 wil->suspend_resp_comp = true; 663 wake_up_interruptible(&wil->wq); 664 } 665 666 return IRQ_HANDLED; 667 } 668 669 /* DEBUG 670 * There is subtle bug in hardware that causes IRQ to raise when it should be 671 * masked. It is quite rare and hard to debug. 672 * 673 * Catch irq issue if it happens and print all I can. 674 */ 675 static int wil6210_debug_irq_mask(struct wil6210_priv *wil, u32 pseudo_cause) 676 { 677 u32 icm_rx, icr_rx, imv_rx; 678 u32 icm_tx, icr_tx, imv_tx; 679 u32 icm_misc, icr_misc, imv_misc; 680 681 if (!test_bit(wil_status_irqen, wil->status)) { 682 if (wil->use_enhanced_dma_hw) { 683 icm_rx = wil_ioread32_and_clear(wil->csr + 684 HOSTADDR(RGF_INT_GEN_RX_ICR) + 685 offsetof(struct RGF_ICR, ICM)); 686 icr_rx = wil_ioread32_and_clear(wil->csr + 687 HOSTADDR(RGF_INT_GEN_RX_ICR) + 688 offsetof(struct RGF_ICR, ICR)); 689 imv_rx = wil_r(wil, RGF_INT_GEN_RX_ICR + 690 offsetof(struct RGF_ICR, IMV)); 691 icm_tx = wil_ioread32_and_clear(wil->csr + 692 HOSTADDR(RGF_INT_GEN_TX_ICR) + 693 offsetof(struct RGF_ICR, ICM)); 694 icr_tx = wil_ioread32_and_clear(wil->csr + 695 HOSTADDR(RGF_INT_GEN_TX_ICR) + 696 offsetof(struct RGF_ICR, ICR)); 697 imv_tx = wil_r(wil, RGF_INT_GEN_TX_ICR + 698 offsetof(struct RGF_ICR, IMV)); 699 } else { 700 icm_rx = wil_ioread32_and_clear(wil->csr + 701 HOSTADDR(RGF_DMA_EP_RX_ICR) + 702 offsetof(struct RGF_ICR, ICM)); 703 icr_rx = wil_ioread32_and_clear(wil->csr + 704 HOSTADDR(RGF_DMA_EP_RX_ICR) + 705 offsetof(struct RGF_ICR, ICR)); 706 imv_rx = wil_r(wil, RGF_DMA_EP_RX_ICR + 707 offsetof(struct RGF_ICR, IMV)); 708 icm_tx = wil_ioread32_and_clear(wil->csr + 709 HOSTADDR(RGF_DMA_EP_TX_ICR) + 710 offsetof(struct RGF_ICR, ICM)); 711 icr_tx = wil_ioread32_and_clear(wil->csr + 712 HOSTADDR(RGF_DMA_EP_TX_ICR) + 713 offsetof(struct RGF_ICR, ICR)); 714 imv_tx = wil_r(wil, RGF_DMA_EP_TX_ICR + 715 offsetof(struct RGF_ICR, IMV)); 716 } 717 icm_misc = wil_ioread32_and_clear(wil->csr + 718 HOSTADDR(RGF_DMA_EP_MISC_ICR) + 719 offsetof(struct RGF_ICR, ICM)); 720 icr_misc = wil_ioread32_and_clear(wil->csr + 721 HOSTADDR(RGF_DMA_EP_MISC_ICR) + 722 offsetof(struct RGF_ICR, ICR)); 723 imv_misc = wil_r(wil, RGF_DMA_EP_MISC_ICR + 724 offsetof(struct RGF_ICR, IMV)); 725 726 /* HALP interrupt can be unmasked when misc interrupts are 727 * masked 728 */ 729 if (icr_misc & BIT_DMA_EP_MISC_ICR_HALP) 730 return 0; 731 732 wil_err(wil, "IRQ when it should be masked: pseudo 0x%08x\n" 733 "Rx icm:icr:imv 0x%08x 0x%08x 0x%08x\n" 734 "Tx icm:icr:imv 0x%08x 0x%08x 0x%08x\n" 735 "Misc icm:icr:imv 0x%08x 0x%08x 0x%08x\n", 736 pseudo_cause, 737 icm_rx, icr_rx, imv_rx, 738 icm_tx, icr_tx, imv_tx, 739 icm_misc, icr_misc, imv_misc); 740 741 return -EINVAL; 742 } 743 744 return 0; 745 } 746 747 static irqreturn_t wil6210_hardirq(int irq, void *cookie) 748 { 749 irqreturn_t rc = IRQ_HANDLED; 750 struct wil6210_priv *wil = cookie; 751 u32 pseudo_cause = wil_r(wil, RGF_DMA_PSEUDO_CAUSE); 752 753 /** 754 * pseudo_cause is Clear-On-Read, no need to ACK 755 */ 756 if (unlikely((pseudo_cause == 0) || ((pseudo_cause & 0xff) == 0xff))) 757 return IRQ_NONE; 758 759 /* IRQ mask debug */ 760 if (unlikely(wil6210_debug_irq_mask(wil, pseudo_cause))) 761 return IRQ_NONE; 762 763 trace_wil6210_irq_pseudo(pseudo_cause); 764 wil_dbg_irq(wil, "Pseudo IRQ 0x%08x\n", pseudo_cause); 765 766 wil6210_mask_irq_pseudo(wil); 767 768 /* Discover real IRQ cause 769 * There are 2 possible phases for every IRQ: 770 * - hard IRQ handler called right here 771 * - threaded handler called later 772 * 773 * Hard IRQ handler reads and clears ISR. 774 * 775 * If threaded handler requested, hard IRQ handler 776 * returns IRQ_WAKE_THREAD and saves ISR register value 777 * for the threaded handler use. 778 * 779 * voting for wake thread - need at least 1 vote 780 */ 781 if ((pseudo_cause & BIT_DMA_PSEUDO_CAUSE_RX) && 782 (wil->txrx_ops.irq_rx(irq, cookie) == IRQ_WAKE_THREAD)) 783 rc = IRQ_WAKE_THREAD; 784 785 if ((pseudo_cause & BIT_DMA_PSEUDO_CAUSE_TX) && 786 (wil->txrx_ops.irq_tx(irq, cookie) == IRQ_WAKE_THREAD)) 787 rc = IRQ_WAKE_THREAD; 788 789 if ((pseudo_cause & BIT_DMA_PSEUDO_CAUSE_MISC) && 790 (wil6210_irq_misc(irq, cookie) == IRQ_WAKE_THREAD)) 791 rc = IRQ_WAKE_THREAD; 792 793 /* if thread is requested, it will unmask IRQ */ 794 if (rc != IRQ_WAKE_THREAD) 795 wil6210_unmask_irq_pseudo(wil); 796 797 return rc; 798 } 799 800 static int wil6210_request_3msi(struct wil6210_priv *wil, int irq) 801 { 802 int rc; 803 804 /* IRQ's are in the following order: 805 * - Tx 806 * - Rx 807 * - Misc 808 */ 809 rc = request_irq(irq, wil->txrx_ops.irq_tx, IRQF_SHARED, 810 WIL_NAME "_tx", wil); 811 if (rc) 812 return rc; 813 814 rc = request_irq(irq + 1, wil->txrx_ops.irq_rx, IRQF_SHARED, 815 WIL_NAME "_rx", wil); 816 if (rc) 817 goto free0; 818 819 rc = request_threaded_irq(irq + 2, wil6210_irq_misc, 820 wil6210_irq_misc_thread, 821 IRQF_SHARED, WIL_NAME "_misc", wil); 822 if (rc) 823 goto free1; 824 825 return 0; 826 free1: 827 free_irq(irq + 1, wil); 828 free0: 829 free_irq(irq, wil); 830 831 return rc; 832 } 833 834 /* can't use wil_ioread32_and_clear because ICC value is not set yet */ 835 static inline void wil_clear32(void __iomem *addr) 836 { 837 u32 x = readl(addr); 838 839 writel(x, addr); 840 } 841 842 void wil6210_clear_irq(struct wil6210_priv *wil) 843 { 844 wil_clear32(wil->csr + HOSTADDR(RGF_DMA_EP_RX_ICR) + 845 offsetof(struct RGF_ICR, ICR)); 846 wil_clear32(wil->csr + HOSTADDR(RGF_DMA_EP_TX_ICR) + 847 offsetof(struct RGF_ICR, ICR)); 848 wil_clear32(wil->csr + HOSTADDR(RGF_INT_GEN_RX_ICR) + 849 offsetof(struct RGF_ICR, ICR)); 850 wil_clear32(wil->csr + HOSTADDR(RGF_INT_GEN_TX_ICR) + 851 offsetof(struct RGF_ICR, ICR)); 852 wil_clear32(wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) + 853 offsetof(struct RGF_ICR, ICR)); 854 wmb(); /* make sure write completed */ 855 } 856 857 void wil6210_set_halp(struct wil6210_priv *wil) 858 { 859 wil_dbg_irq(wil, "set_halp\n"); 860 861 wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, ICS), 862 BIT_DMA_EP_MISC_ICR_HALP); 863 } 864 865 void wil6210_clear_halp(struct wil6210_priv *wil) 866 { 867 wil_dbg_irq(wil, "clear_halp\n"); 868 869 wil_w(wil, RGF_DMA_EP_MISC_ICR + offsetof(struct RGF_ICR, ICR), 870 BIT_DMA_EP_MISC_ICR_HALP); 871 wil6210_unmask_halp(wil); 872 } 873 874 int wil6210_init_irq(struct wil6210_priv *wil, int irq) 875 { 876 int rc; 877 878 wil_dbg_misc(wil, "init_irq: %s, n_msi=%d\n", 879 wil->n_msi ? "MSI" : "INTx", wil->n_msi); 880 881 if (wil->use_enhanced_dma_hw) { 882 wil->txrx_ops.irq_tx = wil6210_irq_tx_edma; 883 wil->txrx_ops.irq_rx = wil6210_irq_rx_edma; 884 } else { 885 wil->txrx_ops.irq_tx = wil6210_irq_tx; 886 wil->txrx_ops.irq_rx = wil6210_irq_rx; 887 } 888 889 if (wil->n_msi == 3) 890 rc = wil6210_request_3msi(wil, irq); 891 else 892 rc = request_threaded_irq(irq, wil6210_hardirq, 893 wil6210_thread_irq, 894 wil->n_msi ? 0 : IRQF_SHARED, 895 WIL_NAME, wil); 896 return rc; 897 } 898 899 void wil6210_fini_irq(struct wil6210_priv *wil, int irq) 900 { 901 wil_dbg_misc(wil, "fini_irq:\n"); 902 903 wil_mask_irq(wil); 904 free_irq(irq, wil); 905 if (wil->n_msi == 3) { 906 free_irq(irq + 1, wil); 907 free_irq(irq + 2, wil); 908 } 909 } 910