1 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright (c) 2007-2018 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 */
78 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
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 /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
92 __checkReturn efx_rc_t
95 __in efx_intr_type_t type,
96 __in efsys_mem_t *esmp)
98 efx_intr_t *eip = &(enp->en_intr);
99 const efx_intr_ops_t *eiop;
102 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
103 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
105 if (enp->en_mod_flags & EFX_MOD_INTR) {
114 enp->en_mod_flags |= EFX_MOD_INTR;
116 switch (enp->en_family) {
118 case EFX_FAMILY_SIENA:
119 eiop = &__efx_intr_siena_ops;
121 #endif /* EFSYS_OPT_SIENA */
123 #if EFSYS_OPT_HUNTINGTON
124 case EFX_FAMILY_HUNTINGTON:
125 eiop = &__efx_intr_ef10_ops;
127 #endif /* EFSYS_OPT_HUNTINGTON */
129 #if EFSYS_OPT_MEDFORD
130 case EFX_FAMILY_MEDFORD:
131 eiop = &__efx_intr_ef10_ops;
133 #endif /* EFSYS_OPT_MEDFORD */
135 #if EFSYS_OPT_MEDFORD2
136 case EFX_FAMILY_MEDFORD2:
137 eiop = &__efx_intr_ef10_ops;
139 #endif /* EFSYS_OPT_MEDFORD2 */
142 EFSYS_ASSERT(B_FALSE);
147 if ((rc = eiop->eio_init(enp, type, esmp)) != 0)
159 EFSYS_PROBE1(fail1, efx_rc_t, rc);
168 efx_intr_t *eip = &(enp->en_intr);
169 const efx_intr_ops_t *eiop = eip->ei_eiop;
171 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
172 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
173 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
177 enp->en_mod_flags &= ~EFX_MOD_INTR;
184 efx_intr_t *eip = &(enp->en_intr);
185 const efx_intr_ops_t *eiop = eip->ei_eiop;
187 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
188 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
190 eiop->eio_enable(enp);
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_INTR);
203 eiop->eio_disable(enp);
207 efx_intr_disable_unlocked(
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_disable_unlocked(enp);
220 __checkReturn efx_rc_t
223 __in unsigned int level)
225 efx_intr_t *eip = &(enp->en_intr);
226 const efx_intr_ops_t *eiop = eip->ei_eiop;
228 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
229 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
231 return (eiop->eio_trigger(enp, level));
235 efx_intr_status_line(
237 __out boolean_t *fatalp,
238 __out uint32_t *qmaskp)
240 efx_intr_t *eip = &(enp->en_intr);
241 const efx_intr_ops_t *eiop = eip->ei_eiop;
243 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
244 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
246 eiop->eio_status_line(enp, fatalp, qmaskp);
250 efx_intr_status_message(
252 __in unsigned int message,
253 __out boolean_t *fatalp)
255 efx_intr_t *eip = &(enp->en_intr);
256 const efx_intr_ops_t *eiop = eip->ei_eiop;
258 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
259 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
261 eiop->eio_status_message(enp, message, fatalp);
268 efx_intr_t *eip = &(enp->en_intr);
269 const efx_intr_ops_t *eiop = eip->ei_eiop;
271 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
272 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
274 eiop->eio_fatal(enp);
278 /* ************************************************************************* */
279 /* ************************************************************************* */
280 /* ************************************************************************* */
284 static __checkReturn efx_rc_t
287 __in efx_intr_type_t type,
288 __in efsys_mem_t *esmp)
290 efx_intr_t *eip = &(enp->en_intr);
294 * bug17213 workaround.
296 * Under legacy interrupts, don't share a level between fatal
297 * interrupts and event queue interrupts. Under MSI-X, they
298 * must share, or we won't get an interrupt.
300 if (enp->en_family == EFX_FAMILY_SIENA &&
301 eip->ei_type == EFX_INTR_LINE)
302 eip->ei_level = 0x1f;
306 /* Enable all the genuinely fatal interrupts */
307 EFX_SET_OWORD(oword);
308 EFX_SET_OWORD_FIELD(oword, FRF_AZ_ILL_ADR_INT_KER_EN, 0);
309 EFX_SET_OWORD_FIELD(oword, FRF_AZ_RBUF_OWN_INT_KER_EN, 0);
310 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TBUF_OWN_INT_KER_EN, 0);
311 if (enp->en_family >= EFX_FAMILY_SIENA)
312 EFX_SET_OWORD_FIELD(oword, FRF_CZ_SRAM_PERR_INT_P_KER_EN, 0);
313 EFX_BAR_WRITEO(enp, FR_AZ_FATAL_INTR_REG_KER, &oword);
315 /* Set up the interrupt address register */
316 EFX_POPULATE_OWORD_3(oword,
317 FRF_AZ_NORM_INT_VEC_DIS_KER, (type == EFX_INTR_MESSAGE) ? 1 : 0,
318 FRF_AZ_INT_ADR_KER_DW0, EFSYS_MEM_ADDR(esmp) & 0xffffffff,
319 FRF_AZ_INT_ADR_KER_DW1, EFSYS_MEM_ADDR(esmp) >> 32);
320 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
329 efx_intr_t *eip = &(enp->en_intr);
332 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
334 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
335 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 1);
336 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
345 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
346 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
347 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
353 siena_intr_disable_unlocked(
358 EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
360 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
361 EFSYS_BAR_WRITEO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
365 static __checkReturn efx_rc_t
368 __in unsigned int level)
370 efx_intr_t *eip = &(enp->en_intr);
376 /* bug16757: No event queues can be initialized */
377 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
379 if (level >= EFX_NINTR_SIENA) {
384 if (level > EFX_MASK32(FRF_AZ_KER_INT_LEVE_SEL))
385 return (ENOTSUP); /* avoid EFSYS_PROBE() */
389 /* Trigger a test interrupt */
390 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
391 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, sel);
392 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER, 1);
393 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
396 * Wait up to 100ms for the interrupt to be raised before restoring
397 * KER_INT_LEVE_SEL. Ignore a failure to raise (the caller will
398 * observe this soon enough anyway), but always reset KER_INT_LEVE_SEL
402 EFSYS_SPIN(100); /* 100us */
404 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
405 } while (EFX_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER) && ++count < 1000);
407 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
408 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
413 EFSYS_PROBE1(fail1, efx_rc_t, rc);
418 static __checkReturn boolean_t
419 siena_intr_check_fatal(
422 efx_intr_t *eip = &(enp->en_intr);
423 efsys_mem_t *esmp = eip->ei_esmp;
426 /* Read the syndrome */
427 EFSYS_MEM_READO(esmp, 0, &oword);
429 if (EFX_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT) != 0) {
432 /* Clear the fatal interrupt condition */
433 EFX_SET_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT, 0);
434 EFSYS_MEM_WRITEO(esmp, 0, &oword);
443 siena_intr_status_line(
445 __out boolean_t *fatalp,
446 __out uint32_t *qmaskp)
448 efx_intr_t *eip = &(enp->en_intr);
451 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
452 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
455 * Read the queue mask and implicitly acknowledge the
458 EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE);
459 *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
461 EFSYS_PROBE1(qmask, uint32_t, *qmaskp);
463 if (*qmaskp & (1U << eip->ei_level))
464 *fatalp = siena_intr_check_fatal(enp);
470 siena_intr_status_message(
472 __in unsigned int message,
473 __out boolean_t *fatalp)
475 efx_intr_t *eip = &(enp->en_intr);
477 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
478 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
480 if (message == eip->ei_level)
481 *fatalp = siena_intr_check_fatal(enp);
491 #if EFSYS_OPT_DECODE_INTR_FATAL
495 EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal);
496 EFX_ZERO_OWORD(mem_per);
498 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0 ||
499 EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
500 EFX_BAR_READO(enp, FR_AZ_MEM_STAT_REG, &mem_per);
502 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRAM_OOB_INT_KER) != 0)
503 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_OOB, 0, 0);
505 if (EFX_OWORD_FIELD(fatal, FRF_AZ_BUFID_DC_OOB_INT_KER) != 0)
506 EFSYS_ERR(enp->en_esip, EFX_ERR_BUFID_DC_OOB, 0, 0);
508 if (EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
509 EFSYS_ERR(enp->en_esip, EFX_ERR_MEM_PERR,
510 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
511 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
513 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RBUF_OWN_INT_KER) != 0)
514 EFSYS_ERR(enp->en_esip, EFX_ERR_RBUF_OWN, 0, 0);
516 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TBUF_OWN_INT_KER) != 0)
517 EFSYS_ERR(enp->en_esip, EFX_ERR_TBUF_OWN, 0, 0);
519 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RDESCQ_OWN_INT_KER) != 0)
520 EFSYS_ERR(enp->en_esip, EFX_ERR_RDESQ_OWN, 0, 0);
522 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TDESCQ_OWN_INT_KER) != 0)
523 EFSYS_ERR(enp->en_esip, EFX_ERR_TDESQ_OWN, 0, 0);
525 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVQ_OWN_INT_KER) != 0)
526 EFSYS_ERR(enp->en_esip, EFX_ERR_EVQ_OWN, 0, 0);
528 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVF_OFLO_INT_KER) != 0)
529 EFSYS_ERR(enp->en_esip, EFX_ERR_EVFF_OFLO, 0, 0);
531 if (EFX_OWORD_FIELD(fatal, FRF_AZ_ILL_ADR_INT_KER) != 0)
532 EFSYS_ERR(enp->en_esip, EFX_ERR_ILL_ADDR, 0, 0);
534 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0)
535 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_PERR,
536 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
537 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
549 /* Clear the interrupt address register */
550 EFX_ZERO_OWORD(oword);
551 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
554 #endif /* EFSYS_OPT_SIENA */