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