2 * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
31 #include "efx_types.h"
38 __in efx_intr_type_t type,
39 __in efsys_mem_t *esmp)
41 efx_intr_t *eip = &(enp->en_intr);
45 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
46 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
48 if (enp->en_mod_flags & EFX_MOD_INTR) {
53 enp->en_mod_flags |= EFX_MOD_INTR;
59 * bug17213 workaround.
61 * Under legacy interrupts, don't share a level between fatal
62 * interrupts and event queue interrupts. Under MSI-X, they
63 * must share, or we won't get an interrupt.
65 if (enp->en_family == EFX_FAMILY_SIENA &&
66 eip->ei_type == EFX_INTR_LINE)
71 /* Enable all the genuinely fatal interrupts */
73 EFX_SET_OWORD_FIELD(oword, FRF_AZ_ILL_ADR_INT_KER_EN, 0);
74 EFX_SET_OWORD_FIELD(oword, FRF_AZ_RBUF_OWN_INT_KER_EN, 0);
75 EFX_SET_OWORD_FIELD(oword, FRF_AZ_TBUF_OWN_INT_KER_EN, 0);
76 if (enp->en_family >= EFX_FAMILY_SIENA)
77 EFX_SET_OWORD_FIELD(oword, FRF_CZ_SRAM_PERR_INT_P_KER_EN, 0);
78 EFX_BAR_WRITEO(enp, FR_AZ_FATAL_INTR_REG_KER, &oword);
80 /* Set up the interrupt address register */
81 EFX_POPULATE_OWORD_3(oword,
82 FRF_AZ_NORM_INT_VEC_DIS_KER, (type == EFX_INTR_MESSAGE) ? 1 : 0,
83 FRF_AZ_INT_ADR_KER_DW0, EFSYS_MEM_ADDR(esmp) & 0xffffffff,
84 FRF_AZ_INT_ADR_KER_DW1, EFSYS_MEM_ADDR(esmp) >> 32);
85 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
90 EFSYS_PROBE1(fail1, int, rc);
99 efx_intr_t *eip = &(enp->en_intr);
102 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
103 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
105 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
107 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
108 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 1);
109 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
118 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
119 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
121 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
122 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
123 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
129 efx_intr_disable_unlocked(
134 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
135 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
137 EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
139 EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
140 EFSYS_BAR_WRITEO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
147 __in unsigned int level)
149 efx_intr_t *eip = &(enp->en_intr);
155 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
156 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
158 /* bug16757: No event queues can be initialized */
159 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
161 switch (enp->en_family) {
162 case EFX_FAMILY_FALCON:
163 if (level > EFX_NINTR_FALCON) {
169 case EFX_FAMILY_SIENA:
170 if (level > EFX_NINTR_SIENA) {
177 EFSYS_ASSERT(B_FALSE);
181 if (level > EFX_MASK32(FRF_AZ_KER_INT_LEVE_SEL))
182 return (ENOTSUP); /* avoid EFSYS_PROBE() */
186 /* Trigger a test interrupt */
187 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
188 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, sel);
189 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER, 1);
190 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
193 * Wait up to 100ms for the interrupt to be raised before restoring
194 * KER_INT_LEVE_SEL. Ignore a failure to raise (the caller will
195 * observe this soon enough anyway), but always reset KER_INT_LEVE_SEL
199 EFSYS_SPIN(100); /* 100us */
201 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
202 } while (EFX_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER) && ++count < 1000);
204 EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
205 EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
210 EFSYS_PROBE1(fail1, int, rc);
215 static __checkReturn boolean_t
216 efx_intr_check_fatal(
219 efx_intr_t *eip = &(enp->en_intr);
220 efsys_mem_t *esmp = eip->ei_esmp;
223 /* Read the syndrome */
224 EFSYS_MEM_READO(esmp, 0, &oword);
226 if (EFX_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT) != 0) {
229 /* Clear the fatal interrupt condition */
230 EFX_SET_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT, 0);
231 EFSYS_MEM_WRITEO(esmp, 0, &oword);
240 efx_intr_status_line(
242 __out boolean_t *fatalp,
243 __out uint32_t *qmaskp)
245 efx_intr_t *eip = &(enp->en_intr);
248 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
249 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
252 * Read the queue mask and implicitly acknowledge the
255 EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE);
256 *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
258 EFSYS_PROBE1(qmask, uint32_t, *qmaskp);
260 if (*qmaskp & (1U << eip->ei_level))
261 *fatalp = efx_intr_check_fatal(enp);
267 efx_intr_status_message(
269 __in unsigned int message,
270 __out boolean_t *fatalp)
272 efx_intr_t *eip = &(enp->en_intr);
274 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
275 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
277 if (message == eip->ei_level)
278 *fatalp = efx_intr_check_fatal(enp);
287 #if EFSYS_OPT_DECODE_INTR_FATAL
291 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
292 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
294 EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal);
295 EFX_ZERO_OWORD(mem_per);
297 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0 ||
298 EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
299 EFX_BAR_READO(enp, FR_AZ_MEM_STAT_REG, &mem_per);
301 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRAM_OOB_INT_KER) != 0)
302 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_OOB, 0, 0);
304 if (EFX_OWORD_FIELD(fatal, FRF_AZ_BUFID_DC_OOB_INT_KER) != 0)
305 EFSYS_ERR(enp->en_esip, EFX_ERR_BUFID_DC_OOB, 0, 0);
307 if (EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
308 EFSYS_ERR(enp->en_esip, EFX_ERR_MEM_PERR,
309 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
310 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
312 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RBUF_OWN_INT_KER) != 0)
313 EFSYS_ERR(enp->en_esip, EFX_ERR_RBUF_OWN, 0, 0);
315 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TBUF_OWN_INT_KER) != 0)
316 EFSYS_ERR(enp->en_esip, EFX_ERR_TBUF_OWN, 0, 0);
318 if (EFX_OWORD_FIELD(fatal, FRF_AZ_RDESCQ_OWN_INT_KER) != 0)
319 EFSYS_ERR(enp->en_esip, EFX_ERR_RDESQ_OWN, 0, 0);
321 if (EFX_OWORD_FIELD(fatal, FRF_AZ_TDESCQ_OWN_INT_KER) != 0)
322 EFSYS_ERR(enp->en_esip, EFX_ERR_TDESQ_OWN, 0, 0);
324 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVQ_OWN_INT_KER) != 0)
325 EFSYS_ERR(enp->en_esip, EFX_ERR_EVQ_OWN, 0, 0);
327 if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVF_OFLO_INT_KER) != 0)
328 EFSYS_ERR(enp->en_esip, EFX_ERR_EVFF_OFLO, 0, 0);
330 if (EFX_OWORD_FIELD(fatal, FRF_AZ_ILL_ADR_INT_KER) != 0)
331 EFSYS_ERR(enp->en_esip, EFX_ERR_ILL_ADDR, 0, 0);
333 if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0)
334 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_PERR,
335 EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
336 EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
348 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
349 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
350 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
352 /* Clear the interrupt address register */
353 EFX_ZERO_OWORD(oword);
354 EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
356 enp->en_mod_flags &= ~EFX_MOD_INTR;