1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright(c) 2019-2021 Xilinx, Inc. 4 * Copyright(c) 2012-2019 Solarflare Communications Inc. 5 */ 6 7 #include "efx.h" 8 #include "efx_impl.h" 9 10 11 #if EFX_OPTS_EF10() 12 13 __checkReturn efx_rc_t 14 ef10_intr_init( 15 __in efx_nic_t *enp, 16 __in efx_intr_type_t type, 17 __in efsys_mem_t *esmp) 18 { 19 _NOTE(ARGUNUSED(enp, type, esmp)) 20 return (0); 21 } 22 23 24 void 25 ef10_intr_enable( 26 __in efx_nic_t *enp) 27 { 28 _NOTE(ARGUNUSED(enp)) 29 } 30 31 32 void 33 ef10_intr_disable( 34 __in efx_nic_t *enp) 35 { 36 _NOTE(ARGUNUSED(enp)) 37 } 38 39 40 void 41 ef10_intr_disable_unlocked( 42 __in efx_nic_t *enp) 43 { 44 _NOTE(ARGUNUSED(enp)) 45 } 46 47 48 static __checkReturn efx_rc_t 49 efx_mcdi_trigger_interrupt( 50 __in efx_nic_t *enp, 51 __in unsigned int level) 52 { 53 efx_mcdi_req_t req; 54 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_TRIGGER_INTERRUPT_IN_LEN, 55 MC_CMD_TRIGGER_INTERRUPT_OUT_LEN); 56 efx_rc_t rc; 57 58 EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp)); 59 60 if (level >= enp->en_nic_cfg.enc_intr_limit) { 61 rc = EINVAL; 62 goto fail1; 63 } 64 65 req.emr_cmd = MC_CMD_TRIGGER_INTERRUPT; 66 req.emr_in_buf = payload; 67 req.emr_in_length = MC_CMD_TRIGGER_INTERRUPT_IN_LEN; 68 req.emr_out_buf = payload; 69 req.emr_out_length = MC_CMD_TRIGGER_INTERRUPT_OUT_LEN; 70 71 MCDI_IN_SET_DWORD(req, TRIGGER_INTERRUPT_IN_INTR_LEVEL, level); 72 73 efx_mcdi_execute(enp, &req); 74 75 if (req.emr_rc != 0) { 76 rc = req.emr_rc; 77 goto fail2; 78 } 79 80 return (0); 81 82 fail2: 83 EFSYS_PROBE(fail2); 84 85 fail1: 86 EFSYS_PROBE1(fail1, efx_rc_t, rc); 87 88 return (rc); 89 } 90 91 __checkReturn efx_rc_t 92 ef10_intr_trigger( 93 __in efx_nic_t *enp, 94 __in unsigned int level) 95 { 96 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 97 efx_rc_t rc; 98 99 if (encp->enc_bug41750_workaround) { 100 /* 101 * bug 41750: Test interrupts don't work on Greenport 102 * bug 50084: Test interrupts don't work on VFs 103 */ 104 rc = ENOTSUP; 105 goto fail1; 106 } 107 108 if ((rc = efx_mcdi_trigger_interrupt(enp, level)) != 0) 109 goto fail2; 110 111 return (0); 112 113 fail2: 114 EFSYS_PROBE(fail2); 115 fail1: 116 EFSYS_PROBE1(fail1, efx_rc_t, rc); 117 118 return (rc); 119 } 120 121 void 122 ef10_intr_status_line( 123 __in efx_nic_t *enp, 124 __out boolean_t *fatalp, 125 __out uint32_t *qmaskp) 126 { 127 efx_dword_t dword; 128 129 EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp)); 130 131 /* Read the queue mask and implicitly acknowledge the interrupt. */ 132 EFX_BAR_READD(enp, ER_DZ_BIU_INT_ISR_REG, &dword, B_FALSE); 133 *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0); 134 135 EFSYS_PROBE1(qmask, uint32_t, *qmaskp); 136 137 *fatalp = B_FALSE; 138 } 139 140 void 141 ef10_intr_status_message( 142 __in efx_nic_t *enp, 143 __in unsigned int message, 144 __out boolean_t *fatalp) 145 { 146 EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp)); 147 148 _NOTE(ARGUNUSED(enp, message)) 149 150 /* EF10 fatal errors are reported via events */ 151 *fatalp = B_FALSE; 152 } 153 154 void 155 ef10_intr_fatal( 156 __in efx_nic_t *enp) 157 { 158 /* EF10 fatal errors are reported via events */ 159 _NOTE(ARGUNUSED(enp)) 160 } 161 162 void 163 ef10_intr_fini( 164 __in efx_nic_t *enp) 165 { 166 _NOTE(ARGUNUSED(enp)) 167 } 168 169 #endif /* EFX_OPTS_EF10() */ 170