1 // SPDX-License-Identifier: GPL-2.0
2 /* Marvell OcteonTx2 RVU Devlink
4 * Copyright (C) 2020 Marvell.
8 #include<linux/bitfield.h>
12 #include "rvu_struct.h"
14 #define DRV_NAME "octeontx2-af"
16 static int rvu_report_pair_start(struct devlink_fmsg *fmsg, const char *name)
20 err = devlink_fmsg_pair_nest_start(fmsg, name);
24 return devlink_fmsg_obj_nest_start(fmsg);
27 static int rvu_report_pair_end(struct devlink_fmsg *fmsg)
31 err = devlink_fmsg_obj_nest_end(fmsg);
35 return devlink_fmsg_pair_nest_end(fmsg);
38 static bool rvu_common_request_irq(struct rvu *rvu, int offset,
39 const char *name, irq_handler_t fn)
41 struct rvu_devlink *rvu_dl = rvu->rvu_dl;
44 sprintf(&rvu->irq_name[offset * NAME_SIZE], name);
45 rc = request_irq(pci_irq_vector(rvu->pdev, offset), fn, 0,
46 &rvu->irq_name[offset * NAME_SIZE], rvu_dl);
48 dev_warn(rvu->dev, "Failed to register %s irq\n", name);
50 rvu->irq_allocated[offset] = true;
52 return rvu->irq_allocated[offset];
55 static void rvu_nix_intr_work(struct work_struct *work)
57 struct rvu_nix_health_reporters *rvu_nix_health_reporter;
59 rvu_nix_health_reporter = container_of(work, struct rvu_nix_health_reporters, intr_work);
60 devlink_health_report(rvu_nix_health_reporter->rvu_hw_nix_intr_reporter,
62 rvu_nix_health_reporter->nix_event_ctx);
65 static irqreturn_t rvu_nix_af_rvu_intr_handler(int irq, void *rvu_irq)
67 struct rvu_nix_event_ctx *nix_event_context;
68 struct rvu_devlink *rvu_dl = rvu_irq;
74 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
78 nix_event_context = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
79 intr = rvu_read64(rvu, blkaddr, NIX_AF_RVU_INT);
80 nix_event_context->nix_af_rvu_int = intr;
82 /* Clear interrupts */
83 rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT, intr);
84 rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT_ENA_W1C, ~0ULL);
85 queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_nix_health_reporter->intr_work);
90 static void rvu_nix_gen_work(struct work_struct *work)
92 struct rvu_nix_health_reporters *rvu_nix_health_reporter;
94 rvu_nix_health_reporter = container_of(work, struct rvu_nix_health_reporters, gen_work);
95 devlink_health_report(rvu_nix_health_reporter->rvu_hw_nix_gen_reporter,
97 rvu_nix_health_reporter->nix_event_ctx);
100 static irqreturn_t rvu_nix_af_rvu_gen_handler(int irq, void *rvu_irq)
102 struct rvu_nix_event_ctx *nix_event_context;
103 struct rvu_devlink *rvu_dl = rvu_irq;
109 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
113 nix_event_context = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
114 intr = rvu_read64(rvu, blkaddr, NIX_AF_GEN_INT);
115 nix_event_context->nix_af_rvu_gen = intr;
117 /* Clear interrupts */
118 rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT, intr);
119 rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT_ENA_W1C, ~0ULL);
120 queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_nix_health_reporter->gen_work);
125 static void rvu_nix_err_work(struct work_struct *work)
127 struct rvu_nix_health_reporters *rvu_nix_health_reporter;
129 rvu_nix_health_reporter = container_of(work, struct rvu_nix_health_reporters, err_work);
130 devlink_health_report(rvu_nix_health_reporter->rvu_hw_nix_err_reporter,
132 rvu_nix_health_reporter->nix_event_ctx);
135 static irqreturn_t rvu_nix_af_rvu_err_handler(int irq, void *rvu_irq)
137 struct rvu_nix_event_ctx *nix_event_context;
138 struct rvu_devlink *rvu_dl = rvu_irq;
144 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
148 nix_event_context = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
149 intr = rvu_read64(rvu, blkaddr, NIX_AF_ERR_INT);
150 nix_event_context->nix_af_rvu_err = intr;
152 /* Clear interrupts */
153 rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT, intr);
154 rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT_ENA_W1C, ~0ULL);
155 queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_nix_health_reporter->err_work);
160 static void rvu_nix_ras_work(struct work_struct *work)
162 struct rvu_nix_health_reporters *rvu_nix_health_reporter;
164 rvu_nix_health_reporter = container_of(work, struct rvu_nix_health_reporters, ras_work);
165 devlink_health_report(rvu_nix_health_reporter->rvu_hw_nix_ras_reporter,
167 rvu_nix_health_reporter->nix_event_ctx);
170 static irqreturn_t rvu_nix_af_rvu_ras_handler(int irq, void *rvu_irq)
172 struct rvu_nix_event_ctx *nix_event_context;
173 struct rvu_devlink *rvu_dl = rvu_irq;
179 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
183 nix_event_context = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
184 intr = rvu_read64(rvu, blkaddr, NIX_AF_ERR_INT);
185 nix_event_context->nix_af_rvu_ras = intr;
187 /* Clear interrupts */
188 rvu_write64(rvu, blkaddr, NIX_AF_RAS, intr);
189 rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1C, ~0ULL);
190 queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_nix_health_reporter->ras_work);
195 static void rvu_nix_unregister_interrupts(struct rvu *rvu)
197 struct rvu_devlink *rvu_dl = rvu->rvu_dl;
198 int offs, i, blkaddr;
200 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
204 offs = rvu_read64(rvu, blkaddr, NIX_PRIV_AF_INT_CFG) & 0x3ff;
208 rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT_ENA_W1C, ~0ULL);
209 rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT_ENA_W1C, ~0ULL);
210 rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT_ENA_W1C, ~0ULL);
211 rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1C, ~0ULL);
213 if (rvu->irq_allocated[offs + NIX_AF_INT_VEC_RVU]) {
214 free_irq(pci_irq_vector(rvu->pdev, offs + NIX_AF_INT_VEC_RVU),
216 rvu->irq_allocated[offs + NIX_AF_INT_VEC_RVU] = false;
219 for (i = NIX_AF_INT_VEC_AF_ERR; i < NIX_AF_INT_VEC_CNT; i++)
220 if (rvu->irq_allocated[offs + i]) {
221 free_irq(pci_irq_vector(rvu->pdev, offs + i), rvu_dl);
222 rvu->irq_allocated[offs + i] = false;
226 static int rvu_nix_register_interrupts(struct rvu *rvu)
231 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
235 /* Get NIX AF MSIX vectors offset. */
236 base = rvu_read64(rvu, blkaddr, NIX_PRIV_AF_INT_CFG) & 0x3ff;
239 "Failed to get NIX%d NIX_AF_INT vector offsets\n",
240 blkaddr - BLKADDR_NIX0);
243 /* Register and enable NIX_AF_RVU_INT interrupt */
244 rc = rvu_common_request_irq(rvu, base + NIX_AF_INT_VEC_RVU,
246 rvu_nix_af_rvu_intr_handler);
249 rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT_ENA_W1S, ~0ULL);
251 /* Register and enable NIX_AF_GEN_INT interrupt */
252 rc = rvu_common_request_irq(rvu, base + NIX_AF_INT_VEC_GEN,
254 rvu_nix_af_rvu_gen_handler);
257 rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT_ENA_W1S, ~0ULL);
259 /* Register and enable NIX_AF_ERR_INT interrupt */
260 rc = rvu_common_request_irq(rvu, base + NIX_AF_INT_VEC_AF_ERR,
262 rvu_nix_af_rvu_err_handler);
265 rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT_ENA_W1S, ~0ULL);
267 /* Register and enable NIX_AF_RAS interrupt */
268 rc = rvu_common_request_irq(rvu, base + NIX_AF_INT_VEC_POISON,
270 rvu_nix_af_rvu_ras_handler);
273 rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1S, ~0ULL);
277 rvu_nix_unregister_interrupts(rvu);
281 static int rvu_nix_report_show(struct devlink_fmsg *fmsg, void *ctx,
282 enum nix_af_rvu_health health_reporter)
284 struct rvu_nix_event_ctx *nix_event_context;
288 nix_event_context = ctx;
289 switch (health_reporter) {
290 case NIX_AF_RVU_INTR:
291 intr_val = nix_event_context->nix_af_rvu_int;
292 err = rvu_report_pair_start(fmsg, "NIX_AF_RVU");
295 err = devlink_fmsg_u64_pair_put(fmsg, "\tNIX RVU Interrupt Reg ",
296 nix_event_context->nix_af_rvu_int);
299 if (intr_val & BIT_ULL(0)) {
300 err = devlink_fmsg_string_put(fmsg, "\n\tUnmap Slot Error");
304 err = rvu_report_pair_end(fmsg);
309 intr_val = nix_event_context->nix_af_rvu_gen;
310 err = rvu_report_pair_start(fmsg, "NIX_AF_GENERAL");
313 err = devlink_fmsg_u64_pair_put(fmsg, "\tNIX General Interrupt Reg ",
314 nix_event_context->nix_af_rvu_gen);
317 if (intr_val & BIT_ULL(0)) {
318 err = devlink_fmsg_string_put(fmsg, "\n\tRx multicast pkt drop");
322 if (intr_val & BIT_ULL(1)) {
323 err = devlink_fmsg_string_put(fmsg, "\n\tRx mirror pkt drop");
327 if (intr_val & BIT_ULL(4)) {
328 err = devlink_fmsg_string_put(fmsg, "\n\tSMQ flush done");
332 err = rvu_report_pair_end(fmsg);
337 intr_val = nix_event_context->nix_af_rvu_err;
338 err = rvu_report_pair_start(fmsg, "NIX_AF_ERR");
341 err = devlink_fmsg_u64_pair_put(fmsg, "\tNIX Error Interrupt Reg ",
342 nix_event_context->nix_af_rvu_err);
345 if (intr_val & BIT_ULL(14)) {
346 err = devlink_fmsg_string_put(fmsg, "\n\tFault on NIX_AQ_INST_S read");
350 if (intr_val & BIT_ULL(13)) {
351 err = devlink_fmsg_string_put(fmsg, "\n\tFault on NIX_AQ_RES_S write");
355 if (intr_val & BIT_ULL(12)) {
356 err = devlink_fmsg_string_put(fmsg, "\n\tAQ Doorbell Error");
360 if (intr_val & BIT_ULL(6)) {
361 err = devlink_fmsg_string_put(fmsg, "\n\tRx on unmapped PF_FUNC");
365 if (intr_val & BIT_ULL(5)) {
366 err = devlink_fmsg_string_put(fmsg, "\n\tRx multicast replication error");
370 if (intr_val & BIT_ULL(4)) {
371 err = devlink_fmsg_string_put(fmsg, "\n\tFault on NIX_RX_MCE_S read");
375 if (intr_val & BIT_ULL(3)) {
376 err = devlink_fmsg_string_put(fmsg, "\n\tFault on multicast WQE read");
380 if (intr_val & BIT_ULL(2)) {
381 err = devlink_fmsg_string_put(fmsg, "\n\tFault on mirror WQE read");
385 if (intr_val & BIT_ULL(1)) {
386 err = devlink_fmsg_string_put(fmsg, "\n\tFault on mirror pkt write");
390 if (intr_val & BIT_ULL(0)) {
391 err = devlink_fmsg_string_put(fmsg, "\n\tFault on multicast pkt write");
395 err = rvu_report_pair_end(fmsg);
400 intr_val = nix_event_context->nix_af_rvu_err;
401 err = rvu_report_pair_start(fmsg, "NIX_AF_RAS");
404 err = devlink_fmsg_u64_pair_put(fmsg, "\tNIX RAS Interrupt Reg ",
405 nix_event_context->nix_af_rvu_err);
408 err = devlink_fmsg_string_put(fmsg, "\n\tPoison Data on:");
411 if (intr_val & BIT_ULL(34)) {
412 err = devlink_fmsg_string_put(fmsg, "\n\tNIX_AQ_INST_S");
416 if (intr_val & BIT_ULL(33)) {
417 err = devlink_fmsg_string_put(fmsg, "\n\tNIX_AQ_RES_S");
421 if (intr_val & BIT_ULL(32)) {
422 err = devlink_fmsg_string_put(fmsg, "\n\tHW ctx");
426 if (intr_val & BIT_ULL(4)) {
427 err = devlink_fmsg_string_put(fmsg, "\n\tPacket from mirror buffer");
431 if (intr_val & BIT_ULL(3)) {
432 err = devlink_fmsg_string_put(fmsg, "\n\tPacket from multicast buffer");
437 if (intr_val & BIT_ULL(2)) {
438 err = devlink_fmsg_string_put(fmsg, "\n\tWQE read from mirror buffer");
442 if (intr_val & BIT_ULL(1)) {
443 err = devlink_fmsg_string_put(fmsg, "\n\tWQE read from multicast buffer");
447 if (intr_val & BIT_ULL(0)) {
448 err = devlink_fmsg_string_put(fmsg, "\n\tNIX_RX_MCE_S read");
452 err = rvu_report_pair_end(fmsg);
463 static int rvu_hw_nix_intr_dump(struct devlink_health_reporter *reporter,
464 struct devlink_fmsg *fmsg, void *ctx,
465 struct netlink_ext_ack *netlink_extack)
467 struct rvu *rvu = devlink_health_reporter_priv(reporter);
468 struct rvu_devlink *rvu_dl = rvu->rvu_dl;
469 struct rvu_nix_event_ctx *nix_ctx;
471 nix_ctx = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
473 return ctx ? rvu_nix_report_show(fmsg, ctx, NIX_AF_RVU_INTR) :
474 rvu_nix_report_show(fmsg, nix_ctx, NIX_AF_RVU_INTR);
477 static int rvu_hw_nix_intr_recover(struct devlink_health_reporter *reporter,
478 void *ctx, struct netlink_ext_ack *netlink_extack)
480 struct rvu *rvu = devlink_health_reporter_priv(reporter);
481 struct rvu_nix_event_ctx *nix_event_ctx = ctx;
484 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
488 if (nix_event_ctx->nix_af_rvu_int)
489 rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT_ENA_W1S, ~0ULL);
494 static int rvu_hw_nix_gen_dump(struct devlink_health_reporter *reporter,
495 struct devlink_fmsg *fmsg, void *ctx,
496 struct netlink_ext_ack *netlink_extack)
498 struct rvu *rvu = devlink_health_reporter_priv(reporter);
499 struct rvu_devlink *rvu_dl = rvu->rvu_dl;
500 struct rvu_nix_event_ctx *nix_ctx;
502 nix_ctx = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
504 return ctx ? rvu_nix_report_show(fmsg, ctx, NIX_AF_RVU_GEN) :
505 rvu_nix_report_show(fmsg, nix_ctx, NIX_AF_RVU_GEN);
508 static int rvu_hw_nix_gen_recover(struct devlink_health_reporter *reporter,
509 void *ctx, struct netlink_ext_ack *netlink_extack)
511 struct rvu *rvu = devlink_health_reporter_priv(reporter);
512 struct rvu_nix_event_ctx *nix_event_ctx = ctx;
515 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
519 if (nix_event_ctx->nix_af_rvu_gen)
520 rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT_ENA_W1S, ~0ULL);
525 static int rvu_hw_nix_err_dump(struct devlink_health_reporter *reporter,
526 struct devlink_fmsg *fmsg, void *ctx,
527 struct netlink_ext_ack *netlink_extack)
529 struct rvu *rvu = devlink_health_reporter_priv(reporter);
530 struct rvu_devlink *rvu_dl = rvu->rvu_dl;
531 struct rvu_nix_event_ctx *nix_ctx;
533 nix_ctx = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
535 return ctx ? rvu_nix_report_show(fmsg, ctx, NIX_AF_RVU_ERR) :
536 rvu_nix_report_show(fmsg, nix_ctx, NIX_AF_RVU_ERR);
539 static int rvu_hw_nix_err_recover(struct devlink_health_reporter *reporter,
540 void *ctx, struct netlink_ext_ack *netlink_extack)
542 struct rvu *rvu = devlink_health_reporter_priv(reporter);
543 struct rvu_nix_event_ctx *nix_event_ctx = ctx;
546 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
550 if (nix_event_ctx->nix_af_rvu_err)
551 rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT_ENA_W1S, ~0ULL);
556 static int rvu_hw_nix_ras_dump(struct devlink_health_reporter *reporter,
557 struct devlink_fmsg *fmsg, void *ctx,
558 struct netlink_ext_ack *netlink_extack)
560 struct rvu *rvu = devlink_health_reporter_priv(reporter);
561 struct rvu_devlink *rvu_dl = rvu->rvu_dl;
562 struct rvu_nix_event_ctx *nix_ctx;
564 nix_ctx = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
566 return ctx ? rvu_nix_report_show(fmsg, ctx, NIX_AF_RVU_RAS) :
567 rvu_nix_report_show(fmsg, nix_ctx, NIX_AF_RVU_RAS);
570 static int rvu_hw_nix_ras_recover(struct devlink_health_reporter *reporter,
571 void *ctx, struct netlink_ext_ack *netlink_extack)
573 struct rvu *rvu = devlink_health_reporter_priv(reporter);
574 struct rvu_nix_event_ctx *nix_event_ctx = ctx;
577 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
581 if (nix_event_ctx->nix_af_rvu_int)
582 rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1S, ~0ULL);
587 RVU_REPORTERS(hw_nix_intr);
588 RVU_REPORTERS(hw_nix_gen);
589 RVU_REPORTERS(hw_nix_err);
590 RVU_REPORTERS(hw_nix_ras);
592 static void rvu_nix_health_reporters_destroy(struct rvu_devlink *rvu_dl);
594 static int rvu_nix_register_reporters(struct rvu_devlink *rvu_dl)
596 struct rvu_nix_health_reporters *rvu_reporters;
597 struct rvu_nix_event_ctx *nix_event_context;
598 struct rvu *rvu = rvu_dl->rvu;
600 rvu_reporters = kzalloc(sizeof(*rvu_reporters), GFP_KERNEL);
604 rvu_dl->rvu_nix_health_reporter = rvu_reporters;
605 nix_event_context = kzalloc(sizeof(*nix_event_context), GFP_KERNEL);
606 if (!nix_event_context)
609 rvu_reporters->nix_event_ctx = nix_event_context;
610 rvu_reporters->rvu_hw_nix_intr_reporter =
611 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_nix_intr_reporter_ops, 0, rvu);
612 if (IS_ERR(rvu_reporters->rvu_hw_nix_intr_reporter)) {
613 dev_warn(rvu->dev, "Failed to create hw_nix_intr reporter, err=%ld\n",
614 PTR_ERR(rvu_reporters->rvu_hw_nix_intr_reporter));
615 return PTR_ERR(rvu_reporters->rvu_hw_nix_intr_reporter);
618 rvu_reporters->rvu_hw_nix_gen_reporter =
619 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_nix_gen_reporter_ops, 0, rvu);
620 if (IS_ERR(rvu_reporters->rvu_hw_nix_gen_reporter)) {
621 dev_warn(rvu->dev, "Failed to create hw_nix_gen reporter, err=%ld\n",
622 PTR_ERR(rvu_reporters->rvu_hw_nix_gen_reporter));
623 return PTR_ERR(rvu_reporters->rvu_hw_nix_gen_reporter);
626 rvu_reporters->rvu_hw_nix_err_reporter =
627 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_nix_err_reporter_ops, 0, rvu);
628 if (IS_ERR(rvu_reporters->rvu_hw_nix_err_reporter)) {
629 dev_warn(rvu->dev, "Failed to create hw_nix_err reporter, err=%ld\n",
630 PTR_ERR(rvu_reporters->rvu_hw_nix_err_reporter));
631 return PTR_ERR(rvu_reporters->rvu_hw_nix_err_reporter);
634 rvu_reporters->rvu_hw_nix_ras_reporter =
635 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_nix_ras_reporter_ops, 0, rvu);
636 if (IS_ERR(rvu_reporters->rvu_hw_nix_ras_reporter)) {
637 dev_warn(rvu->dev, "Failed to create hw_nix_ras reporter, err=%ld\n",
638 PTR_ERR(rvu_reporters->rvu_hw_nix_ras_reporter));
639 return PTR_ERR(rvu_reporters->rvu_hw_nix_ras_reporter);
642 rvu_dl->devlink_wq = create_workqueue("rvu_devlink_wq");
643 if (!rvu_dl->devlink_wq)
646 INIT_WORK(&rvu_reporters->intr_work, rvu_nix_intr_work);
647 INIT_WORK(&rvu_reporters->gen_work, rvu_nix_gen_work);
648 INIT_WORK(&rvu_reporters->err_work, rvu_nix_err_work);
649 INIT_WORK(&rvu_reporters->ras_work, rvu_nix_ras_work);
653 rvu_nix_health_reporters_destroy(rvu_dl);
657 static int rvu_nix_health_reporters_create(struct rvu_devlink *rvu_dl)
659 struct rvu *rvu = rvu_dl->rvu;
662 err = rvu_nix_register_reporters(rvu_dl);
664 dev_warn(rvu->dev, "Failed to create nix reporter, err =%d\n",
668 rvu_nix_register_interrupts(rvu);
673 static void rvu_nix_health_reporters_destroy(struct rvu_devlink *rvu_dl)
675 struct rvu_nix_health_reporters *nix_reporters;
676 struct rvu *rvu = rvu_dl->rvu;
678 nix_reporters = rvu_dl->rvu_nix_health_reporter;
680 if (!nix_reporters->rvu_hw_nix_ras_reporter)
682 if (!IS_ERR_OR_NULL(nix_reporters->rvu_hw_nix_intr_reporter))
683 devlink_health_reporter_destroy(nix_reporters->rvu_hw_nix_intr_reporter);
685 if (!IS_ERR_OR_NULL(nix_reporters->rvu_hw_nix_gen_reporter))
686 devlink_health_reporter_destroy(nix_reporters->rvu_hw_nix_gen_reporter);
688 if (!IS_ERR_OR_NULL(nix_reporters->rvu_hw_nix_err_reporter))
689 devlink_health_reporter_destroy(nix_reporters->rvu_hw_nix_err_reporter);
691 if (!IS_ERR_OR_NULL(nix_reporters->rvu_hw_nix_ras_reporter))
692 devlink_health_reporter_destroy(nix_reporters->rvu_hw_nix_ras_reporter);
694 rvu_nix_unregister_interrupts(rvu);
695 kfree(rvu_dl->rvu_nix_health_reporter->nix_event_ctx);
696 kfree(rvu_dl->rvu_nix_health_reporter);
699 static void rvu_npa_intr_work(struct work_struct *work)
701 struct rvu_npa_health_reporters *rvu_npa_health_reporter;
703 rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, intr_work);
704 devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_intr_reporter,
706 rvu_npa_health_reporter->npa_event_ctx);
709 static irqreturn_t rvu_npa_af_rvu_intr_handler(int irq, void *rvu_irq)
711 struct rvu_npa_event_ctx *npa_event_context;
712 struct rvu_devlink *rvu_dl = rvu_irq;
718 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
722 npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
723 intr = rvu_read64(rvu, blkaddr, NPA_AF_RVU_INT);
724 npa_event_context->npa_af_rvu_int = intr;
726 /* Clear interrupts */
727 rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT, intr);
728 rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1C, ~0ULL);
729 queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->intr_work);
734 static void rvu_npa_gen_work(struct work_struct *work)
736 struct rvu_npa_health_reporters *rvu_npa_health_reporter;
738 rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, gen_work);
739 devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_gen_reporter,
741 rvu_npa_health_reporter->npa_event_ctx);
744 static irqreturn_t rvu_npa_af_gen_intr_handler(int irq, void *rvu_irq)
746 struct rvu_npa_event_ctx *npa_event_context;
747 struct rvu_devlink *rvu_dl = rvu_irq;
753 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
757 npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
758 intr = rvu_read64(rvu, blkaddr, NPA_AF_GEN_INT);
759 npa_event_context->npa_af_rvu_gen = intr;
761 /* Clear interrupts */
762 rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT, intr);
763 rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1C, ~0ULL);
764 queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->gen_work);
769 static void rvu_npa_err_work(struct work_struct *work)
771 struct rvu_npa_health_reporters *rvu_npa_health_reporter;
773 rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, err_work);
774 devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_err_reporter,
776 rvu_npa_health_reporter->npa_event_ctx);
779 static irqreturn_t rvu_npa_af_err_intr_handler(int irq, void *rvu_irq)
781 struct rvu_npa_event_ctx *npa_event_context;
782 struct rvu_devlink *rvu_dl = rvu_irq;
788 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
791 npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
792 intr = rvu_read64(rvu, blkaddr, NPA_AF_ERR_INT);
793 npa_event_context->npa_af_rvu_err = intr;
795 /* Clear interrupts */
796 rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT, intr);
797 rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1C, ~0ULL);
798 queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->err_work);
803 static void rvu_npa_ras_work(struct work_struct *work)
805 struct rvu_npa_health_reporters *rvu_npa_health_reporter;
807 rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, ras_work);
808 devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_ras_reporter,
809 "HW NPA_AF_RAS Error reported",
810 rvu_npa_health_reporter->npa_event_ctx);
813 static irqreturn_t rvu_npa_af_ras_intr_handler(int irq, void *rvu_irq)
815 struct rvu_npa_event_ctx *npa_event_context;
816 struct rvu_devlink *rvu_dl = rvu_irq;
822 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
826 npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
827 intr = rvu_read64(rvu, blkaddr, NPA_AF_RAS);
828 npa_event_context->npa_af_rvu_ras = intr;
830 /* Clear interrupts */
831 rvu_write64(rvu, blkaddr, NPA_AF_RAS, intr);
832 rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1C, ~0ULL);
833 queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->ras_work);
838 static void rvu_npa_unregister_interrupts(struct rvu *rvu)
840 struct rvu_devlink *rvu_dl = rvu->rvu_dl;
841 int i, offs, blkaddr;
844 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
848 reg = rvu_read64(rvu, blkaddr, NPA_PRIV_AF_INT_CFG);
851 rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1C, ~0ULL);
852 rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1C, ~0ULL);
853 rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1C, ~0ULL);
854 rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1C, ~0ULL);
856 for (i = 0; i < NPA_AF_INT_VEC_CNT; i++)
857 if (rvu->irq_allocated[offs + i]) {
858 free_irq(pci_irq_vector(rvu->pdev, offs + i), rvu_dl);
859 rvu->irq_allocated[offs + i] = false;
863 static int rvu_npa_register_interrupts(struct rvu *rvu)
868 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
872 /* Get NPA AF MSIX vectors offset. */
873 base = rvu_read64(rvu, blkaddr, NPA_PRIV_AF_INT_CFG) & 0x3ff;
876 "Failed to get NPA_AF_INT vector offsets\n");
880 /* Register and enable NPA_AF_RVU_INT interrupt */
881 rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_RVU,
883 rvu_npa_af_rvu_intr_handler);
886 rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1S, ~0ULL);
888 /* Register and enable NPA_AF_GEN_INT interrupt */
889 rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_GEN,
891 rvu_npa_af_gen_intr_handler);
894 rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1S, ~0ULL);
896 /* Register and enable NPA_AF_ERR_INT interrupt */
897 rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_AF_ERR,
899 rvu_npa_af_err_intr_handler);
902 rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1S, ~0ULL);
904 /* Register and enable NPA_AF_RAS interrupt */
905 rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_POISON,
907 rvu_npa_af_ras_intr_handler);
910 rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1S, ~0ULL);
914 rvu_npa_unregister_interrupts(rvu);
918 static int rvu_npa_report_show(struct devlink_fmsg *fmsg, void *ctx,
919 enum npa_af_rvu_health health_reporter)
921 struct rvu_npa_event_ctx *npa_event_context;
922 unsigned int alloc_dis, free_dis;
926 npa_event_context = ctx;
927 switch (health_reporter) {
929 intr_val = npa_event_context->npa_af_rvu_gen;
930 err = rvu_report_pair_start(fmsg, "NPA_AF_GENERAL");
933 err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA General Interrupt Reg ",
934 npa_event_context->npa_af_rvu_gen);
937 if (intr_val & BIT_ULL(32)) {
938 err = devlink_fmsg_string_put(fmsg, "\n\tUnmap PF Error");
943 free_dis = FIELD_GET(GENMASK(15, 0), intr_val);
944 if (free_dis & BIT(NPA_INPQ_NIX0_RX)) {
945 err = devlink_fmsg_string_put(fmsg, "\n\tNIX0: free disabled RX");
949 if (free_dis & BIT(NPA_INPQ_NIX0_TX)) {
950 err = devlink_fmsg_string_put(fmsg, "\n\tNIX0:free disabled TX");
954 if (free_dis & BIT(NPA_INPQ_NIX1_RX)) {
955 err = devlink_fmsg_string_put(fmsg, "\n\tNIX1: free disabled RX");
959 if (free_dis & BIT(NPA_INPQ_NIX1_TX)) {
960 err = devlink_fmsg_string_put(fmsg, "\n\tNIX1:free disabled TX");
964 if (free_dis & BIT(NPA_INPQ_SSO)) {
965 err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for SSO");
969 if (free_dis & BIT(NPA_INPQ_TIM)) {
970 err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for TIM");
974 if (free_dis & BIT(NPA_INPQ_DPI)) {
975 err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for DPI");
979 if (free_dis & BIT(NPA_INPQ_AURA_OP)) {
980 err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for AURA");
985 alloc_dis = FIELD_GET(GENMASK(31, 16), intr_val);
986 if (alloc_dis & BIT(NPA_INPQ_NIX0_RX)) {
987 err = devlink_fmsg_string_put(fmsg, "\n\tNIX0: alloc disabled RX");
991 if (alloc_dis & BIT(NPA_INPQ_NIX0_TX)) {
992 err = devlink_fmsg_string_put(fmsg, "\n\tNIX0:alloc disabled TX");
996 if (alloc_dis & BIT(NPA_INPQ_NIX1_RX)) {
997 err = devlink_fmsg_string_put(fmsg, "\n\tNIX1: alloc disabled RX");
1001 if (alloc_dis & BIT(NPA_INPQ_NIX1_TX)) {
1002 err = devlink_fmsg_string_put(fmsg, "\n\tNIX1:alloc disabled TX");
1006 if (alloc_dis & BIT(NPA_INPQ_SSO)) {
1007 err = devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for SSO");
1011 if (alloc_dis & BIT(NPA_INPQ_TIM)) {
1012 err = devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for TIM");
1016 if (alloc_dis & BIT(NPA_INPQ_DPI)) {
1017 err = devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for DPI");
1021 if (alloc_dis & BIT(NPA_INPQ_AURA_OP)) {
1022 err = devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for AURA");
1026 err = rvu_report_pair_end(fmsg);
1030 case NPA_AF_RVU_ERR:
1031 err = rvu_report_pair_start(fmsg, "NPA_AF_ERR");
1034 err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA Error Interrupt Reg ",
1035 npa_event_context->npa_af_rvu_err);
1039 if (npa_event_context->npa_af_rvu_err & BIT_ULL(14)) {
1040 err = devlink_fmsg_string_put(fmsg, "\n\tFault on NPA_AQ_INST_S read");
1044 if (npa_event_context->npa_af_rvu_err & BIT_ULL(13)) {
1045 err = devlink_fmsg_string_put(fmsg, "\n\tFault on NPA_AQ_RES_S write");
1049 if (npa_event_context->npa_af_rvu_err & BIT_ULL(12)) {
1050 err = devlink_fmsg_string_put(fmsg, "\n\tAQ Doorbell Error");
1054 err = rvu_report_pair_end(fmsg);
1058 case NPA_AF_RVU_RAS:
1059 err = rvu_report_pair_start(fmsg, "NPA_AF_RVU_RAS");
1062 err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA RAS Interrupt Reg ",
1063 npa_event_context->npa_af_rvu_ras);
1066 if (npa_event_context->npa_af_rvu_ras & BIT_ULL(34)) {
1067 err = devlink_fmsg_string_put(fmsg, "\n\tPoison data on NPA_AQ_INST_S");
1071 if (npa_event_context->npa_af_rvu_ras & BIT_ULL(33)) {
1072 err = devlink_fmsg_string_put(fmsg, "\n\tPoison data on NPA_AQ_RES_S");
1076 if (npa_event_context->npa_af_rvu_ras & BIT_ULL(32)) {
1077 err = devlink_fmsg_string_put(fmsg, "\n\tPoison data on HW context");
1081 err = rvu_report_pair_end(fmsg);
1085 case NPA_AF_RVU_INTR:
1086 err = rvu_report_pair_start(fmsg, "NPA_AF_RVU");
1089 err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA RVU Interrupt Reg ",
1090 npa_event_context->npa_af_rvu_int);
1093 if (npa_event_context->npa_af_rvu_int & BIT_ULL(0)) {
1094 err = devlink_fmsg_string_put(fmsg, "\n\tUnmap Slot Error");
1098 return rvu_report_pair_end(fmsg);
1106 static int rvu_hw_npa_intr_dump(struct devlink_health_reporter *reporter,
1107 struct devlink_fmsg *fmsg, void *ctx,
1108 struct netlink_ext_ack *netlink_extack)
1110 struct rvu *rvu = devlink_health_reporter_priv(reporter);
1111 struct rvu_devlink *rvu_dl = rvu->rvu_dl;
1112 struct rvu_npa_event_ctx *npa_ctx;
1114 npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
1116 return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_INTR) :
1117 rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_INTR);
1120 static int rvu_hw_npa_intr_recover(struct devlink_health_reporter *reporter,
1121 void *ctx, struct netlink_ext_ack *netlink_extack)
1123 struct rvu *rvu = devlink_health_reporter_priv(reporter);
1124 struct rvu_npa_event_ctx *npa_event_ctx = ctx;
1127 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
1131 if (npa_event_ctx->npa_af_rvu_int)
1132 rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1S, ~0ULL);
1137 static int rvu_hw_npa_gen_dump(struct devlink_health_reporter *reporter,
1138 struct devlink_fmsg *fmsg, void *ctx,
1139 struct netlink_ext_ack *netlink_extack)
1141 struct rvu *rvu = devlink_health_reporter_priv(reporter);
1142 struct rvu_devlink *rvu_dl = rvu->rvu_dl;
1143 struct rvu_npa_event_ctx *npa_ctx;
1145 npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
1147 return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_GEN) :
1148 rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_GEN);
1151 static int rvu_hw_npa_gen_recover(struct devlink_health_reporter *reporter,
1152 void *ctx, struct netlink_ext_ack *netlink_extack)
1154 struct rvu *rvu = devlink_health_reporter_priv(reporter);
1155 struct rvu_npa_event_ctx *npa_event_ctx = ctx;
1158 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
1162 if (npa_event_ctx->npa_af_rvu_gen)
1163 rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1S, ~0ULL);
1168 static int rvu_hw_npa_err_dump(struct devlink_health_reporter *reporter,
1169 struct devlink_fmsg *fmsg, void *ctx,
1170 struct netlink_ext_ack *netlink_extack)
1172 struct rvu *rvu = devlink_health_reporter_priv(reporter);
1173 struct rvu_devlink *rvu_dl = rvu->rvu_dl;
1174 struct rvu_npa_event_ctx *npa_ctx;
1176 npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
1178 return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_ERR) :
1179 rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_ERR);
1182 static int rvu_hw_npa_err_recover(struct devlink_health_reporter *reporter,
1183 void *ctx, struct netlink_ext_ack *netlink_extack)
1185 struct rvu *rvu = devlink_health_reporter_priv(reporter);
1186 struct rvu_npa_event_ctx *npa_event_ctx = ctx;
1189 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
1193 if (npa_event_ctx->npa_af_rvu_err)
1194 rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1S, ~0ULL);
1199 static int rvu_hw_npa_ras_dump(struct devlink_health_reporter *reporter,
1200 struct devlink_fmsg *fmsg, void *ctx,
1201 struct netlink_ext_ack *netlink_extack)
1203 struct rvu *rvu = devlink_health_reporter_priv(reporter);
1204 struct rvu_devlink *rvu_dl = rvu->rvu_dl;
1205 struct rvu_npa_event_ctx *npa_ctx;
1207 npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
1209 return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_RAS) :
1210 rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_RAS);
1213 static int rvu_hw_npa_ras_recover(struct devlink_health_reporter *reporter,
1214 void *ctx, struct netlink_ext_ack *netlink_extack)
1216 struct rvu *rvu = devlink_health_reporter_priv(reporter);
1217 struct rvu_npa_event_ctx *npa_event_ctx = ctx;
1220 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
1224 if (npa_event_ctx->npa_af_rvu_ras)
1225 rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1S, ~0ULL);
1230 RVU_REPORTERS(hw_npa_intr);
1231 RVU_REPORTERS(hw_npa_gen);
1232 RVU_REPORTERS(hw_npa_err);
1233 RVU_REPORTERS(hw_npa_ras);
1235 static void rvu_npa_health_reporters_destroy(struct rvu_devlink *rvu_dl);
1237 static int rvu_npa_register_reporters(struct rvu_devlink *rvu_dl)
1239 struct rvu_npa_health_reporters *rvu_reporters;
1240 struct rvu_npa_event_ctx *npa_event_context;
1241 struct rvu *rvu = rvu_dl->rvu;
1243 rvu_reporters = kzalloc(sizeof(*rvu_reporters), GFP_KERNEL);
1247 rvu_dl->rvu_npa_health_reporter = rvu_reporters;
1248 npa_event_context = kzalloc(sizeof(*npa_event_context), GFP_KERNEL);
1249 if (!npa_event_context)
1252 rvu_reporters->npa_event_ctx = npa_event_context;
1253 rvu_reporters->rvu_hw_npa_intr_reporter =
1254 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_intr_reporter_ops, 0, rvu);
1255 if (IS_ERR(rvu_reporters->rvu_hw_npa_intr_reporter)) {
1256 dev_warn(rvu->dev, "Failed to create hw_npa_intr reporter, err=%ld\n",
1257 PTR_ERR(rvu_reporters->rvu_hw_npa_intr_reporter));
1258 return PTR_ERR(rvu_reporters->rvu_hw_npa_intr_reporter);
1261 rvu_reporters->rvu_hw_npa_gen_reporter =
1262 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_gen_reporter_ops, 0, rvu);
1263 if (IS_ERR(rvu_reporters->rvu_hw_npa_gen_reporter)) {
1264 dev_warn(rvu->dev, "Failed to create hw_npa_gen reporter, err=%ld\n",
1265 PTR_ERR(rvu_reporters->rvu_hw_npa_gen_reporter));
1266 return PTR_ERR(rvu_reporters->rvu_hw_npa_gen_reporter);
1269 rvu_reporters->rvu_hw_npa_err_reporter =
1270 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_err_reporter_ops, 0, rvu);
1271 if (IS_ERR(rvu_reporters->rvu_hw_npa_err_reporter)) {
1272 dev_warn(rvu->dev, "Failed to create hw_npa_err reporter, err=%ld\n",
1273 PTR_ERR(rvu_reporters->rvu_hw_npa_err_reporter));
1274 return PTR_ERR(rvu_reporters->rvu_hw_npa_err_reporter);
1277 rvu_reporters->rvu_hw_npa_ras_reporter =
1278 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_ras_reporter_ops, 0, rvu);
1279 if (IS_ERR(rvu_reporters->rvu_hw_npa_ras_reporter)) {
1280 dev_warn(rvu->dev, "Failed to create hw_npa_ras reporter, err=%ld\n",
1281 PTR_ERR(rvu_reporters->rvu_hw_npa_ras_reporter));
1282 return PTR_ERR(rvu_reporters->rvu_hw_npa_ras_reporter);
1285 rvu_dl->devlink_wq = create_workqueue("rvu_devlink_wq");
1286 if (!rvu_dl->devlink_wq)
1289 INIT_WORK(&rvu_reporters->intr_work, rvu_npa_intr_work);
1290 INIT_WORK(&rvu_reporters->err_work, rvu_npa_err_work);
1291 INIT_WORK(&rvu_reporters->gen_work, rvu_npa_gen_work);
1292 INIT_WORK(&rvu_reporters->ras_work, rvu_npa_ras_work);
1296 rvu_npa_health_reporters_destroy(rvu_dl);
1300 static int rvu_npa_health_reporters_create(struct rvu_devlink *rvu_dl)
1302 struct rvu *rvu = rvu_dl->rvu;
1305 err = rvu_npa_register_reporters(rvu_dl);
1307 dev_warn(rvu->dev, "Failed to create npa reporter, err =%d\n",
1311 rvu_npa_register_interrupts(rvu);
1316 static void rvu_npa_health_reporters_destroy(struct rvu_devlink *rvu_dl)
1318 struct rvu_npa_health_reporters *npa_reporters;
1319 struct rvu *rvu = rvu_dl->rvu;
1321 npa_reporters = rvu_dl->rvu_npa_health_reporter;
1323 if (!npa_reporters->rvu_hw_npa_ras_reporter)
1325 if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_intr_reporter))
1326 devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_intr_reporter);
1328 if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_gen_reporter))
1329 devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_gen_reporter);
1331 if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_err_reporter))
1332 devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_err_reporter);
1334 if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_ras_reporter))
1335 devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_ras_reporter);
1337 rvu_npa_unregister_interrupts(rvu);
1338 kfree(rvu_dl->rvu_npa_health_reporter->npa_event_ctx);
1339 kfree(rvu_dl->rvu_npa_health_reporter);
1342 static int rvu_health_reporters_create(struct rvu *rvu)
1344 struct rvu_devlink *rvu_dl;
1347 rvu_dl = rvu->rvu_dl;
1348 err = rvu_npa_health_reporters_create(rvu_dl);
1352 return rvu_nix_health_reporters_create(rvu_dl);
1355 static void rvu_health_reporters_destroy(struct rvu *rvu)
1357 struct rvu_devlink *rvu_dl;
1362 rvu_dl = rvu->rvu_dl;
1363 rvu_npa_health_reporters_destroy(rvu_dl);
1364 rvu_nix_health_reporters_destroy(rvu_dl);
1367 static int rvu_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode)
1369 struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1370 struct rvu *rvu = rvu_dl->rvu;
1371 struct rvu_switch *rswitch;
1373 rswitch = &rvu->rswitch;
1374 *mode = rswitch->mode;
1379 static int rvu_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
1380 struct netlink_ext_ack *extack)
1382 struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1383 struct rvu *rvu = rvu_dl->rvu;
1384 struct rvu_switch *rswitch;
1386 rswitch = &rvu->rswitch;
1388 case DEVLINK_ESWITCH_MODE_LEGACY:
1389 case DEVLINK_ESWITCH_MODE_SWITCHDEV:
1390 if (rswitch->mode == mode)
1392 rswitch->mode = mode;
1393 if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV)
1394 rvu_switch_enable(rvu);
1396 rvu_switch_disable(rvu);
1405 static int rvu_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
1406 struct netlink_ext_ack *extack)
1408 return devlink_info_driver_name_put(req, DRV_NAME);
1411 static const struct devlink_ops rvu_devlink_ops = {
1412 .info_get = rvu_devlink_info_get,
1413 .eswitch_mode_get = rvu_devlink_eswitch_mode_get,
1414 .eswitch_mode_set = rvu_devlink_eswitch_mode_set,
1417 int rvu_register_dl(struct rvu *rvu)
1419 struct rvu_devlink *rvu_dl;
1423 dl = devlink_alloc(&rvu_devlink_ops, sizeof(struct rvu_devlink));
1425 dev_warn(rvu->dev, "devlink_alloc failed\n");
1429 err = devlink_register(dl, rvu->dev);
1431 dev_err(rvu->dev, "devlink register failed with error %d\n", err);
1436 rvu_dl = devlink_priv(dl);
1439 rvu->rvu_dl = rvu_dl;
1441 return rvu_health_reporters_create(rvu);
1444 void rvu_unregister_dl(struct rvu *rvu)
1446 struct rvu_devlink *rvu_dl = rvu->rvu_dl;
1447 struct devlink *dl = rvu_dl->dl;
1452 rvu_health_reporters_destroy(rvu);
1453 devlink_unregister(dl);