2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2007-2016 Solarflare Communications Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * The views and conclusions contained in the software and documentation are
29 * those of the authors and should not be interpreted as representing official
30 * policies, either expressed or implied, of the FreeBSD Project.
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
42 static __checkReturn efx_rc_t
45 __in efx_intr_type_t type,
46 __in efsys_mem_t *esmp);
57 siena_intr_disable_unlocked(
60 static __checkReturn efx_rc_t
63 __in unsigned int level);
70 siena_intr_status_line(
72 __out boolean_t *fatalp,
73 __out uint32_t *qmaskp);
76 siena_intr_status_message(
78 __in unsigned int message,
79 __out boolean_t *fatalp);
85 static __checkReturn boolean_t
86 siena_intr_check_fatal(
90 #endif /* EFSYS_OPT_SIENA */
94 static const efx_intr_ops_t __efx_intr_siena_ops = {
95 siena_intr_init, /* eio_init */
96 siena_intr_enable, /* eio_enable */
97 siena_intr_disable, /* eio_disable */
98 siena_intr_disable_unlocked, /* eio_disable_unlocked */
99 siena_intr_trigger, /* eio_trigger */
100 siena_intr_status_line, /* eio_status_line */
101 siena_intr_status_message, /* eio_status_message */
102 siena_intr_fatal, /* eio_fatal */
103 siena_intr_fini, /* eio_fini */
105 #endif /* EFSYS_OPT_SIENA */
107 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
108 static const efx_intr_ops_t __efx_intr_ef10_ops = {
109 ef10_intr_init, /* eio_init */
110 ef10_intr_enable, /* eio_enable */
111 ef10_intr_disable, /* eio_disable */
112 ef10_intr_disable_unlocked, /* eio_disable_unlocked */
113 ef10_intr_trigger, /* eio_trigger */
114 ef10_intr_status_line, /* eio_status_line */
115 ef10_intr_status_message, /* eio_status_message */
116 ef10_intr_fatal, /* eio_fatal */
117 ef10_intr_fini, /* eio_fini */
119 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
121 __checkReturn efx_rc_t
124 __in efx_intr_type_t type,
125 __in efsys_mem_t *esmp)
127 efx_intr_t *eip = &(enp->en_intr);
128 const efx_intr_ops_t *eiop;
131 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
132 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
134 if (enp->en_mod_flags & EFX_MOD_INTR) {
143 enp->en_mod_flags |= EFX_MOD_INTR;
145 switch (enp->en_family) {
147 case EFX_FAMILY_SIENA:
148 eiop = &__efx_intr_siena_ops;
150 #endif /* EFSYS_OPT_SIENA */
152 #if EFSYS_OPT_HUNTINGTON
153 case EFX_FAMILY_HUNTINGTON:
154 eiop = &__efx_intr_ef10_ops;
156 #endif /* EFSYS_OPT_HUNTINGTON */
158 #if EFSYS_OPT_MEDFORD
159 case EFX_FAMILY_MEDFORD:
160 eiop = &__efx_intr_ef10_ops;
162 #endif /* EFSYS_OPT_MEDFORD */
165 EFSYS_ASSERT(B_FALSE);
170 if ((rc = eiop->eio_init(enp, type, esmp)) != 0)
182 EFSYS_PROBE1(fail1, efx_rc_t, rc);
191 efx_intr_t *eip = &(enp->en_intr);
192 const efx_intr_ops_t *eiop = eip->ei_eiop;
194 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
195 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
196 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
200 enp->en_mod_flags &= ~EFX_MOD_INTR;
207 efx_intr_t *eip = &(enp->en_intr);
208 const efx_intr_ops_t *eiop = eip->ei_eiop;
210 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
211 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
213 eiop->eio_enable(enp);
220 efx_intr_t *eip = &(enp->en_intr);
221 const efx_intr_ops_t *eiop = eip->ei_eiop;
223 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
224 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
226 eiop->eio_disable(enp);
230 efx_intr_disable_unlocked(
233 efx_intr_t *eip = &(enp->en_intr);
234 const efx_intr_ops_t *eiop = eip->ei_eiop;
236 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
237 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
239 eiop->eio_disable_unlocked(enp);
243 __checkReturn efx_rc_t
246 __in unsigned int level)
248 efx_intr_t *eip = &(enp->en_intr);
249 const efx_intr_ops_t *eiop = eip->ei_eiop;
251 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
252 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
254 return (eiop->eio_trigger(enp, level));
258 efx_intr_status_line(
260 __out boolean_t *fatalp,
261 __out uint32_t *qmaskp)
263 efx_intr_t *eip = &(enp->en_intr);
264 const efx_intr_ops_t *eiop = eip->ei_eiop;
266 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
267 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
269 eiop->eio_status_line(enp, fatalp, qmaskp);
273 efx_intr_status_message(
275 __in unsigned int message,
276 __out boolean_t *fatalp)
278 efx_intr_t *eip = &(enp->en_intr);
279 const efx_intr_ops_t *eiop = eip->ei_eiop;
281 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
282 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
284 eiop->eio_status_message(enp, message, fatalp);
291 efx_intr_t *eip = &(enp->en_intr);
292 const efx_intr_ops_t *eiop = eip->ei_eiop;
294 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
295 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
297 eiop->eio_fatal(enp);
301 /* ************************************************************************* */
302 /* ************************************************************************* */
303 /* ************************************************************************* */
307 static __checkReturn efx_rc_t
310 __in efx_intr_type_t type,
311 __in efsys_mem_t *esmp)
313 efx_intr_t *eip = &(enp->en_intr);
317 * bug17213 workaround.
319 * Under legacy interrupts, don't share a level between fatal
320 * interrupts and event queue interrupts. Under MSI-X, they
321 * must share, or we won't get an interrupt.
323 if (enp->en_family == EFX_FAMILY_SIENA &&
324 eip->ei_type == EFX_INTR_LINE)
325 eip->ei_level = 0x1f;
329 /* Enable all the genuinely fatal interrupts */
330 EFX_SET_OWORD(oword);
331 EFX_SET_OWORD_FIELD(oword, FRF_AZ_ILL_ADR_INT_KER_EN, 0);
332 EFX_SET_OWORD_FIELD(oword, FRF_AZ_RBUF_OWN_INT_KER_EN, 0);
333 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TBUF_OWN_INT_KER_EN, 0);
334 if (enp->en_family >= EFX_FAMILY_SIENA)
335 EFX_SET_OWORD_FIELD(oword, FRF_CZ_SRAM_PERR_INT_P_KER_EN, 0);
336 EFX_BAR_WRITEO(enp, FR_AZ_FATAL_INTR_REG_KER, &oword);
338 /* Set up the interrupt address register */
339 EFX_POPULATE_OWORD_3(oword,
340 FRF_AZ_NORM_INT_VEC_DIS_KER, (type == EFX_INTR_MESSAGE) ? 1 : 0,
341 FRF_AZ_INT_ADR_KER_DW0, EFSYS_MEM_ADDR(esmp) & 0xffffffff,
342 FRF_AZ_INT_ADR_KER_DW1, EFSYS_MEM_ADDR(esmp) >> 32);
343 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
352 efx_intr_t *eip = &(enp->en_intr);
355 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
357 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
358 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 1);
359 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
368 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
369 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
370 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
376 siena_intr_disable_unlocked(
381 EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
383 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
384 EFSYS_BAR_WRITEO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
388 static __checkReturn efx_rc_t
391 __in unsigned int level)
393 efx_intr_t *eip = &(enp->en_intr);
399 /* bug16757: No event queues can be initialized */
400 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
402 if (level >= EFX_NINTR_SIENA) {
407 if (level > EFX_MASK32(FRF_AZ_KER_INT_LEVE_SEL))
408 return (ENOTSUP); /* avoid EFSYS_PROBE() */
412 /* Trigger a test interrupt */
413 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
414 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, sel);
415 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER, 1);
416 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
419 * Wait up to 100ms for the interrupt to be raised before restoring
420 * KER_INT_LEVE_SEL. Ignore a failure to raise (the caller will
421 * observe this soon enough anyway), but always reset KER_INT_LEVE_SEL
425 EFSYS_SPIN(100); /* 100us */
427 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
428 } while (EFX_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER) && ++count < 1000);
430 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
431 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
436 EFSYS_PROBE1(fail1, efx_rc_t, rc);
441 static __checkReturn boolean_t
442 siena_intr_check_fatal(
445 efx_intr_t *eip = &(enp->en_intr);
446 efsys_mem_t *esmp = eip->ei_esmp;
449 /* Read the syndrome */
450 EFSYS_MEM_READO(esmp, 0, &oword);
452 if (EFX_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT) != 0) {
455 /* Clear the fatal interrupt condition */
456 EFX_SET_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT, 0);
457 EFSYS_MEM_WRITEO(esmp, 0, &oword);
466 siena_intr_status_line(
468 __out boolean_t *fatalp,
469 __out uint32_t *qmaskp)
471 efx_intr_t *eip = &(enp->en_intr);
474 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
475 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
478 * Read the queue mask and implicitly acknowledge the
481 EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE);
482 *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
484 EFSYS_PROBE1(qmask, uint32_t, *qmaskp);
486 if (*qmaskp & (1U << eip->ei_level))
487 *fatalp = siena_intr_check_fatal(enp);
493 siena_intr_status_message(
495 __in unsigned int message,
496 __out boolean_t *fatalp)
498 efx_intr_t *eip = &(enp->en_intr);
500 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
501 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
503 if (message == eip->ei_level)
504 *fatalp = siena_intr_check_fatal(enp);
514 #if EFSYS_OPT_DECODE_INTR_FATAL
518 EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal);
519 EFX_ZERO_OWORD(mem_per);
521 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0 ||
522 EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
523 EFX_BAR_READO(enp, FR_AZ_MEM_STAT_REG, &mem_per);
525 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRAM_OOB_INT_KER) != 0)
526 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_OOB, 0, 0);
528 if (EFX_OWORD_FIELD(fatal, FRF_AZ_BUFID_DC_OOB_INT_KER) != 0)
529 EFSYS_ERR(enp->en_esip, EFX_ERR_BUFID_DC_OOB, 0, 0);
531 if (EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
532 EFSYS_ERR(enp->en_esip, EFX_ERR_MEM_PERR,
533 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
534 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
536 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RBUF_OWN_INT_KER) != 0)
537 EFSYS_ERR(enp->en_esip, EFX_ERR_RBUF_OWN, 0, 0);
539 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TBUF_OWN_INT_KER) != 0)
540 EFSYS_ERR(enp->en_esip, EFX_ERR_TBUF_OWN, 0, 0);
542 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RDESCQ_OWN_INT_KER) != 0)
543 EFSYS_ERR(enp->en_esip, EFX_ERR_RDESQ_OWN, 0, 0);
545 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TDESCQ_OWN_INT_KER) != 0)
546 EFSYS_ERR(enp->en_esip, EFX_ERR_TDESQ_OWN, 0, 0);
548 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVQ_OWN_INT_KER) != 0)
549 EFSYS_ERR(enp->en_esip, EFX_ERR_EVQ_OWN, 0, 0);
551 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVF_OFLO_INT_KER) != 0)
552 EFSYS_ERR(enp->en_esip, EFX_ERR_EVFF_OFLO, 0, 0);
554 if (EFX_OWORD_FIELD(fatal, FRF_AZ_ILL_ADR_INT_KER) != 0)
555 EFSYS_ERR(enp->en_esip, EFX_ERR_ILL_ADDR, 0, 0);
557 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0)
558 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_PERR,
559 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
560 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
572 /* Clear the interrupt address register */
573 EFX_ZERO_OWORD(oword);
574 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
577 #endif /* EFSYS_OPT_SIENA */