1 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright(c) 2019-2021 Xilinx, Inc.
4 * Copyright(c) 2007-2019 Solarflare Communications Inc.
13 static __checkReturn efx_rc_t
16 __in efx_intr_type_t type,
17 __in efsys_mem_t *esmp);
28 siena_intr_disable_unlocked(
31 static __checkReturn efx_rc_t
34 __in unsigned int level);
41 siena_intr_status_line(
43 __out boolean_t *fatalp,
44 __out uint32_t *qmaskp);
47 siena_intr_status_message(
49 __in unsigned int message,
50 __out boolean_t *fatalp);
56 static __checkReturn boolean_t
57 siena_intr_check_fatal(
61 #endif /* EFSYS_OPT_SIENA */
65 static const efx_intr_ops_t __efx_intr_siena_ops = {
66 siena_intr_init, /* eio_init */
67 siena_intr_enable, /* eio_enable */
68 siena_intr_disable, /* eio_disable */
69 siena_intr_disable_unlocked, /* eio_disable_unlocked */
70 siena_intr_trigger, /* eio_trigger */
71 siena_intr_status_line, /* eio_status_line */
72 siena_intr_status_message, /* eio_status_message */
73 siena_intr_fatal, /* eio_fatal */
74 siena_intr_fini, /* eio_fini */
76 #endif /* EFSYS_OPT_SIENA */
79 static const efx_intr_ops_t __efx_intr_ef10_ops = {
80 ef10_intr_init, /* eio_init */
81 ef10_intr_enable, /* eio_enable */
82 ef10_intr_disable, /* eio_disable */
83 ef10_intr_disable_unlocked, /* eio_disable_unlocked */
84 ef10_intr_trigger, /* eio_trigger */
85 ef10_intr_status_line, /* eio_status_line */
86 ef10_intr_status_message, /* eio_status_message */
87 ef10_intr_fatal, /* eio_fatal */
88 ef10_intr_fini, /* eio_fini */
90 #endif /* EFX_OPTS_EF10() */
92 #if EFSYS_OPT_RIVERHEAD
93 static const efx_intr_ops_t __efx_intr_rhead_ops = {
94 rhead_intr_init, /* eio_init */
95 rhead_intr_enable, /* eio_enable */
96 rhead_intr_disable, /* eio_disable */
97 rhead_intr_disable_unlocked, /* eio_disable_unlocked */
98 rhead_intr_trigger, /* eio_trigger */
99 rhead_intr_status_line, /* eio_status_line */
100 rhead_intr_status_message, /* eio_status_message */
101 rhead_intr_fatal, /* eio_fatal */
102 rhead_intr_fini, /* eio_fini */
104 #endif /* EFSYS_OPT_RIVERHEAD */
106 __checkReturn efx_rc_t
109 __in efx_intr_type_t type,
110 __in_opt efsys_mem_t *esmp)
112 efx_intr_t *eip = &(enp->en_intr);
113 const efx_intr_ops_t *eiop;
116 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
117 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
119 if (enp->en_mod_flags & EFX_MOD_INTR) {
128 enp->en_mod_flags |= EFX_MOD_INTR;
130 switch (enp->en_family) {
132 case EFX_FAMILY_SIENA:
133 eiop = &__efx_intr_siena_ops;
135 #endif /* EFSYS_OPT_SIENA */
137 #if EFSYS_OPT_HUNTINGTON
138 case EFX_FAMILY_HUNTINGTON:
139 eiop = &__efx_intr_ef10_ops;
141 #endif /* EFSYS_OPT_HUNTINGTON */
143 #if EFSYS_OPT_MEDFORD
144 case EFX_FAMILY_MEDFORD:
145 eiop = &__efx_intr_ef10_ops;
147 #endif /* EFSYS_OPT_MEDFORD */
149 #if EFSYS_OPT_MEDFORD2
150 case EFX_FAMILY_MEDFORD2:
151 eiop = &__efx_intr_ef10_ops;
153 #endif /* EFSYS_OPT_MEDFORD2 */
155 #if EFSYS_OPT_RIVERHEAD
156 case EFX_FAMILY_RIVERHEAD:
157 eiop = &__efx_intr_rhead_ops;
159 #endif /* EFSYS_OPT_RIVERHEAD */
162 EFSYS_ASSERT(B_FALSE);
167 if ((rc = eiop->eio_init(enp, type, esmp)) != 0)
179 EFSYS_PROBE1(fail1, efx_rc_t, rc);
188 efx_intr_t *eip = &(enp->en_intr);
189 const efx_intr_ops_t *eiop = eip->ei_eiop;
191 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
192 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
193 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
197 enp->en_mod_flags &= ~EFX_MOD_INTR;
204 efx_intr_t *eip = &(enp->en_intr);
205 const efx_intr_ops_t *eiop = eip->ei_eiop;
207 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
208 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
210 eiop->eio_enable(enp);
217 efx_intr_t *eip = &(enp->en_intr);
218 const efx_intr_ops_t *eiop = eip->ei_eiop;
220 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
221 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
223 eiop->eio_disable(enp);
227 efx_intr_disable_unlocked(
230 efx_intr_t *eip = &(enp->en_intr);
231 const efx_intr_ops_t *eiop = eip->ei_eiop;
233 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
234 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
236 eiop->eio_disable_unlocked(enp);
240 __checkReturn efx_rc_t
243 __in unsigned int level)
245 efx_intr_t *eip = &(enp->en_intr);
246 const efx_intr_ops_t *eiop = eip->ei_eiop;
248 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
249 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
251 return (eiop->eio_trigger(enp, level));
255 efx_intr_status_line(
257 __out boolean_t *fatalp,
258 __out uint32_t *qmaskp)
260 efx_intr_t *eip = &(enp->en_intr);
261 const efx_intr_ops_t *eiop = eip->ei_eiop;
263 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
264 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
266 eiop->eio_status_line(enp, fatalp, qmaskp);
270 efx_intr_status_message(
272 __in unsigned int message,
273 __out boolean_t *fatalp)
275 efx_intr_t *eip = &(enp->en_intr);
276 const efx_intr_ops_t *eiop = eip->ei_eiop;
278 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
279 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
281 eiop->eio_status_message(enp, message, fatalp);
288 efx_intr_t *eip = &(enp->en_intr);
289 const efx_intr_ops_t *eiop = eip->ei_eiop;
291 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
292 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
294 eiop->eio_fatal(enp);
298 /* ************************************************************************* */
299 /* ************************************************************************* */
300 /* ************************************************************************* */
304 static __checkReturn efx_rc_t
307 __in efx_intr_type_t type,
308 __in efsys_mem_t *esmp)
310 efx_intr_t *eip = &(enp->en_intr);
314 if ((esmp == NULL) || (EFSYS_MEM_SIZE(esmp) < EFX_INTR_SIZE)) {
320 * bug17213 workaround.
322 * Under legacy interrupts, don't share a level between fatal
323 * interrupts and event queue interrupts. Under MSI-X, they
324 * must share, or we won't get an interrupt.
326 if (enp->en_family == EFX_FAMILY_SIENA &&
327 eip->ei_type == EFX_INTR_LINE)
328 eip->ei_level = 0x1f;
332 /* Enable all the genuinely fatal interrupts */
333 EFX_SET_OWORD(oword);
334 EFX_SET_OWORD_FIELD(oword, FRF_AZ_ILL_ADR_INT_KER_EN, 0);
335 EFX_SET_OWORD_FIELD(oword, FRF_AZ_RBUF_OWN_INT_KER_EN, 0);
336 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TBUF_OWN_INT_KER_EN, 0);
337 if (enp->en_family >= EFX_FAMILY_SIENA)
338 EFX_SET_OWORD_FIELD(oword, FRF_CZ_SRAM_PERR_INT_P_KER_EN, 0);
339 EFX_BAR_WRITEO(enp, FR_AZ_FATAL_INTR_REG_KER, &oword);
341 /* Set up the interrupt address register */
342 EFX_POPULATE_OWORD_3(oword,
343 FRF_AZ_NORM_INT_VEC_DIS_KER, (type == EFX_INTR_MESSAGE) ? 1 : 0,
344 FRF_AZ_INT_ADR_KER_DW0, EFSYS_MEM_ADDR(esmp) & 0xffffffff,
345 FRF_AZ_INT_ADR_KER_DW1, EFSYS_MEM_ADDR(esmp) >> 32);
346 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
351 EFSYS_PROBE1(fail1, efx_rc_t, rc);
360 efx_intr_t *eip = &(enp->en_intr);
363 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
365 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
366 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 1);
367 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
376 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
377 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
378 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
384 siena_intr_disable_unlocked(
389 EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
391 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
392 EFSYS_BAR_WRITEO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
396 static __checkReturn efx_rc_t
399 __in unsigned int level)
401 efx_intr_t *eip = &(enp->en_intr);
407 /* bug16757: No event queues can be initialized */
408 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
410 if (level >= EFX_NINTR_SIENA) {
415 if (level > EFX_MASK32(FRF_AZ_KER_INT_LEVE_SEL))
416 return (ENOTSUP); /* avoid EFSYS_PROBE() */
420 /* Trigger a test interrupt */
421 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
422 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, sel);
423 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER, 1);
424 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
427 * Wait up to 100ms for the interrupt to be raised before restoring
428 * KER_INT_LEVE_SEL. Ignore a failure to raise (the caller will
429 * observe this soon enough anyway), but always reset KER_INT_LEVE_SEL
433 EFSYS_SPIN(100); /* 100us */
435 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
436 } while (EFX_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER) && ++count < 1000);
438 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
439 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
444 EFSYS_PROBE1(fail1, efx_rc_t, rc);
449 static __checkReturn boolean_t
450 siena_intr_check_fatal(
453 efx_intr_t *eip = &(enp->en_intr);
454 efsys_mem_t *esmp = eip->ei_esmp;
457 /* Read the syndrome */
458 EFSYS_MEM_READO(esmp, 0, &oword);
460 if (EFX_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT) != 0) {
463 /* Clear the fatal interrupt condition */
464 EFX_SET_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT, 0);
465 EFSYS_MEM_WRITEO(esmp, 0, &oword);
474 siena_intr_status_line(
476 __out boolean_t *fatalp,
477 __out uint32_t *qmaskp)
479 efx_intr_t *eip = &(enp->en_intr);
482 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
483 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
486 * Read the queue mask and implicitly acknowledge the
489 EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE);
490 *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
492 EFSYS_PROBE1(qmask, uint32_t, *qmaskp);
494 if (*qmaskp & (1U << eip->ei_level))
495 *fatalp = siena_intr_check_fatal(enp);
501 siena_intr_status_message(
503 __in unsigned int message,
504 __out boolean_t *fatalp)
506 efx_intr_t *eip = &(enp->en_intr);
508 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
509 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
511 if (message == eip->ei_level)
512 *fatalp = siena_intr_check_fatal(enp);
522 #if EFSYS_OPT_DECODE_INTR_FATAL
526 EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal);
527 EFX_ZERO_OWORD(mem_per);
529 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0 ||
530 EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
531 EFX_BAR_READO(enp, FR_AZ_MEM_STAT_REG, &mem_per);
533 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRAM_OOB_INT_KER) != 0)
534 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_OOB, 0, 0);
536 if (EFX_OWORD_FIELD(fatal, FRF_AZ_BUFID_DC_OOB_INT_KER) != 0)
537 EFSYS_ERR(enp->en_esip, EFX_ERR_BUFID_DC_OOB, 0, 0);
539 if (EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
540 EFSYS_ERR(enp->en_esip, EFX_ERR_MEM_PERR,
541 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
542 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
544 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RBUF_OWN_INT_KER) != 0)
545 EFSYS_ERR(enp->en_esip, EFX_ERR_RBUF_OWN, 0, 0);
547 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TBUF_OWN_INT_KER) != 0)
548 EFSYS_ERR(enp->en_esip, EFX_ERR_TBUF_OWN, 0, 0);
550 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RDESCQ_OWN_INT_KER) != 0)
551 EFSYS_ERR(enp->en_esip, EFX_ERR_RDESQ_OWN, 0, 0);
553 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TDESCQ_OWN_INT_KER) != 0)
554 EFSYS_ERR(enp->en_esip, EFX_ERR_TDESQ_OWN, 0, 0);
556 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVQ_OWN_INT_KER) != 0)
557 EFSYS_ERR(enp->en_esip, EFX_ERR_EVQ_OWN, 0, 0);
559 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVF_OFLO_INT_KER) != 0)
560 EFSYS_ERR(enp->en_esip, EFX_ERR_EVFF_OFLO, 0, 0);
562 if (EFX_OWORD_FIELD(fatal, FRF_AZ_ILL_ADR_INT_KER) != 0)
563 EFSYS_ERR(enp->en_esip, EFX_ERR_ILL_ADDR, 0, 0);
565 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0)
566 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_PERR,
567 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
568 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
580 /* Clear the interrupt address register */
581 EFX_ZERO_OWORD(oword);
582 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
585 #endif /* EFSYS_OPT_SIENA */