xref: /freebsd/sys/dev/sfxge/common/efx_intr.c (revision 325151a3)
1 /*-
2  * Copyright (c) 2007-2015 Solarflare Communications Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  *    this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright notice,
11  *    this list of conditions and the following disclaimer in the documentation
12  *    and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * The views and conclusions contained in the software and documentation are
27  * those of the authors and should not be interpreted as representing official
28  * policies, either expressed or implied, of the FreeBSD Project.
29  */
30 
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 
34 #include "efsys.h"
35 #include "efx.h"
36 #include "efx_types.h"
37 #include "efx_regs.h"
38 #include "efx_impl.h"
39 
40 
41 #if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
42 
43 static	__checkReturn	int
44 falconsiena_intr_init(
45 	__in		efx_nic_t *enp,
46 	__in		efx_intr_type_t type,
47 	__in		efsys_mem_t *esmp);
48 
49 static			void
50 falconsiena_intr_enable(
51 	__in		efx_nic_t *enp);
52 
53 static			void
54 falconsiena_intr_disable(
55 	__in		efx_nic_t *enp);
56 
57 static			void
58 falconsiena_intr_disable_unlocked(
59 	__in		efx_nic_t *enp);
60 
61 static	__checkReturn	int
62 falconsiena_intr_trigger(
63 	__in		efx_nic_t *enp,
64 	__in		unsigned int level);
65 
66 static			void
67 falconsiena_intr_fini(
68 	__in		efx_nic_t *enp);
69 
70 
71 static	__checkReturn	boolean_t
72 falconsiena_intr_check_fatal(
73 	__in		efx_nic_t *enp);
74 
75 static			void
76 falconsiena_intr_fatal(
77 	__in		efx_nic_t *enp);
78 
79 #endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
80 
81 
82 #if EFSYS_OPT_FALCON
83 static efx_intr_ops_t	__efx_intr_falcon_ops = {
84 	falconsiena_intr_init,			/* eio_init */
85 	falconsiena_intr_enable,		/* eio_enable */
86 	falconsiena_intr_disable,		/* eio_disable */
87 	falconsiena_intr_disable_unlocked,	/* eio_disable_unlocked */
88 	falconsiena_intr_trigger,		/* eio_trigger */
89 	falconsiena_intr_fini,			/* eio_fini */
90 };
91 #endif	/* EFSYS_OPT_FALCON */
92 
93 #if EFSYS_OPT_SIENA
94 static efx_intr_ops_t	__efx_intr_siena_ops = {
95 	falconsiena_intr_init,			/* eio_init */
96 	falconsiena_intr_enable,		/* eio_enable */
97 	falconsiena_intr_disable,		/* eio_disable */
98 	falconsiena_intr_disable_unlocked,	/* eio_disable_unlocked */
99 	falconsiena_intr_trigger,		/* eio_trigger */
100 	falconsiena_intr_fini,			/* eio_fini */
101 };
102 #endif	/* EFSYS_OPT_SIENA */
103 
104 #if EFSYS_OPT_HUNTINGTON
105 static efx_intr_ops_t	__efx_intr_hunt_ops = {
106 	hunt_intr_init,			/* eio_init */
107 	hunt_intr_enable,		/* eio_enable */
108 	hunt_intr_disable,		/* eio_disable */
109 	hunt_intr_disable_unlocked,	/* eio_disable_unlocked */
110 	hunt_intr_trigger,		/* eio_trigger */
111 	hunt_intr_fini,			/* eio_fini */
112 };
113 #endif	/* EFSYS_OPT_HUNTINGTON */
114 
115 
116 	__checkReturn	int
117 efx_intr_init(
118 	__in		efx_nic_t *enp,
119 	__in		efx_intr_type_t type,
120 	__in		efsys_mem_t *esmp)
121 {
122 	efx_intr_t *eip = &(enp->en_intr);
123 	efx_intr_ops_t *eiop;
124 	int rc;
125 
126 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
127 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
128 
129 	if (enp->en_mod_flags & EFX_MOD_INTR) {
130 		rc = EINVAL;
131 		goto fail1;
132 	}
133 
134 	eip->ei_esmp = esmp;
135 	eip->ei_type = type;
136 	eip->ei_level = 0;
137 
138 	enp->en_mod_flags |= EFX_MOD_INTR;
139 
140 	switch (enp->en_family) {
141 #if EFSYS_OPT_FALCON
142 	case EFX_FAMILY_FALCON:
143 		eiop = (efx_intr_ops_t *)&__efx_intr_falcon_ops;
144 		break;
145 #endif	/* EFSYS_OPT_FALCON */
146 
147 #if EFSYS_OPT_SIENA
148 	case EFX_FAMILY_SIENA:
149 		eiop = (efx_intr_ops_t *)&__efx_intr_siena_ops;
150 		break;
151 #endif	/* EFSYS_OPT_SIENA */
152 
153 #if EFSYS_OPT_HUNTINGTON
154 	case EFX_FAMILY_HUNTINGTON:
155 		eiop = (efx_intr_ops_t *)&__efx_intr_hunt_ops;
156 		break;
157 #endif	/* EFSYS_OPT_HUNTINGTON */
158 
159 	default:
160 		EFSYS_ASSERT(B_FALSE);
161 		rc = ENOTSUP;
162 		goto fail2;
163 	}
164 
165 	if ((rc = eiop->eio_init(enp, type, esmp)) != 0)
166 		goto fail3;
167 
168 	eip->ei_eiop = eiop;
169 
170 	return (0);
171 
172 fail3:
173 	EFSYS_PROBE(fail3);
174 fail2:
175 	EFSYS_PROBE(fail2);
176 fail1:
177 	EFSYS_PROBE1(fail1, int, rc);
178 
179 	return (rc);
180 }
181 
182 		void
183 efx_intr_fini(
184 	__in	efx_nic_t *enp)
185 {
186 	efx_intr_t *eip = &(enp->en_intr);
187 	efx_intr_ops_t *eiop = eip->ei_eiop;
188 
189 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
190 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
191 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
192 
193 	eiop->eio_fini(enp);
194 
195 	enp->en_mod_flags &= ~EFX_MOD_INTR;
196 }
197 
198 			void
199 efx_intr_enable(
200 	__in		efx_nic_t *enp)
201 {
202 	efx_intr_t *eip = &(enp->en_intr);
203 	efx_intr_ops_t *eiop = eip->ei_eiop;
204 
205 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
206 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
207 
208 	eiop->eio_enable(enp);
209 }
210 
211 			void
212 efx_intr_disable(
213 	__in		efx_nic_t *enp)
214 {
215 	efx_intr_t *eip = &(enp->en_intr);
216 	efx_intr_ops_t *eiop = eip->ei_eiop;
217 
218 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
219 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
220 
221 	eiop->eio_disable(enp);
222 }
223 
224 			void
225 efx_intr_disable_unlocked(
226 	__in		efx_nic_t *enp)
227 {
228 	efx_intr_t *eip = &(enp->en_intr);
229 	efx_intr_ops_t *eiop = eip->ei_eiop;
230 
231 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
232 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
233 
234 	eiop->eio_disable_unlocked(enp);
235 }
236 
237 
238 	__checkReturn	int
239 efx_intr_trigger(
240 	__in		efx_nic_t *enp,
241 	__in		unsigned int level)
242 {
243 	efx_intr_t *eip = &(enp->en_intr);
244 	efx_intr_ops_t *eiop = eip->ei_eiop;
245 
246 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
247 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
248 
249 	return (eiop->eio_trigger(enp, level));
250 }
251 
252 			void
253 efx_intr_status_line(
254 	__in		efx_nic_t *enp,
255 	__out		boolean_t *fatalp,
256 	__out		uint32_t *qmaskp)
257 {
258 	efx_intr_t *eip = &(enp->en_intr);
259 	efx_dword_t dword;
260 
261 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
262 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
263 
264 	/* Ensure Huntington and Falcon/Siena ISR at same location */
265 	EFX_STATIC_ASSERT(FR_BZ_INT_ISR0_REG_OFST ==
266 	    ER_DZ_BIU_INT_ISR_REG_OFST);
267 
268 	/*
269 	 * Read the queue mask and implicitly acknowledge the
270 	 * interrupt.
271 	 */
272 	EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE);
273 	*qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
274 
275 	EFSYS_PROBE1(qmask, uint32_t, *qmaskp);
276 
277 #if EFSYS_OPT_HUNTINGTON
278 	if (enp->en_family == EFX_FAMILY_HUNTINGTON) {
279 		/* Huntington reports fatal errors via events */
280 		*fatalp = B_FALSE;
281 		return;
282 	}
283 #endif
284 	if (*qmaskp & (1U << eip->ei_level))
285 		*fatalp = falconsiena_intr_check_fatal(enp);
286 	else
287 		*fatalp = B_FALSE;
288 }
289 
290 			void
291 efx_intr_status_message(
292 	__in		efx_nic_t *enp,
293 	__in		unsigned int message,
294 	__out		boolean_t *fatalp)
295 {
296 	efx_intr_t *eip = &(enp->en_intr);
297 
298 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
299 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
300 
301 #if EFSYS_OPT_HUNTINGTON
302 	if (enp->en_family == EFX_FAMILY_HUNTINGTON) {
303 		/* Huntington reports fatal errors via events */
304 		*fatalp = B_FALSE;
305 		return;
306 	}
307 #endif
308 	if (message == eip->ei_level)
309 		*fatalp = falconsiena_intr_check_fatal(enp);
310 	else
311 		*fatalp = B_FALSE;
312 }
313 
314 		void
315 efx_intr_fatal(
316 	__in	efx_nic_t *enp)
317 {
318 	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
319 	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
320 
321 #if EFSYS_OPT_HUNTINGTON
322 	if (enp->en_family == EFX_FAMILY_HUNTINGTON) {
323 		/* Huntington reports fatal errors via events */
324 		return;
325 	}
326 #endif
327 #if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
328 	falconsiena_intr_fatal(enp);
329 #endif
330 }
331 
332 
333 /* ************************************************************************* */
334 /* ************************************************************************* */
335 /* ************************************************************************* */
336 
337 #if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
338 
339 static	__checkReturn	int
340 falconsiena_intr_init(
341 	__in		efx_nic_t *enp,
342 	__in		efx_intr_type_t type,
343 	__in		efsys_mem_t *esmp)
344 {
345 	efx_intr_t *eip = &(enp->en_intr);
346 	efx_oword_t oword;
347 
348 	/*
349 	 * bug17213 workaround.
350 	 *
351 	 * Under legacy interrupts, don't share a level between fatal
352 	 * interrupts and event queue interrupts. Under MSI-X, they
353 	 * must share, or we won't get an interrupt.
354 	 */
355 	if (enp->en_family == EFX_FAMILY_SIENA &&
356 	    eip->ei_type == EFX_INTR_LINE)
357 		eip->ei_level = 0x1f;
358 	else
359 		eip->ei_level = 0;
360 
361 	/* Enable all the genuinely fatal interrupts */
362 	EFX_SET_OWORD(oword);
363 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_ILL_ADR_INT_KER_EN, 0);
364 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_RBUF_OWN_INT_KER_EN, 0);
365 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_TBUF_OWN_INT_KER_EN, 0);
366 	if (enp->en_family >= EFX_FAMILY_SIENA)
367 		EFX_SET_OWORD_FIELD(oword, FRF_CZ_SRAM_PERR_INT_P_KER_EN, 0);
368 	EFX_BAR_WRITEO(enp, FR_AZ_FATAL_INTR_REG_KER, &oword);
369 
370 	/* Set up the interrupt address register */
371 	EFX_POPULATE_OWORD_3(oword,
372 	    FRF_AZ_NORM_INT_VEC_DIS_KER, (type == EFX_INTR_MESSAGE) ? 1 : 0,
373 	    FRF_AZ_INT_ADR_KER_DW0, EFSYS_MEM_ADDR(esmp) & 0xffffffff,
374 	    FRF_AZ_INT_ADR_KER_DW1, EFSYS_MEM_ADDR(esmp) >> 32);
375 	EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
376 
377 	return (0);
378 }
379 
380 static			void
381 falconsiena_intr_enable(
382 	__in		efx_nic_t *enp)
383 {
384 	efx_intr_t *eip = &(enp->en_intr);
385 	efx_oword_t oword;
386 
387 	EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
388 
389 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
390 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 1);
391 	EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
392 }
393 
394 static			void
395 falconsiena_intr_disable(
396 	__in		efx_nic_t *enp)
397 {
398 	efx_oword_t oword;
399 
400 	EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
401 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
402 	EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
403 
404 	EFSYS_SPIN(10);
405 }
406 
407 static			void
408 falconsiena_intr_disable_unlocked(
409 	__in		efx_nic_t *enp)
410 {
411 	efx_oword_t oword;
412 
413 	EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
414 			&oword, B_FALSE);
415 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
416 	EFSYS_BAR_WRITEO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
417 	    &oword, B_FALSE);
418 }
419 
420 static	__checkReturn	int
421 falconsiena_intr_trigger(
422 	__in		efx_nic_t *enp,
423 	__in		unsigned int level)
424 {
425 	efx_intr_t *eip = &(enp->en_intr);
426 	efx_oword_t oword;
427 	unsigned int count;
428 	uint32_t sel;
429 	int rc;
430 
431 	/* bug16757: No event queues can be initialized */
432 	EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
433 
434 	switch (enp->en_family) {
435 	case EFX_FAMILY_FALCON:
436 		if (level >= EFX_NINTR_FALCON) {
437 			rc = EINVAL;
438 			goto fail1;
439 		}
440 		break;
441 
442 	case EFX_FAMILY_SIENA:
443 		if (level >= EFX_NINTR_SIENA) {
444 			rc = EINVAL;
445 			goto fail1;
446 		}
447 		break;
448 
449 	default:
450 		EFSYS_ASSERT(B_FALSE);
451 		break;
452 	}
453 
454 	if (level > EFX_MASK32(FRF_AZ_KER_INT_LEVE_SEL))
455 		return (ENOTSUP); /* avoid EFSYS_PROBE() */
456 
457 	sel = level;
458 
459 	/* Trigger a test interrupt */
460 	EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
461 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, sel);
462 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER, 1);
463 	EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
464 
465 	/*
466 	 * Wait up to 100ms for the interrupt to be raised before restoring
467 	 * KER_INT_LEVE_SEL. Ignore a failure to raise (the caller will
468 	 * observe this soon enough anyway), but always reset KER_INT_LEVE_SEL
469 	 */
470 	count = 0;
471 	do {
472 		EFSYS_SPIN(100);	/* 100us */
473 
474 		EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
475 	} while (EFX_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER) && ++count < 1000);
476 
477 	EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
478 	EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
479 
480 	return (0);
481 
482 fail1:
483 	EFSYS_PROBE1(fail1, int, rc);
484 
485 	return (rc);
486 }
487 
488 static	__checkReturn	boolean_t
489 falconsiena_intr_check_fatal(
490 	__in		efx_nic_t *enp)
491 {
492 	efx_intr_t *eip = &(enp->en_intr);
493 	efsys_mem_t *esmp = eip->ei_esmp;
494 	efx_oword_t oword;
495 
496 	/* Read the syndrome */
497 	EFSYS_MEM_READO(esmp, 0, &oword);
498 
499 	if (EFX_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT) != 0) {
500 		EFSYS_PROBE(fatal);
501 
502 		/* Clear the fatal interrupt condition */
503 		EFX_SET_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT, 0);
504 		EFSYS_MEM_WRITEO(esmp, 0, &oword);
505 
506 		return (B_TRUE);
507 	}
508 
509 	return (B_FALSE);
510 }
511 
512 static		void
513 falconsiena_intr_fatal(
514 	__in	efx_nic_t *enp)
515 {
516 #if EFSYS_OPT_DECODE_INTR_FATAL
517 	efx_oword_t fatal;
518 	efx_oword_t mem_per;
519 
520 	EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal);
521 	EFX_ZERO_OWORD(mem_per);
522 
523 	if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0 ||
524 	    EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
525 		EFX_BAR_READO(enp, FR_AZ_MEM_STAT_REG, &mem_per);
526 
527 	if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRAM_OOB_INT_KER) != 0)
528 		EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_OOB, 0, 0);
529 
530 	if (EFX_OWORD_FIELD(fatal, FRF_AZ_BUFID_DC_OOB_INT_KER) != 0)
531 		EFSYS_ERR(enp->en_esip, EFX_ERR_BUFID_DC_OOB, 0, 0);
532 
533 	if (EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
534 		EFSYS_ERR(enp->en_esip, EFX_ERR_MEM_PERR,
535 		    EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
536 		    EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
537 
538 	if (EFX_OWORD_FIELD(fatal, FRF_AZ_RBUF_OWN_INT_KER) != 0)
539 		EFSYS_ERR(enp->en_esip, EFX_ERR_RBUF_OWN, 0, 0);
540 
541 	if (EFX_OWORD_FIELD(fatal, FRF_AZ_TBUF_OWN_INT_KER) != 0)
542 		EFSYS_ERR(enp->en_esip, EFX_ERR_TBUF_OWN, 0, 0);
543 
544 	if (EFX_OWORD_FIELD(fatal, FRF_AZ_RDESCQ_OWN_INT_KER) != 0)
545 		EFSYS_ERR(enp->en_esip, EFX_ERR_RDESQ_OWN, 0, 0);
546 
547 	if (EFX_OWORD_FIELD(fatal, FRF_AZ_TDESCQ_OWN_INT_KER) != 0)
548 		EFSYS_ERR(enp->en_esip, EFX_ERR_TDESQ_OWN, 0, 0);
549 
550 	if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVQ_OWN_INT_KER) != 0)
551 		EFSYS_ERR(enp->en_esip, EFX_ERR_EVQ_OWN, 0, 0);
552 
553 	if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVF_OFLO_INT_KER) != 0)
554 		EFSYS_ERR(enp->en_esip, EFX_ERR_EVFF_OFLO, 0, 0);
555 
556 	if (EFX_OWORD_FIELD(fatal, FRF_AZ_ILL_ADR_INT_KER) != 0)
557 		EFSYS_ERR(enp->en_esip, EFX_ERR_ILL_ADDR, 0, 0);
558 
559 	if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0)
560 		EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_PERR,
561 		    EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
562 		    EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
563 #else
564 	EFSYS_ASSERT(0);
565 #endif
566 }
567 
568 static		void
569 falconsiena_intr_fini(
570 	__in	efx_nic_t *enp)
571 {
572 	efx_oword_t oword;
573 
574 	/* Clear the interrupt address register */
575 	EFX_ZERO_OWORD(oword);
576 	EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
577 }
578 
579 #endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
580