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$");
41 static __checkReturn efx_rc_t
44 __in efx_intr_type_t type,
45 __in efsys_mem_t *esmp);
56 siena_intr_disable_unlocked(
59 static __checkReturn efx_rc_t
62 __in unsigned int level);
69 siena_intr_status_line(
71 __out boolean_t *fatalp,
72 __out uint32_t *qmaskp);
75 siena_intr_status_message(
77 __in unsigned int message,
78 __out boolean_t *fatalp);
84 static __checkReturn boolean_t
85 siena_intr_check_fatal(
88 #endif /* EFSYS_OPT_SIENA */
91 static const efx_intr_ops_t __efx_intr_siena_ops = {
92 siena_intr_init, /* eio_init */
93 siena_intr_enable, /* eio_enable */
94 siena_intr_disable, /* eio_disable */
95 siena_intr_disable_unlocked, /* eio_disable_unlocked */
96 siena_intr_trigger, /* eio_trigger */
97 siena_intr_status_line, /* eio_status_line */
98 siena_intr_status_message, /* eio_status_message */
99 siena_intr_fatal, /* eio_fatal */
100 siena_intr_fini, /* eio_fini */
102 #endif /* EFSYS_OPT_SIENA */
104 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
105 static const efx_intr_ops_t __efx_intr_ef10_ops = {
106 ef10_intr_init, /* eio_init */
107 ef10_intr_enable, /* eio_enable */
108 ef10_intr_disable, /* eio_disable */
109 ef10_intr_disable_unlocked, /* eio_disable_unlocked */
110 ef10_intr_trigger, /* eio_trigger */
111 ef10_intr_status_line, /* eio_status_line */
112 ef10_intr_status_message, /* eio_status_message */
113 ef10_intr_fatal, /* eio_fatal */
114 ef10_intr_fini, /* eio_fini */
116 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
118 __checkReturn efx_rc_t
121 __in efx_intr_type_t type,
122 __in_opt efsys_mem_t *esmp)
124 efx_intr_t *eip = &(enp->en_intr);
125 const efx_intr_ops_t *eiop;
128 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
129 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
131 if (enp->en_mod_flags & EFX_MOD_INTR) {
140 enp->en_mod_flags |= EFX_MOD_INTR;
142 switch (enp->en_family) {
144 case EFX_FAMILY_SIENA:
145 eiop = &__efx_intr_siena_ops;
147 #endif /* EFSYS_OPT_SIENA */
149 #if EFSYS_OPT_HUNTINGTON
150 case EFX_FAMILY_HUNTINGTON:
151 eiop = &__efx_intr_ef10_ops;
153 #endif /* EFSYS_OPT_HUNTINGTON */
155 #if EFSYS_OPT_MEDFORD
156 case EFX_FAMILY_MEDFORD:
157 eiop = &__efx_intr_ef10_ops;
159 #endif /* EFSYS_OPT_MEDFORD */
161 #if EFSYS_OPT_MEDFORD2
162 case EFX_FAMILY_MEDFORD2:
163 eiop = &__efx_intr_ef10_ops;
165 #endif /* EFSYS_OPT_MEDFORD2 */
168 EFSYS_ASSERT(B_FALSE);
173 if ((rc = eiop->eio_init(enp, type, esmp)) != 0)
185 EFSYS_PROBE1(fail1, efx_rc_t, rc);
194 efx_intr_t *eip = &(enp->en_intr);
195 const efx_intr_ops_t *eiop = eip->ei_eiop;
197 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
198 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
199 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
203 enp->en_mod_flags &= ~EFX_MOD_INTR;
210 efx_intr_t *eip = &(enp->en_intr);
211 const efx_intr_ops_t *eiop = eip->ei_eiop;
213 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
214 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
216 eiop->eio_enable(enp);
223 efx_intr_t *eip = &(enp->en_intr);
224 const efx_intr_ops_t *eiop = eip->ei_eiop;
226 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
227 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
229 eiop->eio_disable(enp);
233 efx_intr_disable_unlocked(
236 efx_intr_t *eip = &(enp->en_intr);
237 const efx_intr_ops_t *eiop = eip->ei_eiop;
239 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
240 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
242 eiop->eio_disable_unlocked(enp);
245 __checkReturn efx_rc_t
248 __in unsigned int level)
250 efx_intr_t *eip = &(enp->en_intr);
251 const efx_intr_ops_t *eiop = eip->ei_eiop;
253 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
254 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
256 return (eiop->eio_trigger(enp, level));
260 efx_intr_status_line(
262 __out boolean_t *fatalp,
263 __out uint32_t *qmaskp)
265 efx_intr_t *eip = &(enp->en_intr);
266 const efx_intr_ops_t *eiop = eip->ei_eiop;
268 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
269 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
271 eiop->eio_status_line(enp, fatalp, qmaskp);
275 efx_intr_status_message(
277 __in unsigned int message,
278 __out boolean_t *fatalp)
280 efx_intr_t *eip = &(enp->en_intr);
281 const efx_intr_ops_t *eiop = eip->ei_eiop;
283 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
284 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
286 eiop->eio_status_message(enp, message, fatalp);
293 efx_intr_t *eip = &(enp->en_intr);
294 const efx_intr_ops_t *eiop = eip->ei_eiop;
296 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
297 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
299 eiop->eio_fatal(enp);
302 /* ************************************************************************* */
303 /* ************************************************************************* */
304 /* ************************************************************************* */
308 static __checkReturn efx_rc_t
311 __in efx_intr_type_t type,
312 __in efsys_mem_t *esmp)
314 efx_intr_t *eip = &(enp->en_intr);
318 if ((esmp == NULL) || (EFSYS_MEM_SIZE(esmp) < EFX_INTR_SIZE)) {
324 * bug17213 workaround.
326 * Under legacy interrupts, don't share a level between fatal
327 * interrupts and event queue interrupts. Under MSI-X, they
328 * must share, or we won't get an interrupt.
330 if (enp->en_family == EFX_FAMILY_SIENA &&
331 eip->ei_type == EFX_INTR_LINE)
332 eip->ei_level = 0x1f;
336 /* Enable all the genuinely fatal interrupts */
337 EFX_SET_OWORD(oword);
338 EFX_SET_OWORD_FIELD(oword, FRF_AZ_ILL_ADR_INT_KER_EN, 0);
339 EFX_SET_OWORD_FIELD(oword, FRF_AZ_RBUF_OWN_INT_KER_EN, 0);
340 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TBUF_OWN_INT_KER_EN, 0);
341 if (enp->en_family >= EFX_FAMILY_SIENA)
342 EFX_SET_OWORD_FIELD(oword, FRF_CZ_SRAM_PERR_INT_P_KER_EN, 0);
343 EFX_BAR_WRITEO(enp, FR_AZ_FATAL_INTR_REG_KER, &oword);
345 /* Set up the interrupt address register */
346 EFX_POPULATE_OWORD_3(oword,
347 FRF_AZ_NORM_INT_VEC_DIS_KER, (type == EFX_INTR_MESSAGE) ? 1 : 0,
348 FRF_AZ_INT_ADR_KER_DW0, EFSYS_MEM_ADDR(esmp) & 0xffffffff,
349 FRF_AZ_INT_ADR_KER_DW1, EFSYS_MEM_ADDR(esmp) >> 32);
350 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
355 EFSYS_PROBE1(fail1, efx_rc_t, rc);
364 efx_intr_t *eip = &(enp->en_intr);
367 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
369 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
370 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 1);
371 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
380 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
381 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
382 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
388 siena_intr_disable_unlocked(
393 EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
395 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
396 EFSYS_BAR_WRITEO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
400 static __checkReturn efx_rc_t
403 __in unsigned int level)
405 efx_intr_t *eip = &(enp->en_intr);
411 /* bug16757: No event queues can be initialized */
412 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
414 if (level >= EFX_NINTR_SIENA) {
419 if (level > EFX_MASK32(FRF_AZ_KER_INT_LEVE_SEL))
420 return (ENOTSUP); /* avoid EFSYS_PROBE() */
424 /* Trigger a test interrupt */
425 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
426 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, sel);
427 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER, 1);
428 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
431 * Wait up to 100ms for the interrupt to be raised before restoring
432 * KER_INT_LEVE_SEL. Ignore a failure to raise (the caller will
433 * observe this soon enough anyway), but always reset KER_INT_LEVE_SEL
437 EFSYS_SPIN(100); /* 100us */
439 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
440 } while (EFX_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER) && ++count < 1000);
442 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
443 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
448 EFSYS_PROBE1(fail1, efx_rc_t, rc);
453 static __checkReturn boolean_t
454 siena_intr_check_fatal(
457 efx_intr_t *eip = &(enp->en_intr);
458 efsys_mem_t *esmp = eip->ei_esmp;
461 /* Read the syndrome */
462 EFSYS_MEM_READO(esmp, 0, &oword);
464 if (EFX_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT) != 0) {
467 /* Clear the fatal interrupt condition */
468 EFX_SET_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT, 0);
469 EFSYS_MEM_WRITEO(esmp, 0, &oword);
478 siena_intr_status_line(
480 __out boolean_t *fatalp,
481 __out uint32_t *qmaskp)
483 efx_intr_t *eip = &(enp->en_intr);
486 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
487 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
490 * Read the queue mask and implicitly acknowledge the
493 EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE);
494 *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
496 EFSYS_PROBE1(qmask, uint32_t, *qmaskp);
498 if (*qmaskp & (1U << eip->ei_level))
499 *fatalp = siena_intr_check_fatal(enp);
505 siena_intr_status_message(
507 __in unsigned int message,
508 __out boolean_t *fatalp)
510 efx_intr_t *eip = &(enp->en_intr);
512 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
513 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
515 if (message == eip->ei_level)
516 *fatalp = siena_intr_check_fatal(enp);
525 #if EFSYS_OPT_DECODE_INTR_FATAL
529 EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal);
530 EFX_ZERO_OWORD(mem_per);
532 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0 ||
533 EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
534 EFX_BAR_READO(enp, FR_AZ_MEM_STAT_REG, &mem_per);
536 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRAM_OOB_INT_KER) != 0)
537 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_OOB, 0, 0);
539 if (EFX_OWORD_FIELD(fatal, FRF_AZ_BUFID_DC_OOB_INT_KER) != 0)
540 EFSYS_ERR(enp->en_esip, EFX_ERR_BUFID_DC_OOB, 0, 0);
542 if (EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
543 EFSYS_ERR(enp->en_esip, EFX_ERR_MEM_PERR,
544 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
545 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
547 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RBUF_OWN_INT_KER) != 0)
548 EFSYS_ERR(enp->en_esip, EFX_ERR_RBUF_OWN, 0, 0);
550 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TBUF_OWN_INT_KER) != 0)
551 EFSYS_ERR(enp->en_esip, EFX_ERR_TBUF_OWN, 0, 0);
553 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RDESCQ_OWN_INT_KER) != 0)
554 EFSYS_ERR(enp->en_esip, EFX_ERR_RDESQ_OWN, 0, 0);
556 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TDESCQ_OWN_INT_KER) != 0)
557 EFSYS_ERR(enp->en_esip, EFX_ERR_TDESQ_OWN, 0, 0);
559 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVQ_OWN_INT_KER) != 0)
560 EFSYS_ERR(enp->en_esip, EFX_ERR_EVQ_OWN, 0, 0);
562 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVF_OFLO_INT_KER) != 0)
563 EFSYS_ERR(enp->en_esip, EFX_ERR_EVFF_OFLO, 0, 0);
565 if (EFX_OWORD_FIELD(fatal, FRF_AZ_ILL_ADR_INT_KER) != 0)
566 EFSYS_ERR(enp->en_esip, EFX_ERR_ILL_ADDR, 0, 0);
568 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0)
569 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_PERR,
570 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
571 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
583 /* Clear the interrupt address register */
584 EFX_ZERO_OWORD(oword);
585 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
588 #endif /* EFSYS_OPT_SIENA */