]> CyberLeo.Net >> Repos - FreeBSD/releng/10.3.git/blob - sys/dev/sfxge/common/efx_intr.c
- Copy stable/10@296371 to releng/10.3 in preparation for 10.3-RC1
[FreeBSD/releng/10.3.git] / sys / dev / sfxge / common / efx_intr.c
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 "efx.h"
35 #include "efx_impl.h"
36
37
38 #if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
39
40 static  __checkReturn   efx_rc_t
41 falconsiena_intr_init(
42         __in            efx_nic_t *enp,
43         __in            efx_intr_type_t type,
44         __in            efsys_mem_t *esmp);
45
46 static                  void
47 falconsiena_intr_enable(
48         __in            efx_nic_t *enp);
49
50 static                  void
51 falconsiena_intr_disable(
52         __in            efx_nic_t *enp);
53
54 static                  void
55 falconsiena_intr_disable_unlocked(
56         __in            efx_nic_t *enp);
57
58 static  __checkReturn   efx_rc_t
59 falconsiena_intr_trigger(
60         __in            efx_nic_t *enp,
61         __in            unsigned int level);
62
63 static                  void
64 falconsiena_intr_fini(
65         __in            efx_nic_t *enp);
66
67 static                  void
68 falconsiena_intr_status_line(
69         __in            efx_nic_t *enp,
70         __out           boolean_t *fatalp,
71         __out           uint32_t *qmaskp);
72
73 static                  void
74 falconsiena_intr_status_message(
75         __in            efx_nic_t *enp,
76         __in            unsigned int message,
77         __out           boolean_t *fatalp);
78
79 static                  void
80 falconsiena_intr_fatal(
81         __in            efx_nic_t *enp);
82
83 static  __checkReturn   boolean_t
84 falconsiena_intr_check_fatal(
85         __in            efx_nic_t *enp);
86
87
88 #endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
89
90
91 #if EFSYS_OPT_FALCON
92 static efx_intr_ops_t   __efx_intr_falcon_ops = {
93         falconsiena_intr_init,                  /* eio_init */
94         falconsiena_intr_enable,                /* eio_enable */
95         falconsiena_intr_disable,               /* eio_disable */
96         falconsiena_intr_disable_unlocked,      /* eio_disable_unlocked */
97         falconsiena_intr_trigger,               /* eio_trigger */
98         falconsiena_intr_status_line,           /* eio_status_line */
99         falconsiena_intr_status_message,        /* eio_status_message */
100         falconsiena_intr_fatal,                 /* eio_fatal */
101         falconsiena_intr_fini,                  /* eio_fini */
102 };
103 #endif  /* EFSYS_OPT_FALCON */
104
105 #if EFSYS_OPT_SIENA
106 static efx_intr_ops_t   __efx_intr_siena_ops = {
107         falconsiena_intr_init,                  /* eio_init */
108         falconsiena_intr_enable,                /* eio_enable */
109         falconsiena_intr_disable,               /* eio_disable */
110         falconsiena_intr_disable_unlocked,      /* eio_disable_unlocked */
111         falconsiena_intr_trigger,               /* eio_trigger */
112         falconsiena_intr_status_line,           /* eio_status_line */
113         falconsiena_intr_status_message,        /* eio_status_message */
114         falconsiena_intr_fatal,                 /* eio_fatal */
115         falconsiena_intr_fini,                  /* eio_fini */
116 };
117 #endif  /* EFSYS_OPT_SIENA */
118
119 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
120 static efx_intr_ops_t   __efx_intr_ef10_ops = {
121         ef10_intr_init,                 /* eio_init */
122         ef10_intr_enable,               /* eio_enable */
123         ef10_intr_disable,              /* eio_disable */
124         ef10_intr_disable_unlocked,     /* eio_disable_unlocked */
125         ef10_intr_trigger,              /* eio_trigger */
126         ef10_intr_status_line,          /* eio_status_line */
127         ef10_intr_status_message,       /* eio_status_message */
128         ef10_intr_fatal,                /* eio_fatal */
129         ef10_intr_fini,                 /* eio_fini */
130 };
131 #endif  /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
132
133         __checkReturn   efx_rc_t
134 efx_intr_init(
135         __in            efx_nic_t *enp,
136         __in            efx_intr_type_t type,
137         __in            efsys_mem_t *esmp)
138 {
139         efx_intr_t *eip = &(enp->en_intr);
140         efx_intr_ops_t *eiop;
141         efx_rc_t rc;
142
143         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
144         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
145
146         if (enp->en_mod_flags & EFX_MOD_INTR) {
147                 rc = EINVAL;
148                 goto fail1;
149         }
150
151         eip->ei_esmp = esmp;
152         eip->ei_type = type;
153         eip->ei_level = 0;
154
155         enp->en_mod_flags |= EFX_MOD_INTR;
156
157         switch (enp->en_family) {
158 #if EFSYS_OPT_FALCON
159         case EFX_FAMILY_FALCON:
160                 eiop = (efx_intr_ops_t *)&__efx_intr_falcon_ops;
161                 break;
162 #endif  /* EFSYS_OPT_FALCON */
163
164 #if EFSYS_OPT_SIENA
165         case EFX_FAMILY_SIENA:
166                 eiop = (efx_intr_ops_t *)&__efx_intr_siena_ops;
167                 break;
168 #endif  /* EFSYS_OPT_SIENA */
169
170 #if EFSYS_OPT_HUNTINGTON
171         case EFX_FAMILY_HUNTINGTON:
172                 eiop = (efx_intr_ops_t *)&__efx_intr_ef10_ops;
173                 break;
174 #endif  /* EFSYS_OPT_HUNTINGTON */
175
176 #if EFSYS_OPT_MEDFORD
177         case EFX_FAMILY_MEDFORD:
178                 eiop = (efx_intr_ops_t *)&__efx_intr_ef10_ops;
179                 break;
180 #endif  /* EFSYS_OPT_MEDFORD */
181
182         default:
183                 EFSYS_ASSERT(B_FALSE);
184                 rc = ENOTSUP;
185                 goto fail2;
186         }
187
188         if ((rc = eiop->eio_init(enp, type, esmp)) != 0)
189                 goto fail3;
190
191         eip->ei_eiop = eiop;
192
193         return (0);
194
195 fail3:
196         EFSYS_PROBE(fail3);
197 fail2:
198         EFSYS_PROBE(fail2);
199 fail1:
200         EFSYS_PROBE1(fail1, efx_rc_t, rc);
201
202         return (rc);
203 }
204
205                 void
206 efx_intr_fini(
207         __in    efx_nic_t *enp)
208 {
209         efx_intr_t *eip = &(enp->en_intr);
210         efx_intr_ops_t *eiop = eip->ei_eiop;
211
212         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
213         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
214         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
215
216         eiop->eio_fini(enp);
217
218         enp->en_mod_flags &= ~EFX_MOD_INTR;
219 }
220
221                         void
222 efx_intr_enable(
223         __in            efx_nic_t *enp)
224 {
225         efx_intr_t *eip = &(enp->en_intr);
226         efx_intr_ops_t *eiop = eip->ei_eiop;
227
228         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
229         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
230
231         eiop->eio_enable(enp);
232 }
233
234                         void
235 efx_intr_disable(
236         __in            efx_nic_t *enp)
237 {
238         efx_intr_t *eip = &(enp->en_intr);
239         efx_intr_ops_t *eiop = eip->ei_eiop;
240
241         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
242         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
243
244         eiop->eio_disable(enp);
245 }
246
247                         void
248 efx_intr_disable_unlocked(
249         __in            efx_nic_t *enp)
250 {
251         efx_intr_t *eip = &(enp->en_intr);
252         efx_intr_ops_t *eiop = eip->ei_eiop;
253
254         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
255         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
256
257         eiop->eio_disable_unlocked(enp);
258 }
259
260
261         __checkReturn   efx_rc_t
262 efx_intr_trigger(
263         __in            efx_nic_t *enp,
264         __in            unsigned int level)
265 {
266         efx_intr_t *eip = &(enp->en_intr);
267         efx_intr_ops_t *eiop = eip->ei_eiop;
268
269         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
270         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
271
272         return (eiop->eio_trigger(enp, level));
273 }
274
275                         void
276 efx_intr_status_line(
277         __in            efx_nic_t *enp,
278         __out           boolean_t *fatalp,
279         __out           uint32_t *qmaskp)
280 {
281         efx_intr_t *eip = &(enp->en_intr);
282         efx_intr_ops_t *eiop = eip->ei_eiop;
283
284         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
285         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
286
287         eiop->eio_status_line(enp, fatalp, qmaskp);
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         efx_intr_ops_t *eiop = eip->ei_eiop;
298
299         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
300         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
301
302         eiop->eio_status_message(enp, message, fatalp);
303 }
304
305                 void
306 efx_intr_fatal(
307         __in    efx_nic_t *enp)
308 {
309         efx_intr_t *eip = &(enp->en_intr);
310         efx_intr_ops_t *eiop = eip->ei_eiop;
311
312         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
313         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
314
315         eiop->eio_fatal(enp);
316 }
317
318
319 /* ************************************************************************* */
320 /* ************************************************************************* */
321 /* ************************************************************************* */
322
323 #if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
324
325 static  __checkReturn   efx_rc_t
326 falconsiena_intr_init(
327         __in            efx_nic_t *enp,
328         __in            efx_intr_type_t type,
329         __in            efsys_mem_t *esmp)
330 {
331         efx_intr_t *eip = &(enp->en_intr);
332         efx_oword_t oword;
333
334         /*
335          * bug17213 workaround.
336          *
337          * Under legacy interrupts, don't share a level between fatal
338          * interrupts and event queue interrupts. Under MSI-X, they
339          * must share, or we won't get an interrupt.
340          */
341         if (enp->en_family == EFX_FAMILY_SIENA &&
342             eip->ei_type == EFX_INTR_LINE)
343                 eip->ei_level = 0x1f;
344         else
345                 eip->ei_level = 0;
346
347         /* Enable all the genuinely fatal interrupts */
348         EFX_SET_OWORD(oword);
349         EFX_SET_OWORD_FIELD(oword, FRF_AZ_ILL_ADR_INT_KER_EN, 0);
350         EFX_SET_OWORD_FIELD(oword, FRF_AZ_RBUF_OWN_INT_KER_EN, 0);
351         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TBUF_OWN_INT_KER_EN, 0);
352         if (enp->en_family >= EFX_FAMILY_SIENA)
353                 EFX_SET_OWORD_FIELD(oword, FRF_CZ_SRAM_PERR_INT_P_KER_EN, 0);
354         EFX_BAR_WRITEO(enp, FR_AZ_FATAL_INTR_REG_KER, &oword);
355
356         /* Set up the interrupt address register */
357         EFX_POPULATE_OWORD_3(oword,
358             FRF_AZ_NORM_INT_VEC_DIS_KER, (type == EFX_INTR_MESSAGE) ? 1 : 0,
359             FRF_AZ_INT_ADR_KER_DW0, EFSYS_MEM_ADDR(esmp) & 0xffffffff,
360             FRF_AZ_INT_ADR_KER_DW1, EFSYS_MEM_ADDR(esmp) >> 32);
361         EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
362
363         return (0);
364 }
365
366 static                  void
367 falconsiena_intr_enable(
368         __in            efx_nic_t *enp)
369 {
370         efx_intr_t *eip = &(enp->en_intr);
371         efx_oword_t oword;
372
373         EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
374
375         EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
376         EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 1);
377         EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
378 }
379
380 static                  void
381 falconsiena_intr_disable(
382         __in            efx_nic_t *enp)
383 {
384         efx_oword_t oword;
385
386         EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
387         EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
388         EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
389
390         EFSYS_SPIN(10);
391 }
392
393 static                  void
394 falconsiena_intr_disable_unlocked(
395         __in            efx_nic_t *enp)
396 {
397         efx_oword_t oword;
398
399         EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
400                         &oword, B_FALSE);
401         EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
402         EFSYS_BAR_WRITEO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
403             &oword, B_FALSE);
404 }
405
406 static  __checkReturn   efx_rc_t
407 falconsiena_intr_trigger(
408         __in            efx_nic_t *enp,
409         __in            unsigned int level)
410 {
411         efx_intr_t *eip = &(enp->en_intr);
412         efx_oword_t oword;
413         unsigned int count;
414         uint32_t sel;
415         efx_rc_t rc;
416
417         /* bug16757: No event queues can be initialized */
418         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
419
420         switch (enp->en_family) {
421         case EFX_FAMILY_FALCON:
422                 if (level >= EFX_NINTR_FALCON) {
423                         rc = EINVAL;
424                         goto fail1;
425                 }
426                 break;
427
428         case EFX_FAMILY_SIENA:
429                 if (level >= EFX_NINTR_SIENA) {
430                         rc = EINVAL;
431                         goto fail1;
432                 }
433                 break;
434
435         default:
436                 EFSYS_ASSERT(B_FALSE);
437                 break;
438         }
439
440         if (level > EFX_MASK32(FRF_AZ_KER_INT_LEVE_SEL))
441                 return (ENOTSUP); /* avoid EFSYS_PROBE() */
442
443         sel = level;
444
445         /* Trigger a test interrupt */
446         EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
447         EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, sel);
448         EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER, 1);
449         EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
450
451         /*
452          * Wait up to 100ms for the interrupt to be raised before restoring
453          * KER_INT_LEVE_SEL. Ignore a failure to raise (the caller will
454          * observe this soon enough anyway), but always reset KER_INT_LEVE_SEL
455          */
456         count = 0;
457         do {
458                 EFSYS_SPIN(100);        /* 100us */
459
460                 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
461         } while (EFX_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER) && ++count < 1000);
462
463         EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
464         EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
465
466         return (0);
467
468 fail1:
469         EFSYS_PROBE1(fail1, efx_rc_t, rc);
470
471         return (rc);
472 }
473
474 static  __checkReturn   boolean_t
475 falconsiena_intr_check_fatal(
476         __in            efx_nic_t *enp)
477 {
478         efx_intr_t *eip = &(enp->en_intr);
479         efsys_mem_t *esmp = eip->ei_esmp;
480         efx_oword_t oword;
481
482         /* Read the syndrome */
483         EFSYS_MEM_READO(esmp, 0, &oword);
484
485         if (EFX_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT) != 0) {
486                 EFSYS_PROBE(fatal);
487
488                 /* Clear the fatal interrupt condition */
489                 EFX_SET_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT, 0);
490                 EFSYS_MEM_WRITEO(esmp, 0, &oword);
491
492                 return (B_TRUE);
493         }
494
495         return (B_FALSE);
496 }
497
498 static                  void
499 falconsiena_intr_status_line(
500         __in            efx_nic_t *enp,
501         __out           boolean_t *fatalp,
502         __out           uint32_t *qmaskp)
503 {
504         efx_intr_t *eip = &(enp->en_intr);
505         efx_dword_t dword;
506
507         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
508         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
509
510         /*
511          * Read the queue mask and implicitly acknowledge the
512          * interrupt.
513          */
514         EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE);
515         *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
516
517         EFSYS_PROBE1(qmask, uint32_t, *qmaskp);
518
519         if (*qmaskp & (1U << eip->ei_level))
520                 *fatalp = falconsiena_intr_check_fatal(enp);
521         else
522                 *fatalp = B_FALSE;
523 }
524
525 static                  void
526 falconsiena_intr_status_message(
527         __in            efx_nic_t *enp,
528         __in            unsigned int message,
529         __out           boolean_t *fatalp)
530 {
531         efx_intr_t *eip = &(enp->en_intr);
532
533         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
534         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
535
536         if (message == eip->ei_level)
537                 *fatalp = falconsiena_intr_check_fatal(enp);
538         else
539                 *fatalp = B_FALSE;
540 }
541
542
543 static          void
544 falconsiena_intr_fatal(
545         __in    efx_nic_t *enp)
546 {
547 #if EFSYS_OPT_DECODE_INTR_FATAL
548         efx_oword_t fatal;
549         efx_oword_t mem_per;
550
551         EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal);
552         EFX_ZERO_OWORD(mem_per);
553
554         if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0 ||
555             EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
556                 EFX_BAR_READO(enp, FR_AZ_MEM_STAT_REG, &mem_per);
557
558         if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRAM_OOB_INT_KER) != 0)
559                 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_OOB, 0, 0);
560
561         if (EFX_OWORD_FIELD(fatal, FRF_AZ_BUFID_DC_OOB_INT_KER) != 0)
562                 EFSYS_ERR(enp->en_esip, EFX_ERR_BUFID_DC_OOB, 0, 0);
563
564         if (EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
565                 EFSYS_ERR(enp->en_esip, EFX_ERR_MEM_PERR,
566                     EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
567                     EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
568
569         if (EFX_OWORD_FIELD(fatal, FRF_AZ_RBUF_OWN_INT_KER) != 0)
570                 EFSYS_ERR(enp->en_esip, EFX_ERR_RBUF_OWN, 0, 0);
571
572         if (EFX_OWORD_FIELD(fatal, FRF_AZ_TBUF_OWN_INT_KER) != 0)
573                 EFSYS_ERR(enp->en_esip, EFX_ERR_TBUF_OWN, 0, 0);
574
575         if (EFX_OWORD_FIELD(fatal, FRF_AZ_RDESCQ_OWN_INT_KER) != 0)
576                 EFSYS_ERR(enp->en_esip, EFX_ERR_RDESQ_OWN, 0, 0);
577
578         if (EFX_OWORD_FIELD(fatal, FRF_AZ_TDESCQ_OWN_INT_KER) != 0)
579                 EFSYS_ERR(enp->en_esip, EFX_ERR_TDESQ_OWN, 0, 0);
580
581         if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVQ_OWN_INT_KER) != 0)
582                 EFSYS_ERR(enp->en_esip, EFX_ERR_EVQ_OWN, 0, 0);
583
584         if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVF_OFLO_INT_KER) != 0)
585                 EFSYS_ERR(enp->en_esip, EFX_ERR_EVFF_OFLO, 0, 0);
586
587         if (EFX_OWORD_FIELD(fatal, FRF_AZ_ILL_ADR_INT_KER) != 0)
588                 EFSYS_ERR(enp->en_esip, EFX_ERR_ILL_ADDR, 0, 0);
589
590         if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0)
591                 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_PERR,
592                     EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
593                     EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
594 #else
595         EFSYS_ASSERT(0);
596 #endif
597 }
598
599 static          void
600 falconsiena_intr_fini(
601         __in    efx_nic_t *enp)
602 {
603         efx_oword_t oword;
604
605         /* Clear the interrupt address register */
606         EFX_ZERO_OWORD(oword);
607         EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
608 }
609
610 #endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */