New upstream version 18.08
[deb_dpdk.git] / drivers / net / sfc / base / ef10_intr.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright (c) 2012-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_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
12
13         __checkReturn   efx_rc_t
14 ef10_intr_init(
15         __in            efx_nic_t *enp,
16         __in            efx_intr_type_t type,
17         __in            efsys_mem_t *esmp)
18 {
19         _NOTE(ARGUNUSED(enp, type, esmp))
20         return (0);
21 }
22
23
24                         void
25 ef10_intr_enable(
26         __in            efx_nic_t *enp)
27 {
28         _NOTE(ARGUNUSED(enp))
29 }
30
31
32                         void
33 ef10_intr_disable(
34         __in            efx_nic_t *enp)
35 {
36         _NOTE(ARGUNUSED(enp))
37 }
38
39
40                         void
41 ef10_intr_disable_unlocked(
42         __in            efx_nic_t *enp)
43 {
44         _NOTE(ARGUNUSED(enp))
45 }
46
47
48 static  __checkReturn   efx_rc_t
49 efx_mcdi_trigger_interrupt(
50         __in            efx_nic_t *enp,
51         __in            unsigned int level)
52 {
53         efx_mcdi_req_t req;
54         uint8_t payload[MAX(MC_CMD_TRIGGER_INTERRUPT_IN_LEN,
55                             MC_CMD_TRIGGER_INTERRUPT_OUT_LEN)];
56         efx_rc_t rc;
57
58         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
59             enp->en_family == EFX_FAMILY_MEDFORD ||
60             enp->en_family == EFX_FAMILY_MEDFORD2);
61
62         if (level >= enp->en_nic_cfg.enc_intr_limit) {
63                 rc = EINVAL;
64                 goto fail1;
65         }
66
67         (void) memset(payload, 0, sizeof (payload));
68         req.emr_cmd = MC_CMD_TRIGGER_INTERRUPT;
69         req.emr_in_buf = payload;
70         req.emr_in_length = MC_CMD_TRIGGER_INTERRUPT_IN_LEN;
71         req.emr_out_buf = payload;
72         req.emr_out_length = MC_CMD_TRIGGER_INTERRUPT_OUT_LEN;
73
74         MCDI_IN_SET_DWORD(req, TRIGGER_INTERRUPT_IN_INTR_LEVEL, level);
75
76         efx_mcdi_execute(enp, &req);
77
78         if (req.emr_rc != 0) {
79                 rc = req.emr_rc;
80                 goto fail2;
81         }
82
83         return (0);
84
85 fail2:
86         EFSYS_PROBE(fail2);
87
88 fail1:
89         EFSYS_PROBE1(fail1, efx_rc_t, rc);
90
91         return (rc);
92 }
93
94         __checkReturn   efx_rc_t
95 ef10_intr_trigger(
96         __in            efx_nic_t *enp,
97         __in            unsigned int level)
98 {
99         efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
100         efx_rc_t rc;
101
102         if (encp->enc_bug41750_workaround) {
103                 /*
104                  * bug 41750: Test interrupts don't work on Greenport
105                  * bug 50084: Test interrupts don't work on VFs
106                  */
107                 rc = ENOTSUP;
108                 goto fail1;
109         }
110
111         if ((rc = efx_mcdi_trigger_interrupt(enp, level)) != 0)
112                 goto fail2;
113
114         return (0);
115
116 fail2:
117         EFSYS_PROBE(fail2);
118 fail1:
119         EFSYS_PROBE1(fail1, efx_rc_t, rc);
120
121         return (rc);
122 }
123
124                         void
125 ef10_intr_status_line(
126         __in            efx_nic_t *enp,
127         __out           boolean_t *fatalp,
128         __out           uint32_t *qmaskp)
129 {
130         efx_dword_t dword;
131
132         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
133             enp->en_family == EFX_FAMILY_MEDFORD ||
134             enp->en_family == EFX_FAMILY_MEDFORD2);
135
136         /* Read the queue mask and implicitly acknowledge the interrupt. */
137         EFX_BAR_READD(enp, ER_DZ_BIU_INT_ISR_REG, &dword, B_FALSE);
138         *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
139
140         EFSYS_PROBE1(qmask, uint32_t, *qmaskp);
141
142         *fatalp = B_FALSE;
143 }
144
145                         void
146 ef10_intr_status_message(
147         __in            efx_nic_t *enp,
148         __in            unsigned int message,
149         __out           boolean_t *fatalp)
150 {
151         EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON ||
152             enp->en_family == EFX_FAMILY_MEDFORD ||
153             enp->en_family == EFX_FAMILY_MEDFORD2);
154
155         _NOTE(ARGUNUSED(enp, message))
156
157         /* EF10 fatal errors are reported via events */
158         *fatalp = B_FALSE;
159 }
160
161                         void
162 ef10_intr_fatal(
163         __in            efx_nic_t *enp)
164 {
165         /* EF10 fatal errors are reported via events */
166         _NOTE(ARGUNUSED(enp))
167 }
168
169                         void
170 ef10_intr_fini(
171         __in            efx_nic_t *enp)
172 {
173         _NOTE(ARGUNUSED(enp))
174 }
175
176 #endif  /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */