066aca7a5a488eaaa734aabbe4201b07d3784178
[dpdk.git] / drivers / net / octeontx2 / otx2_ethdev_irq.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include <inttypes.h>
6
7 #include <rte_bus_pci.h>
8
9 #include "otx2_ethdev.h"
10
11 static void
12 nix_lf_err_irq(void *param)
13 {
14         struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param;
15         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
16         uint64_t intr;
17
18         intr = otx2_read64(dev->base + NIX_LF_ERR_INT);
19         if (intr == 0)
20                 return;
21
22         otx2_err("Err_intr=0x%" PRIx64 " pf=%d, vf=%d", intr, dev->pf, dev->vf);
23
24         /* Clear interrupt */
25         otx2_write64(intr, dev->base + NIX_LF_ERR_INT);
26
27         /* Dump registers to std out */
28         otx2_nix_reg_dump(dev, NULL);
29         otx2_nix_queues_ctx_dump(eth_dev);
30 }
31
32 static int
33 nix_lf_register_err_irq(struct rte_eth_dev *eth_dev)
34 {
35         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
36         struct rte_intr_handle *handle = &pci_dev->intr_handle;
37         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
38         int rc, vec;
39
40         vec = dev->nix_msixoff + NIX_LF_INT_VEC_ERR_INT;
41
42         /* Clear err interrupt */
43         otx2_write64(~0ull, dev->base + NIX_LF_ERR_INT_ENA_W1C);
44         /* Set used interrupt vectors */
45         rc = otx2_register_irq(handle, nix_lf_err_irq, eth_dev, vec);
46         /* Enable all dev interrupt except for RQ_DISABLED */
47         otx2_write64(~BIT_ULL(11), dev->base + NIX_LF_ERR_INT_ENA_W1S);
48
49         return rc;
50 }
51
52 static void
53 nix_lf_unregister_err_irq(struct rte_eth_dev *eth_dev)
54 {
55         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
56         struct rte_intr_handle *handle = &pci_dev->intr_handle;
57         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
58         int vec;
59
60         vec = dev->nix_msixoff + NIX_LF_INT_VEC_ERR_INT;
61
62         /* Clear err interrupt */
63         otx2_write64(~0ull, dev->base + NIX_LF_ERR_INT_ENA_W1C);
64         otx2_unregister_irq(handle, nix_lf_err_irq, eth_dev, vec);
65 }
66
67 static void
68 nix_lf_ras_irq(void *param)
69 {
70         struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param;
71         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
72         uint64_t intr;
73
74         intr = otx2_read64(dev->base + NIX_LF_RAS);
75         if (intr == 0)
76                 return;
77
78         otx2_err("Ras_intr=0x%" PRIx64 " pf=%d, vf=%d", intr, dev->pf, dev->vf);
79
80         /* Clear interrupt */
81         otx2_write64(intr, dev->base + NIX_LF_RAS);
82
83         /* Dump registers to std out */
84         otx2_nix_reg_dump(dev, NULL);
85         otx2_nix_queues_ctx_dump(eth_dev);
86 }
87
88 static int
89 nix_lf_register_ras_irq(struct rte_eth_dev *eth_dev)
90 {
91         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
92         struct rte_intr_handle *handle = &pci_dev->intr_handle;
93         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
94         int rc, vec;
95
96         vec = dev->nix_msixoff + NIX_LF_INT_VEC_POISON;
97
98         /* Clear err interrupt */
99         otx2_write64(~0ull, dev->base + NIX_LF_RAS_ENA_W1C);
100         /* Set used interrupt vectors */
101         rc = otx2_register_irq(handle, nix_lf_ras_irq, eth_dev, vec);
102         /* Enable dev interrupt */
103         otx2_write64(~0ull, dev->base + NIX_LF_RAS_ENA_W1S);
104
105         return rc;
106 }
107
108 static void
109 nix_lf_unregister_ras_irq(struct rte_eth_dev *eth_dev)
110 {
111         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
112         struct rte_intr_handle *handle = &pci_dev->intr_handle;
113         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
114         int vec;
115
116         vec = dev->nix_msixoff + NIX_LF_INT_VEC_POISON;
117
118         /* Clear err interrupt */
119         otx2_write64(~0ull, dev->base + NIX_LF_RAS_ENA_W1C);
120         otx2_unregister_irq(handle, nix_lf_ras_irq, eth_dev, vec);
121 }
122
123 static inline uint8_t
124 nix_lf_q_irq_get_and_clear(struct otx2_eth_dev *dev, uint16_t q,
125                            uint32_t off, uint64_t mask)
126 {
127         uint64_t reg, wdata;
128         uint8_t qint;
129
130         wdata = (uint64_t)q << 44;
131         reg = otx2_atomic64_add_nosync(wdata, (int64_t *)(dev->base + off));
132
133         if (reg & BIT_ULL(42) /* OP_ERR */) {
134                 otx2_err("Failed execute irq get off=0x%x", off);
135                 return 0;
136         }
137
138         qint = reg & 0xff;
139         wdata &= mask;
140         otx2_write64(wdata, dev->base + off);
141
142         return qint;
143 }
144
145 static inline uint8_t
146 nix_lf_rq_irq_get_and_clear(struct otx2_eth_dev *dev, uint16_t rq)
147 {
148         return nix_lf_q_irq_get_and_clear(dev, rq, NIX_LF_RQ_OP_INT, ~0xff00);
149 }
150
151 static inline uint8_t
152 nix_lf_cq_irq_get_and_clear(struct otx2_eth_dev *dev, uint16_t cq)
153 {
154         return nix_lf_q_irq_get_and_clear(dev, cq, NIX_LF_CQ_OP_INT, ~0xff00);
155 }
156
157 static inline uint8_t
158 nix_lf_sq_irq_get_and_clear(struct otx2_eth_dev *dev, uint16_t sq)
159 {
160         return nix_lf_q_irq_get_and_clear(dev, sq, NIX_LF_SQ_OP_INT, ~0x1ff00);
161 }
162
163 static inline void
164 nix_lf_sq_debug_reg(struct otx2_eth_dev *dev, uint32_t off)
165 {
166         uint64_t reg;
167
168         reg = otx2_read64(dev->base + off);
169         if (reg & BIT_ULL(44))
170                 otx2_err("SQ=%d err_code=0x%x",
171                          (int)((reg >> 8) & 0xfffff), (uint8_t)(reg & 0xff));
172 }
173
174 static void
175 nix_lf_q_irq(void *param)
176 {
177         struct otx2_qint *qint = (struct otx2_qint *)param;
178         struct rte_eth_dev *eth_dev = qint->eth_dev;
179         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
180         uint8_t irq, qintx = qint->qintx;
181         int q, cq, rq, sq;
182         uint64_t intr;
183
184         intr = otx2_read64(dev->base + NIX_LF_QINTX_INT(qintx));
185         if (intr == 0)
186                 return;
187
188         otx2_err("Queue_intr=0x%" PRIx64 " qintx=%d pf=%d, vf=%d",
189                  intr, qintx, dev->pf, dev->vf);
190
191         /* Handle RQ interrupts */
192         for (q = 0; q < eth_dev->data->nb_rx_queues; q++) {
193                 rq = q % dev->qints;
194                 irq = nix_lf_rq_irq_get_and_clear(dev, rq);
195
196                 if (irq & BIT_ULL(NIX_RQINT_DROP))
197                         otx2_err("RQ=%d NIX_RQINT_DROP", rq);
198
199                 if (irq & BIT_ULL(NIX_RQINT_RED))
200                         otx2_err("RQ=%d NIX_RQINT_RED", rq);
201         }
202
203         /* Handle CQ interrupts */
204         for (q = 0; q < eth_dev->data->nb_rx_queues; q++) {
205                 cq = q % dev->qints;
206                 irq = nix_lf_cq_irq_get_and_clear(dev, cq);
207
208                 if (irq & BIT_ULL(NIX_CQERRINT_DOOR_ERR))
209                         otx2_err("CQ=%d NIX_CQERRINT_DOOR_ERR", cq);
210
211                 if (irq & BIT_ULL(NIX_CQERRINT_WR_FULL))
212                         otx2_err("CQ=%d NIX_CQERRINT_WR_FULL", cq);
213
214                 if (irq & BIT_ULL(NIX_CQERRINT_CQE_FAULT))
215                         otx2_err("CQ=%d NIX_CQERRINT_CQE_FAULT", cq);
216         }
217
218         /* Handle SQ interrupts */
219         for (q = 0; q < eth_dev->data->nb_tx_queues; q++) {
220                 sq = q % dev->qints;
221                 irq = nix_lf_sq_irq_get_and_clear(dev, sq);
222
223                 if (irq & BIT_ULL(NIX_SQINT_LMT_ERR)) {
224                         otx2_err("SQ=%d NIX_SQINT_LMT_ERR", sq);
225                         nix_lf_sq_debug_reg(dev, NIX_LF_SQ_OP_ERR_DBG);
226                 }
227                 if (irq & BIT_ULL(NIX_SQINT_MNQ_ERR)) {
228                         otx2_err("SQ=%d NIX_SQINT_MNQ_ERR", sq);
229                         nix_lf_sq_debug_reg(dev, NIX_LF_MNQ_ERR_DBG);
230                 }
231                 if (irq & BIT_ULL(NIX_SQINT_SEND_ERR)) {
232                         otx2_err("SQ=%d NIX_SQINT_SEND_ERR", sq);
233                         nix_lf_sq_debug_reg(dev, NIX_LF_SEND_ERR_DBG);
234                 }
235                 if (irq & BIT_ULL(NIX_SQINT_SQB_ALLOC_FAIL)) {
236                         otx2_err("SQ=%d NIX_SQINT_SQB_ALLOC_FAIL", sq);
237                         nix_lf_sq_debug_reg(dev, NIX_LF_SEND_ERR_DBG);
238                 }
239         }
240
241         /* Clear interrupt */
242         otx2_write64(intr, dev->base + NIX_LF_QINTX_INT(qintx));
243
244         /* Dump registers to std out */
245         otx2_nix_reg_dump(dev, NULL);
246         otx2_nix_queues_ctx_dump(eth_dev);
247 }
248
249 int
250 oxt2_nix_register_queue_irqs(struct rte_eth_dev *eth_dev)
251 {
252         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
253         struct rte_intr_handle *handle = &pci_dev->intr_handle;
254         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
255         int vec, q, sqs, rqs, qs, rc = 0;
256
257         /* Figure out max qintx required */
258         rqs = RTE_MIN(dev->qints, eth_dev->data->nb_rx_queues);
259         sqs = RTE_MIN(dev->qints, eth_dev->data->nb_tx_queues);
260         qs  = RTE_MAX(rqs, sqs);
261
262         dev->configured_qints = qs;
263
264         for (q = 0; q < qs; q++) {
265                 vec = dev->nix_msixoff + NIX_LF_INT_VEC_QINT_START + q;
266
267                 /* Clear QINT CNT */
268                 otx2_write64(0, dev->base + NIX_LF_QINTX_CNT(q));
269
270                 /* Clear interrupt */
271                 otx2_write64(~0ull, dev->base + NIX_LF_QINTX_ENA_W1C(q));
272
273                 dev->qints_mem[q].eth_dev = eth_dev;
274                 dev->qints_mem[q].qintx = q;
275
276                 /* Sync qints_mem update */
277                 rte_smp_wmb();
278
279                 /* Register queue irq vector */
280                 rc = otx2_register_irq(handle, nix_lf_q_irq,
281                                        &dev->qints_mem[q], vec);
282                 if (rc)
283                         break;
284
285                 otx2_write64(0, dev->base + NIX_LF_QINTX_CNT(q));
286                 otx2_write64(0, dev->base + NIX_LF_QINTX_INT(q));
287                 /* Enable QINT interrupt */
288                 otx2_write64(~0ull, dev->base + NIX_LF_QINTX_ENA_W1S(q));
289         }
290
291         return rc;
292 }
293
294 void
295 oxt2_nix_unregister_queue_irqs(struct rte_eth_dev *eth_dev)
296 {
297         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
298         struct rte_intr_handle *handle = &pci_dev->intr_handle;
299         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
300         int vec, q;
301
302         for (q = 0; q < dev->configured_qints; q++) {
303                 vec = dev->nix_msixoff + NIX_LF_INT_VEC_QINT_START + q;
304
305                 /* Clear QINT CNT */
306                 otx2_write64(0, dev->base + NIX_LF_QINTX_CNT(q));
307                 otx2_write64(0, dev->base + NIX_LF_QINTX_INT(q));
308
309                 /* Clear interrupt */
310                 otx2_write64(~0ull, dev->base + NIX_LF_QINTX_ENA_W1C(q));
311
312                 /* Unregister queue irq vector */
313                 otx2_unregister_irq(handle, nix_lf_q_irq,
314                                     &dev->qints_mem[q], vec);
315         }
316 }
317
318 int
319 otx2_nix_register_irqs(struct rte_eth_dev *eth_dev)
320 {
321         struct otx2_eth_dev *dev = otx2_eth_pmd_priv(eth_dev);
322         int rc;
323
324         if (dev->nix_msixoff == MSIX_VECTOR_INVALID) {
325                 otx2_err("Invalid NIXLF MSIX vector offset vector: 0x%x",
326                          dev->nix_msixoff);
327                 return -EINVAL;
328         }
329
330         /* Register lf err interrupt */
331         rc = nix_lf_register_err_irq(eth_dev);
332         /* Register RAS interrupt */
333         rc |= nix_lf_register_ras_irq(eth_dev);
334
335         return rc;
336 }
337
338 void
339 otx2_nix_unregister_irqs(struct rte_eth_dev *eth_dev)
340 {
341         nix_lf_unregister_err_irq(eth_dev);
342         nix_lf_unregister_ras_irq(eth_dev);
343 }