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 || EFSYS_OPT_MEDFORD2
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 || EFSYS_OPT_MEDFORD2 */
121 __checkReturn efx_rc_t
124 __in efx_intr_type_t type,
125 __in_opt 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 */
164 #if EFSYS_OPT_MEDFORD2
165 case EFX_FAMILY_MEDFORD2:
166 eiop = &__efx_intr_ef10_ops;
168 #endif /* EFSYS_OPT_MEDFORD2 */
171 EFSYS_ASSERT(B_FALSE);
176 if ((rc = eiop->eio_init(enp, type, esmp)) != 0)
188 EFSYS_PROBE1(fail1, efx_rc_t, rc);
197 efx_intr_t *eip = &(enp->en_intr);
198 const efx_intr_ops_t *eiop = eip->ei_eiop;
200 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
201 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
202 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
206 enp->en_mod_flags &= ~EFX_MOD_INTR;
213 efx_intr_t *eip = &(enp->en_intr);
214 const efx_intr_ops_t *eiop = eip->ei_eiop;
216 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
217 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
219 eiop->eio_enable(enp);
226 efx_intr_t *eip = &(enp->en_intr);
227 const efx_intr_ops_t *eiop = eip->ei_eiop;
229 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
230 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
232 eiop->eio_disable(enp);
236 efx_intr_disable_unlocked(
239 efx_intr_t *eip = &(enp->en_intr);
240 const efx_intr_ops_t *eiop = eip->ei_eiop;
242 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
243 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
245 eiop->eio_disable_unlocked(enp);
249 __checkReturn efx_rc_t
252 __in unsigned int level)
254 efx_intr_t *eip = &(enp->en_intr);
255 const efx_intr_ops_t *eiop = eip->ei_eiop;
257 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
258 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
260 return (eiop->eio_trigger(enp, level));
264 efx_intr_status_line(
266 __out boolean_t *fatalp,
267 __out uint32_t *qmaskp)
269 efx_intr_t *eip = &(enp->en_intr);
270 const efx_intr_ops_t *eiop = eip->ei_eiop;
272 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
273 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
275 eiop->eio_status_line(enp, fatalp, qmaskp);
279 efx_intr_status_message(
281 __in unsigned int message,
282 __out boolean_t *fatalp)
284 efx_intr_t *eip = &(enp->en_intr);
285 const efx_intr_ops_t *eiop = eip->ei_eiop;
287 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
288 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
290 eiop->eio_status_message(enp, message, fatalp);
297 efx_intr_t *eip = &(enp->en_intr);
298 const efx_intr_ops_t *eiop = eip->ei_eiop;
300 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
301 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
303 eiop->eio_fatal(enp);
307 /* ************************************************************************* */
308 /* ************************************************************************* */
309 /* ************************************************************************* */
313 static __checkReturn efx_rc_t
316 __in efx_intr_type_t type,
317 __in efsys_mem_t *esmp)
319 efx_intr_t *eip = &(enp->en_intr);
323 if ((esmp == NULL) || (EFSYS_MEM_SIZE(esmp) < EFX_INTR_SIZE)) {
329 * bug17213 workaround.
331 * Under legacy interrupts, don't share a level between fatal
332 * interrupts and event queue interrupts. Under MSI-X, they
333 * must share, or we won't get an interrupt.
335 if (enp->en_family == EFX_FAMILY_SIENA &&
336 eip->ei_type == EFX_INTR_LINE)
337 eip->ei_level = 0x1f;
341 /* Enable all the genuinely fatal interrupts */
342 EFX_SET_OWORD(oword);
343 EFX_SET_OWORD_FIELD(oword, FRF_AZ_ILL_ADR_INT_KER_EN, 0);
344 EFX_SET_OWORD_FIELD(oword, FRF_AZ_RBUF_OWN_INT_KER_EN, 0);
345 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TBUF_OWN_INT_KER_EN, 0);
346 if (enp->en_family >= EFX_FAMILY_SIENA)
347 EFX_SET_OWORD_FIELD(oword, FRF_CZ_SRAM_PERR_INT_P_KER_EN, 0);
348 EFX_BAR_WRITEO(enp, FR_AZ_FATAL_INTR_REG_KER, &oword);
350 /* Set up the interrupt address register */
351 EFX_POPULATE_OWORD_3(oword,
352 FRF_AZ_NORM_INT_VEC_DIS_KER, (type == EFX_INTR_MESSAGE) ? 1 : 0,
353 FRF_AZ_INT_ADR_KER_DW0, EFSYS_MEM_ADDR(esmp) & 0xffffffff,
354 FRF_AZ_INT_ADR_KER_DW1, EFSYS_MEM_ADDR(esmp) >> 32);
355 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
360 EFSYS_PROBE1(fail1, efx_rc_t, rc);
369 efx_intr_t *eip = &(enp->en_intr);
372 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
374 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
375 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 1);
376 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
385 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
386 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
387 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
393 siena_intr_disable_unlocked(
398 EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
400 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
401 EFSYS_BAR_WRITEO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
405 static __checkReturn efx_rc_t
408 __in unsigned int level)
410 efx_intr_t *eip = &(enp->en_intr);
416 /* bug16757: No event queues can be initialized */
417 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
419 if (level >= EFX_NINTR_SIENA) {
424 if (level > EFX_MASK32(FRF_AZ_KER_INT_LEVE_SEL))
425 return (ENOTSUP); /* avoid EFSYS_PROBE() */
429 /* Trigger a test interrupt */
430 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
431 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, sel);
432 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER, 1);
433 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
436 * Wait up to 100ms for the interrupt to be raised before restoring
437 * KER_INT_LEVE_SEL. Ignore a failure to raise (the caller will
438 * observe this soon enough anyway), but always reset KER_INT_LEVE_SEL
442 EFSYS_SPIN(100); /* 100us */
444 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
445 } while (EFX_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER) && ++count < 1000);
447 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
448 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
453 EFSYS_PROBE1(fail1, efx_rc_t, rc);
458 static __checkReturn boolean_t
459 siena_intr_check_fatal(
462 efx_intr_t *eip = &(enp->en_intr);
463 efsys_mem_t *esmp = eip->ei_esmp;
466 /* Read the syndrome */
467 EFSYS_MEM_READO(esmp, 0, &oword);
469 if (EFX_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT) != 0) {
472 /* Clear the fatal interrupt condition */
473 EFX_SET_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT, 0);
474 EFSYS_MEM_WRITEO(esmp, 0, &oword);
483 siena_intr_status_line(
485 __out boolean_t *fatalp,
486 __out uint32_t *qmaskp)
488 efx_intr_t *eip = &(enp->en_intr);
491 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
492 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
495 * Read the queue mask and implicitly acknowledge the
498 EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE);
499 *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
501 EFSYS_PROBE1(qmask, uint32_t, *qmaskp);
503 if (*qmaskp & (1U << eip->ei_level))
504 *fatalp = siena_intr_check_fatal(enp);
510 siena_intr_status_message(
512 __in unsigned int message,
513 __out boolean_t *fatalp)
515 efx_intr_t *eip = &(enp->en_intr);
517 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
518 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
520 if (message == eip->ei_level)
521 *fatalp = siena_intr_check_fatal(enp);
531 #if EFSYS_OPT_DECODE_INTR_FATAL
535 EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal);
536 EFX_ZERO_OWORD(mem_per);
538 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0 ||
539 EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
540 EFX_BAR_READO(enp, FR_AZ_MEM_STAT_REG, &mem_per);
542 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRAM_OOB_INT_KER) != 0)
543 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_OOB, 0, 0);
545 if (EFX_OWORD_FIELD(fatal, FRF_AZ_BUFID_DC_OOB_INT_KER) != 0)
546 EFSYS_ERR(enp->en_esip, EFX_ERR_BUFID_DC_OOB, 0, 0);
548 if (EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
549 EFSYS_ERR(enp->en_esip, EFX_ERR_MEM_PERR,
550 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
551 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
553 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RBUF_OWN_INT_KER) != 0)
554 EFSYS_ERR(enp->en_esip, EFX_ERR_RBUF_OWN, 0, 0);
556 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TBUF_OWN_INT_KER) != 0)
557 EFSYS_ERR(enp->en_esip, EFX_ERR_TBUF_OWN, 0, 0);
559 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RDESCQ_OWN_INT_KER) != 0)
560 EFSYS_ERR(enp->en_esip, EFX_ERR_RDESQ_OWN, 0, 0);
562 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TDESCQ_OWN_INT_KER) != 0)
563 EFSYS_ERR(enp->en_esip, EFX_ERR_TDESQ_OWN, 0, 0);
565 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVQ_OWN_INT_KER) != 0)
566 EFSYS_ERR(enp->en_esip, EFX_ERR_EVQ_OWN, 0, 0);
568 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVF_OFLO_INT_KER) != 0)
569 EFSYS_ERR(enp->en_esip, EFX_ERR_EVFF_OFLO, 0, 0);
571 if (EFX_OWORD_FIELD(fatal, FRF_AZ_ILL_ADR_INT_KER) != 0)
572 EFSYS_ERR(enp->en_esip, EFX_ERR_ILL_ADDR, 0, 0);
574 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0)
575 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_PERR,
576 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
577 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
589 /* Clear the interrupt address register */
590 EFX_ZERO_OWORD(oword);
591 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
594 #endif /* EFSYS_OPT_SIENA */