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