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