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