New upstream version 18.02
[deb_dpdk.git] / drivers / net / sfc / base / efx_intr.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright (c) 2007-2018 Solarflare Communications Inc.
4  * All rights reserved.
5  */
6
7 #include "efx.h"
8 #include "efx_impl.h"
9
10
11 #if EFSYS_OPT_SIENA
12
13 static  __checkReturn   efx_rc_t
14 siena_intr_init(
15         __in            efx_nic_t *enp,
16         __in            efx_intr_type_t type,
17         __in            efsys_mem_t *esmp);
18
19 static                  void
20 siena_intr_enable(
21         __in            efx_nic_t *enp);
22
23 static                  void
24 siena_intr_disable(
25         __in            efx_nic_t *enp);
26
27 static                  void
28 siena_intr_disable_unlocked(
29         __in            efx_nic_t *enp);
30
31 static  __checkReturn   efx_rc_t
32 siena_intr_trigger(
33         __in            efx_nic_t *enp,
34         __in            unsigned int level);
35
36 static                  void
37 siena_intr_fini(
38         __in            efx_nic_t *enp);
39
40 static                  void
41 siena_intr_status_line(
42         __in            efx_nic_t *enp,
43         __out           boolean_t *fatalp,
44         __out           uint32_t *qmaskp);
45
46 static                  void
47 siena_intr_status_message(
48         __in            efx_nic_t *enp,
49         __in            unsigned int message,
50         __out           boolean_t *fatalp);
51
52 static                  void
53 siena_intr_fatal(
54         __in            efx_nic_t *enp);
55
56 static  __checkReturn   boolean_t
57 siena_intr_check_fatal(
58         __in            efx_nic_t *enp);
59
60
61 #endif /* EFSYS_OPT_SIENA */
62
63
64 #if EFSYS_OPT_SIENA
65 static const efx_intr_ops_t     __efx_intr_siena_ops = {
66         siena_intr_init,                /* eio_init */
67         siena_intr_enable,              /* eio_enable */
68         siena_intr_disable,             /* eio_disable */
69         siena_intr_disable_unlocked,    /* eio_disable_unlocked */
70         siena_intr_trigger,             /* eio_trigger */
71         siena_intr_status_line,         /* eio_status_line */
72         siena_intr_status_message,      /* eio_status_message */
73         siena_intr_fatal,               /* eio_fatal */
74         siena_intr_fini,                /* eio_fini */
75 };
76 #endif  /* EFSYS_OPT_SIENA */
77
78 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
79 static const efx_intr_ops_t     __efx_intr_ef10_ops = {
80         ef10_intr_init,                 /* eio_init */
81         ef10_intr_enable,               /* eio_enable */
82         ef10_intr_disable,              /* eio_disable */
83         ef10_intr_disable_unlocked,     /* eio_disable_unlocked */
84         ef10_intr_trigger,              /* eio_trigger */
85         ef10_intr_status_line,          /* eio_status_line */
86         ef10_intr_status_message,       /* eio_status_message */
87         ef10_intr_fatal,                /* eio_fatal */
88         ef10_intr_fini,                 /* eio_fini */
89 };
90 #endif  /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */
91
92         __checkReturn   efx_rc_t
93 efx_intr_init(
94         __in            efx_nic_t *enp,
95         __in            efx_intr_type_t type,
96         __in            efsys_mem_t *esmp)
97 {
98         efx_intr_t *eip = &(enp->en_intr);
99         const efx_intr_ops_t *eiop;
100         efx_rc_t rc;
101
102         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
103         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
104
105         if (enp->en_mod_flags & EFX_MOD_INTR) {
106                 rc = EINVAL;
107                 goto fail1;
108         }
109
110         eip->ei_esmp = esmp;
111         eip->ei_type = type;
112         eip->ei_level = 0;
113
114         enp->en_mod_flags |= EFX_MOD_INTR;
115
116         switch (enp->en_family) {
117 #if EFSYS_OPT_SIENA
118         case EFX_FAMILY_SIENA:
119                 eiop = &__efx_intr_siena_ops;
120                 break;
121 #endif  /* EFSYS_OPT_SIENA */
122
123 #if EFSYS_OPT_HUNTINGTON
124         case EFX_FAMILY_HUNTINGTON:
125                 eiop = &__efx_intr_ef10_ops;
126                 break;
127 #endif  /* EFSYS_OPT_HUNTINGTON */
128
129 #if EFSYS_OPT_MEDFORD
130         case EFX_FAMILY_MEDFORD:
131                 eiop = &__efx_intr_ef10_ops;
132                 break;
133 #endif  /* EFSYS_OPT_MEDFORD */
134
135         default:
136                 EFSYS_ASSERT(B_FALSE);
137                 rc = ENOTSUP;
138                 goto fail2;
139         }
140
141         if ((rc = eiop->eio_init(enp, type, esmp)) != 0)
142                 goto fail3;
143
144         eip->ei_eiop = eiop;
145
146         return (0);
147
148 fail3:
149         EFSYS_PROBE(fail3);
150 fail2:
151         EFSYS_PROBE(fail2);
152 fail1:
153         EFSYS_PROBE1(fail1, efx_rc_t, rc);
154
155         return (rc);
156 }
157
158                 void
159 efx_intr_fini(
160         __in    efx_nic_t *enp)
161 {
162         efx_intr_t *eip = &(enp->en_intr);
163         const efx_intr_ops_t *eiop = eip->ei_eiop;
164
165         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
166         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
167         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
168
169         eiop->eio_fini(enp);
170
171         enp->en_mod_flags &= ~EFX_MOD_INTR;
172 }
173
174                         void
175 efx_intr_enable(
176         __in            efx_nic_t *enp)
177 {
178         efx_intr_t *eip = &(enp->en_intr);
179         const efx_intr_ops_t *eiop = eip->ei_eiop;
180
181         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
182         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
183
184         eiop->eio_enable(enp);
185 }
186
187                         void
188 efx_intr_disable(
189         __in            efx_nic_t *enp)
190 {
191         efx_intr_t *eip = &(enp->en_intr);
192         const efx_intr_ops_t *eiop = eip->ei_eiop;
193
194         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
195         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
196
197         eiop->eio_disable(enp);
198 }
199
200                         void
201 efx_intr_disable_unlocked(
202         __in            efx_nic_t *enp)
203 {
204         efx_intr_t *eip = &(enp->en_intr);
205         const efx_intr_ops_t *eiop = eip->ei_eiop;
206
207         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
208         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
209
210         eiop->eio_disable_unlocked(enp);
211 }
212
213
214         __checkReturn   efx_rc_t
215 efx_intr_trigger(
216         __in            efx_nic_t *enp,
217         __in            unsigned int level)
218 {
219         efx_intr_t *eip = &(enp->en_intr);
220         const efx_intr_ops_t *eiop = eip->ei_eiop;
221
222         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
223         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
224
225         return (eiop->eio_trigger(enp, level));
226 }
227
228                         void
229 efx_intr_status_line(
230         __in            efx_nic_t *enp,
231         __out           boolean_t *fatalp,
232         __out           uint32_t *qmaskp)
233 {
234         efx_intr_t *eip = &(enp->en_intr);
235         const efx_intr_ops_t *eiop = eip->ei_eiop;
236
237         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
238         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
239
240         eiop->eio_status_line(enp, fatalp, qmaskp);
241 }
242
243                         void
244 efx_intr_status_message(
245         __in            efx_nic_t *enp,
246         __in            unsigned int message,
247         __out           boolean_t *fatalp)
248 {
249         efx_intr_t *eip = &(enp->en_intr);
250         const efx_intr_ops_t *eiop = eip->ei_eiop;
251
252         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
253         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
254
255         eiop->eio_status_message(enp, message, fatalp);
256 }
257
258                 void
259 efx_intr_fatal(
260         __in    efx_nic_t *enp)
261 {
262         efx_intr_t *eip = &(enp->en_intr);
263         const efx_intr_ops_t *eiop = eip->ei_eiop;
264
265         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
266         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
267
268         eiop->eio_fatal(enp);
269 }
270
271
272 /* ************************************************************************* */
273 /* ************************************************************************* */
274 /* ************************************************************************* */
275
276 #if EFSYS_OPT_SIENA
277
278 static  __checkReturn   efx_rc_t
279 siena_intr_init(
280         __in            efx_nic_t *enp,
281         __in            efx_intr_type_t type,
282         __in            efsys_mem_t *esmp)
283 {
284         efx_intr_t *eip = &(enp->en_intr);
285         efx_oword_t oword;
286
287         /*
288          * bug17213 workaround.
289          *
290          * Under legacy interrupts, don't share a level between fatal
291          * interrupts and event queue interrupts. Under MSI-X, they
292          * must share, or we won't get an interrupt.
293          */
294         if (enp->en_family == EFX_FAMILY_SIENA &&
295             eip->ei_type == EFX_INTR_LINE)
296                 eip->ei_level = 0x1f;
297         else
298                 eip->ei_level = 0;
299
300         /* Enable all the genuinely fatal interrupts */
301         EFX_SET_OWORD(oword);
302         EFX_SET_OWORD_FIELD(oword, FRF_AZ_ILL_ADR_INT_KER_EN, 0);
303         EFX_SET_OWORD_FIELD(oword, FRF_AZ_RBUF_OWN_INT_KER_EN, 0);
304         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TBUF_OWN_INT_KER_EN, 0);
305         if (enp->en_family >= EFX_FAMILY_SIENA)
306                 EFX_SET_OWORD_FIELD(oword, FRF_CZ_SRAM_PERR_INT_P_KER_EN, 0);
307         EFX_BAR_WRITEO(enp, FR_AZ_FATAL_INTR_REG_KER, &oword);
308
309         /* Set up the interrupt address register */
310         EFX_POPULATE_OWORD_3(oword,
311             FRF_AZ_NORM_INT_VEC_DIS_KER, (type == EFX_INTR_MESSAGE) ? 1 : 0,
312             FRF_AZ_INT_ADR_KER_DW0, EFSYS_MEM_ADDR(esmp) & 0xffffffff,
313             FRF_AZ_INT_ADR_KER_DW1, EFSYS_MEM_ADDR(esmp) >> 32);
314         EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
315
316         return (0);
317 }
318
319 static                  void
320 siena_intr_enable(
321         __in            efx_nic_t *enp)
322 {
323         efx_intr_t *eip = &(enp->en_intr);
324         efx_oword_t oword;
325
326         EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
327
328         EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
329         EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 1);
330         EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
331 }
332
333 static                  void
334 siena_intr_disable(
335         __in            efx_nic_t *enp)
336 {
337         efx_oword_t oword;
338
339         EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
340         EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
341         EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
342
343         EFSYS_SPIN(10);
344 }
345
346 static                  void
347 siena_intr_disable_unlocked(
348         __in            efx_nic_t *enp)
349 {
350         efx_oword_t oword;
351
352         EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
353                         &oword, B_FALSE);
354         EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
355         EFSYS_BAR_WRITEO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
356             &oword, B_FALSE);
357 }
358
359 static  __checkReturn   efx_rc_t
360 siena_intr_trigger(
361         __in            efx_nic_t *enp,
362         __in            unsigned int level)
363 {
364         efx_intr_t *eip = &(enp->en_intr);
365         efx_oword_t oword;
366         unsigned int count;
367         uint32_t sel;
368         efx_rc_t rc;
369
370         /* bug16757: No event queues can be initialized */
371         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
372
373         if (level >= EFX_NINTR_SIENA) {
374                 rc = EINVAL;
375                 goto fail1;
376         }
377
378         if (level > EFX_MASK32(FRF_AZ_KER_INT_LEVE_SEL))
379                 return (ENOTSUP); /* avoid EFSYS_PROBE() */
380
381         sel = level;
382
383         /* Trigger a test interrupt */
384         EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
385         EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, sel);
386         EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER, 1);
387         EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
388
389         /*
390          * Wait up to 100ms for the interrupt to be raised before restoring
391          * KER_INT_LEVE_SEL. Ignore a failure to raise (the caller will
392          * observe this soon enough anyway), but always reset KER_INT_LEVE_SEL
393          */
394         count = 0;
395         do {
396                 EFSYS_SPIN(100);        /* 100us */
397
398                 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
399         } while (EFX_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER) && ++count < 1000);
400
401         EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
402         EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
403
404         return (0);
405
406 fail1:
407         EFSYS_PROBE1(fail1, efx_rc_t, rc);
408
409         return (rc);
410 }
411
412 static  __checkReturn   boolean_t
413 siena_intr_check_fatal(
414         __in            efx_nic_t *enp)
415 {
416         efx_intr_t *eip = &(enp->en_intr);
417         efsys_mem_t *esmp = eip->ei_esmp;
418         efx_oword_t oword;
419
420         /* Read the syndrome */
421         EFSYS_MEM_READO(esmp, 0, &oword);
422
423         if (EFX_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT) != 0) {
424                 EFSYS_PROBE(fatal);
425
426                 /* Clear the fatal interrupt condition */
427                 EFX_SET_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT, 0);
428                 EFSYS_MEM_WRITEO(esmp, 0, &oword);
429
430                 return (B_TRUE);
431         }
432
433         return (B_FALSE);
434 }
435
436 static                  void
437 siena_intr_status_line(
438         __in            efx_nic_t *enp,
439         __out           boolean_t *fatalp,
440         __out           uint32_t *qmaskp)
441 {
442         efx_intr_t *eip = &(enp->en_intr);
443         efx_dword_t dword;
444
445         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
446         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
447
448         /*
449          * Read the queue mask and implicitly acknowledge the
450          * interrupt.
451          */
452         EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE);
453         *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
454
455         EFSYS_PROBE1(qmask, uint32_t, *qmaskp);
456
457         if (*qmaskp & (1U << eip->ei_level))
458                 *fatalp = siena_intr_check_fatal(enp);
459         else
460                 *fatalp = B_FALSE;
461 }
462
463 static                  void
464 siena_intr_status_message(
465         __in            efx_nic_t *enp,
466         __in            unsigned int message,
467         __out           boolean_t *fatalp)
468 {
469         efx_intr_t *eip = &(enp->en_intr);
470
471         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
472         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
473
474         if (message == eip->ei_level)
475                 *fatalp = siena_intr_check_fatal(enp);
476         else
477                 *fatalp = B_FALSE;
478 }
479
480
481 static          void
482 siena_intr_fatal(
483         __in    efx_nic_t *enp)
484 {
485 #if EFSYS_OPT_DECODE_INTR_FATAL
486         efx_oword_t fatal;
487         efx_oword_t mem_per;
488
489         EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal);
490         EFX_ZERO_OWORD(mem_per);
491
492         if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0 ||
493             EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
494                 EFX_BAR_READO(enp, FR_AZ_MEM_STAT_REG, &mem_per);
495
496         if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRAM_OOB_INT_KER) != 0)
497                 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_OOB, 0, 0);
498
499         if (EFX_OWORD_FIELD(fatal, FRF_AZ_BUFID_DC_OOB_INT_KER) != 0)
500                 EFSYS_ERR(enp->en_esip, EFX_ERR_BUFID_DC_OOB, 0, 0);
501
502         if (EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
503                 EFSYS_ERR(enp->en_esip, EFX_ERR_MEM_PERR,
504                     EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
505                     EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
506
507         if (EFX_OWORD_FIELD(fatal, FRF_AZ_RBUF_OWN_INT_KER) != 0)
508                 EFSYS_ERR(enp->en_esip, EFX_ERR_RBUF_OWN, 0, 0);
509
510         if (EFX_OWORD_FIELD(fatal, FRF_AZ_TBUF_OWN_INT_KER) != 0)
511                 EFSYS_ERR(enp->en_esip, EFX_ERR_TBUF_OWN, 0, 0);
512
513         if (EFX_OWORD_FIELD(fatal, FRF_AZ_RDESCQ_OWN_INT_KER) != 0)
514                 EFSYS_ERR(enp->en_esip, EFX_ERR_RDESQ_OWN, 0, 0);
515
516         if (EFX_OWORD_FIELD(fatal, FRF_AZ_TDESCQ_OWN_INT_KER) != 0)
517                 EFSYS_ERR(enp->en_esip, EFX_ERR_TDESQ_OWN, 0, 0);
518
519         if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVQ_OWN_INT_KER) != 0)
520                 EFSYS_ERR(enp->en_esip, EFX_ERR_EVQ_OWN, 0, 0);
521
522         if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVF_OFLO_INT_KER) != 0)
523                 EFSYS_ERR(enp->en_esip, EFX_ERR_EVFF_OFLO, 0, 0);
524
525         if (EFX_OWORD_FIELD(fatal, FRF_AZ_ILL_ADR_INT_KER) != 0)
526                 EFSYS_ERR(enp->en_esip, EFX_ERR_ILL_ADDR, 0, 0);
527
528         if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0)
529                 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_PERR,
530                     EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
531                     EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
532 #else
533         EFSYS_ASSERT(0);
534 #endif
535 }
536
537 static          void
538 siena_intr_fini(
539         __in    efx_nic_t *enp)
540 {
541         efx_oword_t oword;
542
543         /* Clear the interrupt address register */
544         EFX_ZERO_OWORD(oword);
545         EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
546 }
547
548 #endif /* EFSYS_OPT_SIENA */