2 * Copyright (c) 2007-2016 Solarflare Communications Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
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.
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.
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.
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
40 static __checkReturn efx_rc_t
43 __in efx_intr_type_t type,
44 __in efsys_mem_t *esmp);
55 siena_intr_disable_unlocked(
58 static __checkReturn efx_rc_t
61 __in unsigned int level);
68 siena_intr_status_line(
70 __out boolean_t *fatalp,
71 __out uint32_t *qmaskp);
74 siena_intr_status_message(
76 __in unsigned int message,
77 __out boolean_t *fatalp);
83 static __checkReturn boolean_t
84 siena_intr_check_fatal(
88 #endif /* 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 */
103 #endif /* EFSYS_OPT_SIENA */
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 */
117 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
119 __checkReturn efx_rc_t
122 __in efx_intr_type_t type,
123 __in efsys_mem_t *esmp)
125 efx_intr_t *eip = &(enp->en_intr);
126 const efx_intr_ops_t *eiop;
129 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
130 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
132 if (enp->en_mod_flags & EFX_MOD_INTR) {
141 enp->en_mod_flags |= EFX_MOD_INTR;
143 switch (enp->en_family) {
145 case EFX_FAMILY_SIENA:
146 eiop = &__efx_intr_siena_ops;
148 #endif /* EFSYS_OPT_SIENA */
150 #if EFSYS_OPT_HUNTINGTON
151 case EFX_FAMILY_HUNTINGTON:
152 eiop = &__efx_intr_ef10_ops;
154 #endif /* EFSYS_OPT_HUNTINGTON */
156 #if EFSYS_OPT_MEDFORD
157 case EFX_FAMILY_MEDFORD:
158 eiop = &__efx_intr_ef10_ops;
160 #endif /* EFSYS_OPT_MEDFORD */
163 EFSYS_ASSERT(B_FALSE);
168 if ((rc = eiop->eio_init(enp, type, esmp)) != 0)
180 EFSYS_PROBE1(fail1, efx_rc_t, rc);
189 efx_intr_t *eip = &(enp->en_intr);
190 const efx_intr_ops_t *eiop = eip->ei_eiop;
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);
198 enp->en_mod_flags &= ~EFX_MOD_INTR;
205 efx_intr_t *eip = &(enp->en_intr);
206 const efx_intr_ops_t *eiop = eip->ei_eiop;
208 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
209 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
211 eiop->eio_enable(enp);
218 efx_intr_t *eip = &(enp->en_intr);
219 const efx_intr_ops_t *eiop = eip->ei_eiop;
221 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
222 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
224 eiop->eio_disable(enp);
228 efx_intr_disable_unlocked(
231 efx_intr_t *eip = &(enp->en_intr);
232 const efx_intr_ops_t *eiop = eip->ei_eiop;
234 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
235 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
237 eiop->eio_disable_unlocked(enp);
241 __checkReturn efx_rc_t
244 __in unsigned int level)
246 efx_intr_t *eip = &(enp->en_intr);
247 const efx_intr_ops_t *eiop = eip->ei_eiop;
249 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
250 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
252 return (eiop->eio_trigger(enp, level));
256 efx_intr_status_line(
258 __out boolean_t *fatalp,
259 __out uint32_t *qmaskp)
261 efx_intr_t *eip = &(enp->en_intr);
262 const efx_intr_ops_t *eiop = eip->ei_eiop;
264 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
265 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
267 eiop->eio_status_line(enp, fatalp, qmaskp);
271 efx_intr_status_message(
273 __in unsigned int message,
274 __out boolean_t *fatalp)
276 efx_intr_t *eip = &(enp->en_intr);
277 const efx_intr_ops_t *eiop = eip->ei_eiop;
279 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
280 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
282 eiop->eio_status_message(enp, message, fatalp);
289 efx_intr_t *eip = &(enp->en_intr);
290 const efx_intr_ops_t *eiop = eip->ei_eiop;
292 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
293 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
295 eiop->eio_fatal(enp);
299 /* ************************************************************************* */
300 /* ************************************************************************* */
301 /* ************************************************************************* */
305 static __checkReturn efx_rc_t
308 __in efx_intr_type_t type,
309 __in efsys_mem_t *esmp)
311 efx_intr_t *eip = &(enp->en_intr);
315 * bug17213 workaround.
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.
321 if (enp->en_family == EFX_FAMILY_SIENA &&
322 eip->ei_type == EFX_INTR_LINE)
323 eip->ei_level = 0x1f;
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);
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);
350 efx_intr_t *eip = &(enp->en_intr);
353 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
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);
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);
374 siena_intr_disable_unlocked(
379 EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
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,
386 static __checkReturn efx_rc_t
389 __in unsigned int level)
391 efx_intr_t *eip = &(enp->en_intr);
397 /* bug16757: No event queues can be initialized */
398 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
400 if (level >= EFX_NINTR_SIENA) {
405 if (level > EFX_MASK32(FRF_AZ_KER_INT_LEVE_SEL))
406 return (ENOTSUP); /* avoid EFSYS_PROBE() */
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);
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
423 EFSYS_SPIN(100); /* 100us */
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);
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);
434 EFSYS_PROBE1(fail1, efx_rc_t, rc);
439 static __checkReturn boolean_t
440 siena_intr_check_fatal(
443 efx_intr_t *eip = &(enp->en_intr);
444 efsys_mem_t *esmp = eip->ei_esmp;
447 /* Read the syndrome */
448 EFSYS_MEM_READO(esmp, 0, &oword);
450 if (EFX_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT) != 0) {
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);
464 siena_intr_status_line(
466 __out boolean_t *fatalp,
467 __out uint32_t *qmaskp)
469 efx_intr_t *eip = &(enp->en_intr);
472 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
473 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
476 * Read the queue mask and implicitly acknowledge the
479 EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE);
480 *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
482 EFSYS_PROBE1(qmask, uint32_t, *qmaskp);
484 if (*qmaskp & (1U << eip->ei_level))
485 *fatalp = siena_intr_check_fatal(enp);
491 siena_intr_status_message(
493 __in unsigned int message,
494 __out boolean_t *fatalp)
496 efx_intr_t *eip = &(enp->en_intr);
498 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
499 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
501 if (message == eip->ei_level)
502 *fatalp = siena_intr_check_fatal(enp);
512 #if EFSYS_OPT_DECODE_INTR_FATAL
516 EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal);
517 EFX_ZERO_OWORD(mem_per);
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);
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);
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);
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));
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);
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);
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);
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);
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);
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);
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);
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));
570 /* Clear the interrupt address register */
571 EFX_ZERO_OWORD(oword);
572 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
575 #endif /* EFSYS_OPT_SIENA */