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