15e111ed8SAndrew Rybchenko /* SPDX-License-Identifier: BSD-3-Clause
25e111ed8SAndrew Rybchenko *
3*672386c1SAndrew Rybchenko * Copyright(c) 2019-2021 Xilinx, Inc.
45e111ed8SAndrew Rybchenko * Copyright(c) 2012-2019 Solarflare Communications Inc.
55e111ed8SAndrew Rybchenko */
65e111ed8SAndrew Rybchenko
75e111ed8SAndrew Rybchenko #include "efx.h"
85e111ed8SAndrew Rybchenko #include "efx_impl.h"
95e111ed8SAndrew Rybchenko
105e111ed8SAndrew Rybchenko
115e111ed8SAndrew Rybchenko #if EFX_OPTS_EF10()
125e111ed8SAndrew Rybchenko
135e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_intr_init(__in efx_nic_t * enp,__in efx_intr_type_t type,__in efsys_mem_t * esmp)145e111ed8SAndrew Rybchenko ef10_intr_init(
155e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
165e111ed8SAndrew Rybchenko __in efx_intr_type_t type,
175e111ed8SAndrew Rybchenko __in efsys_mem_t *esmp)
185e111ed8SAndrew Rybchenko {
195e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(enp, type, esmp))
205e111ed8SAndrew Rybchenko return (0);
215e111ed8SAndrew Rybchenko }
225e111ed8SAndrew Rybchenko
235e111ed8SAndrew Rybchenko
245e111ed8SAndrew Rybchenko void
ef10_intr_enable(__in efx_nic_t * enp)255e111ed8SAndrew Rybchenko ef10_intr_enable(
265e111ed8SAndrew Rybchenko __in efx_nic_t *enp)
275e111ed8SAndrew Rybchenko {
285e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(enp))
295e111ed8SAndrew Rybchenko }
305e111ed8SAndrew Rybchenko
315e111ed8SAndrew Rybchenko
325e111ed8SAndrew Rybchenko void
ef10_intr_disable(__in efx_nic_t * enp)335e111ed8SAndrew Rybchenko ef10_intr_disable(
345e111ed8SAndrew Rybchenko __in efx_nic_t *enp)
355e111ed8SAndrew Rybchenko {
365e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(enp))
375e111ed8SAndrew Rybchenko }
385e111ed8SAndrew Rybchenko
395e111ed8SAndrew Rybchenko
405e111ed8SAndrew Rybchenko void
ef10_intr_disable_unlocked(__in efx_nic_t * enp)415e111ed8SAndrew Rybchenko ef10_intr_disable_unlocked(
425e111ed8SAndrew Rybchenko __in efx_nic_t *enp)
435e111ed8SAndrew Rybchenko {
445e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(enp))
455e111ed8SAndrew Rybchenko }
465e111ed8SAndrew Rybchenko
475e111ed8SAndrew Rybchenko
485e111ed8SAndrew Rybchenko static __checkReturn efx_rc_t
efx_mcdi_trigger_interrupt(__in efx_nic_t * enp,__in unsigned int level)495e111ed8SAndrew Rybchenko efx_mcdi_trigger_interrupt(
505e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
515e111ed8SAndrew Rybchenko __in unsigned int level)
525e111ed8SAndrew Rybchenko {
535e111ed8SAndrew Rybchenko efx_mcdi_req_t req;
545e111ed8SAndrew Rybchenko EFX_MCDI_DECLARE_BUF(payload, MC_CMD_TRIGGER_INTERRUPT_IN_LEN,
555e111ed8SAndrew Rybchenko MC_CMD_TRIGGER_INTERRUPT_OUT_LEN);
565e111ed8SAndrew Rybchenko efx_rc_t rc;
575e111ed8SAndrew Rybchenko
585e111ed8SAndrew Rybchenko EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
595e111ed8SAndrew Rybchenko
605e111ed8SAndrew Rybchenko if (level >= enp->en_nic_cfg.enc_intr_limit) {
615e111ed8SAndrew Rybchenko rc = EINVAL;
625e111ed8SAndrew Rybchenko goto fail1;
635e111ed8SAndrew Rybchenko }
645e111ed8SAndrew Rybchenko
655e111ed8SAndrew Rybchenko req.emr_cmd = MC_CMD_TRIGGER_INTERRUPT;
665e111ed8SAndrew Rybchenko req.emr_in_buf = payload;
675e111ed8SAndrew Rybchenko req.emr_in_length = MC_CMD_TRIGGER_INTERRUPT_IN_LEN;
685e111ed8SAndrew Rybchenko req.emr_out_buf = payload;
695e111ed8SAndrew Rybchenko req.emr_out_length = MC_CMD_TRIGGER_INTERRUPT_OUT_LEN;
705e111ed8SAndrew Rybchenko
715e111ed8SAndrew Rybchenko MCDI_IN_SET_DWORD(req, TRIGGER_INTERRUPT_IN_INTR_LEVEL, level);
725e111ed8SAndrew Rybchenko
735e111ed8SAndrew Rybchenko efx_mcdi_execute(enp, &req);
745e111ed8SAndrew Rybchenko
755e111ed8SAndrew Rybchenko if (req.emr_rc != 0) {
765e111ed8SAndrew Rybchenko rc = req.emr_rc;
775e111ed8SAndrew Rybchenko goto fail2;
785e111ed8SAndrew Rybchenko }
795e111ed8SAndrew Rybchenko
805e111ed8SAndrew Rybchenko return (0);
815e111ed8SAndrew Rybchenko
825e111ed8SAndrew Rybchenko fail2:
835e111ed8SAndrew Rybchenko EFSYS_PROBE(fail2);
845e111ed8SAndrew Rybchenko
855e111ed8SAndrew Rybchenko fail1:
865e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
875e111ed8SAndrew Rybchenko
885e111ed8SAndrew Rybchenko return (rc);
895e111ed8SAndrew Rybchenko }
905e111ed8SAndrew Rybchenko
915e111ed8SAndrew Rybchenko __checkReturn efx_rc_t
ef10_intr_trigger(__in efx_nic_t * enp,__in unsigned int level)925e111ed8SAndrew Rybchenko ef10_intr_trigger(
935e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
945e111ed8SAndrew Rybchenko __in unsigned int level)
955e111ed8SAndrew Rybchenko {
965e111ed8SAndrew Rybchenko efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
975e111ed8SAndrew Rybchenko efx_rc_t rc;
985e111ed8SAndrew Rybchenko
995e111ed8SAndrew Rybchenko if (encp->enc_bug41750_workaround) {
1005e111ed8SAndrew Rybchenko /*
1015e111ed8SAndrew Rybchenko * bug 41750: Test interrupts don't work on Greenport
1025e111ed8SAndrew Rybchenko * bug 50084: Test interrupts don't work on VFs
1035e111ed8SAndrew Rybchenko */
1045e111ed8SAndrew Rybchenko rc = ENOTSUP;
1055e111ed8SAndrew Rybchenko goto fail1;
1065e111ed8SAndrew Rybchenko }
1075e111ed8SAndrew Rybchenko
1085e111ed8SAndrew Rybchenko if ((rc = efx_mcdi_trigger_interrupt(enp, level)) != 0)
1095e111ed8SAndrew Rybchenko goto fail2;
1105e111ed8SAndrew Rybchenko
1115e111ed8SAndrew Rybchenko return (0);
1125e111ed8SAndrew Rybchenko
1135e111ed8SAndrew Rybchenko fail2:
1145e111ed8SAndrew Rybchenko EFSYS_PROBE(fail2);
1155e111ed8SAndrew Rybchenko fail1:
1165e111ed8SAndrew Rybchenko EFSYS_PROBE1(fail1, efx_rc_t, rc);
1175e111ed8SAndrew Rybchenko
1185e111ed8SAndrew Rybchenko return (rc);
1195e111ed8SAndrew Rybchenko }
1205e111ed8SAndrew Rybchenko
1215e111ed8SAndrew Rybchenko void
ef10_intr_status_line(__in efx_nic_t * enp,__out boolean_t * fatalp,__out uint32_t * qmaskp)1225e111ed8SAndrew Rybchenko ef10_intr_status_line(
1235e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
1245e111ed8SAndrew Rybchenko __out boolean_t *fatalp,
1255e111ed8SAndrew Rybchenko __out uint32_t *qmaskp)
1265e111ed8SAndrew Rybchenko {
1275e111ed8SAndrew Rybchenko efx_dword_t dword;
1285e111ed8SAndrew Rybchenko
1295e111ed8SAndrew Rybchenko EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
1305e111ed8SAndrew Rybchenko
1315e111ed8SAndrew Rybchenko /* Read the queue mask and implicitly acknowledge the interrupt. */
1325e111ed8SAndrew Rybchenko EFX_BAR_READD(enp, ER_DZ_BIU_INT_ISR_REG, &dword, B_FALSE);
1335e111ed8SAndrew Rybchenko *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
1345e111ed8SAndrew Rybchenko
1355e111ed8SAndrew Rybchenko EFSYS_PROBE1(qmask, uint32_t, *qmaskp);
1365e111ed8SAndrew Rybchenko
1375e111ed8SAndrew Rybchenko *fatalp = B_FALSE;
1385e111ed8SAndrew Rybchenko }
1395e111ed8SAndrew Rybchenko
1405e111ed8SAndrew Rybchenko void
ef10_intr_status_message(__in efx_nic_t * enp,__in unsigned int message,__out boolean_t * fatalp)1415e111ed8SAndrew Rybchenko ef10_intr_status_message(
1425e111ed8SAndrew Rybchenko __in efx_nic_t *enp,
1435e111ed8SAndrew Rybchenko __in unsigned int message,
1445e111ed8SAndrew Rybchenko __out boolean_t *fatalp)
1455e111ed8SAndrew Rybchenko {
1465e111ed8SAndrew Rybchenko EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
1475e111ed8SAndrew Rybchenko
1485e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(enp, message))
1495e111ed8SAndrew Rybchenko
1505e111ed8SAndrew Rybchenko /* EF10 fatal errors are reported via events */
1515e111ed8SAndrew Rybchenko *fatalp = B_FALSE;
1525e111ed8SAndrew Rybchenko }
1535e111ed8SAndrew Rybchenko
1545e111ed8SAndrew Rybchenko void
ef10_intr_fatal(__in efx_nic_t * enp)1555e111ed8SAndrew Rybchenko ef10_intr_fatal(
1565e111ed8SAndrew Rybchenko __in efx_nic_t *enp)
1575e111ed8SAndrew Rybchenko {
1585e111ed8SAndrew Rybchenko /* EF10 fatal errors are reported via events */
1595e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(enp))
1605e111ed8SAndrew Rybchenko }
1615e111ed8SAndrew Rybchenko
1625e111ed8SAndrew Rybchenko void
ef10_intr_fini(__in efx_nic_t * enp)1635e111ed8SAndrew Rybchenko ef10_intr_fini(
1645e111ed8SAndrew Rybchenko __in efx_nic_t *enp)
1655e111ed8SAndrew Rybchenko {
1665e111ed8SAndrew Rybchenko _NOTE(ARGUNUSED(enp))
1675e111ed8SAndrew Rybchenko }
1685e111ed8SAndrew Rybchenko
1695e111ed8SAndrew Rybchenko #endif /* EFX_OPTS_EF10() */
170