Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : :
5 : : #include "roc_api.h"
6 : : #include "roc_priv.h"
7 : :
8 : : static void
9 : 0 : npa_err_irq(void *param)
10 : : {
11 : : struct npa_lf *lf = (struct npa_lf *)param;
12 : : uint64_t intr;
13 : :
14 [ # # ]: 0 : intr = plt_read64(lf->base + NPA_LF_ERR_INT);
15 [ # # ]: 0 : if (intr == 0)
16 : : return;
17 : :
18 : 0 : plt_err("Err_intr=0x%" PRIx64 "", intr);
19 : :
20 : : /* Clear interrupt */
21 : 0 : plt_write64(intr, lf->base + NPA_LF_ERR_INT);
22 : : }
23 : :
24 : : static int
25 : 0 : npa_register_err_irq(struct npa_lf *lf)
26 : : {
27 : 0 : struct plt_intr_handle *handle = lf->intr_handle;
28 : : int rc, vec;
29 : :
30 : 0 : vec = lf->npa_msixoff + NPA_LF_INT_VEC_ERR_INT;
31 : :
32 : : /* Clear err interrupt */
33 : 0 : plt_write64(~0ull, lf->base + NPA_LF_ERR_INT_ENA_W1C);
34 : : /* Register err interrupt vector */
35 : 0 : rc = dev_irq_register(handle, npa_err_irq, lf, vec);
36 : :
37 : : /* Enable hw interrupt */
38 : 0 : plt_write64(~0ull, lf->base + NPA_LF_ERR_INT_ENA_W1S);
39 : :
40 : 0 : return rc;
41 : : }
42 : :
43 : : static void
44 : 0 : npa_unregister_err_irq(struct npa_lf *lf)
45 : : {
46 : 0 : struct plt_intr_handle *handle = lf->intr_handle;
47 : : int vec;
48 : :
49 : 0 : vec = lf->npa_msixoff + NPA_LF_INT_VEC_ERR_INT;
50 : :
51 : : /* Clear err interrupt */
52 : 0 : plt_write64(~0ull, lf->base + NPA_LF_ERR_INT_ENA_W1C);
53 : 0 : dev_irq_unregister(handle, npa_err_irq, lf, vec);
54 : 0 : }
55 : :
56 : : static void
57 : 0 : npa_ras_irq(void *param)
58 : : {
59 : : struct npa_lf *lf = (struct npa_lf *)param;
60 : : uint64_t intr;
61 : :
62 [ # # ]: 0 : intr = plt_read64(lf->base + NPA_LF_RAS);
63 [ # # ]: 0 : if (intr == 0)
64 : : return;
65 : :
66 : 0 : plt_err("Ras_intr=0x%" PRIx64 "", intr);
67 : :
68 : : /* Clear interrupt */
69 : 0 : plt_write64(intr, lf->base + NPA_LF_RAS);
70 : : }
71 : :
72 : : static int
73 : 0 : npa_register_ras_irq(struct npa_lf *lf)
74 : : {
75 : 0 : struct plt_intr_handle *handle = lf->intr_handle;
76 : : int rc, vec;
77 : :
78 : 0 : vec = lf->npa_msixoff + NPA_LF_INT_VEC_POISON;
79 : :
80 : : /* Clear err interrupt */
81 : 0 : plt_write64(~0ull, lf->base + NPA_LF_RAS_ENA_W1C);
82 : : /* Set used interrupt vectors */
83 : 0 : rc = dev_irq_register(handle, npa_ras_irq, lf, vec);
84 : : /* Enable hw interrupt */
85 : 0 : plt_write64(~0ull, lf->base + NPA_LF_RAS_ENA_W1S);
86 : :
87 : 0 : return rc;
88 : : }
89 : :
90 : : static void
91 : 0 : npa_unregister_ras_irq(struct npa_lf *lf)
92 : : {
93 : : int vec;
94 : 0 : struct plt_intr_handle *handle = lf->intr_handle;
95 : :
96 : 0 : vec = lf->npa_msixoff + NPA_LF_INT_VEC_POISON;
97 : :
98 : : /* Clear err interrupt */
99 : 0 : plt_write64(~0ull, lf->base + NPA_LF_RAS_ENA_W1C);
100 : 0 : dev_irq_unregister(handle, npa_ras_irq, lf, vec);
101 : 0 : }
102 : :
103 : : static inline uint8_t
104 : : npa_q_irq_get_and_clear(struct npa_lf *lf, uint32_t q, uint32_t off,
105 : : uint64_t mask)
106 : : {
107 : : uint64_t reg, wdata, shift;
108 : : uint8_t qint;
109 : :
110 [ # # # # ]: 0 : shift = roc_model_is_cn20k() ? 47 : 44;
111 : 0 : wdata = (uint64_t)q << shift;
112 : 0 : reg = roc_atomic64_add_nosync(wdata, (int64_t *)(lf->base + off));
113 : :
114 : : if (reg & BIT_ULL(42) /* OP_ERR */) {
115 : : plt_err("Failed execute irq get off=0x%x reg=0x%" PRIu64, off, reg);
116 : : return 0;
117 : : }
118 : :
119 : : qint = reg & 0xff;
120 : 0 : wdata &= mask;
121 : : plt_write64(wdata | qint, lf->base + off);
122 : :
123 : : return qint;
124 : : }
125 : :
126 : : static inline uint8_t
127 : : npa_pool_irq_get_and_clear(struct npa_lf *lf, uint32_t p)
128 : : {
129 : : return npa_q_irq_get_and_clear(lf, p, NPA_LF_POOL_OP_INT, ~0xff00);
130 : : }
131 : :
132 : : static inline uint8_t
133 : : npa_aura_irq_get_and_clear(struct npa_lf *lf, uint32_t a)
134 : : {
135 : : return npa_q_irq_get_and_clear(lf, a, NPA_LF_AURA_OP_INT, ~0xff00);
136 : : }
137 : :
138 : : static void
139 : 0 : npa_q_irq(void *param)
140 : : {
141 : : struct npa_qint *qint = (struct npa_qint *)param;
142 : 0 : struct npa_lf *lf = qint->lf;
143 : 0 : uint8_t irq, qintx = qint->qintx;
144 : : uint32_t q, pool, aura;
145 : : uint64_t intr;
146 : :
147 [ # # ]: 0 : intr = plt_read64(lf->base + NPA_LF_QINTX_INT(qintx));
148 [ # # ]: 0 : if (intr == 0)
149 : : return;
150 : :
151 : 0 : plt_err("queue_intr=0x%" PRIx64 " qintx=%d", intr, qintx);
152 : :
153 : : /* Handle pool queue interrupts */
154 [ # # ]: 0 : for (q = 0; q < lf->nr_pools; q++) {
155 : : /* Skip disabled POOL */
156 [ # # ]: 0 : if (plt_bitmap_get(lf->npa_bmp, q))
157 : 0 : continue;
158 : :
159 [ # # ]: 0 : pool = q % lf->qints;
160 : : irq = npa_pool_irq_get_and_clear(lf, pool);
161 : :
162 : : if (irq & BIT_ULL(NPA_POOL_ERR_INT_OVFLS))
163 : : plt_err("Pool=%d NPA_POOL_ERR_INT_OVFLS", pool);
164 : :
165 : : if (irq & BIT_ULL(NPA_POOL_ERR_INT_RANGE))
166 : : plt_err("Pool=%d NPA_POOL_ERR_INT_RANGE", pool);
167 : :
168 : : if (irq & BIT_ULL(NPA_POOL_ERR_INT_PERR))
169 : : plt_err("Pool=%d NPA_POOL_ERR_INT_PERR", pool);
170 : : }
171 : :
172 : : /* Handle aura queue interrupts */
173 [ # # ]: 0 : for (q = 0; q < lf->nr_pools; q++) {
174 : : /* Skip disabled AURA */
175 [ # # ]: 0 : if (plt_bitmap_get(lf->npa_bmp, q))
176 : 0 : continue;
177 : :
178 [ # # ]: 0 : aura = q % lf->qints;
179 : : irq = npa_aura_irq_get_and_clear(lf, aura);
180 : :
181 : : if (irq & BIT_ULL(NPA_AURA_ERR_INT_AURA_ADD_OVER))
182 : : plt_err("Aura=%d NPA_AURA_ERR_INT_ADD_OVER", aura);
183 : :
184 : : if (irq & BIT_ULL(NPA_AURA_ERR_INT_AURA_ADD_UNDER))
185 : : plt_err("Aura=%d NPA_AURA_ERR_INT_ADD_UNDER", aura);
186 : :
187 : : if (irq & BIT_ULL(NPA_AURA_ERR_INT_AURA_FREE_UNDER))
188 : : plt_err("Aura=%d NPA_AURA_ERR_INT_FREE_UNDER", aura);
189 : :
190 : : if (irq & BIT_ULL(NPA_AURA_ERR_INT_POOL_DIS))
191 : : plt_err("Aura=%d NPA_AURA_ERR_POOL_DIS", aura);
192 : : }
193 : :
194 : : /* Clear interrupt */
195 : 0 : plt_write64(intr, lf->base + NPA_LF_QINTX_INT(qintx));
196 : 0 : roc_npa_ctx_dump();
197 : : }
198 : :
199 : : static int
200 : 0 : npa_register_queue_irqs(struct npa_lf *lf)
201 : : {
202 : 0 : struct plt_intr_handle *handle = lf->intr_handle;
203 : : int vec, q, qs, rc = 0;
204 : :
205 : : /* Figure out max qintx required */
206 : 0 : qs = PLT_MIN(lf->qints, lf->nr_pools);
207 : :
208 [ # # ]: 0 : for (q = 0; q < qs; q++) {
209 : 0 : vec = lf->npa_msixoff + NPA_LF_INT_VEC_QINT_START + q;
210 : :
211 : : /* Clear QINT CNT */
212 : 0 : plt_write64(0, lf->base + NPA_LF_QINTX_CNT(q));
213 : :
214 : : /* Clear interrupt */
215 : 0 : plt_write64(~0ull, lf->base + NPA_LF_QINTX_ENA_W1C(q));
216 : :
217 : 0 : struct npa_qint *qintmem = lf->npa_qint_mem;
218 : :
219 : 0 : qintmem += q;
220 : :
221 : 0 : qintmem->lf = lf;
222 : 0 : qintmem->qintx = q;
223 : :
224 : : /* Sync qints_mem update */
225 : : plt_wmb();
226 : :
227 : : /* Register queue irq vector */
228 : 0 : rc = dev_irq_register(handle, npa_q_irq, qintmem, vec);
229 [ # # ]: 0 : if (rc)
230 : : break;
231 : :
232 : 0 : plt_write64(0, lf->base + NPA_LF_QINTX_CNT(q));
233 : 0 : plt_write64(0, lf->base + NPA_LF_QINTX_INT(q));
234 : : /* Enable QINT interrupt */
235 : 0 : plt_write64(~0ull, lf->base + NPA_LF_QINTX_ENA_W1S(q));
236 : : }
237 : :
238 : 0 : return rc;
239 : : }
240 : :
241 : : static void
242 : 0 : npa_unregister_queue_irqs(struct npa_lf *lf)
243 : : {
244 : 0 : struct plt_intr_handle *handle = lf->intr_handle;
245 : : int vec, q, qs;
246 : :
247 : : /* Figure out max qintx required */
248 : 0 : qs = PLT_MIN(lf->qints, lf->nr_pools);
249 : :
250 [ # # ]: 0 : for (q = 0; q < qs; q++) {
251 : 0 : vec = lf->npa_msixoff + NPA_LF_INT_VEC_QINT_START + q;
252 : :
253 : : /* Clear QINT CNT */
254 : 0 : plt_write64(0, lf->base + NPA_LF_QINTX_CNT(q));
255 : 0 : plt_write64(0, lf->base + NPA_LF_QINTX_INT(q));
256 : :
257 : : /* Clear interrupt */
258 : 0 : plt_write64(~0ull, lf->base + NPA_LF_QINTX_ENA_W1C(q));
259 : :
260 : 0 : struct npa_qint *qintmem = lf->npa_qint_mem;
261 : :
262 : 0 : qintmem += q;
263 : :
264 : : /* Unregister queue irq vector */
265 : 0 : dev_irq_unregister(handle, npa_q_irq, qintmem, vec);
266 : :
267 : 0 : qintmem->lf = NULL;
268 : 0 : qintmem->qintx = 0;
269 : : }
270 : 0 : }
271 : :
272 : : int
273 : 0 : npa_register_irqs(struct npa_lf *lf)
274 : : {
275 : : int rc;
276 : :
277 [ # # ]: 0 : if (lf->npa_msixoff == MSIX_VECTOR_INVALID) {
278 : 0 : plt_err("Invalid NPALF MSIX vector offset vector: 0x%x",
279 : : lf->npa_msixoff);
280 : 0 : return NPA_ERR_PARAM;
281 : : }
282 : :
283 : : /* Register lf err interrupt */
284 : 0 : rc = npa_register_err_irq(lf);
285 : : /* Register RAS interrupt */
286 : 0 : rc |= npa_register_ras_irq(lf);
287 : : /* Register queue interrupts */
288 : 0 : rc |= npa_register_queue_irqs(lf);
289 : :
290 : 0 : return rc;
291 : : }
292 : :
293 : : void
294 : 0 : npa_unregister_irqs(struct npa_lf *lf)
295 : : {
296 : 0 : npa_unregister_err_irq(lf);
297 : 0 : npa_unregister_ras_irq(lf);
298 : 0 : npa_unregister_queue_irqs(lf);
299 : 0 : }
|