e4407f09c9d34bb27213d22772161769b9745bc1
[platform/kernel/linux-rpi.git] / drivers / net / ethernet / marvell / octeontx2 / af / rvu_devlink.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Marvell RVU Admin Function Devlink
3  *
4  * Copyright (C) 2020 Marvell.
5  *
6  */
7
8 #include<linux/bitfield.h>
9
10 #include "rvu.h"
11 #include "rvu_reg.h"
12 #include "rvu_struct.h"
13 #include "rvu_npc_hash.h"
14
15 #define DRV_NAME "octeontx2-af"
16
17 static int rvu_report_pair_start(struct devlink_fmsg *fmsg, const char *name)
18 {
19         int err;
20
21         err = devlink_fmsg_pair_nest_start(fmsg, name);
22         if (err)
23                 return err;
24
25         return  devlink_fmsg_obj_nest_start(fmsg);
26 }
27
28 static int rvu_report_pair_end(struct devlink_fmsg *fmsg)
29 {
30         int err;
31
32         err = devlink_fmsg_obj_nest_end(fmsg);
33         if (err)
34                 return err;
35
36         return devlink_fmsg_pair_nest_end(fmsg);
37 }
38
39 static bool rvu_common_request_irq(struct rvu *rvu, int offset,
40                                    const char *name, irq_handler_t fn)
41 {
42         struct rvu_devlink *rvu_dl = rvu->rvu_dl;
43         int rc;
44
45         sprintf(&rvu->irq_name[offset * NAME_SIZE], "%s", name);
46         rc = request_irq(pci_irq_vector(rvu->pdev, offset), fn, 0,
47                          &rvu->irq_name[offset * NAME_SIZE], rvu_dl);
48         if (rc)
49                 dev_warn(rvu->dev, "Failed to register %s irq\n", name);
50         else
51                 rvu->irq_allocated[offset] = true;
52
53         return rvu->irq_allocated[offset];
54 }
55
56 static void rvu_nix_intr_work(struct work_struct *work)
57 {
58         struct rvu_nix_health_reporters *rvu_nix_health_reporter;
59
60         rvu_nix_health_reporter = container_of(work, struct rvu_nix_health_reporters, intr_work);
61         devlink_health_report(rvu_nix_health_reporter->rvu_hw_nix_intr_reporter,
62                               "NIX_AF_RVU Error",
63                               rvu_nix_health_reporter->nix_event_ctx);
64 }
65
66 static irqreturn_t rvu_nix_af_rvu_intr_handler(int irq, void *rvu_irq)
67 {
68         struct rvu_nix_event_ctx *nix_event_context;
69         struct rvu_devlink *rvu_dl = rvu_irq;
70         struct rvu *rvu;
71         int blkaddr;
72         u64 intr;
73
74         rvu = rvu_dl->rvu;
75         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
76         if (blkaddr < 0)
77                 return IRQ_NONE;
78
79         nix_event_context = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
80         intr = rvu_read64(rvu, blkaddr, NIX_AF_RVU_INT);
81         nix_event_context->nix_af_rvu_int = intr;
82
83         /* Clear interrupts */
84         rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT, intr);
85         rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT_ENA_W1C, ~0ULL);
86         queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_nix_health_reporter->intr_work);
87
88         return IRQ_HANDLED;
89 }
90
91 static void rvu_nix_gen_work(struct work_struct *work)
92 {
93         struct rvu_nix_health_reporters *rvu_nix_health_reporter;
94
95         rvu_nix_health_reporter = container_of(work, struct rvu_nix_health_reporters, gen_work);
96         devlink_health_report(rvu_nix_health_reporter->rvu_hw_nix_gen_reporter,
97                               "NIX_AF_GEN Error",
98                               rvu_nix_health_reporter->nix_event_ctx);
99 }
100
101 static irqreturn_t rvu_nix_af_rvu_gen_handler(int irq, void *rvu_irq)
102 {
103         struct rvu_nix_event_ctx *nix_event_context;
104         struct rvu_devlink *rvu_dl = rvu_irq;
105         struct rvu *rvu;
106         int blkaddr;
107         u64 intr;
108
109         rvu = rvu_dl->rvu;
110         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
111         if (blkaddr < 0)
112                 return IRQ_NONE;
113
114         nix_event_context = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
115         intr = rvu_read64(rvu, blkaddr, NIX_AF_GEN_INT);
116         nix_event_context->nix_af_rvu_gen = intr;
117
118         /* Clear interrupts */
119         rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT, intr);
120         rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT_ENA_W1C, ~0ULL);
121         queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_nix_health_reporter->gen_work);
122
123         return IRQ_HANDLED;
124 }
125
126 static void rvu_nix_err_work(struct work_struct *work)
127 {
128         struct rvu_nix_health_reporters *rvu_nix_health_reporter;
129
130         rvu_nix_health_reporter = container_of(work, struct rvu_nix_health_reporters, err_work);
131         devlink_health_report(rvu_nix_health_reporter->rvu_hw_nix_err_reporter,
132                               "NIX_AF_ERR Error",
133                               rvu_nix_health_reporter->nix_event_ctx);
134 }
135
136 static irqreturn_t rvu_nix_af_rvu_err_handler(int irq, void *rvu_irq)
137 {
138         struct rvu_nix_event_ctx *nix_event_context;
139         struct rvu_devlink *rvu_dl = rvu_irq;
140         struct rvu *rvu;
141         int blkaddr;
142         u64 intr;
143
144         rvu = rvu_dl->rvu;
145         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
146         if (blkaddr < 0)
147                 return IRQ_NONE;
148
149         nix_event_context = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
150         intr = rvu_read64(rvu, blkaddr, NIX_AF_ERR_INT);
151         nix_event_context->nix_af_rvu_err = intr;
152
153         /* Clear interrupts */
154         rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT, intr);
155         rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT_ENA_W1C, ~0ULL);
156         queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_nix_health_reporter->err_work);
157
158         return IRQ_HANDLED;
159 }
160
161 static void rvu_nix_ras_work(struct work_struct *work)
162 {
163         struct rvu_nix_health_reporters *rvu_nix_health_reporter;
164
165         rvu_nix_health_reporter = container_of(work, struct rvu_nix_health_reporters, ras_work);
166         devlink_health_report(rvu_nix_health_reporter->rvu_hw_nix_ras_reporter,
167                               "NIX_AF_RAS Error",
168                               rvu_nix_health_reporter->nix_event_ctx);
169 }
170
171 static irqreturn_t rvu_nix_af_rvu_ras_handler(int irq, void *rvu_irq)
172 {
173         struct rvu_nix_event_ctx *nix_event_context;
174         struct rvu_devlink *rvu_dl = rvu_irq;
175         struct rvu *rvu;
176         int blkaddr;
177         u64 intr;
178
179         rvu = rvu_dl->rvu;
180         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
181         if (blkaddr < 0)
182                 return IRQ_NONE;
183
184         nix_event_context = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
185         intr = rvu_read64(rvu, blkaddr, NIX_AF_ERR_INT);
186         nix_event_context->nix_af_rvu_ras = intr;
187
188         /* Clear interrupts */
189         rvu_write64(rvu, blkaddr, NIX_AF_RAS, intr);
190         rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1C, ~0ULL);
191         queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_nix_health_reporter->ras_work);
192
193         return IRQ_HANDLED;
194 }
195
196 static void rvu_nix_unregister_interrupts(struct rvu *rvu)
197 {
198         struct rvu_devlink *rvu_dl = rvu->rvu_dl;
199         int offs, i, blkaddr;
200
201         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
202         if (blkaddr < 0)
203                 return;
204
205         offs = rvu_read64(rvu, blkaddr, NIX_PRIV_AF_INT_CFG) & 0x3ff;
206         if (!offs)
207                 return;
208
209         rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT_ENA_W1C, ~0ULL);
210         rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT_ENA_W1C, ~0ULL);
211         rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT_ENA_W1C, ~0ULL);
212         rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1C, ~0ULL);
213
214         if (rvu->irq_allocated[offs + NIX_AF_INT_VEC_RVU]) {
215                 free_irq(pci_irq_vector(rvu->pdev, offs + NIX_AF_INT_VEC_RVU),
216                          rvu_dl);
217                 rvu->irq_allocated[offs + NIX_AF_INT_VEC_RVU] = false;
218         }
219
220         for (i = NIX_AF_INT_VEC_AF_ERR; i < NIX_AF_INT_VEC_CNT; i++)
221                 if (rvu->irq_allocated[offs + i]) {
222                         free_irq(pci_irq_vector(rvu->pdev, offs + i), rvu_dl);
223                         rvu->irq_allocated[offs + i] = false;
224                 }
225 }
226
227 static int rvu_nix_register_interrupts(struct rvu *rvu)
228 {
229         int blkaddr, base;
230         bool rc;
231
232         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
233         if (blkaddr < 0)
234                 return blkaddr;
235
236         /* Get NIX AF MSIX vectors offset. */
237         base = rvu_read64(rvu, blkaddr, NIX_PRIV_AF_INT_CFG) & 0x3ff;
238         if (!base) {
239                 dev_warn(rvu->dev,
240                          "Failed to get NIX%d NIX_AF_INT vector offsets\n",
241                          blkaddr - BLKADDR_NIX0);
242                 return 0;
243         }
244         /* Register and enable NIX_AF_RVU_INT interrupt */
245         rc = rvu_common_request_irq(rvu, base +  NIX_AF_INT_VEC_RVU,
246                                     "NIX_AF_RVU_INT",
247                                     rvu_nix_af_rvu_intr_handler);
248         if (!rc)
249                 goto err;
250         rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT_ENA_W1S, ~0ULL);
251
252         /* Register and enable NIX_AF_GEN_INT interrupt */
253         rc = rvu_common_request_irq(rvu, base +  NIX_AF_INT_VEC_GEN,
254                                     "NIX_AF_GEN_INT",
255                                     rvu_nix_af_rvu_gen_handler);
256         if (!rc)
257                 goto err;
258         rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT_ENA_W1S, ~0ULL);
259
260         /* Register and enable NIX_AF_ERR_INT interrupt */
261         rc = rvu_common_request_irq(rvu, base + NIX_AF_INT_VEC_AF_ERR,
262                                     "NIX_AF_ERR_INT",
263                                     rvu_nix_af_rvu_err_handler);
264         if (!rc)
265                 goto err;
266         rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT_ENA_W1S, ~0ULL);
267
268         /* Register and enable NIX_AF_RAS interrupt */
269         rc = rvu_common_request_irq(rvu, base + NIX_AF_INT_VEC_POISON,
270                                     "NIX_AF_RAS",
271                                     rvu_nix_af_rvu_ras_handler);
272         if (!rc)
273                 goto err;
274         rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1S, ~0ULL);
275
276         return 0;
277 err:
278         rvu_nix_unregister_interrupts(rvu);
279         return rc;
280 }
281
282 static int rvu_nix_report_show(struct devlink_fmsg *fmsg, void *ctx,
283                                enum nix_af_rvu_health health_reporter)
284 {
285         struct rvu_nix_event_ctx *nix_event_context;
286         u64 intr_val;
287         int err;
288
289         nix_event_context = ctx;
290         switch (health_reporter) {
291         case NIX_AF_RVU_INTR:
292                 intr_val = nix_event_context->nix_af_rvu_int;
293                 err = rvu_report_pair_start(fmsg, "NIX_AF_RVU");
294                 if (err)
295                         return err;
296                 err = devlink_fmsg_u64_pair_put(fmsg, "\tNIX RVU Interrupt Reg ",
297                                                 nix_event_context->nix_af_rvu_int);
298                 if (err)
299                         return err;
300                 if (intr_val & BIT_ULL(0)) {
301                         err = devlink_fmsg_string_put(fmsg, "\n\tUnmap Slot Error");
302                         if (err)
303                                 return err;
304                 }
305                 err = rvu_report_pair_end(fmsg);
306                 if (err)
307                         return err;
308                 break;
309         case NIX_AF_RVU_GEN:
310                 intr_val = nix_event_context->nix_af_rvu_gen;
311                 err = rvu_report_pair_start(fmsg, "NIX_AF_GENERAL");
312                 if (err)
313                         return err;
314                 err = devlink_fmsg_u64_pair_put(fmsg, "\tNIX General Interrupt Reg ",
315                                                 nix_event_context->nix_af_rvu_gen);
316                 if (err)
317                         return err;
318                 if (intr_val & BIT_ULL(0)) {
319                         err = devlink_fmsg_string_put(fmsg, "\n\tRx multicast pkt drop");
320                         if (err)
321                                 return err;
322                 }
323                 if (intr_val & BIT_ULL(1)) {
324                         err = devlink_fmsg_string_put(fmsg, "\n\tRx mirror pkt drop");
325                         if (err)
326                                 return err;
327                 }
328                 if (intr_val & BIT_ULL(4)) {
329                         err = devlink_fmsg_string_put(fmsg, "\n\tSMQ flush done");
330                         if (err)
331                                 return err;
332                 }
333                 err = rvu_report_pair_end(fmsg);
334                 if (err)
335                         return err;
336                 break;
337         case NIX_AF_RVU_ERR:
338                 intr_val = nix_event_context->nix_af_rvu_err;
339                 err = rvu_report_pair_start(fmsg, "NIX_AF_ERR");
340                 if (err)
341                         return err;
342                 err = devlink_fmsg_u64_pair_put(fmsg, "\tNIX Error Interrupt Reg ",
343                                                 nix_event_context->nix_af_rvu_err);
344                 if (err)
345                         return err;
346                 if (intr_val & BIT_ULL(14)) {
347                         err = devlink_fmsg_string_put(fmsg, "\n\tFault on NIX_AQ_INST_S read");
348                         if (err)
349                                 return err;
350                 }
351                 if (intr_val & BIT_ULL(13)) {
352                         err = devlink_fmsg_string_put(fmsg, "\n\tFault on NIX_AQ_RES_S write");
353                         if (err)
354                                 return err;
355                 }
356                 if (intr_val & BIT_ULL(12)) {
357                         err = devlink_fmsg_string_put(fmsg, "\n\tAQ Doorbell Error");
358                         if (err)
359                                 return err;
360                 }
361                 if (intr_val & BIT_ULL(6)) {
362                         err = devlink_fmsg_string_put(fmsg, "\n\tRx on unmapped PF_FUNC");
363                         if (err)
364                                 return err;
365                 }
366                 if (intr_val & BIT_ULL(5)) {
367                         err = devlink_fmsg_string_put(fmsg, "\n\tRx multicast replication error");
368                         if (err)
369                                 return err;
370                 }
371                 if (intr_val & BIT_ULL(4)) {
372                         err = devlink_fmsg_string_put(fmsg, "\n\tFault on NIX_RX_MCE_S read");
373                         if (err)
374                                 return err;
375                 }
376                 if (intr_val & BIT_ULL(3)) {
377                         err = devlink_fmsg_string_put(fmsg, "\n\tFault on multicast WQE read");
378                         if (err)
379                                 return err;
380                 }
381                 if (intr_val & BIT_ULL(2)) {
382                         err = devlink_fmsg_string_put(fmsg, "\n\tFault on mirror WQE read");
383                         if (err)
384                                 return err;
385                 }
386                 if (intr_val & BIT_ULL(1)) {
387                         err = devlink_fmsg_string_put(fmsg, "\n\tFault on mirror pkt write");
388                         if (err)
389                                 return err;
390                 }
391                 if (intr_val & BIT_ULL(0)) {
392                         err = devlink_fmsg_string_put(fmsg, "\n\tFault on multicast pkt write");
393                         if (err)
394                                 return err;
395                 }
396                 err = rvu_report_pair_end(fmsg);
397                 if (err)
398                         return err;
399                 break;
400         case NIX_AF_RVU_RAS:
401                 intr_val = nix_event_context->nix_af_rvu_err;
402                 err = rvu_report_pair_start(fmsg, "NIX_AF_RAS");
403                 if (err)
404                         return err;
405                 err = devlink_fmsg_u64_pair_put(fmsg, "\tNIX RAS Interrupt Reg ",
406                                                 nix_event_context->nix_af_rvu_err);
407                 if (err)
408                         return err;
409                 err = devlink_fmsg_string_put(fmsg, "\n\tPoison Data on:");
410                 if (err)
411                         return err;
412                 if (intr_val & BIT_ULL(34)) {
413                         err = devlink_fmsg_string_put(fmsg, "\n\tNIX_AQ_INST_S");
414                         if (err)
415                                 return err;
416                 }
417                 if (intr_val & BIT_ULL(33)) {
418                         err = devlink_fmsg_string_put(fmsg, "\n\tNIX_AQ_RES_S");
419                         if (err)
420                                 return err;
421                 }
422                 if (intr_val & BIT_ULL(32)) {
423                         err = devlink_fmsg_string_put(fmsg, "\n\tHW ctx");
424                         if (err)
425                                 return err;
426                 }
427                 if (intr_val & BIT_ULL(4)) {
428                         err = devlink_fmsg_string_put(fmsg, "\n\tPacket from mirror buffer");
429                         if (err)
430                                 return err;
431                 }
432                 if (intr_val & BIT_ULL(3)) {
433                         err = devlink_fmsg_string_put(fmsg, "\n\tPacket from multicast buffer");
434
435                         if (err)
436                                 return err;
437                 }
438                 if (intr_val & BIT_ULL(2)) {
439                         err = devlink_fmsg_string_put(fmsg, "\n\tWQE read from mirror buffer");
440                         if (err)
441                                 return err;
442                 }
443                 if (intr_val & BIT_ULL(1)) {
444                         err = devlink_fmsg_string_put(fmsg, "\n\tWQE read from multicast buffer");
445                         if (err)
446                                 return err;
447                 }
448                 if (intr_val & BIT_ULL(0)) {
449                         err = devlink_fmsg_string_put(fmsg, "\n\tNIX_RX_MCE_S read");
450                         if (err)
451                                 return err;
452                 }
453                 err = rvu_report_pair_end(fmsg);
454                 if (err)
455                         return err;
456                 break;
457         default:
458                 return -EINVAL;
459         }
460
461         return 0;
462 }
463
464 static int rvu_hw_nix_intr_dump(struct devlink_health_reporter *reporter,
465                                 struct devlink_fmsg *fmsg, void *ctx,
466                                 struct netlink_ext_ack *netlink_extack)
467 {
468         struct rvu *rvu = devlink_health_reporter_priv(reporter);
469         struct rvu_devlink *rvu_dl = rvu->rvu_dl;
470         struct rvu_nix_event_ctx *nix_ctx;
471
472         nix_ctx = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
473
474         return ctx ? rvu_nix_report_show(fmsg, ctx, NIX_AF_RVU_INTR) :
475                      rvu_nix_report_show(fmsg, nix_ctx, NIX_AF_RVU_INTR);
476 }
477
478 static int rvu_hw_nix_intr_recover(struct devlink_health_reporter *reporter,
479                                    void *ctx, struct netlink_ext_ack *netlink_extack)
480 {
481         struct rvu *rvu = devlink_health_reporter_priv(reporter);
482         struct rvu_nix_event_ctx *nix_event_ctx = ctx;
483         int blkaddr;
484
485         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
486         if (blkaddr < 0)
487                 return blkaddr;
488
489         if (nix_event_ctx->nix_af_rvu_int)
490                 rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT_ENA_W1S, ~0ULL);
491
492         return 0;
493 }
494
495 static int rvu_hw_nix_gen_dump(struct devlink_health_reporter *reporter,
496                                struct devlink_fmsg *fmsg, void *ctx,
497                                struct netlink_ext_ack *netlink_extack)
498 {
499         struct rvu *rvu = devlink_health_reporter_priv(reporter);
500         struct rvu_devlink *rvu_dl = rvu->rvu_dl;
501         struct rvu_nix_event_ctx *nix_ctx;
502
503         nix_ctx = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
504
505         return ctx ? rvu_nix_report_show(fmsg, ctx, NIX_AF_RVU_GEN) :
506                      rvu_nix_report_show(fmsg, nix_ctx, NIX_AF_RVU_GEN);
507 }
508
509 static int rvu_hw_nix_gen_recover(struct devlink_health_reporter *reporter,
510                                   void *ctx, struct netlink_ext_ack *netlink_extack)
511 {
512         struct rvu *rvu = devlink_health_reporter_priv(reporter);
513         struct rvu_nix_event_ctx *nix_event_ctx = ctx;
514         int blkaddr;
515
516         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
517         if (blkaddr < 0)
518                 return blkaddr;
519
520         if (nix_event_ctx->nix_af_rvu_gen)
521                 rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT_ENA_W1S, ~0ULL);
522
523         return 0;
524 }
525
526 static int rvu_hw_nix_err_dump(struct devlink_health_reporter *reporter,
527                                struct devlink_fmsg *fmsg, void *ctx,
528                                struct netlink_ext_ack *netlink_extack)
529 {
530         struct rvu *rvu = devlink_health_reporter_priv(reporter);
531         struct rvu_devlink *rvu_dl = rvu->rvu_dl;
532         struct rvu_nix_event_ctx *nix_ctx;
533
534         nix_ctx = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
535
536         return ctx ? rvu_nix_report_show(fmsg, ctx, NIX_AF_RVU_ERR) :
537                      rvu_nix_report_show(fmsg, nix_ctx, NIX_AF_RVU_ERR);
538 }
539
540 static int rvu_hw_nix_err_recover(struct devlink_health_reporter *reporter,
541                                   void *ctx, struct netlink_ext_ack *netlink_extack)
542 {
543         struct rvu *rvu = devlink_health_reporter_priv(reporter);
544         struct rvu_nix_event_ctx *nix_event_ctx = ctx;
545         int blkaddr;
546
547         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
548         if (blkaddr < 0)
549                 return blkaddr;
550
551         if (nix_event_ctx->nix_af_rvu_err)
552                 rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT_ENA_W1S, ~0ULL);
553
554         return 0;
555 }
556
557 static int rvu_hw_nix_ras_dump(struct devlink_health_reporter *reporter,
558                                struct devlink_fmsg *fmsg, void *ctx,
559                                struct netlink_ext_ack *netlink_extack)
560 {
561         struct rvu *rvu = devlink_health_reporter_priv(reporter);
562         struct rvu_devlink *rvu_dl = rvu->rvu_dl;
563         struct rvu_nix_event_ctx *nix_ctx;
564
565         nix_ctx = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
566
567         return ctx ? rvu_nix_report_show(fmsg, ctx, NIX_AF_RVU_RAS) :
568                      rvu_nix_report_show(fmsg, nix_ctx, NIX_AF_RVU_RAS);
569 }
570
571 static int rvu_hw_nix_ras_recover(struct devlink_health_reporter *reporter,
572                                   void *ctx, struct netlink_ext_ack *netlink_extack)
573 {
574         struct rvu *rvu = devlink_health_reporter_priv(reporter);
575         struct rvu_nix_event_ctx *nix_event_ctx = ctx;
576         int blkaddr;
577
578         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
579         if (blkaddr < 0)
580                 return blkaddr;
581
582         if (nix_event_ctx->nix_af_rvu_int)
583                 rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1S, ~0ULL);
584
585         return 0;
586 }
587
588 RVU_REPORTERS(hw_nix_intr);
589 RVU_REPORTERS(hw_nix_gen);
590 RVU_REPORTERS(hw_nix_err);
591 RVU_REPORTERS(hw_nix_ras);
592
593 static void rvu_nix_health_reporters_destroy(struct rvu_devlink *rvu_dl);
594
595 static int rvu_nix_register_reporters(struct rvu_devlink *rvu_dl)
596 {
597         struct rvu_nix_health_reporters *rvu_reporters;
598         struct rvu_nix_event_ctx *nix_event_context;
599         struct rvu *rvu = rvu_dl->rvu;
600
601         rvu_reporters = kzalloc(sizeof(*rvu_reporters), GFP_KERNEL);
602         if (!rvu_reporters)
603                 return -ENOMEM;
604
605         rvu_dl->rvu_nix_health_reporter = rvu_reporters;
606         nix_event_context = kzalloc(sizeof(*nix_event_context), GFP_KERNEL);
607         if (!nix_event_context)
608                 return -ENOMEM;
609
610         rvu_reporters->nix_event_ctx = nix_event_context;
611         rvu_reporters->rvu_hw_nix_intr_reporter =
612                 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_nix_intr_reporter_ops, 0, rvu);
613         if (IS_ERR(rvu_reporters->rvu_hw_nix_intr_reporter)) {
614                 dev_warn(rvu->dev, "Failed to create hw_nix_intr reporter, err=%ld\n",
615                          PTR_ERR(rvu_reporters->rvu_hw_nix_intr_reporter));
616                 return PTR_ERR(rvu_reporters->rvu_hw_nix_intr_reporter);
617         }
618
619         rvu_reporters->rvu_hw_nix_gen_reporter =
620                 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_nix_gen_reporter_ops, 0, rvu);
621         if (IS_ERR(rvu_reporters->rvu_hw_nix_gen_reporter)) {
622                 dev_warn(rvu->dev, "Failed to create hw_nix_gen reporter, err=%ld\n",
623                          PTR_ERR(rvu_reporters->rvu_hw_nix_gen_reporter));
624                 return PTR_ERR(rvu_reporters->rvu_hw_nix_gen_reporter);
625         }
626
627         rvu_reporters->rvu_hw_nix_err_reporter =
628                 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_nix_err_reporter_ops, 0, rvu);
629         if (IS_ERR(rvu_reporters->rvu_hw_nix_err_reporter)) {
630                 dev_warn(rvu->dev, "Failed to create hw_nix_err reporter, err=%ld\n",
631                          PTR_ERR(rvu_reporters->rvu_hw_nix_err_reporter));
632                 return PTR_ERR(rvu_reporters->rvu_hw_nix_err_reporter);
633         }
634
635         rvu_reporters->rvu_hw_nix_ras_reporter =
636                 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_nix_ras_reporter_ops, 0, rvu);
637         if (IS_ERR(rvu_reporters->rvu_hw_nix_ras_reporter)) {
638                 dev_warn(rvu->dev, "Failed to create hw_nix_ras reporter, err=%ld\n",
639                          PTR_ERR(rvu_reporters->rvu_hw_nix_ras_reporter));
640                 return PTR_ERR(rvu_reporters->rvu_hw_nix_ras_reporter);
641         }
642
643         rvu_dl->devlink_wq = create_workqueue("rvu_devlink_wq");
644         if (!rvu_dl->devlink_wq)
645                 goto err;
646
647         INIT_WORK(&rvu_reporters->intr_work, rvu_nix_intr_work);
648         INIT_WORK(&rvu_reporters->gen_work, rvu_nix_gen_work);
649         INIT_WORK(&rvu_reporters->err_work, rvu_nix_err_work);
650         INIT_WORK(&rvu_reporters->ras_work, rvu_nix_ras_work);
651
652         return 0;
653 err:
654         rvu_nix_health_reporters_destroy(rvu_dl);
655         return -ENOMEM;
656 }
657
658 static int rvu_nix_health_reporters_create(struct rvu_devlink *rvu_dl)
659 {
660         struct rvu *rvu = rvu_dl->rvu;
661         int err;
662
663         err = rvu_nix_register_reporters(rvu_dl);
664         if (err) {
665                 dev_warn(rvu->dev, "Failed to create nix reporter, err =%d\n",
666                          err);
667                 return err;
668         }
669         rvu_nix_register_interrupts(rvu);
670
671         return 0;
672 }
673
674 static void rvu_nix_health_reporters_destroy(struct rvu_devlink *rvu_dl)
675 {
676         struct rvu_nix_health_reporters *nix_reporters;
677         struct rvu *rvu = rvu_dl->rvu;
678
679         nix_reporters = rvu_dl->rvu_nix_health_reporter;
680
681         if (!nix_reporters->rvu_hw_nix_ras_reporter)
682                 return;
683         if (!IS_ERR_OR_NULL(nix_reporters->rvu_hw_nix_intr_reporter))
684                 devlink_health_reporter_destroy(nix_reporters->rvu_hw_nix_intr_reporter);
685
686         if (!IS_ERR_OR_NULL(nix_reporters->rvu_hw_nix_gen_reporter))
687                 devlink_health_reporter_destroy(nix_reporters->rvu_hw_nix_gen_reporter);
688
689         if (!IS_ERR_OR_NULL(nix_reporters->rvu_hw_nix_err_reporter))
690                 devlink_health_reporter_destroy(nix_reporters->rvu_hw_nix_err_reporter);
691
692         if (!IS_ERR_OR_NULL(nix_reporters->rvu_hw_nix_ras_reporter))
693                 devlink_health_reporter_destroy(nix_reporters->rvu_hw_nix_ras_reporter);
694
695         rvu_nix_unregister_interrupts(rvu);
696         kfree(rvu_dl->rvu_nix_health_reporter->nix_event_ctx);
697         kfree(rvu_dl->rvu_nix_health_reporter);
698 }
699
700 static void rvu_npa_intr_work(struct work_struct *work)
701 {
702         struct rvu_npa_health_reporters *rvu_npa_health_reporter;
703
704         rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, intr_work);
705         devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_intr_reporter,
706                               "NPA_AF_RVU Error",
707                               rvu_npa_health_reporter->npa_event_ctx);
708 }
709
710 static irqreturn_t rvu_npa_af_rvu_intr_handler(int irq, void *rvu_irq)
711 {
712         struct rvu_npa_event_ctx *npa_event_context;
713         struct rvu_devlink *rvu_dl = rvu_irq;
714         struct rvu *rvu;
715         int blkaddr;
716         u64 intr;
717
718         rvu = rvu_dl->rvu;
719         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
720         if (blkaddr < 0)
721                 return IRQ_NONE;
722
723         npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
724         intr = rvu_read64(rvu, blkaddr, NPA_AF_RVU_INT);
725         npa_event_context->npa_af_rvu_int = intr;
726
727         /* Clear interrupts */
728         rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT, intr);
729         rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1C, ~0ULL);
730         queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->intr_work);
731
732         return IRQ_HANDLED;
733 }
734
735 static void rvu_npa_gen_work(struct work_struct *work)
736 {
737         struct rvu_npa_health_reporters *rvu_npa_health_reporter;
738
739         rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, gen_work);
740         devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_gen_reporter,
741                               "NPA_AF_GEN Error",
742                               rvu_npa_health_reporter->npa_event_ctx);
743 }
744
745 static irqreturn_t rvu_npa_af_gen_intr_handler(int irq, void *rvu_irq)
746 {
747         struct rvu_npa_event_ctx *npa_event_context;
748         struct rvu_devlink *rvu_dl = rvu_irq;
749         struct rvu *rvu;
750         int blkaddr;
751         u64 intr;
752
753         rvu = rvu_dl->rvu;
754         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
755         if (blkaddr < 0)
756                 return IRQ_NONE;
757
758         npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
759         intr = rvu_read64(rvu, blkaddr, NPA_AF_GEN_INT);
760         npa_event_context->npa_af_rvu_gen = intr;
761
762         /* Clear interrupts */
763         rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT, intr);
764         rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1C, ~0ULL);
765         queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->gen_work);
766
767         return IRQ_HANDLED;
768 }
769
770 static void rvu_npa_err_work(struct work_struct *work)
771 {
772         struct rvu_npa_health_reporters *rvu_npa_health_reporter;
773
774         rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, err_work);
775         devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_err_reporter,
776                               "NPA_AF_ERR Error",
777                               rvu_npa_health_reporter->npa_event_ctx);
778 }
779
780 static irqreturn_t rvu_npa_af_err_intr_handler(int irq, void *rvu_irq)
781 {
782         struct rvu_npa_event_ctx *npa_event_context;
783         struct rvu_devlink *rvu_dl = rvu_irq;
784         struct rvu *rvu;
785         int blkaddr;
786         u64 intr;
787
788         rvu = rvu_dl->rvu;
789         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
790         if (blkaddr < 0)
791                 return IRQ_NONE;
792         npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
793         intr = rvu_read64(rvu, blkaddr, NPA_AF_ERR_INT);
794         npa_event_context->npa_af_rvu_err = intr;
795
796         /* Clear interrupts */
797         rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT, intr);
798         rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1C, ~0ULL);
799         queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->err_work);
800
801         return IRQ_HANDLED;
802 }
803
804 static void rvu_npa_ras_work(struct work_struct *work)
805 {
806         struct rvu_npa_health_reporters *rvu_npa_health_reporter;
807
808         rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, ras_work);
809         devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_ras_reporter,
810                               "HW NPA_AF_RAS Error reported",
811                               rvu_npa_health_reporter->npa_event_ctx);
812 }
813
814 static irqreturn_t rvu_npa_af_ras_intr_handler(int irq, void *rvu_irq)
815 {
816         struct rvu_npa_event_ctx *npa_event_context;
817         struct rvu_devlink *rvu_dl = rvu_irq;
818         struct rvu *rvu;
819         int blkaddr;
820         u64 intr;
821
822         rvu = rvu_dl->rvu;
823         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
824         if (blkaddr < 0)
825                 return IRQ_NONE;
826
827         npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
828         intr = rvu_read64(rvu, blkaddr, NPA_AF_RAS);
829         npa_event_context->npa_af_rvu_ras = intr;
830
831         /* Clear interrupts */
832         rvu_write64(rvu, blkaddr, NPA_AF_RAS, intr);
833         rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1C, ~0ULL);
834         queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->ras_work);
835
836         return IRQ_HANDLED;
837 }
838
839 static void rvu_npa_unregister_interrupts(struct rvu *rvu)
840 {
841         struct rvu_devlink *rvu_dl = rvu->rvu_dl;
842         int i, offs, blkaddr;
843         u64 reg;
844
845         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
846         if (blkaddr < 0)
847                 return;
848
849         reg = rvu_read64(rvu, blkaddr, NPA_PRIV_AF_INT_CFG);
850         offs = reg & 0x3FF;
851
852         rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1C, ~0ULL);
853         rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1C, ~0ULL);
854         rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1C, ~0ULL);
855         rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1C, ~0ULL);
856
857         for (i = 0; i < NPA_AF_INT_VEC_CNT; i++)
858                 if (rvu->irq_allocated[offs + i]) {
859                         free_irq(pci_irq_vector(rvu->pdev, offs + i), rvu_dl);
860                         rvu->irq_allocated[offs + i] = false;
861                 }
862 }
863
864 static int rvu_npa_register_interrupts(struct rvu *rvu)
865 {
866         int blkaddr, base;
867         bool rc;
868
869         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
870         if (blkaddr < 0)
871                 return blkaddr;
872
873         /* Get NPA AF MSIX vectors offset. */
874         base = rvu_read64(rvu, blkaddr, NPA_PRIV_AF_INT_CFG) & 0x3ff;
875         if (!base) {
876                 dev_warn(rvu->dev,
877                          "Failed to get NPA_AF_INT vector offsets\n");
878                 return 0;
879         }
880
881         /* Register and enable NPA_AF_RVU_INT interrupt */
882         rc = rvu_common_request_irq(rvu, base +  NPA_AF_INT_VEC_RVU,
883                                     "NPA_AF_RVU_INT",
884                                     rvu_npa_af_rvu_intr_handler);
885         if (!rc)
886                 goto err;
887         rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1S, ~0ULL);
888
889         /* Register and enable NPA_AF_GEN_INT interrupt */
890         rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_GEN,
891                                     "NPA_AF_RVU_GEN",
892                                     rvu_npa_af_gen_intr_handler);
893         if (!rc)
894                 goto err;
895         rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1S, ~0ULL);
896
897         /* Register and enable NPA_AF_ERR_INT interrupt */
898         rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_AF_ERR,
899                                     "NPA_AF_ERR_INT",
900                                     rvu_npa_af_err_intr_handler);
901         if (!rc)
902                 goto err;
903         rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1S, ~0ULL);
904
905         /* Register and enable NPA_AF_RAS interrupt */
906         rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_POISON,
907                                     "NPA_AF_RAS",
908                                     rvu_npa_af_ras_intr_handler);
909         if (!rc)
910                 goto err;
911         rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1S, ~0ULL);
912
913         return 0;
914 err:
915         rvu_npa_unregister_interrupts(rvu);
916         return rc;
917 }
918
919 static int rvu_npa_report_show(struct devlink_fmsg *fmsg, void *ctx,
920                                enum npa_af_rvu_health health_reporter)
921 {
922         struct rvu_npa_event_ctx *npa_event_context;
923         unsigned int alloc_dis, free_dis;
924         u64 intr_val;
925         int err;
926
927         npa_event_context = ctx;
928         switch (health_reporter) {
929         case NPA_AF_RVU_GEN:
930                 intr_val = npa_event_context->npa_af_rvu_gen;
931                 err = rvu_report_pair_start(fmsg, "NPA_AF_GENERAL");
932                 if (err)
933                         return err;
934                 err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA General Interrupt Reg ",
935                                                 npa_event_context->npa_af_rvu_gen);
936                 if (err)
937                         return err;
938                 if (intr_val & BIT_ULL(32)) {
939                         err = devlink_fmsg_string_put(fmsg, "\n\tUnmap PF Error");
940                         if (err)
941                                 return err;
942                 }
943
944                 free_dis = FIELD_GET(GENMASK(15, 0), intr_val);
945                 if (free_dis & BIT(NPA_INPQ_NIX0_RX)) {
946                         err = devlink_fmsg_string_put(fmsg, "\n\tNIX0: free disabled RX");
947                         if (err)
948                                 return err;
949                 }
950                 if (free_dis & BIT(NPA_INPQ_NIX0_TX)) {
951                         err = devlink_fmsg_string_put(fmsg, "\n\tNIX0:free disabled TX");
952                         if (err)
953                                 return err;
954                 }
955                 if (free_dis & BIT(NPA_INPQ_NIX1_RX)) {
956                         err = devlink_fmsg_string_put(fmsg, "\n\tNIX1: free disabled RX");
957                         if (err)
958                                 return err;
959                 }
960                 if (free_dis & BIT(NPA_INPQ_NIX1_TX)) {
961                         err = devlink_fmsg_string_put(fmsg, "\n\tNIX1:free disabled TX");
962                         if (err)
963                                 return err;
964                 }
965                 if (free_dis & BIT(NPA_INPQ_SSO)) {
966                         err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for SSO");
967                         if (err)
968                                 return err;
969                 }
970                 if (free_dis & BIT(NPA_INPQ_TIM)) {
971                         err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for TIM");
972                         if (err)
973                                 return err;
974                 }
975                 if (free_dis & BIT(NPA_INPQ_DPI)) {
976                         err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for DPI");
977                         if (err)
978                                 return err;
979                 }
980                 if (free_dis & BIT(NPA_INPQ_AURA_OP)) {
981                         err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for AURA");
982                         if (err)
983                                 return err;
984                 }
985
986                 alloc_dis = FIELD_GET(GENMASK(31, 16), intr_val);
987                 if (alloc_dis & BIT(NPA_INPQ_NIX0_RX)) {
988                         err = devlink_fmsg_string_put(fmsg, "\n\tNIX0: alloc disabled RX");
989                         if (err)
990                                 return err;
991                 }
992                 if (alloc_dis & BIT(NPA_INPQ_NIX0_TX)) {
993                         err = devlink_fmsg_string_put(fmsg, "\n\tNIX0:alloc disabled TX");
994                         if (err)
995                                 return err;
996                 }
997                 if (alloc_dis & BIT(NPA_INPQ_NIX1_RX)) {
998                         err = devlink_fmsg_string_put(fmsg, "\n\tNIX1: alloc disabled RX");
999                         if (err)
1000                                 return err;
1001                 }
1002                 if (alloc_dis & BIT(NPA_INPQ_NIX1_TX)) {
1003                         err = devlink_fmsg_string_put(fmsg, "\n\tNIX1:alloc disabled TX");
1004                         if (err)
1005                                 return err;
1006                 }
1007                 if (alloc_dis & BIT(NPA_INPQ_SSO)) {
1008                         err = devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for SSO");
1009                         if (err)
1010                                 return err;
1011                 }
1012                 if (alloc_dis & BIT(NPA_INPQ_TIM)) {
1013                         err = devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for TIM");
1014                         if (err)
1015                                 return err;
1016                 }
1017                 if (alloc_dis & BIT(NPA_INPQ_DPI)) {
1018                         err = devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for DPI");
1019                         if (err)
1020                                 return err;
1021                 }
1022                 if (alloc_dis & BIT(NPA_INPQ_AURA_OP)) {
1023                         err = devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for AURA");
1024                         if (err)
1025                                 return err;
1026                 }
1027                 err = rvu_report_pair_end(fmsg);
1028                 if (err)
1029                         return err;
1030                 break;
1031         case NPA_AF_RVU_ERR:
1032                 err = rvu_report_pair_start(fmsg, "NPA_AF_ERR");
1033                 if (err)
1034                         return err;
1035                 err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA Error Interrupt Reg ",
1036                                                 npa_event_context->npa_af_rvu_err);
1037                 if (err)
1038                         return err;
1039
1040                 if (npa_event_context->npa_af_rvu_err & BIT_ULL(14)) {
1041                         err = devlink_fmsg_string_put(fmsg, "\n\tFault on NPA_AQ_INST_S read");
1042                         if (err)
1043                                 return err;
1044                 }
1045                 if (npa_event_context->npa_af_rvu_err & BIT_ULL(13)) {
1046                         err = devlink_fmsg_string_put(fmsg, "\n\tFault on NPA_AQ_RES_S write");
1047                         if (err)
1048                                 return err;
1049                 }
1050                 if (npa_event_context->npa_af_rvu_err & BIT_ULL(12)) {
1051                         err = devlink_fmsg_string_put(fmsg, "\n\tAQ Doorbell Error");
1052                         if (err)
1053                                 return err;
1054                 }
1055                 err = rvu_report_pair_end(fmsg);
1056                 if (err)
1057                         return err;
1058                 break;
1059         case NPA_AF_RVU_RAS:
1060                 err = rvu_report_pair_start(fmsg, "NPA_AF_RVU_RAS");
1061                 if (err)
1062                         return err;
1063                 err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA RAS Interrupt Reg ",
1064                                                 npa_event_context->npa_af_rvu_ras);
1065                 if (err)
1066                         return err;
1067                 if (npa_event_context->npa_af_rvu_ras & BIT_ULL(34)) {
1068                         err = devlink_fmsg_string_put(fmsg, "\n\tPoison data on NPA_AQ_INST_S");
1069                         if (err)
1070                                 return err;
1071                 }
1072                 if (npa_event_context->npa_af_rvu_ras & BIT_ULL(33)) {
1073                         err = devlink_fmsg_string_put(fmsg, "\n\tPoison data on NPA_AQ_RES_S");
1074                         if (err)
1075                                 return err;
1076                 }
1077                 if (npa_event_context->npa_af_rvu_ras & BIT_ULL(32)) {
1078                         err = devlink_fmsg_string_put(fmsg, "\n\tPoison data on HW context");
1079                         if (err)
1080                                 return err;
1081                 }
1082                 err = rvu_report_pair_end(fmsg);
1083                 if (err)
1084                         return err;
1085                 break;
1086         case NPA_AF_RVU_INTR:
1087                 err = rvu_report_pair_start(fmsg, "NPA_AF_RVU");
1088                 if (err)
1089                         return err;
1090                 err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA RVU Interrupt Reg ",
1091                                                 npa_event_context->npa_af_rvu_int);
1092                 if (err)
1093                         return err;
1094                 if (npa_event_context->npa_af_rvu_int & BIT_ULL(0)) {
1095                         err = devlink_fmsg_string_put(fmsg, "\n\tUnmap Slot Error");
1096                         if (err)
1097                                 return err;
1098                 }
1099                 return rvu_report_pair_end(fmsg);
1100         default:
1101                 return -EINVAL;
1102         }
1103
1104         return 0;
1105 }
1106
1107 static int rvu_hw_npa_intr_dump(struct devlink_health_reporter *reporter,
1108                                 struct devlink_fmsg *fmsg, void *ctx,
1109                                 struct netlink_ext_ack *netlink_extack)
1110 {
1111         struct rvu *rvu = devlink_health_reporter_priv(reporter);
1112         struct rvu_devlink *rvu_dl = rvu->rvu_dl;
1113         struct rvu_npa_event_ctx *npa_ctx;
1114
1115         npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
1116
1117         return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_INTR) :
1118                      rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_INTR);
1119 }
1120
1121 static int rvu_hw_npa_intr_recover(struct devlink_health_reporter *reporter,
1122                                    void *ctx, struct netlink_ext_ack *netlink_extack)
1123 {
1124         struct rvu *rvu = devlink_health_reporter_priv(reporter);
1125         struct rvu_npa_event_ctx *npa_event_ctx = ctx;
1126         int blkaddr;
1127
1128         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
1129         if (blkaddr < 0)
1130                 return blkaddr;
1131
1132         if (npa_event_ctx->npa_af_rvu_int)
1133                 rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1S, ~0ULL);
1134
1135         return 0;
1136 }
1137
1138 static int rvu_hw_npa_gen_dump(struct devlink_health_reporter *reporter,
1139                                struct devlink_fmsg *fmsg, void *ctx,
1140                                struct netlink_ext_ack *netlink_extack)
1141 {
1142         struct rvu *rvu = devlink_health_reporter_priv(reporter);
1143         struct rvu_devlink *rvu_dl = rvu->rvu_dl;
1144         struct rvu_npa_event_ctx *npa_ctx;
1145
1146         npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
1147
1148         return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_GEN) :
1149                      rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_GEN);
1150 }
1151
1152 static int rvu_hw_npa_gen_recover(struct devlink_health_reporter *reporter,
1153                                   void *ctx, struct netlink_ext_ack *netlink_extack)
1154 {
1155         struct rvu *rvu = devlink_health_reporter_priv(reporter);
1156         struct rvu_npa_event_ctx *npa_event_ctx = ctx;
1157         int blkaddr;
1158
1159         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
1160         if (blkaddr < 0)
1161                 return blkaddr;
1162
1163         if (npa_event_ctx->npa_af_rvu_gen)
1164                 rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1S, ~0ULL);
1165
1166         return 0;
1167 }
1168
1169 static int rvu_hw_npa_err_dump(struct devlink_health_reporter *reporter,
1170                                struct devlink_fmsg *fmsg, void *ctx,
1171                                struct netlink_ext_ack *netlink_extack)
1172 {
1173         struct rvu *rvu = devlink_health_reporter_priv(reporter);
1174         struct rvu_devlink *rvu_dl = rvu->rvu_dl;
1175         struct rvu_npa_event_ctx *npa_ctx;
1176
1177         npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
1178
1179         return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_ERR) :
1180                      rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_ERR);
1181 }
1182
1183 static int rvu_hw_npa_err_recover(struct devlink_health_reporter *reporter,
1184                                   void *ctx, struct netlink_ext_ack *netlink_extack)
1185 {
1186         struct rvu *rvu = devlink_health_reporter_priv(reporter);
1187         struct rvu_npa_event_ctx *npa_event_ctx = ctx;
1188         int blkaddr;
1189
1190         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
1191         if (blkaddr < 0)
1192                 return blkaddr;
1193
1194         if (npa_event_ctx->npa_af_rvu_err)
1195                 rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1S, ~0ULL);
1196
1197         return 0;
1198 }
1199
1200 static int rvu_hw_npa_ras_dump(struct devlink_health_reporter *reporter,
1201                                struct devlink_fmsg *fmsg, void *ctx,
1202                                struct netlink_ext_ack *netlink_extack)
1203 {
1204         struct rvu *rvu = devlink_health_reporter_priv(reporter);
1205         struct rvu_devlink *rvu_dl = rvu->rvu_dl;
1206         struct rvu_npa_event_ctx *npa_ctx;
1207
1208         npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
1209
1210         return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_RAS) :
1211                      rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_RAS);
1212 }
1213
1214 static int rvu_hw_npa_ras_recover(struct devlink_health_reporter *reporter,
1215                                   void *ctx, struct netlink_ext_ack *netlink_extack)
1216 {
1217         struct rvu *rvu = devlink_health_reporter_priv(reporter);
1218         struct rvu_npa_event_ctx *npa_event_ctx = ctx;
1219         int blkaddr;
1220
1221         blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
1222         if (blkaddr < 0)
1223                 return blkaddr;
1224
1225         if (npa_event_ctx->npa_af_rvu_ras)
1226                 rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1S, ~0ULL);
1227
1228         return 0;
1229 }
1230
1231 RVU_REPORTERS(hw_npa_intr);
1232 RVU_REPORTERS(hw_npa_gen);
1233 RVU_REPORTERS(hw_npa_err);
1234 RVU_REPORTERS(hw_npa_ras);
1235
1236 static void rvu_npa_health_reporters_destroy(struct rvu_devlink *rvu_dl);
1237
1238 static int rvu_npa_register_reporters(struct rvu_devlink *rvu_dl)
1239 {
1240         struct rvu_npa_health_reporters *rvu_reporters;
1241         struct rvu_npa_event_ctx *npa_event_context;
1242         struct rvu *rvu = rvu_dl->rvu;
1243
1244         rvu_reporters = kzalloc(sizeof(*rvu_reporters), GFP_KERNEL);
1245         if (!rvu_reporters)
1246                 return -ENOMEM;
1247
1248         rvu_dl->rvu_npa_health_reporter = rvu_reporters;
1249         npa_event_context = kzalloc(sizeof(*npa_event_context), GFP_KERNEL);
1250         if (!npa_event_context)
1251                 return -ENOMEM;
1252
1253         rvu_reporters->npa_event_ctx = npa_event_context;
1254         rvu_reporters->rvu_hw_npa_intr_reporter =
1255                 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_intr_reporter_ops, 0, rvu);
1256         if (IS_ERR(rvu_reporters->rvu_hw_npa_intr_reporter)) {
1257                 dev_warn(rvu->dev, "Failed to create hw_npa_intr reporter, err=%ld\n",
1258                          PTR_ERR(rvu_reporters->rvu_hw_npa_intr_reporter));
1259                 return PTR_ERR(rvu_reporters->rvu_hw_npa_intr_reporter);
1260         }
1261
1262         rvu_reporters->rvu_hw_npa_gen_reporter =
1263                 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_gen_reporter_ops, 0, rvu);
1264         if (IS_ERR(rvu_reporters->rvu_hw_npa_gen_reporter)) {
1265                 dev_warn(rvu->dev, "Failed to create hw_npa_gen reporter, err=%ld\n",
1266                          PTR_ERR(rvu_reporters->rvu_hw_npa_gen_reporter));
1267                 return PTR_ERR(rvu_reporters->rvu_hw_npa_gen_reporter);
1268         }
1269
1270         rvu_reporters->rvu_hw_npa_err_reporter =
1271                 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_err_reporter_ops, 0, rvu);
1272         if (IS_ERR(rvu_reporters->rvu_hw_npa_err_reporter)) {
1273                 dev_warn(rvu->dev, "Failed to create hw_npa_err reporter, err=%ld\n",
1274                          PTR_ERR(rvu_reporters->rvu_hw_npa_err_reporter));
1275                 return PTR_ERR(rvu_reporters->rvu_hw_npa_err_reporter);
1276         }
1277
1278         rvu_reporters->rvu_hw_npa_ras_reporter =
1279                 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_ras_reporter_ops, 0, rvu);
1280         if (IS_ERR(rvu_reporters->rvu_hw_npa_ras_reporter)) {
1281                 dev_warn(rvu->dev, "Failed to create hw_npa_ras reporter, err=%ld\n",
1282                          PTR_ERR(rvu_reporters->rvu_hw_npa_ras_reporter));
1283                 return PTR_ERR(rvu_reporters->rvu_hw_npa_ras_reporter);
1284         }
1285
1286         rvu_dl->devlink_wq = create_workqueue("rvu_devlink_wq");
1287         if (!rvu_dl->devlink_wq)
1288                 goto err;
1289
1290         INIT_WORK(&rvu_reporters->intr_work, rvu_npa_intr_work);
1291         INIT_WORK(&rvu_reporters->err_work, rvu_npa_err_work);
1292         INIT_WORK(&rvu_reporters->gen_work, rvu_npa_gen_work);
1293         INIT_WORK(&rvu_reporters->ras_work, rvu_npa_ras_work);
1294
1295         return 0;
1296 err:
1297         rvu_npa_health_reporters_destroy(rvu_dl);
1298         return -ENOMEM;
1299 }
1300
1301 static int rvu_npa_health_reporters_create(struct rvu_devlink *rvu_dl)
1302 {
1303         struct rvu *rvu = rvu_dl->rvu;
1304         int err;
1305
1306         err = rvu_npa_register_reporters(rvu_dl);
1307         if (err) {
1308                 dev_warn(rvu->dev, "Failed to create npa reporter, err =%d\n",
1309                          err);
1310                 return err;
1311         }
1312         rvu_npa_register_interrupts(rvu);
1313
1314         return 0;
1315 }
1316
1317 static void rvu_npa_health_reporters_destroy(struct rvu_devlink *rvu_dl)
1318 {
1319         struct rvu_npa_health_reporters *npa_reporters;
1320         struct rvu *rvu = rvu_dl->rvu;
1321
1322         npa_reporters = rvu_dl->rvu_npa_health_reporter;
1323
1324         if (!npa_reporters->rvu_hw_npa_ras_reporter)
1325                 return;
1326         if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_intr_reporter))
1327                 devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_intr_reporter);
1328
1329         if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_gen_reporter))
1330                 devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_gen_reporter);
1331
1332         if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_err_reporter))
1333                 devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_err_reporter);
1334
1335         if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_ras_reporter))
1336                 devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_ras_reporter);
1337
1338         rvu_npa_unregister_interrupts(rvu);
1339         kfree(rvu_dl->rvu_npa_health_reporter->npa_event_ctx);
1340         kfree(rvu_dl->rvu_npa_health_reporter);
1341 }
1342
1343 static int rvu_health_reporters_create(struct rvu *rvu)
1344 {
1345         struct rvu_devlink *rvu_dl;
1346         int err;
1347
1348         rvu_dl = rvu->rvu_dl;
1349         err = rvu_npa_health_reporters_create(rvu_dl);
1350         if (err)
1351                 return err;
1352
1353         return rvu_nix_health_reporters_create(rvu_dl);
1354 }
1355
1356 static void rvu_health_reporters_destroy(struct rvu *rvu)
1357 {
1358         struct rvu_devlink *rvu_dl;
1359
1360         if (!rvu->rvu_dl)
1361                 return;
1362
1363         rvu_dl = rvu->rvu_dl;
1364         rvu_npa_health_reporters_destroy(rvu_dl);
1365         rvu_nix_health_reporters_destroy(rvu_dl);
1366 }
1367
1368 /* Devlink Params APIs */
1369 static int rvu_af_dl_dwrr_mtu_validate(struct devlink *devlink, u32 id,
1370                                        union devlink_param_value val,
1371                                        struct netlink_ext_ack *extack)
1372 {
1373         struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1374         struct rvu *rvu = rvu_dl->rvu;
1375         int dwrr_mtu = val.vu32;
1376         struct nix_txsch *txsch;
1377         struct nix_hw *nix_hw;
1378
1379         if (!rvu->hw->cap.nix_common_dwrr_mtu) {
1380                 NL_SET_ERR_MSG_MOD(extack,
1381                                    "Setting DWRR_MTU is not supported on this silicon");
1382                 return -EOPNOTSUPP;
1383         }
1384
1385         if ((dwrr_mtu > 65536 || !is_power_of_2(dwrr_mtu)) &&
1386             (dwrr_mtu != 9728 && dwrr_mtu != 10240)) {
1387                 NL_SET_ERR_MSG_MOD(extack,
1388                                    "Invalid, supported MTUs are 0,2,4,8.16,32,64....4K,8K,32K,64K and 9728, 10240");
1389                 return -EINVAL;
1390         }
1391
1392         nix_hw = get_nix_hw(rvu->hw, BLKADDR_NIX0);
1393         if (!nix_hw)
1394                 return -ENODEV;
1395
1396         txsch = &nix_hw->txsch[NIX_TXSCH_LVL_SMQ];
1397         if (rvu_rsrc_free_count(&txsch->schq) != txsch->schq.max) {
1398                 NL_SET_ERR_MSG_MOD(extack,
1399                                    "Changing DWRR MTU is not supported when there are active NIXLFs");
1400                 NL_SET_ERR_MSG_MOD(extack,
1401                                    "Make sure none of the PF/VF interfaces are initialized and retry");
1402                 return -EOPNOTSUPP;
1403         }
1404
1405         return 0;
1406 }
1407
1408 static int rvu_af_dl_dwrr_mtu_set(struct devlink *devlink, u32 id,
1409                                   struct devlink_param_gset_ctx *ctx)
1410 {
1411         struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1412         struct rvu *rvu = rvu_dl->rvu;
1413         u64 dwrr_mtu;
1414
1415         dwrr_mtu = convert_bytes_to_dwrr_mtu(ctx->val.vu32);
1416         rvu_write64(rvu, BLKADDR_NIX0, NIX_AF_DWRR_RPM_MTU, dwrr_mtu);
1417
1418         return 0;
1419 }
1420
1421 static int rvu_af_dl_dwrr_mtu_get(struct devlink *devlink, u32 id,
1422                                   struct devlink_param_gset_ctx *ctx)
1423 {
1424         struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1425         struct rvu *rvu = rvu_dl->rvu;
1426         u64 dwrr_mtu;
1427
1428         if (!rvu->hw->cap.nix_common_dwrr_mtu)
1429                 return -EOPNOTSUPP;
1430
1431         dwrr_mtu = rvu_read64(rvu, BLKADDR_NIX0, NIX_AF_DWRR_RPM_MTU);
1432         ctx->val.vu32 = convert_dwrr_mtu_to_bytes(dwrr_mtu);
1433
1434         return 0;
1435 }
1436
1437 enum rvu_af_dl_param_id {
1438         RVU_AF_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
1439         RVU_AF_DEVLINK_PARAM_ID_DWRR_MTU,
1440         RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE,
1441 };
1442
1443 static int rvu_af_npc_exact_feature_get(struct devlink *devlink, u32 id,
1444                                         struct devlink_param_gset_ctx *ctx)
1445 {
1446         struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1447         struct rvu *rvu = rvu_dl->rvu;
1448         bool enabled;
1449
1450         enabled = rvu_npc_exact_has_match_table(rvu);
1451
1452         snprintf(ctx->val.vstr, sizeof(ctx->val.vstr), "%s",
1453                  enabled ? "enabled" : "disabled");
1454
1455         return 0;
1456 }
1457
1458 static int rvu_af_npc_exact_feature_disable(struct devlink *devlink, u32 id,
1459                                             struct devlink_param_gset_ctx *ctx)
1460 {
1461         struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1462         struct rvu *rvu = rvu_dl->rvu;
1463
1464         rvu_npc_exact_disable_feature(rvu);
1465
1466         return 0;
1467 }
1468
1469 static int rvu_af_npc_exact_feature_validate(struct devlink *devlink, u32 id,
1470                                              union devlink_param_value val,
1471                                              struct netlink_ext_ack *extack)
1472 {
1473         struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1474         struct rvu *rvu = rvu_dl->rvu;
1475         u64 enable;
1476
1477         if (kstrtoull(val.vstr, 10, &enable)) {
1478                 NL_SET_ERR_MSG_MOD(extack,
1479                                    "Only 1 value is supported");
1480                 return -EINVAL;
1481         }
1482
1483         if (enable != 1) {
1484                 NL_SET_ERR_MSG_MOD(extack,
1485                                    "Only disabling exact match feature is supported");
1486                 return -EINVAL;
1487         }
1488
1489         if (rvu_npc_exact_can_disable_feature(rvu))
1490                 return 0;
1491
1492         NL_SET_ERR_MSG_MOD(extack,
1493                            "Can't disable exact match feature; Please try before any configuration");
1494         return -EFAULT;
1495 }
1496
1497 static const struct devlink_param rvu_af_dl_params[] = {
1498         DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_DWRR_MTU,
1499                              "dwrr_mtu", DEVLINK_PARAM_TYPE_U32,
1500                              BIT(DEVLINK_PARAM_CMODE_RUNTIME),
1501                              rvu_af_dl_dwrr_mtu_get, rvu_af_dl_dwrr_mtu_set,
1502                              rvu_af_dl_dwrr_mtu_validate),
1503 };
1504
1505 static const struct devlink_param rvu_af_dl_param_exact_match[] = {
1506         DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE,
1507                              "npc_exact_feature_disable", DEVLINK_PARAM_TYPE_STRING,
1508                              BIT(DEVLINK_PARAM_CMODE_RUNTIME),
1509                              rvu_af_npc_exact_feature_get,
1510                              rvu_af_npc_exact_feature_disable,
1511                              rvu_af_npc_exact_feature_validate),
1512 };
1513
1514 /* Devlink switch mode */
1515 static int rvu_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode)
1516 {
1517         struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1518         struct rvu *rvu = rvu_dl->rvu;
1519         struct rvu_switch *rswitch;
1520
1521         rswitch = &rvu->rswitch;
1522         *mode = rswitch->mode;
1523
1524         return 0;
1525 }
1526
1527 static int rvu_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
1528                                         struct netlink_ext_ack *extack)
1529 {
1530         struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1531         struct rvu *rvu = rvu_dl->rvu;
1532         struct rvu_switch *rswitch;
1533
1534         rswitch = &rvu->rswitch;
1535         switch (mode) {
1536         case DEVLINK_ESWITCH_MODE_LEGACY:
1537         case DEVLINK_ESWITCH_MODE_SWITCHDEV:
1538                 if (rswitch->mode == mode)
1539                         return 0;
1540                 rswitch->mode = mode;
1541                 if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV)
1542                         rvu_switch_enable(rvu);
1543                 else
1544                         rvu_switch_disable(rvu);
1545                 break;
1546         default:
1547                 return -EINVAL;
1548         }
1549
1550         return 0;
1551 }
1552
1553 static const struct devlink_ops rvu_devlink_ops = {
1554         .eswitch_mode_get = rvu_devlink_eswitch_mode_get,
1555         .eswitch_mode_set = rvu_devlink_eswitch_mode_set,
1556 };
1557
1558 int rvu_register_dl(struct rvu *rvu)
1559 {
1560         struct rvu_devlink *rvu_dl;
1561         struct devlink *dl;
1562         int err;
1563
1564         dl = devlink_alloc(&rvu_devlink_ops, sizeof(struct rvu_devlink),
1565                            rvu->dev);
1566         if (!dl) {
1567                 dev_warn(rvu->dev, "devlink_alloc failed\n");
1568                 return -ENOMEM;
1569         }
1570
1571         rvu_dl = devlink_priv(dl);
1572         rvu_dl->dl = dl;
1573         rvu_dl->rvu = rvu;
1574         rvu->rvu_dl = rvu_dl;
1575
1576         err = rvu_health_reporters_create(rvu);
1577         if (err) {
1578                 dev_err(rvu->dev,
1579                         "devlink health reporter creation failed with error %d\n", err);
1580                 goto err_dl_health;
1581         }
1582
1583         err = devlink_params_register(dl, rvu_af_dl_params, ARRAY_SIZE(rvu_af_dl_params));
1584         if (err) {
1585                 dev_err(rvu->dev,
1586                         "devlink params register failed with error %d", err);
1587                 goto err_dl_health;
1588         }
1589
1590         /* Register exact match devlink only for CN10K-B */
1591         if (!rvu_npc_exact_has_match_table(rvu))
1592                 goto done;
1593
1594         err = devlink_params_register(dl, rvu_af_dl_param_exact_match,
1595                                       ARRAY_SIZE(rvu_af_dl_param_exact_match));
1596         if (err) {
1597                 dev_err(rvu->dev,
1598                         "devlink exact match params register failed with error %d", err);
1599                 goto err_dl_exact_match;
1600         }
1601
1602 done:
1603         devlink_register(dl);
1604         return 0;
1605
1606 err_dl_exact_match:
1607         devlink_params_unregister(dl, rvu_af_dl_params, ARRAY_SIZE(rvu_af_dl_params));
1608
1609 err_dl_health:
1610         rvu_health_reporters_destroy(rvu);
1611         devlink_free(dl);
1612         return err;
1613 }
1614
1615 void rvu_unregister_dl(struct rvu *rvu)
1616 {
1617         struct rvu_devlink *rvu_dl = rvu->rvu_dl;
1618         struct devlink *dl = rvu_dl->dl;
1619
1620         devlink_unregister(dl);
1621
1622         devlink_params_unregister(dl, rvu_af_dl_params, ARRAY_SIZE(rvu_af_dl_params));
1623
1624         /* Unregister exact match devlink only for CN10K-B */
1625         if (rvu_npc_exact_has_match_table(rvu))
1626                 devlink_params_unregister(dl, rvu_af_dl_param_exact_match,
1627                                           ARRAY_SIZE(rvu_af_dl_param_exact_match));
1628
1629         rvu_health_reporters_destroy(rvu);
1630         devlink_free(dl);
1631 }