common/sfc_efx/base: add interrupts module for Riverhead
[dpdk.git] / drivers / common / sfc_efx / base / efx_intr.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2019-2020 Xilinx, Inc.
4  * Copyright(c) 2007-2019 Solarflare Communications Inc.
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 EFX_OPTS_EF10()
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  /* EFX_OPTS_EF10() */
91
92 #if EFSYS_OPT_RIVERHEAD
93 static const efx_intr_ops_t     __efx_intr_rhead_ops = {
94         rhead_intr_init,                /* eio_init */
95         rhead_intr_enable,              /* eio_enable */
96         rhead_intr_disable,             /* eio_disable */
97         rhead_intr_disable_unlocked,    /* eio_disable_unlocked */
98         rhead_intr_trigger,             /* eio_trigger */
99         rhead_intr_status_line,         /* eio_status_line */
100         rhead_intr_status_message,      /* eio_status_message */
101         rhead_intr_fatal,               /* eio_fatal */
102         rhead_intr_fini,                /* eio_fini */
103 };
104 #endif  /* EFSYS_OPT_RIVERHEAD */
105
106         __checkReturn   efx_rc_t
107 efx_intr_init(
108         __in            efx_nic_t *enp,
109         __in            efx_intr_type_t type,
110         __in_opt        efsys_mem_t *esmp)
111 {
112         efx_intr_t *eip = &(enp->en_intr);
113         const efx_intr_ops_t *eiop;
114         efx_rc_t rc;
115
116         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
117         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
118
119         if (enp->en_mod_flags & EFX_MOD_INTR) {
120                 rc = EINVAL;
121                 goto fail1;
122         }
123
124         eip->ei_esmp = esmp;
125         eip->ei_type = type;
126         eip->ei_level = 0;
127
128         enp->en_mod_flags |= EFX_MOD_INTR;
129
130         switch (enp->en_family) {
131 #if EFSYS_OPT_SIENA
132         case EFX_FAMILY_SIENA:
133                 eiop = &__efx_intr_siena_ops;
134                 break;
135 #endif  /* EFSYS_OPT_SIENA */
136
137 #if EFSYS_OPT_HUNTINGTON
138         case EFX_FAMILY_HUNTINGTON:
139                 eiop = &__efx_intr_ef10_ops;
140                 break;
141 #endif  /* EFSYS_OPT_HUNTINGTON */
142
143 #if EFSYS_OPT_MEDFORD
144         case EFX_FAMILY_MEDFORD:
145                 eiop = &__efx_intr_ef10_ops;
146                 break;
147 #endif  /* EFSYS_OPT_MEDFORD */
148
149 #if EFSYS_OPT_MEDFORD2
150         case EFX_FAMILY_MEDFORD2:
151                 eiop = &__efx_intr_ef10_ops;
152                 break;
153 #endif  /* EFSYS_OPT_MEDFORD2 */
154
155 #if EFSYS_OPT_RIVERHEAD
156         case EFX_FAMILY_RIVERHEAD:
157                 eiop = &__efx_intr_rhead_ops;
158                 break;
159 #endif  /* EFSYS_OPT_RIVERHEAD */
160
161         default:
162                 EFSYS_ASSERT(B_FALSE);
163                 rc = ENOTSUP;
164                 goto fail2;
165         }
166
167         if ((rc = eiop->eio_init(enp, type, esmp)) != 0)
168                 goto fail3;
169
170         eip->ei_eiop = eiop;
171
172         return (0);
173
174 fail3:
175         EFSYS_PROBE(fail3);
176 fail2:
177         EFSYS_PROBE(fail2);
178 fail1:
179         EFSYS_PROBE1(fail1, efx_rc_t, rc);
180
181         return (rc);
182 }
183
184                 void
185 efx_intr_fini(
186         __in    efx_nic_t *enp)
187 {
188         efx_intr_t *eip = &(enp->en_intr);
189         const efx_intr_ops_t *eiop = eip->ei_eiop;
190
191         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
192         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
193         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
194
195         eiop->eio_fini(enp);
196
197         enp->en_mod_flags &= ~EFX_MOD_INTR;
198 }
199
200                         void
201 efx_intr_enable(
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_enable(enp);
211 }
212
213                         void
214 efx_intr_disable(
215         __in            efx_nic_t *enp)
216 {
217         efx_intr_t *eip = &(enp->en_intr);
218         const efx_intr_ops_t *eiop = eip->ei_eiop;
219
220         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
221         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
222
223         eiop->eio_disable(enp);
224 }
225
226                         void
227 efx_intr_disable_unlocked(
228         __in            efx_nic_t *enp)
229 {
230         efx_intr_t *eip = &(enp->en_intr);
231         const efx_intr_ops_t *eiop = eip->ei_eiop;
232
233         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
234         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
235
236         eiop->eio_disable_unlocked(enp);
237 }
238
239
240         __checkReturn   efx_rc_t
241 efx_intr_trigger(
242         __in            efx_nic_t *enp,
243         __in            unsigned int level)
244 {
245         efx_intr_t *eip = &(enp->en_intr);
246         const efx_intr_ops_t *eiop = eip->ei_eiop;
247
248         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
249         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
250
251         return (eiop->eio_trigger(enp, level));
252 }
253
254                         void
255 efx_intr_status_line(
256         __in            efx_nic_t *enp,
257         __out           boolean_t *fatalp,
258         __out           uint32_t *qmaskp)
259 {
260         efx_intr_t *eip = &(enp->en_intr);
261         const efx_intr_ops_t *eiop = eip->ei_eiop;
262
263         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
264         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
265
266         eiop->eio_status_line(enp, fatalp, qmaskp);
267 }
268
269                         void
270 efx_intr_status_message(
271         __in            efx_nic_t *enp,
272         __in            unsigned int message,
273         __out           boolean_t *fatalp)
274 {
275         efx_intr_t *eip = &(enp->en_intr);
276         const efx_intr_ops_t *eiop = eip->ei_eiop;
277
278         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
279         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
280
281         eiop->eio_status_message(enp, message, fatalp);
282 }
283
284                 void
285 efx_intr_fatal(
286         __in    efx_nic_t *enp)
287 {
288         efx_intr_t *eip = &(enp->en_intr);
289         const efx_intr_ops_t *eiop = eip->ei_eiop;
290
291         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
292         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
293
294         eiop->eio_fatal(enp);
295 }
296
297
298 /* ************************************************************************* */
299 /* ************************************************************************* */
300 /* ************************************************************************* */
301
302 #if EFSYS_OPT_SIENA
303
304 static  __checkReturn   efx_rc_t
305 siena_intr_init(
306         __in            efx_nic_t *enp,
307         __in            efx_intr_type_t type,
308         __in            efsys_mem_t *esmp)
309 {
310         efx_intr_t *eip = &(enp->en_intr);
311         efx_oword_t oword;
312         efx_rc_t rc;
313
314         if ((esmp == NULL) || (EFSYS_MEM_SIZE(esmp) < EFX_INTR_SIZE)) {
315                 rc = EINVAL;
316                 goto fail1;
317         }
318
319         /*
320          * bug17213 workaround.
321          *
322          * Under legacy interrupts, don't share a level between fatal
323          * interrupts and event queue interrupts. Under MSI-X, they
324          * must share, or we won't get an interrupt.
325          */
326         if (enp->en_family == EFX_FAMILY_SIENA &&
327             eip->ei_type == EFX_INTR_LINE)
328                 eip->ei_level = 0x1f;
329         else
330                 eip->ei_level = 0;
331
332         /* Enable all the genuinely fatal interrupts */
333         EFX_SET_OWORD(oword);
334         EFX_SET_OWORD_FIELD(oword, FRF_AZ_ILL_ADR_INT_KER_EN, 0);
335         EFX_SET_OWORD_FIELD(oword, FRF_AZ_RBUF_OWN_INT_KER_EN, 0);
336         EFX_SET_OWORD_FIELD(oword, FRF_AZ_TBUF_OWN_INT_KER_EN, 0);
337         if (enp->en_family >= EFX_FAMILY_SIENA)
338                 EFX_SET_OWORD_FIELD(oword, FRF_CZ_SRAM_PERR_INT_P_KER_EN, 0);
339         EFX_BAR_WRITEO(enp, FR_AZ_FATAL_INTR_REG_KER, &oword);
340
341         /* Set up the interrupt address register */
342         EFX_POPULATE_OWORD_3(oword,
343             FRF_AZ_NORM_INT_VEC_DIS_KER, (type == EFX_INTR_MESSAGE) ? 1 : 0,
344             FRF_AZ_INT_ADR_KER_DW0, EFSYS_MEM_ADDR(esmp) & 0xffffffff,
345             FRF_AZ_INT_ADR_KER_DW1, EFSYS_MEM_ADDR(esmp) >> 32);
346         EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
347
348         return (0);
349
350 fail1:
351         EFSYS_PROBE1(fail1, efx_rc_t, rc);
352
353         return (rc);
354 }
355
356 static                  void
357 siena_intr_enable(
358         __in            efx_nic_t *enp)
359 {
360         efx_intr_t *eip = &(enp->en_intr);
361         efx_oword_t oword;
362
363         EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
364
365         EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
366         EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 1);
367         EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
368 }
369
370 static                  void
371 siena_intr_disable(
372         __in            efx_nic_t *enp)
373 {
374         efx_oword_t oword;
375
376         EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
377         EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
378         EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
379
380         EFSYS_SPIN(10);
381 }
382
383 static                  void
384 siena_intr_disable_unlocked(
385         __in            efx_nic_t *enp)
386 {
387         efx_oword_t oword;
388
389         EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
390                         &oword, B_FALSE);
391         EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
392         EFSYS_BAR_WRITEO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
393             &oword, B_FALSE);
394 }
395
396 static  __checkReturn   efx_rc_t
397 siena_intr_trigger(
398         __in            efx_nic_t *enp,
399         __in            unsigned int level)
400 {
401         efx_intr_t *eip = &(enp->en_intr);
402         efx_oword_t oword;
403         unsigned int count;
404         uint32_t sel;
405         efx_rc_t rc;
406
407         /* bug16757: No event queues can be initialized */
408         EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
409
410         if (level >= EFX_NINTR_SIENA) {
411                 rc = EINVAL;
412                 goto fail1;
413         }
414
415         if (level > EFX_MASK32(FRF_AZ_KER_INT_LEVE_SEL))
416                 return (ENOTSUP); /* avoid EFSYS_PROBE() */
417
418         sel = level;
419
420         /* Trigger a test interrupt */
421         EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
422         EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, sel);
423         EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER, 1);
424         EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
425
426         /*
427          * Wait up to 100ms for the interrupt to be raised before restoring
428          * KER_INT_LEVE_SEL. Ignore a failure to raise (the caller will
429          * observe this soon enough anyway), but always reset KER_INT_LEVE_SEL
430          */
431         count = 0;
432         do {
433                 EFSYS_SPIN(100);        /* 100us */
434
435                 EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
436         } while (EFX_OWORD_FIELD(oword, FRF_AZ_KER_INT_KER) && ++count < 1000);
437
438         EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
439         EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
440
441         return (0);
442
443 fail1:
444         EFSYS_PROBE1(fail1, efx_rc_t, rc);
445
446         return (rc);
447 }
448
449 static  __checkReturn   boolean_t
450 siena_intr_check_fatal(
451         __in            efx_nic_t *enp)
452 {
453         efx_intr_t *eip = &(enp->en_intr);
454         efsys_mem_t *esmp = eip->ei_esmp;
455         efx_oword_t oword;
456
457         /* Read the syndrome */
458         EFSYS_MEM_READO(esmp, 0, &oword);
459
460         if (EFX_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT) != 0) {
461                 EFSYS_PROBE(fatal);
462
463                 /* Clear the fatal interrupt condition */
464                 EFX_SET_OWORD_FIELD(oword, FSF_AZ_NET_IVEC_FATAL_INT, 0);
465                 EFSYS_MEM_WRITEO(esmp, 0, &oword);
466
467                 return (B_TRUE);
468         }
469
470         return (B_FALSE);
471 }
472
473 static                  void
474 siena_intr_status_line(
475         __in            efx_nic_t *enp,
476         __out           boolean_t *fatalp,
477         __out           uint32_t *qmaskp)
478 {
479         efx_intr_t *eip = &(enp->en_intr);
480         efx_dword_t dword;
481
482         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
483         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
484
485         /*
486          * Read the queue mask and implicitly acknowledge the
487          * interrupt.
488          */
489         EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE);
490         *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
491
492         EFSYS_PROBE1(qmask, uint32_t, *qmaskp);
493
494         if (*qmaskp & (1U << eip->ei_level))
495                 *fatalp = siena_intr_check_fatal(enp);
496         else
497                 *fatalp = B_FALSE;
498 }
499
500 static                  void
501 siena_intr_status_message(
502         __in            efx_nic_t *enp,
503         __in            unsigned int message,
504         __out           boolean_t *fatalp)
505 {
506         efx_intr_t *eip = &(enp->en_intr);
507
508         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
509         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
510
511         if (message == eip->ei_level)
512                 *fatalp = siena_intr_check_fatal(enp);
513         else
514                 *fatalp = B_FALSE;
515 }
516
517
518 static          void
519 siena_intr_fatal(
520         __in    efx_nic_t *enp)
521 {
522 #if EFSYS_OPT_DECODE_INTR_FATAL
523         efx_oword_t fatal;
524         efx_oword_t mem_per;
525
526         EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal);
527         EFX_ZERO_OWORD(mem_per);
528
529         if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0 ||
530             EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
531                 EFX_BAR_READO(enp, FR_AZ_MEM_STAT_REG, &mem_per);
532
533         if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRAM_OOB_INT_KER) != 0)
534                 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_OOB, 0, 0);
535
536         if (EFX_OWORD_FIELD(fatal, FRF_AZ_BUFID_DC_OOB_INT_KER) != 0)
537                 EFSYS_ERR(enp->en_esip, EFX_ERR_BUFID_DC_OOB, 0, 0);
538
539         if (EFX_OWORD_FIELD(fatal, FRF_AZ_MEM_PERR_INT_KER) != 0)
540                 EFSYS_ERR(enp->en_esip, EFX_ERR_MEM_PERR,
541                     EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
542                     EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
543
544         if (EFX_OWORD_FIELD(fatal, FRF_AZ_RBUF_OWN_INT_KER) != 0)
545                 EFSYS_ERR(enp->en_esip, EFX_ERR_RBUF_OWN, 0, 0);
546
547         if (EFX_OWORD_FIELD(fatal, FRF_AZ_TBUF_OWN_INT_KER) != 0)
548                 EFSYS_ERR(enp->en_esip, EFX_ERR_TBUF_OWN, 0, 0);
549
550         if (EFX_OWORD_FIELD(fatal, FRF_AZ_RDESCQ_OWN_INT_KER) != 0)
551                 EFSYS_ERR(enp->en_esip, EFX_ERR_RDESQ_OWN, 0, 0);
552
553         if (EFX_OWORD_FIELD(fatal, FRF_AZ_TDESCQ_OWN_INT_KER) != 0)
554                 EFSYS_ERR(enp->en_esip, EFX_ERR_TDESQ_OWN, 0, 0);
555
556         if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVQ_OWN_INT_KER) != 0)
557                 EFSYS_ERR(enp->en_esip, EFX_ERR_EVQ_OWN, 0, 0);
558
559         if (EFX_OWORD_FIELD(fatal, FRF_AZ_EVF_OFLO_INT_KER) != 0)
560                 EFSYS_ERR(enp->en_esip, EFX_ERR_EVFF_OFLO, 0, 0);
561
562         if (EFX_OWORD_FIELD(fatal, FRF_AZ_ILL_ADR_INT_KER) != 0)
563                 EFSYS_ERR(enp->en_esip, EFX_ERR_ILL_ADDR, 0, 0);
564
565         if (EFX_OWORD_FIELD(fatal, FRF_AZ_SRM_PERR_INT_KER) != 0)
566                 EFSYS_ERR(enp->en_esip, EFX_ERR_SRAM_PERR,
567                     EFX_OWORD_FIELD(mem_per, EFX_DWORD_0),
568                     EFX_OWORD_FIELD(mem_per, EFX_DWORD_1));
569 #else
570         EFSYS_ASSERT(0);
571 #endif
572 }
573
574 static          void
575 siena_intr_fini(
576         __in    efx_nic_t *enp)
577 {
578         efx_oword_t oword;
579
580         /* Clear the interrupt address register */
581         EFX_ZERO_OWORD(oword);
582         EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
583 }
584
585 #endif /* EFSYS_OPT_SIENA */