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 efx_rc_t
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 efx_rc_t
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 efx_rc_t
efx_intr_init(__in efx_nic_t * enp,__in efx_intr_type_t type,__in efsys_mem_t * esmp)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 efx_rc_t 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, efx_rc_t, rc);
178
179 return (rc);
180 }
181
182 void
efx_intr_fini(__in efx_nic_t * enp)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
efx_intr_enable(__in efx_nic_t * enp)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
efx_intr_disable(__in efx_nic_t * enp)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
efx_intr_disable_unlocked(__in efx_nic_t * enp)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 efx_rc_t
efx_intr_trigger(__in efx_nic_t * enp,__in unsigned int level)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
efx_intr_status_line(__in efx_nic_t * enp,__out boolean_t * fatalp,__out uint32_t * qmaskp)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
efx_intr_status_message(__in efx_nic_t * enp,__in unsigned int message,__out boolean_t * fatalp)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
efx_intr_fatal(__in efx_nic_t * enp)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 efx_rc_t
falconsiena_intr_init(__in efx_nic_t * enp,__in efx_intr_type_t type,__in efsys_mem_t * esmp)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
falconsiena_intr_enable(__in efx_nic_t * enp)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
falconsiena_intr_disable(__in efx_nic_t * enp)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
falconsiena_intr_disable_unlocked(__in efx_nic_t * enp)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 efx_rc_t
falconsiena_intr_trigger(__in efx_nic_t * enp,__in unsigned int level)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 efx_rc_t 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, efx_rc_t, rc);
484
485 return (rc);
486 }
487
488 static __checkReturn boolean_t
falconsiena_intr_check_fatal(__in efx_nic_t * enp)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
falconsiena_intr_fatal(__in efx_nic_t * enp)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
falconsiena_intr_fini(__in efx_nic_t * enp)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