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
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 */
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 */
136 EFSYS_ASSERT(B_FALSE);
141 if ((rc = eiop->eio_init(enp, type, esmp)) != 0)
153 EFSYS_PROBE1(fail1, efx_rc_t, rc);
162 efx_intr_t *eip = &(enp->en_intr);
163 const efx_intr_ops_t *eiop = eip->ei_eiop;
165 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
166 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
167 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
171 enp->en_mod_flags &= ~EFX_MOD_INTR;
178 efx_intr_t *eip = &(enp->en_intr);
179 const efx_intr_ops_t *eiop = eip->ei_eiop;
181 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
182 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
184 eiop->eio_enable(enp);
191 efx_intr_t *eip = &(enp->en_intr);
192 const efx_intr_ops_t *eiop = eip->ei_eiop;
194 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
195 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
197 eiop->eio_disable(enp);
201 efx_intr_disable_unlocked(
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_disable_unlocked(enp);
214 __checkReturn efx_rc_t
217 __in unsigned int level)
219 efx_intr_t *eip = &(enp->en_intr);
220 const efx_intr_ops_t *eiop = eip->ei_eiop;
222 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
223 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
225 return (eiop->eio_trigger(enp, level));
229 efx_intr_status_line(
231 __out boolean_t *fatalp,
232 __out uint32_t *qmaskp)
234 efx_intr_t *eip = &(enp->en_intr);
235 const efx_intr_ops_t *eiop = eip->ei_eiop;
237 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
238 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
240 eiop->eio_status_line(enp, fatalp, qmaskp);
244 efx_intr_status_message(
246 __in unsigned int message,
247 __out boolean_t *fatalp)
249 efx_intr_t *eip = &(enp->en_intr);
250 const efx_intr_ops_t *eiop = eip->ei_eiop;
252 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
253 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
255 eiop->eio_status_message(enp, message, fatalp);
262 efx_intr_t *eip = &(enp->en_intr);
263 const efx_intr_ops_t *eiop = eip->ei_eiop;
265 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
266 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
268 eiop->eio_fatal(enp);
272 /* ************************************************************************* */
273 /* ************************************************************************* */
274 /* ************************************************************************* */
278 static __checkReturn efx_rc_t
281 __in efx_intr_type_t type,
282 __in efsys_mem_t *esmp)
284 efx_intr_t *eip = &(enp->en_intr);
288 * bug17213 workaround.
290 * Under legacy interrupts, don't share a level between fatal
291 * interrupts and event queue interrupts. Under MSI-X, they
292 * must share, or we won't get an interrupt.
294 if (enp->en_family == EFX_FAMILY_SIENA &&
295 eip->ei_type == EFX_INTR_LINE)
296 eip->ei_level = 0x1f;
300 /* Enable all the genuinely fatal interrupts */
301 EFX_SET_OWORD(oword);
302 EFX_SET_OWORD_FIELD(oword, FRF_AZ_ILL_ADR_INT_KER_EN, 0);
303 EFX_SET_OWORD_FIELD(oword, FRF_AZ_RBUF_OWN_INT_KER_EN, 0);
304 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TBUF_OWN_INT_KER_EN, 0);
305 if (enp->en_family >= EFX_FAMILY_SIENA)
306 EFX_SET_OWORD_FIELD(oword, FRF_CZ_SRAM_PERR_INT_P_KER_EN, 0);
307 EFX_BAR_WRITEO(enp, FR_AZ_FATAL_INTR_REG_KER, &oword);
309 /* Set up the interrupt address register */
310 EFX_POPULATE_OWORD_3(oword,
311 FRF_AZ_NORM_INT_VEC_DIS_KER, (type == EFX_INTR_MESSAGE) ? 1 : 0,
312 FRF_AZ_INT_ADR_KER_DW0, EFSYS_MEM_ADDR(esmp) & 0xffffffff,
313 FRF_AZ_INT_ADR_KER_DW1, EFSYS_MEM_ADDR(esmp) >> 32);
314 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
323 efx_intr_t *eip = &(enp->en_intr);
326 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
328 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
329 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 1);
330 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
339 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
340 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
341 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
347 siena_intr_disable_unlocked(
352 EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
354 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
355 EFSYS_BAR_WRITEO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
359 static __checkReturn efx_rc_t
362 __in unsigned int level)
364 efx_intr_t *eip = &(enp->en_intr);
370 /* bug16757: No event queues can be initialized */
371 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
373 if (level >= EFX_NINTR_SIENA) {
378 if (level > EFX_MASK32(FRF_AZ_KER_INT_LEVE_SEL))
379 return (ENOTSUP); /* avoid EFSYS_PROBE() */
383 /* Trigger a test interrupt */
384 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
385 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, sel);
386 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER, 1);
387 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
390 * Wait up to 100ms for the interrupt to be raised before restoring
391 * KER_INT_LEVE_SEL. Ignore a failure to raise (the caller will
392 * observe this soon enough anyway), but always reset KER_INT_LEVE_SEL
396 EFSYS_SPIN(100); /* 100us */
398 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
399 } while (EFX_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER) && ++count < 1000);
401 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
402 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
407 EFSYS_PROBE1(fail1, efx_rc_t, rc);
412 static __checkReturn boolean_t
413 siena_intr_check_fatal(
416 efx_intr_t *eip = &(enp->en_intr);
417 efsys_mem_t *esmp = eip->ei_esmp;
420 /* Read the syndrome */
421 EFSYS_MEM_READO(esmp, 0, &oword);
423 if (EFX_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT) != 0) {
426 /* Clear the fatal interrupt condition */
427 EFX_SET_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT, 0);
428 EFSYS_MEM_WRITEO(esmp, 0, &oword);
437 siena_intr_status_line(
439 __out boolean_t *fatalp,
440 __out uint32_t *qmaskp)
442 efx_intr_t *eip = &(enp->en_intr);
445 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
446 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
449 * Read the queue mask and implicitly acknowledge the
452 EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE);
453 *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
455 EFSYS_PROBE1(qmask, uint32_t, *qmaskp);
457 if (*qmaskp & (1U << eip->ei_level))
458 *fatalp = siena_intr_check_fatal(enp);
464 siena_intr_status_message(
466 __in unsigned int message,
467 __out boolean_t *fatalp)
469 efx_intr_t *eip = &(enp->en_intr);
471 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
472 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
474 if (message == eip->ei_level)
475 *fatalp = siena_intr_check_fatal(enp);
485 #if EFSYS_OPT_DECODE_INTR_FATAL
489 EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal);
490 EFX_ZERO_OWORD(mem_per);
492 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0 ||
493 EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
494 EFX_BAR_READO(enp, FR_AZ_MEM_STAT_REG, &mem_per);
496 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRAM_OOB_INT_KER) != 0)
497 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_OOB, 0, 0);
499 if (EFX_OWORD_FIELD(fatal, FRF_AZ_BUFID_DC_OOB_INT_KER) != 0)
500 EFSYS_ERR(enp->en_esip, EFX_ERR_BUFID_DC_OOB, 0, 0);
502 if (EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
503 EFSYS_ERR(enp->en_esip, EFX_ERR_MEM_PERR,
504 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
505 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
507 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RBUF_OWN_INT_KER) != 0)
508 EFSYS_ERR(enp->en_esip, EFX_ERR_RBUF_OWN, 0, 0);
510 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TBUF_OWN_INT_KER) != 0)
511 EFSYS_ERR(enp->en_esip, EFX_ERR_TBUF_OWN, 0, 0);
513 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RDESCQ_OWN_INT_KER) != 0)
514 EFSYS_ERR(enp->en_esip, EFX_ERR_RDESQ_OWN, 0, 0);
516 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TDESCQ_OWN_INT_KER) != 0)
517 EFSYS_ERR(enp->en_esip, EFX_ERR_TDESQ_OWN, 0, 0);
519 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVQ_OWN_INT_KER) != 0)
520 EFSYS_ERR(enp->en_esip, EFX_ERR_EVQ_OWN, 0, 0);
522 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVF_OFLO_INT_KER) != 0)
523 EFSYS_ERR(enp->en_esip, EFX_ERR_EVFF_OFLO, 0, 0);
525 if (EFX_OWORD_FIELD(fatal, FRF_AZ_ILL_ADR_INT_KER) != 0)
526 EFSYS_ERR(enp->en_esip, EFX_ERR_ILL_ADDR, 0, 0);
528 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0)
529 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_PERR,
530 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
531 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
543 /* Clear the interrupt address register */
544 EFX_ZERO_OWORD(oword);
545 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
548 #endif /* EFSYS_OPT_SIENA */