1283514Sarybchik/*- 2300607Sarybchik * Copyright (c) 2012-2016 Solarflare Communications Inc. 3283514Sarybchik * All rights reserved. 4283514Sarybchik * 5283514Sarybchik * Redistribution and use in source and binary forms, with or without 6283514Sarybchik * modification, are permitted provided that the following conditions are met: 7283514Sarybchik * 8283514Sarybchik * 1. Redistributions of source code must retain the above copyright notice, 9283514Sarybchik * this list of conditions and the following disclaimer. 10283514Sarybchik * 2. Redistributions in binary form must reproduce the above copyright notice, 11283514Sarybchik * this list of conditions and the following disclaimer in the documentation 12283514Sarybchik * and/or other materials provided with the distribution. 13283514Sarybchik * 14283514Sarybchik * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15283514Sarybchik * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16283514Sarybchik * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17283514Sarybchik * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18283514Sarybchik * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19283514Sarybchik * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20283514Sarybchik * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21283514Sarybchik * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22283514Sarybchik * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23283514Sarybchik * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 24283514Sarybchik * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25283514Sarybchik * 26283514Sarybchik * The views and conclusions contained in the software and documentation are 27283514Sarybchik * those of the authors and should not be interpreted as representing official 28283514Sarybchik * policies, either expressed or implied, of the FreeBSD Project. 29283514Sarybchik */ 30283514Sarybchik 31283514Sarybchik#include <sys/cdefs.h> 32283514Sarybchik__FBSDID("$FreeBSD: stable/11/sys/dev/sfxge/common/ef10_intr.c 342445 2018-12-25 07:27:45Z arybchik $"); 33283514Sarybchik 34283514Sarybchik#include "efx.h" 35283514Sarybchik#include "efx_impl.h" 36283514Sarybchik 37283514Sarybchik 38299598Sarybchik#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD 39283514Sarybchik 40291436Sarybchik __checkReturn efx_rc_t 41293751Sarybchikef10_intr_init( 42283514Sarybchik __in efx_nic_t *enp, 43283514Sarybchik __in efx_intr_type_t type, 44283514Sarybchik __in efsys_mem_t *esmp) 45283514Sarybchik{ 46283514Sarybchik _NOTE(ARGUNUSED(enp, type, esmp)) 47283514Sarybchik return (0); 48283514Sarybchik} 49283514Sarybchik 50283514Sarybchik 51283514Sarybchik void 52293751Sarybchikef10_intr_enable( 53283514Sarybchik __in efx_nic_t *enp) 54283514Sarybchik{ 55283514Sarybchik _NOTE(ARGUNUSED(enp)) 56283514Sarybchik} 57283514Sarybchik 58283514Sarybchik 59283514Sarybchik void 60293751Sarybchikef10_intr_disable( 61283514Sarybchik __in efx_nic_t *enp) 62283514Sarybchik{ 63283514Sarybchik _NOTE(ARGUNUSED(enp)) 64283514Sarybchik} 65283514Sarybchik 66283514Sarybchik 67283514Sarybchik void 68293751Sarybchikef10_intr_disable_unlocked( 69283514Sarybchik __in efx_nic_t *enp) 70283514Sarybchik{ 71283514Sarybchik _NOTE(ARGUNUSED(enp)) 72283514Sarybchik} 73283514Sarybchik 74283514Sarybchik 75291436Sarybchikstatic __checkReturn efx_rc_t 76283514Sarybchikefx_mcdi_trigger_interrupt( 77283514Sarybchik __in efx_nic_t *enp, 78283514Sarybchik __in unsigned int level) 79283514Sarybchik{ 80283514Sarybchik efx_mcdi_req_t req; 81342445Sarybchik EFX_MCDI_DECLARE_BUF(payload, MC_CMD_TRIGGER_INTERRUPT_IN_LEN, 82342445Sarybchik MC_CMD_TRIGGER_INTERRUPT_OUT_LEN); 83291436Sarybchik efx_rc_t rc; 84283514Sarybchik 85293751Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 86293751Sarybchik enp->en_family == EFX_FAMILY_MEDFORD); 87283514Sarybchik 88283514Sarybchik if (level >= enp->en_nic_cfg.enc_intr_limit) { 89283514Sarybchik rc = EINVAL; 90283514Sarybchik goto fail1; 91283514Sarybchik } 92283514Sarybchik 93283514Sarybchik req.emr_cmd = MC_CMD_TRIGGER_INTERRUPT; 94283514Sarybchik req.emr_in_buf = payload; 95283514Sarybchik req.emr_in_length = MC_CMD_TRIGGER_INTERRUPT_IN_LEN; 96283514Sarybchik req.emr_out_buf = payload; 97283514Sarybchik req.emr_out_length = MC_CMD_TRIGGER_INTERRUPT_OUT_LEN; 98283514Sarybchik 99283514Sarybchik MCDI_IN_SET_DWORD(req, TRIGGER_INTERRUPT_IN_INTR_LEVEL, level); 100283514Sarybchik 101283514Sarybchik efx_mcdi_execute(enp, &req); 102283514Sarybchik 103283514Sarybchik if (req.emr_rc != 0) { 104283514Sarybchik rc = req.emr_rc; 105283514Sarybchik goto fail2; 106283514Sarybchik } 107283514Sarybchik 108283514Sarybchik return (0); 109283514Sarybchik 110283514Sarybchikfail2: 111283514Sarybchik EFSYS_PROBE(fail2); 112283514Sarybchik 113283514Sarybchikfail1: 114291436Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 115283514Sarybchik 116283514Sarybchik return (rc); 117283514Sarybchik} 118283514Sarybchik 119291436Sarybchik __checkReturn efx_rc_t 120293751Sarybchikef10_intr_trigger( 121283514Sarybchik __in efx_nic_t *enp, 122283514Sarybchik __in unsigned int level) 123283514Sarybchik{ 124283514Sarybchik efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 125291436Sarybchik efx_rc_t rc; 126283514Sarybchik 127283514Sarybchik if (encp->enc_bug41750_workaround) { 128293751Sarybchik /* 129293751Sarybchik * bug 41750: Test interrupts don't work on Greenport 130293751Sarybchik * bug 50084: Test interrupts don't work on VFs 131293751Sarybchik */ 132283514Sarybchik rc = ENOTSUP; 133283514Sarybchik goto fail1; 134283514Sarybchik } 135283514Sarybchik 136283514Sarybchik if ((rc = efx_mcdi_trigger_interrupt(enp, level)) != 0) 137283514Sarybchik goto fail2; 138283514Sarybchik 139283514Sarybchik return (0); 140283514Sarybchik 141283514Sarybchikfail2: 142283514Sarybchik EFSYS_PROBE(fail2); 143283514Sarybchikfail1: 144291436Sarybchik EFSYS_PROBE1(fail1, efx_rc_t, rc); 145283514Sarybchik 146283514Sarybchik return (rc); 147283514Sarybchik} 148283514Sarybchik 149293769Sarybchik void 150293769Sarybchikef10_intr_status_line( 151293769Sarybchik __in efx_nic_t *enp, 152293769Sarybchik __out boolean_t *fatalp, 153293769Sarybchik __out uint32_t *qmaskp) 154293769Sarybchik{ 155293769Sarybchik efx_dword_t dword; 156283514Sarybchik 157293769Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 158293769Sarybchik enp->en_family == EFX_FAMILY_MEDFORD); 159293769Sarybchik 160293769Sarybchik /* Read the queue mask and implicitly acknowledge the interrupt. */ 161293769Sarybchik EFX_BAR_READD(enp, ER_DZ_BIU_INT_ISR_REG, &dword, B_FALSE); 162293769Sarybchik *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0); 163293769Sarybchik 164293769Sarybchik EFSYS_PROBE1(qmask, uint32_t, *qmaskp); 165293769Sarybchik 166293769Sarybchik *fatalp = B_FALSE; 167293769Sarybchik} 168293769Sarybchik 169283514Sarybchik void 170293769Sarybchikef10_intr_status_message( 171293769Sarybchik __in efx_nic_t *enp, 172293769Sarybchik __in unsigned int message, 173293769Sarybchik __out boolean_t *fatalp) 174293769Sarybchik{ 175293769Sarybchik EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 176293769Sarybchik enp->en_family == EFX_FAMILY_MEDFORD); 177293769Sarybchik 178293769Sarybchik _NOTE(ARGUNUSED(enp, message)) 179293769Sarybchik 180293769Sarybchik /* EF10 fatal errors are reported via events */ 181293769Sarybchik *fatalp = B_FALSE; 182293769Sarybchik} 183293769Sarybchik 184293769Sarybchik void 185293769Sarybchikef10_intr_fatal( 186293769Sarybchik __in efx_nic_t *enp) 187293769Sarybchik{ 188293769Sarybchik /* EF10 fatal errors are reported via events */ 189293769Sarybchik _NOTE(ARGUNUSED(enp)) 190293769Sarybchik} 191293769Sarybchik 192293769Sarybchik void 193293751Sarybchikef10_intr_fini( 194283514Sarybchik __in efx_nic_t *enp) 195283514Sarybchik{ 196283514Sarybchik _NOTE(ARGUNUSED(enp)) 197283514Sarybchik} 198283514Sarybchik 199299598Sarybchik#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */ 200