1/*- 2 * Copyright (c) 2012-2016 Solarflare Communications Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * The views and conclusions contained in the software and documentation are 27 * those of the authors and should not be interpreted as representing official 28 * policies, either expressed or implied, of the FreeBSD Project. 29 */ 30 31#include <sys/cdefs.h> 32#include "efx.h" 33#include "efx_impl.h" 34 35#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 36 37 __checkReturn efx_rc_t 38ef10_intr_init( 39 __in efx_nic_t *enp, 40 __in efx_intr_type_t type, 41 __in efsys_mem_t *esmp) 42{ 43 _NOTE(ARGUNUSED(enp, type, esmp)) 44 return (0); 45} 46 47 void 48ef10_intr_enable( 49 __in efx_nic_t *enp) 50{ 51 _NOTE(ARGUNUSED(enp)) 52} 53 54 void 55ef10_intr_disable( 56 __in efx_nic_t *enp) 57{ 58 _NOTE(ARGUNUSED(enp)) 59} 60 61 void 62ef10_intr_disable_unlocked( 63 __in efx_nic_t *enp) 64{ 65 _NOTE(ARGUNUSED(enp)) 66} 67 68static __checkReturn efx_rc_t 69efx_mcdi_trigger_interrupt( 70 __in efx_nic_t *enp, 71 __in unsigned int level) 72{ 73 efx_mcdi_req_t req; 74 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_TRIGGER_INTERRUPT_IN_LEN, 75 MC_CMD_TRIGGER_INTERRUPT_OUT_LEN); 76 efx_rc_t rc; 77 78 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 79 enp->en_family == EFX_FAMILY_MEDFORD || 80 enp->en_family == EFX_FAMILY_MEDFORD2); 81 82 if (level >= enp->en_nic_cfg.enc_intr_limit) { 83 rc = EINVAL; 84 goto fail1; 85 } 86 87 req.emr_cmd = MC_CMD_TRIGGER_INTERRUPT; 88 req.emr_in_buf = payload; 89 req.emr_in_length = MC_CMD_TRIGGER_INTERRUPT_IN_LEN; 90 req.emr_out_buf = payload; 91 req.emr_out_length = MC_CMD_TRIGGER_INTERRUPT_OUT_LEN; 92 93 MCDI_IN_SET_DWORD(req, TRIGGER_INTERRUPT_IN_INTR_LEVEL, level); 94 95 efx_mcdi_execute(enp, &req); 96 97 if (req.emr_rc != 0) { 98 rc = req.emr_rc; 99 goto fail2; 100 } 101 102 return (0); 103 104fail2: 105 EFSYS_PROBE(fail2); 106 107fail1: 108 EFSYS_PROBE1(fail1, efx_rc_t, rc); 109 110 return (rc); 111} 112 113 __checkReturn efx_rc_t 114ef10_intr_trigger( 115 __in efx_nic_t *enp, 116 __in unsigned int level) 117{ 118 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 119 efx_rc_t rc; 120 121 if (encp->enc_bug41750_workaround) { 122 /* 123 * bug 41750: Test interrupts don't work on Greenport 124 * bug 50084: Test interrupts don't work on VFs 125 */ 126 rc = ENOTSUP; 127 goto fail1; 128 } 129 130 if ((rc = efx_mcdi_trigger_interrupt(enp, level)) != 0) 131 goto fail2; 132 133 return (0); 134 135fail2: 136 EFSYS_PROBE(fail2); 137fail1: 138 EFSYS_PROBE1(fail1, efx_rc_t, rc); 139 140 return (rc); 141} 142 143 void 144ef10_intr_status_line( 145 __in efx_nic_t *enp, 146 __out boolean_t *fatalp, 147 __out uint32_t *qmaskp) 148{ 149 efx_dword_t dword; 150 151 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 152 enp->en_family == EFX_FAMILY_MEDFORD || 153 enp->en_family == EFX_FAMILY_MEDFORD2); 154 155 /* Read the queue mask and implicitly acknowledge the interrupt. */ 156 EFX_BAR_READD(enp, ER_DZ_BIU_INT_ISR_REG, &dword, B_FALSE); 157 *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0); 158 159 EFSYS_PROBE1(qmask, uint32_t, *qmaskp); 160 161 *fatalp = B_FALSE; 162} 163 164 void 165ef10_intr_status_message( 166 __in efx_nic_t *enp, 167 __in unsigned int message, 168 __out boolean_t *fatalp) 169{ 170 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 171 enp->en_family == EFX_FAMILY_MEDFORD || 172 enp->en_family == EFX_FAMILY_MEDFORD2); 173 174 _NOTE(ARGUNUSED(enp, message)) 175 176 /* EF10 fatal errors are reported via events */ 177 *fatalp = B_FALSE; 178} 179 180 void 181ef10_intr_fatal( 182 __in efx_nic_t *enp) 183{ 184 /* EF10 fatal errors are reported via events */ 185 _NOTE(ARGUNUSED(enp)) 186} 187 188 void 189ef10_intr_fini( 190 __in efx_nic_t *enp) 191{ 192 _NOTE(ARGUNUSED(enp)) 193} 194 195#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */ 196