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 */
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 __checkReturn efx_rc_t
95 __in efx_intr_type_t type,
96 __in_opt 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 if ((esmp == NULL) || (EFSYS_MEM_SIZE(esmp) < EFX_INTR_SIZE)) {
300 * bug17213 workaround.
302 * Under legacy interrupts, don't share a level between fatal
303 * interrupts and event queue interrupts. Under MSI-X, they
304 * must share, or we won't get an interrupt.
306 if (enp->en_family == EFX_FAMILY_SIENA &&
307 eip->ei_type == EFX_INTR_LINE)
308 eip->ei_level = 0x1f;
312 /* Enable all the genuinely fatal interrupts */
313 EFX_SET_OWORD(oword);
314 EFX_SET_OWORD_FIELD(oword, FRF_AZ_ILL_ADR_INT_KER_EN, 0);
315 EFX_SET_OWORD_FIELD(oword, FRF_AZ_RBUF_OWN_INT_KER_EN, 0);
316 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TBUF_OWN_INT_KER_EN, 0);
317 if (enp->en_family >= EFX_FAMILY_SIENA)
318 EFX_SET_OWORD_FIELD(oword, FRF_CZ_SRAM_PERR_INT_P_KER_EN, 0);
319 EFX_BAR_WRITEO(enp, FR_AZ_FATAL_INTR_REG_KER, &oword);
321 /* Set up the interrupt address register */
322 EFX_POPULATE_OWORD_3(oword,
323 FRF_AZ_NORM_INT_VEC_DIS_KER, (type == EFX_INTR_MESSAGE) ? 1 : 0,
324 FRF_AZ_INT_ADR_KER_DW0, EFSYS_MEM_ADDR(esmp) & 0xffffffff,
325 FRF_AZ_INT_ADR_KER_DW1, EFSYS_MEM_ADDR(esmp) >> 32);
326 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
331 EFSYS_PROBE1(fail1, efx_rc_t, rc);
340 efx_intr_t *eip = &(enp->en_intr);
343 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
345 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
346 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 1);
347 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
356 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
357 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
358 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
364 siena_intr_disable_unlocked(
369 EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
371 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
372 EFSYS_BAR_WRITEO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
376 static __checkReturn efx_rc_t
379 __in unsigned int level)
381 efx_intr_t *eip = &(enp->en_intr);
387 /* bug16757: No event queues can be initialized */
388 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
390 if (level >= EFX_NINTR_SIENA) {
395 if (level > EFX_MASK32(FRF_AZ_KER_INT_LEVE_SEL))
396 return (ENOTSUP); /* avoid EFSYS_PROBE() */
400 /* Trigger a test interrupt */
401 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
402 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, sel);
403 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER, 1);
404 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
407 * Wait up to 100ms for the interrupt to be raised before restoring
408 * KER_INT_LEVE_SEL. Ignore a failure to raise (the caller will
409 * observe this soon enough anyway), but always reset KER_INT_LEVE_SEL
413 EFSYS_SPIN(100); /* 100us */
415 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
416 } while (EFX_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER) && ++count < 1000);
418 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
419 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
424 EFSYS_PROBE1(fail1, efx_rc_t, rc);
429 static __checkReturn boolean_t
430 siena_intr_check_fatal(
433 efx_intr_t *eip = &(enp->en_intr);
434 efsys_mem_t *esmp = eip->ei_esmp;
437 /* Read the syndrome */
438 EFSYS_MEM_READO(esmp, 0, &oword);
440 if (EFX_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT) != 0) {
443 /* Clear the fatal interrupt condition */
444 EFX_SET_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT, 0);
445 EFSYS_MEM_WRITEO(esmp, 0, &oword);
454 siena_intr_status_line(
456 __out boolean_t *fatalp,
457 __out uint32_t *qmaskp)
459 efx_intr_t *eip = &(enp->en_intr);
462 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
463 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
466 * Read the queue mask and implicitly acknowledge the
469 EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE);
470 *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
472 EFSYS_PROBE1(qmask, uint32_t, *qmaskp);
474 if (*qmaskp & (1U << eip->ei_level))
475 *fatalp = siena_intr_check_fatal(enp);
481 siena_intr_status_message(
483 __in unsigned int message,
484 __out boolean_t *fatalp)
486 efx_intr_t *eip = &(enp->en_intr);
488 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
489 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
491 if (message == eip->ei_level)
492 *fatalp = siena_intr_check_fatal(enp);
502 #if EFSYS_OPT_DECODE_INTR_FATAL
506 EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal);
507 EFX_ZERO_OWORD(mem_per);
509 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0 ||
510 EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
511 EFX_BAR_READO(enp, FR_AZ_MEM_STAT_REG, &mem_per);
513 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRAM_OOB_INT_KER) != 0)
514 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_OOB, 0, 0);
516 if (EFX_OWORD_FIELD(fatal, FRF_AZ_BUFID_DC_OOB_INT_KER) != 0)
517 EFSYS_ERR(enp->en_esip, EFX_ERR_BUFID_DC_OOB, 0, 0);
519 if (EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
520 EFSYS_ERR(enp->en_esip, EFX_ERR_MEM_PERR,
521 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
522 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
524 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RBUF_OWN_INT_KER) != 0)
525 EFSYS_ERR(enp->en_esip, EFX_ERR_RBUF_OWN, 0, 0);
527 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TBUF_OWN_INT_KER) != 0)
528 EFSYS_ERR(enp->en_esip, EFX_ERR_TBUF_OWN, 0, 0);
530 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RDESCQ_OWN_INT_KER) != 0)
531 EFSYS_ERR(enp->en_esip, EFX_ERR_RDESQ_OWN, 0, 0);
533 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TDESCQ_OWN_INT_KER) != 0)
534 EFSYS_ERR(enp->en_esip, EFX_ERR_TDESQ_OWN, 0, 0);
536 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVQ_OWN_INT_KER) != 0)
537 EFSYS_ERR(enp->en_esip, EFX_ERR_EVQ_OWN, 0, 0);
539 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVF_OFLO_INT_KER) != 0)
540 EFSYS_ERR(enp->en_esip, EFX_ERR_EVFF_OFLO, 0, 0);
542 if (EFX_OWORD_FIELD(fatal, FRF_AZ_ILL_ADR_INT_KER) != 0)
543 EFSYS_ERR(enp->en_esip, EFX_ERR_ILL_ADDR, 0, 0);
545 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0)
546 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_PERR,
547 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
548 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
560 /* Clear the interrupt address register */
561 EFX_ZERO_OWORD(oword);
562 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
565 #endif /* EFSYS_OPT_SIENA */