Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Marvell RVU Admin Function Devlink
0003  *
0004  * Copyright (C) 2020 Marvell.
0005  *
0006  */
0007 
0008 #include<linux/bitfield.h>
0009 
0010 #include "rvu.h"
0011 #include "rvu_reg.h"
0012 #include "rvu_struct.h"
0013 #include "rvu_npc_hash.h"
0014 
0015 #define DRV_NAME "octeontx2-af"
0016 
0017 static int rvu_report_pair_start(struct devlink_fmsg *fmsg, const char *name)
0018 {
0019     int err;
0020 
0021     err = devlink_fmsg_pair_nest_start(fmsg, name);
0022     if (err)
0023         return err;
0024 
0025     return  devlink_fmsg_obj_nest_start(fmsg);
0026 }
0027 
0028 static int rvu_report_pair_end(struct devlink_fmsg *fmsg)
0029 {
0030     int err;
0031 
0032     err = devlink_fmsg_obj_nest_end(fmsg);
0033     if (err)
0034         return err;
0035 
0036     return devlink_fmsg_pair_nest_end(fmsg);
0037 }
0038 
0039 static bool rvu_common_request_irq(struct rvu *rvu, int offset,
0040                    const char *name, irq_handler_t fn)
0041 {
0042     struct rvu_devlink *rvu_dl = rvu->rvu_dl;
0043     int rc;
0044 
0045     sprintf(&rvu->irq_name[offset * NAME_SIZE], "%s", name);
0046     rc = request_irq(pci_irq_vector(rvu->pdev, offset), fn, 0,
0047              &rvu->irq_name[offset * NAME_SIZE], rvu_dl);
0048     if (rc)
0049         dev_warn(rvu->dev, "Failed to register %s irq\n", name);
0050     else
0051         rvu->irq_allocated[offset] = true;
0052 
0053     return rvu->irq_allocated[offset];
0054 }
0055 
0056 static void rvu_nix_intr_work(struct work_struct *work)
0057 {
0058     struct rvu_nix_health_reporters *rvu_nix_health_reporter;
0059 
0060     rvu_nix_health_reporter = container_of(work, struct rvu_nix_health_reporters, intr_work);
0061     devlink_health_report(rvu_nix_health_reporter->rvu_hw_nix_intr_reporter,
0062                   "NIX_AF_RVU Error",
0063                   rvu_nix_health_reporter->nix_event_ctx);
0064 }
0065 
0066 static irqreturn_t rvu_nix_af_rvu_intr_handler(int irq, void *rvu_irq)
0067 {
0068     struct rvu_nix_event_ctx *nix_event_context;
0069     struct rvu_devlink *rvu_dl = rvu_irq;
0070     struct rvu *rvu;
0071     int blkaddr;
0072     u64 intr;
0073 
0074     rvu = rvu_dl->rvu;
0075     blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
0076     if (blkaddr < 0)
0077         return IRQ_NONE;
0078 
0079     nix_event_context = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
0080     intr = rvu_read64(rvu, blkaddr, NIX_AF_RVU_INT);
0081     nix_event_context->nix_af_rvu_int = intr;
0082 
0083     /* Clear interrupts */
0084     rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT, intr);
0085     rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT_ENA_W1C, ~0ULL);
0086     queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_nix_health_reporter->intr_work);
0087 
0088     return IRQ_HANDLED;
0089 }
0090 
0091 static void rvu_nix_gen_work(struct work_struct *work)
0092 {
0093     struct rvu_nix_health_reporters *rvu_nix_health_reporter;
0094 
0095     rvu_nix_health_reporter = container_of(work, struct rvu_nix_health_reporters, gen_work);
0096     devlink_health_report(rvu_nix_health_reporter->rvu_hw_nix_gen_reporter,
0097                   "NIX_AF_GEN Error",
0098                   rvu_nix_health_reporter->nix_event_ctx);
0099 }
0100 
0101 static irqreturn_t rvu_nix_af_rvu_gen_handler(int irq, void *rvu_irq)
0102 {
0103     struct rvu_nix_event_ctx *nix_event_context;
0104     struct rvu_devlink *rvu_dl = rvu_irq;
0105     struct rvu *rvu;
0106     int blkaddr;
0107     u64 intr;
0108 
0109     rvu = rvu_dl->rvu;
0110     blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
0111     if (blkaddr < 0)
0112         return IRQ_NONE;
0113 
0114     nix_event_context = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
0115     intr = rvu_read64(rvu, blkaddr, NIX_AF_GEN_INT);
0116     nix_event_context->nix_af_rvu_gen = intr;
0117 
0118     /* Clear interrupts */
0119     rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT, intr);
0120     rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT_ENA_W1C, ~0ULL);
0121     queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_nix_health_reporter->gen_work);
0122 
0123     return IRQ_HANDLED;
0124 }
0125 
0126 static void rvu_nix_err_work(struct work_struct *work)
0127 {
0128     struct rvu_nix_health_reporters *rvu_nix_health_reporter;
0129 
0130     rvu_nix_health_reporter = container_of(work, struct rvu_nix_health_reporters, err_work);
0131     devlink_health_report(rvu_nix_health_reporter->rvu_hw_nix_err_reporter,
0132                   "NIX_AF_ERR Error",
0133                   rvu_nix_health_reporter->nix_event_ctx);
0134 }
0135 
0136 static irqreturn_t rvu_nix_af_rvu_err_handler(int irq, void *rvu_irq)
0137 {
0138     struct rvu_nix_event_ctx *nix_event_context;
0139     struct rvu_devlink *rvu_dl = rvu_irq;
0140     struct rvu *rvu;
0141     int blkaddr;
0142     u64 intr;
0143 
0144     rvu = rvu_dl->rvu;
0145     blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
0146     if (blkaddr < 0)
0147         return IRQ_NONE;
0148 
0149     nix_event_context = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
0150     intr = rvu_read64(rvu, blkaddr, NIX_AF_ERR_INT);
0151     nix_event_context->nix_af_rvu_err = intr;
0152 
0153     /* Clear interrupts */
0154     rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT, intr);
0155     rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT_ENA_W1C, ~0ULL);
0156     queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_nix_health_reporter->err_work);
0157 
0158     return IRQ_HANDLED;
0159 }
0160 
0161 static void rvu_nix_ras_work(struct work_struct *work)
0162 {
0163     struct rvu_nix_health_reporters *rvu_nix_health_reporter;
0164 
0165     rvu_nix_health_reporter = container_of(work, struct rvu_nix_health_reporters, ras_work);
0166     devlink_health_report(rvu_nix_health_reporter->rvu_hw_nix_ras_reporter,
0167                   "NIX_AF_RAS Error",
0168                   rvu_nix_health_reporter->nix_event_ctx);
0169 }
0170 
0171 static irqreturn_t rvu_nix_af_rvu_ras_handler(int irq, void *rvu_irq)
0172 {
0173     struct rvu_nix_event_ctx *nix_event_context;
0174     struct rvu_devlink *rvu_dl = rvu_irq;
0175     struct rvu *rvu;
0176     int blkaddr;
0177     u64 intr;
0178 
0179     rvu = rvu_dl->rvu;
0180     blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
0181     if (blkaddr < 0)
0182         return IRQ_NONE;
0183 
0184     nix_event_context = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
0185     intr = rvu_read64(rvu, blkaddr, NIX_AF_ERR_INT);
0186     nix_event_context->nix_af_rvu_ras = intr;
0187 
0188     /* Clear interrupts */
0189     rvu_write64(rvu, blkaddr, NIX_AF_RAS, intr);
0190     rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1C, ~0ULL);
0191     queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_nix_health_reporter->ras_work);
0192 
0193     return IRQ_HANDLED;
0194 }
0195 
0196 static void rvu_nix_unregister_interrupts(struct rvu *rvu)
0197 {
0198     struct rvu_devlink *rvu_dl = rvu->rvu_dl;
0199     int offs, i, blkaddr;
0200 
0201     blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
0202     if (blkaddr < 0)
0203         return;
0204 
0205     offs = rvu_read64(rvu, blkaddr, NIX_PRIV_AF_INT_CFG) & 0x3ff;
0206     if (!offs)
0207         return;
0208 
0209     rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT_ENA_W1C, ~0ULL);
0210     rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT_ENA_W1C, ~0ULL);
0211     rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT_ENA_W1C, ~0ULL);
0212     rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1C, ~0ULL);
0213 
0214     if (rvu->irq_allocated[offs + NIX_AF_INT_VEC_RVU]) {
0215         free_irq(pci_irq_vector(rvu->pdev, offs + NIX_AF_INT_VEC_RVU),
0216              rvu_dl);
0217         rvu->irq_allocated[offs + NIX_AF_INT_VEC_RVU] = false;
0218     }
0219 
0220     for (i = NIX_AF_INT_VEC_AF_ERR; i < NIX_AF_INT_VEC_CNT; i++)
0221         if (rvu->irq_allocated[offs + i]) {
0222             free_irq(pci_irq_vector(rvu->pdev, offs + i), rvu_dl);
0223             rvu->irq_allocated[offs + i] = false;
0224         }
0225 }
0226 
0227 static int rvu_nix_register_interrupts(struct rvu *rvu)
0228 {
0229     int blkaddr, base;
0230     bool rc;
0231 
0232     blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
0233     if (blkaddr < 0)
0234         return blkaddr;
0235 
0236     /* Get NIX AF MSIX vectors offset. */
0237     base = rvu_read64(rvu, blkaddr, NIX_PRIV_AF_INT_CFG) & 0x3ff;
0238     if (!base) {
0239         dev_warn(rvu->dev,
0240              "Failed to get NIX%d NIX_AF_INT vector offsets\n",
0241              blkaddr - BLKADDR_NIX0);
0242         return 0;
0243     }
0244     /* Register and enable NIX_AF_RVU_INT interrupt */
0245     rc = rvu_common_request_irq(rvu, base +  NIX_AF_INT_VEC_RVU,
0246                     "NIX_AF_RVU_INT",
0247                     rvu_nix_af_rvu_intr_handler);
0248     if (!rc)
0249         goto err;
0250     rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT_ENA_W1S, ~0ULL);
0251 
0252     /* Register and enable NIX_AF_GEN_INT interrupt */
0253     rc = rvu_common_request_irq(rvu, base +  NIX_AF_INT_VEC_GEN,
0254                     "NIX_AF_GEN_INT",
0255                     rvu_nix_af_rvu_gen_handler);
0256     if (!rc)
0257         goto err;
0258     rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT_ENA_W1S, ~0ULL);
0259 
0260     /* Register and enable NIX_AF_ERR_INT interrupt */
0261     rc = rvu_common_request_irq(rvu, base + NIX_AF_INT_VEC_AF_ERR,
0262                     "NIX_AF_ERR_INT",
0263                     rvu_nix_af_rvu_err_handler);
0264     if (!rc)
0265         goto err;
0266     rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT_ENA_W1S, ~0ULL);
0267 
0268     /* Register and enable NIX_AF_RAS interrupt */
0269     rc = rvu_common_request_irq(rvu, base + NIX_AF_INT_VEC_POISON,
0270                     "NIX_AF_RAS",
0271                     rvu_nix_af_rvu_ras_handler);
0272     if (!rc)
0273         goto err;
0274     rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1S, ~0ULL);
0275 
0276     return 0;
0277 err:
0278     rvu_nix_unregister_interrupts(rvu);
0279     return rc;
0280 }
0281 
0282 static int rvu_nix_report_show(struct devlink_fmsg *fmsg, void *ctx,
0283                    enum nix_af_rvu_health health_reporter)
0284 {
0285     struct rvu_nix_event_ctx *nix_event_context;
0286     u64 intr_val;
0287     int err;
0288 
0289     nix_event_context = ctx;
0290     switch (health_reporter) {
0291     case NIX_AF_RVU_INTR:
0292         intr_val = nix_event_context->nix_af_rvu_int;
0293         err = rvu_report_pair_start(fmsg, "NIX_AF_RVU");
0294         if (err)
0295             return err;
0296         err = devlink_fmsg_u64_pair_put(fmsg, "\tNIX RVU Interrupt Reg ",
0297                         nix_event_context->nix_af_rvu_int);
0298         if (err)
0299             return err;
0300         if (intr_val & BIT_ULL(0)) {
0301             err = devlink_fmsg_string_put(fmsg, "\n\tUnmap Slot Error");
0302             if (err)
0303                 return err;
0304         }
0305         err = rvu_report_pair_end(fmsg);
0306         if (err)
0307             return err;
0308         break;
0309     case NIX_AF_RVU_GEN:
0310         intr_val = nix_event_context->nix_af_rvu_gen;
0311         err = rvu_report_pair_start(fmsg, "NIX_AF_GENERAL");
0312         if (err)
0313             return err;
0314         err = devlink_fmsg_u64_pair_put(fmsg, "\tNIX General Interrupt Reg ",
0315                         nix_event_context->nix_af_rvu_gen);
0316         if (err)
0317             return err;
0318         if (intr_val & BIT_ULL(0)) {
0319             err = devlink_fmsg_string_put(fmsg, "\n\tRx multicast pkt drop");
0320             if (err)
0321                 return err;
0322         }
0323         if (intr_val & BIT_ULL(1)) {
0324             err = devlink_fmsg_string_put(fmsg, "\n\tRx mirror pkt drop");
0325             if (err)
0326                 return err;
0327         }
0328         if (intr_val & BIT_ULL(4)) {
0329             err = devlink_fmsg_string_put(fmsg, "\n\tSMQ flush done");
0330             if (err)
0331                 return err;
0332         }
0333         err = rvu_report_pair_end(fmsg);
0334         if (err)
0335             return err;
0336         break;
0337     case NIX_AF_RVU_ERR:
0338         intr_val = nix_event_context->nix_af_rvu_err;
0339         err = rvu_report_pair_start(fmsg, "NIX_AF_ERR");
0340         if (err)
0341             return err;
0342         err = devlink_fmsg_u64_pair_put(fmsg, "\tNIX Error Interrupt Reg ",
0343                         nix_event_context->nix_af_rvu_err);
0344         if (err)
0345             return err;
0346         if (intr_val & BIT_ULL(14)) {
0347             err = devlink_fmsg_string_put(fmsg, "\n\tFault on NIX_AQ_INST_S read");
0348             if (err)
0349                 return err;
0350         }
0351         if (intr_val & BIT_ULL(13)) {
0352             err = devlink_fmsg_string_put(fmsg, "\n\tFault on NIX_AQ_RES_S write");
0353             if (err)
0354                 return err;
0355         }
0356         if (intr_val & BIT_ULL(12)) {
0357             err = devlink_fmsg_string_put(fmsg, "\n\tAQ Doorbell Error");
0358             if (err)
0359                 return err;
0360         }
0361         if (intr_val & BIT_ULL(6)) {
0362             err = devlink_fmsg_string_put(fmsg, "\n\tRx on unmapped PF_FUNC");
0363             if (err)
0364                 return err;
0365         }
0366         if (intr_val & BIT_ULL(5)) {
0367             err = devlink_fmsg_string_put(fmsg, "\n\tRx multicast replication error");
0368             if (err)
0369                 return err;
0370         }
0371         if (intr_val & BIT_ULL(4)) {
0372             err = devlink_fmsg_string_put(fmsg, "\n\tFault on NIX_RX_MCE_S read");
0373             if (err)
0374                 return err;
0375         }
0376         if (intr_val & BIT_ULL(3)) {
0377             err = devlink_fmsg_string_put(fmsg, "\n\tFault on multicast WQE read");
0378             if (err)
0379                 return err;
0380         }
0381         if (intr_val & BIT_ULL(2)) {
0382             err = devlink_fmsg_string_put(fmsg, "\n\tFault on mirror WQE read");
0383             if (err)
0384                 return err;
0385         }
0386         if (intr_val & BIT_ULL(1)) {
0387             err = devlink_fmsg_string_put(fmsg, "\n\tFault on mirror pkt write");
0388             if (err)
0389                 return err;
0390         }
0391         if (intr_val & BIT_ULL(0)) {
0392             err = devlink_fmsg_string_put(fmsg, "\n\tFault on multicast pkt write");
0393             if (err)
0394                 return err;
0395         }
0396         err = rvu_report_pair_end(fmsg);
0397         if (err)
0398             return err;
0399         break;
0400     case NIX_AF_RVU_RAS:
0401         intr_val = nix_event_context->nix_af_rvu_err;
0402         err = rvu_report_pair_start(fmsg, "NIX_AF_RAS");
0403         if (err)
0404             return err;
0405         err = devlink_fmsg_u64_pair_put(fmsg, "\tNIX RAS Interrupt Reg ",
0406                         nix_event_context->nix_af_rvu_err);
0407         if (err)
0408             return err;
0409         err = devlink_fmsg_string_put(fmsg, "\n\tPoison Data on:");
0410         if (err)
0411             return err;
0412         if (intr_val & BIT_ULL(34)) {
0413             err = devlink_fmsg_string_put(fmsg, "\n\tNIX_AQ_INST_S");
0414             if (err)
0415                 return err;
0416         }
0417         if (intr_val & BIT_ULL(33)) {
0418             err = devlink_fmsg_string_put(fmsg, "\n\tNIX_AQ_RES_S");
0419             if (err)
0420                 return err;
0421         }
0422         if (intr_val & BIT_ULL(32)) {
0423             err = devlink_fmsg_string_put(fmsg, "\n\tHW ctx");
0424             if (err)
0425                 return err;
0426         }
0427         if (intr_val & BIT_ULL(4)) {
0428             err = devlink_fmsg_string_put(fmsg, "\n\tPacket from mirror buffer");
0429             if (err)
0430                 return err;
0431         }
0432         if (intr_val & BIT_ULL(3)) {
0433             err = devlink_fmsg_string_put(fmsg, "\n\tPacket from multicast buffer");
0434 
0435             if (err)
0436                 return err;
0437         }
0438         if (intr_val & BIT_ULL(2)) {
0439             err = devlink_fmsg_string_put(fmsg, "\n\tWQE read from mirror buffer");
0440             if (err)
0441                 return err;
0442         }
0443         if (intr_val & BIT_ULL(1)) {
0444             err = devlink_fmsg_string_put(fmsg, "\n\tWQE read from multicast buffer");
0445             if (err)
0446                 return err;
0447         }
0448         if (intr_val & BIT_ULL(0)) {
0449             err = devlink_fmsg_string_put(fmsg, "\n\tNIX_RX_MCE_S read");
0450             if (err)
0451                 return err;
0452         }
0453         err = rvu_report_pair_end(fmsg);
0454         if (err)
0455             return err;
0456         break;
0457     default:
0458         return -EINVAL;
0459     }
0460 
0461     return 0;
0462 }
0463 
0464 static int rvu_hw_nix_intr_dump(struct devlink_health_reporter *reporter,
0465                 struct devlink_fmsg *fmsg, void *ctx,
0466                 struct netlink_ext_ack *netlink_extack)
0467 {
0468     struct rvu *rvu = devlink_health_reporter_priv(reporter);
0469     struct rvu_devlink *rvu_dl = rvu->rvu_dl;
0470     struct rvu_nix_event_ctx *nix_ctx;
0471 
0472     nix_ctx = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
0473 
0474     return ctx ? rvu_nix_report_show(fmsg, ctx, NIX_AF_RVU_INTR) :
0475              rvu_nix_report_show(fmsg, nix_ctx, NIX_AF_RVU_INTR);
0476 }
0477 
0478 static int rvu_hw_nix_intr_recover(struct devlink_health_reporter *reporter,
0479                    void *ctx, struct netlink_ext_ack *netlink_extack)
0480 {
0481     struct rvu *rvu = devlink_health_reporter_priv(reporter);
0482     struct rvu_nix_event_ctx *nix_event_ctx = ctx;
0483     int blkaddr;
0484 
0485     blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
0486     if (blkaddr < 0)
0487         return blkaddr;
0488 
0489     if (nix_event_ctx->nix_af_rvu_int)
0490         rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT_ENA_W1S, ~0ULL);
0491 
0492     return 0;
0493 }
0494 
0495 static int rvu_hw_nix_gen_dump(struct devlink_health_reporter *reporter,
0496                    struct devlink_fmsg *fmsg, void *ctx,
0497                    struct netlink_ext_ack *netlink_extack)
0498 {
0499     struct rvu *rvu = devlink_health_reporter_priv(reporter);
0500     struct rvu_devlink *rvu_dl = rvu->rvu_dl;
0501     struct rvu_nix_event_ctx *nix_ctx;
0502 
0503     nix_ctx = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
0504 
0505     return ctx ? rvu_nix_report_show(fmsg, ctx, NIX_AF_RVU_GEN) :
0506              rvu_nix_report_show(fmsg, nix_ctx, NIX_AF_RVU_GEN);
0507 }
0508 
0509 static int rvu_hw_nix_gen_recover(struct devlink_health_reporter *reporter,
0510                   void *ctx, struct netlink_ext_ack *netlink_extack)
0511 {
0512     struct rvu *rvu = devlink_health_reporter_priv(reporter);
0513     struct rvu_nix_event_ctx *nix_event_ctx = ctx;
0514     int blkaddr;
0515 
0516     blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
0517     if (blkaddr < 0)
0518         return blkaddr;
0519 
0520     if (nix_event_ctx->nix_af_rvu_gen)
0521         rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT_ENA_W1S, ~0ULL);
0522 
0523     return 0;
0524 }
0525 
0526 static int rvu_hw_nix_err_dump(struct devlink_health_reporter *reporter,
0527                    struct devlink_fmsg *fmsg, void *ctx,
0528                    struct netlink_ext_ack *netlink_extack)
0529 {
0530     struct rvu *rvu = devlink_health_reporter_priv(reporter);
0531     struct rvu_devlink *rvu_dl = rvu->rvu_dl;
0532     struct rvu_nix_event_ctx *nix_ctx;
0533 
0534     nix_ctx = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
0535 
0536     return ctx ? rvu_nix_report_show(fmsg, ctx, NIX_AF_RVU_ERR) :
0537              rvu_nix_report_show(fmsg, nix_ctx, NIX_AF_RVU_ERR);
0538 }
0539 
0540 static int rvu_hw_nix_err_recover(struct devlink_health_reporter *reporter,
0541                   void *ctx, struct netlink_ext_ack *netlink_extack)
0542 {
0543     struct rvu *rvu = devlink_health_reporter_priv(reporter);
0544     struct rvu_nix_event_ctx *nix_event_ctx = ctx;
0545     int blkaddr;
0546 
0547     blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
0548     if (blkaddr < 0)
0549         return blkaddr;
0550 
0551     if (nix_event_ctx->nix_af_rvu_err)
0552         rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT_ENA_W1S, ~0ULL);
0553 
0554     return 0;
0555 }
0556 
0557 static int rvu_hw_nix_ras_dump(struct devlink_health_reporter *reporter,
0558                    struct devlink_fmsg *fmsg, void *ctx,
0559                    struct netlink_ext_ack *netlink_extack)
0560 {
0561     struct rvu *rvu = devlink_health_reporter_priv(reporter);
0562     struct rvu_devlink *rvu_dl = rvu->rvu_dl;
0563     struct rvu_nix_event_ctx *nix_ctx;
0564 
0565     nix_ctx = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
0566 
0567     return ctx ? rvu_nix_report_show(fmsg, ctx, NIX_AF_RVU_RAS) :
0568              rvu_nix_report_show(fmsg, nix_ctx, NIX_AF_RVU_RAS);
0569 }
0570 
0571 static int rvu_hw_nix_ras_recover(struct devlink_health_reporter *reporter,
0572                   void *ctx, struct netlink_ext_ack *netlink_extack)
0573 {
0574     struct rvu *rvu = devlink_health_reporter_priv(reporter);
0575     struct rvu_nix_event_ctx *nix_event_ctx = ctx;
0576     int blkaddr;
0577 
0578     blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
0579     if (blkaddr < 0)
0580         return blkaddr;
0581 
0582     if (nix_event_ctx->nix_af_rvu_int)
0583         rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1S, ~0ULL);
0584 
0585     return 0;
0586 }
0587 
0588 RVU_REPORTERS(hw_nix_intr);
0589 RVU_REPORTERS(hw_nix_gen);
0590 RVU_REPORTERS(hw_nix_err);
0591 RVU_REPORTERS(hw_nix_ras);
0592 
0593 static void rvu_nix_health_reporters_destroy(struct rvu_devlink *rvu_dl);
0594 
0595 static int rvu_nix_register_reporters(struct rvu_devlink *rvu_dl)
0596 {
0597     struct rvu_nix_health_reporters *rvu_reporters;
0598     struct rvu_nix_event_ctx *nix_event_context;
0599     struct rvu *rvu = rvu_dl->rvu;
0600 
0601     rvu_reporters = kzalloc(sizeof(*rvu_reporters), GFP_KERNEL);
0602     if (!rvu_reporters)
0603         return -ENOMEM;
0604 
0605     rvu_dl->rvu_nix_health_reporter = rvu_reporters;
0606     nix_event_context = kzalloc(sizeof(*nix_event_context), GFP_KERNEL);
0607     if (!nix_event_context)
0608         return -ENOMEM;
0609 
0610     rvu_reporters->nix_event_ctx = nix_event_context;
0611     rvu_reporters->rvu_hw_nix_intr_reporter =
0612         devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_nix_intr_reporter_ops, 0, rvu);
0613     if (IS_ERR(rvu_reporters->rvu_hw_nix_intr_reporter)) {
0614         dev_warn(rvu->dev, "Failed to create hw_nix_intr reporter, err=%ld\n",
0615              PTR_ERR(rvu_reporters->rvu_hw_nix_intr_reporter));
0616         return PTR_ERR(rvu_reporters->rvu_hw_nix_intr_reporter);
0617     }
0618 
0619     rvu_reporters->rvu_hw_nix_gen_reporter =
0620         devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_nix_gen_reporter_ops, 0, rvu);
0621     if (IS_ERR(rvu_reporters->rvu_hw_nix_gen_reporter)) {
0622         dev_warn(rvu->dev, "Failed to create hw_nix_gen reporter, err=%ld\n",
0623              PTR_ERR(rvu_reporters->rvu_hw_nix_gen_reporter));
0624         return PTR_ERR(rvu_reporters->rvu_hw_nix_gen_reporter);
0625     }
0626 
0627     rvu_reporters->rvu_hw_nix_err_reporter =
0628         devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_nix_err_reporter_ops, 0, rvu);
0629     if (IS_ERR(rvu_reporters->rvu_hw_nix_err_reporter)) {
0630         dev_warn(rvu->dev, "Failed to create hw_nix_err reporter, err=%ld\n",
0631              PTR_ERR(rvu_reporters->rvu_hw_nix_err_reporter));
0632         return PTR_ERR(rvu_reporters->rvu_hw_nix_err_reporter);
0633     }
0634 
0635     rvu_reporters->rvu_hw_nix_ras_reporter =
0636         devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_nix_ras_reporter_ops, 0, rvu);
0637     if (IS_ERR(rvu_reporters->rvu_hw_nix_ras_reporter)) {
0638         dev_warn(rvu->dev, "Failed to create hw_nix_ras reporter, err=%ld\n",
0639              PTR_ERR(rvu_reporters->rvu_hw_nix_ras_reporter));
0640         return PTR_ERR(rvu_reporters->rvu_hw_nix_ras_reporter);
0641     }
0642 
0643     rvu_dl->devlink_wq = create_workqueue("rvu_devlink_wq");
0644     if (!rvu_dl->devlink_wq)
0645         goto err;
0646 
0647     INIT_WORK(&rvu_reporters->intr_work, rvu_nix_intr_work);
0648     INIT_WORK(&rvu_reporters->gen_work, rvu_nix_gen_work);
0649     INIT_WORK(&rvu_reporters->err_work, rvu_nix_err_work);
0650     INIT_WORK(&rvu_reporters->ras_work, rvu_nix_ras_work);
0651 
0652     return 0;
0653 err:
0654     rvu_nix_health_reporters_destroy(rvu_dl);
0655     return -ENOMEM;
0656 }
0657 
0658 static int rvu_nix_health_reporters_create(struct rvu_devlink *rvu_dl)
0659 {
0660     struct rvu *rvu = rvu_dl->rvu;
0661     int err;
0662 
0663     err = rvu_nix_register_reporters(rvu_dl);
0664     if (err) {
0665         dev_warn(rvu->dev, "Failed to create nix reporter, err =%d\n",
0666              err);
0667         return err;
0668     }
0669     rvu_nix_register_interrupts(rvu);
0670 
0671     return 0;
0672 }
0673 
0674 static void rvu_nix_health_reporters_destroy(struct rvu_devlink *rvu_dl)
0675 {
0676     struct rvu_nix_health_reporters *nix_reporters;
0677     struct rvu *rvu = rvu_dl->rvu;
0678 
0679     nix_reporters = rvu_dl->rvu_nix_health_reporter;
0680 
0681     if (!nix_reporters->rvu_hw_nix_ras_reporter)
0682         return;
0683     if (!IS_ERR_OR_NULL(nix_reporters->rvu_hw_nix_intr_reporter))
0684         devlink_health_reporter_destroy(nix_reporters->rvu_hw_nix_intr_reporter);
0685 
0686     if (!IS_ERR_OR_NULL(nix_reporters->rvu_hw_nix_gen_reporter))
0687         devlink_health_reporter_destroy(nix_reporters->rvu_hw_nix_gen_reporter);
0688 
0689     if (!IS_ERR_OR_NULL(nix_reporters->rvu_hw_nix_err_reporter))
0690         devlink_health_reporter_destroy(nix_reporters->rvu_hw_nix_err_reporter);
0691 
0692     if (!IS_ERR_OR_NULL(nix_reporters->rvu_hw_nix_ras_reporter))
0693         devlink_health_reporter_destroy(nix_reporters->rvu_hw_nix_ras_reporter);
0694 
0695     rvu_nix_unregister_interrupts(rvu);
0696     kfree(rvu_dl->rvu_nix_health_reporter->nix_event_ctx);
0697     kfree(rvu_dl->rvu_nix_health_reporter);
0698 }
0699 
0700 static void rvu_npa_intr_work(struct work_struct *work)
0701 {
0702     struct rvu_npa_health_reporters *rvu_npa_health_reporter;
0703 
0704     rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, intr_work);
0705     devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_intr_reporter,
0706                   "NPA_AF_RVU Error",
0707                   rvu_npa_health_reporter->npa_event_ctx);
0708 }
0709 
0710 static irqreturn_t rvu_npa_af_rvu_intr_handler(int irq, void *rvu_irq)
0711 {
0712     struct rvu_npa_event_ctx *npa_event_context;
0713     struct rvu_devlink *rvu_dl = rvu_irq;
0714     struct rvu *rvu;
0715     int blkaddr;
0716     u64 intr;
0717 
0718     rvu = rvu_dl->rvu;
0719     blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
0720     if (blkaddr < 0)
0721         return IRQ_NONE;
0722 
0723     npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
0724     intr = rvu_read64(rvu, blkaddr, NPA_AF_RVU_INT);
0725     npa_event_context->npa_af_rvu_int = intr;
0726 
0727     /* Clear interrupts */
0728     rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT, intr);
0729     rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1C, ~0ULL);
0730     queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->intr_work);
0731 
0732     return IRQ_HANDLED;
0733 }
0734 
0735 static void rvu_npa_gen_work(struct work_struct *work)
0736 {
0737     struct rvu_npa_health_reporters *rvu_npa_health_reporter;
0738 
0739     rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, gen_work);
0740     devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_gen_reporter,
0741                   "NPA_AF_GEN Error",
0742                   rvu_npa_health_reporter->npa_event_ctx);
0743 }
0744 
0745 static irqreturn_t rvu_npa_af_gen_intr_handler(int irq, void *rvu_irq)
0746 {
0747     struct rvu_npa_event_ctx *npa_event_context;
0748     struct rvu_devlink *rvu_dl = rvu_irq;
0749     struct rvu *rvu;
0750     int blkaddr;
0751     u64 intr;
0752 
0753     rvu = rvu_dl->rvu;
0754     blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
0755     if (blkaddr < 0)
0756         return IRQ_NONE;
0757 
0758     npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
0759     intr = rvu_read64(rvu, blkaddr, NPA_AF_GEN_INT);
0760     npa_event_context->npa_af_rvu_gen = intr;
0761 
0762     /* Clear interrupts */
0763     rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT, intr);
0764     rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1C, ~0ULL);
0765     queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->gen_work);
0766 
0767     return IRQ_HANDLED;
0768 }
0769 
0770 static void rvu_npa_err_work(struct work_struct *work)
0771 {
0772     struct rvu_npa_health_reporters *rvu_npa_health_reporter;
0773 
0774     rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, err_work);
0775     devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_err_reporter,
0776                   "NPA_AF_ERR Error",
0777                   rvu_npa_health_reporter->npa_event_ctx);
0778 }
0779 
0780 static irqreturn_t rvu_npa_af_err_intr_handler(int irq, void *rvu_irq)
0781 {
0782     struct rvu_npa_event_ctx *npa_event_context;
0783     struct rvu_devlink *rvu_dl = rvu_irq;
0784     struct rvu *rvu;
0785     int blkaddr;
0786     u64 intr;
0787 
0788     rvu = rvu_dl->rvu;
0789     blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
0790     if (blkaddr < 0)
0791         return IRQ_NONE;
0792     npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
0793     intr = rvu_read64(rvu, blkaddr, NPA_AF_ERR_INT);
0794     npa_event_context->npa_af_rvu_err = intr;
0795 
0796     /* Clear interrupts */
0797     rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT, intr);
0798     rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1C, ~0ULL);
0799     queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->err_work);
0800 
0801     return IRQ_HANDLED;
0802 }
0803 
0804 static void rvu_npa_ras_work(struct work_struct *work)
0805 {
0806     struct rvu_npa_health_reporters *rvu_npa_health_reporter;
0807 
0808     rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, ras_work);
0809     devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_ras_reporter,
0810                   "HW NPA_AF_RAS Error reported",
0811                   rvu_npa_health_reporter->npa_event_ctx);
0812 }
0813 
0814 static irqreturn_t rvu_npa_af_ras_intr_handler(int irq, void *rvu_irq)
0815 {
0816     struct rvu_npa_event_ctx *npa_event_context;
0817     struct rvu_devlink *rvu_dl = rvu_irq;
0818     struct rvu *rvu;
0819     int blkaddr;
0820     u64 intr;
0821 
0822     rvu = rvu_dl->rvu;
0823     blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
0824     if (blkaddr < 0)
0825         return IRQ_NONE;
0826 
0827     npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
0828     intr = rvu_read64(rvu, blkaddr, NPA_AF_RAS);
0829     npa_event_context->npa_af_rvu_ras = intr;
0830 
0831     /* Clear interrupts */
0832     rvu_write64(rvu, blkaddr, NPA_AF_RAS, intr);
0833     rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1C, ~0ULL);
0834     queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->ras_work);
0835 
0836     return IRQ_HANDLED;
0837 }
0838 
0839 static void rvu_npa_unregister_interrupts(struct rvu *rvu)
0840 {
0841     struct rvu_devlink *rvu_dl = rvu->rvu_dl;
0842     int i, offs, blkaddr;
0843     u64 reg;
0844 
0845     blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
0846     if (blkaddr < 0)
0847         return;
0848 
0849     reg = rvu_read64(rvu, blkaddr, NPA_PRIV_AF_INT_CFG);
0850     offs = reg & 0x3FF;
0851 
0852     rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1C, ~0ULL);
0853     rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1C, ~0ULL);
0854     rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1C, ~0ULL);
0855     rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1C, ~0ULL);
0856 
0857     for (i = 0; i < NPA_AF_INT_VEC_CNT; i++)
0858         if (rvu->irq_allocated[offs + i]) {
0859             free_irq(pci_irq_vector(rvu->pdev, offs + i), rvu_dl);
0860             rvu->irq_allocated[offs + i] = false;
0861         }
0862 }
0863 
0864 static int rvu_npa_register_interrupts(struct rvu *rvu)
0865 {
0866     int blkaddr, base;
0867     bool rc;
0868 
0869     blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
0870     if (blkaddr < 0)
0871         return blkaddr;
0872 
0873     /* Get NPA AF MSIX vectors offset. */
0874     base = rvu_read64(rvu, blkaddr, NPA_PRIV_AF_INT_CFG) & 0x3ff;
0875     if (!base) {
0876         dev_warn(rvu->dev,
0877              "Failed to get NPA_AF_INT vector offsets\n");
0878         return 0;
0879     }
0880 
0881     /* Register and enable NPA_AF_RVU_INT interrupt */
0882     rc = rvu_common_request_irq(rvu, base +  NPA_AF_INT_VEC_RVU,
0883                     "NPA_AF_RVU_INT",
0884                     rvu_npa_af_rvu_intr_handler);
0885     if (!rc)
0886         goto err;
0887     rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1S, ~0ULL);
0888 
0889     /* Register and enable NPA_AF_GEN_INT interrupt */
0890     rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_GEN,
0891                     "NPA_AF_RVU_GEN",
0892                     rvu_npa_af_gen_intr_handler);
0893     if (!rc)
0894         goto err;
0895     rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1S, ~0ULL);
0896 
0897     /* Register and enable NPA_AF_ERR_INT interrupt */
0898     rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_AF_ERR,
0899                     "NPA_AF_ERR_INT",
0900                     rvu_npa_af_err_intr_handler);
0901     if (!rc)
0902         goto err;
0903     rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1S, ~0ULL);
0904 
0905     /* Register and enable NPA_AF_RAS interrupt */
0906     rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_POISON,
0907                     "NPA_AF_RAS",
0908                     rvu_npa_af_ras_intr_handler);
0909     if (!rc)
0910         goto err;
0911     rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1S, ~0ULL);
0912 
0913     return 0;
0914 err:
0915     rvu_npa_unregister_interrupts(rvu);
0916     return rc;
0917 }
0918 
0919 static int rvu_npa_report_show(struct devlink_fmsg *fmsg, void *ctx,
0920                    enum npa_af_rvu_health health_reporter)
0921 {
0922     struct rvu_npa_event_ctx *npa_event_context;
0923     unsigned int alloc_dis, free_dis;
0924     u64 intr_val;
0925     int err;
0926 
0927     npa_event_context = ctx;
0928     switch (health_reporter) {
0929     case NPA_AF_RVU_GEN:
0930         intr_val = npa_event_context->npa_af_rvu_gen;
0931         err = rvu_report_pair_start(fmsg, "NPA_AF_GENERAL");
0932         if (err)
0933             return err;
0934         err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA General Interrupt Reg ",
0935                         npa_event_context->npa_af_rvu_gen);
0936         if (err)
0937             return err;
0938         if (intr_val & BIT_ULL(32)) {
0939             err = devlink_fmsg_string_put(fmsg, "\n\tUnmap PF Error");
0940             if (err)
0941                 return err;
0942         }
0943 
0944         free_dis = FIELD_GET(GENMASK(15, 0), intr_val);
0945         if (free_dis & BIT(NPA_INPQ_NIX0_RX)) {
0946             err = devlink_fmsg_string_put(fmsg, "\n\tNIX0: free disabled RX");
0947             if (err)
0948                 return err;
0949         }
0950         if (free_dis & BIT(NPA_INPQ_NIX0_TX)) {
0951             err = devlink_fmsg_string_put(fmsg, "\n\tNIX0:free disabled TX");
0952             if (err)
0953                 return err;
0954         }
0955         if (free_dis & BIT(NPA_INPQ_NIX1_RX)) {
0956             err = devlink_fmsg_string_put(fmsg, "\n\tNIX1: free disabled RX");
0957             if (err)
0958                 return err;
0959         }
0960         if (free_dis & BIT(NPA_INPQ_NIX1_TX)) {
0961             err = devlink_fmsg_string_put(fmsg, "\n\tNIX1:free disabled TX");
0962             if (err)
0963                 return err;
0964         }
0965         if (free_dis & BIT(NPA_INPQ_SSO)) {
0966             err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for SSO");
0967             if (err)
0968                 return err;
0969         }
0970         if (free_dis & BIT(NPA_INPQ_TIM)) {
0971             err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for TIM");
0972             if (err)
0973                 return err;
0974         }
0975         if (free_dis & BIT(NPA_INPQ_DPI)) {
0976             err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for DPI");
0977             if (err)
0978                 return err;
0979         }
0980         if (free_dis & BIT(NPA_INPQ_AURA_OP)) {
0981             err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for AURA");
0982             if (err)
0983                 return err;
0984         }
0985 
0986         alloc_dis = FIELD_GET(GENMASK(31, 16), intr_val);
0987         if (alloc_dis & BIT(NPA_INPQ_NIX0_RX)) {
0988             err = devlink_fmsg_string_put(fmsg, "\n\tNIX0: alloc disabled RX");
0989             if (err)
0990                 return err;
0991         }
0992         if (alloc_dis & BIT(NPA_INPQ_NIX0_TX)) {
0993             err = devlink_fmsg_string_put(fmsg, "\n\tNIX0:alloc disabled TX");
0994             if (err)
0995                 return err;
0996         }
0997         if (alloc_dis & BIT(NPA_INPQ_NIX1_RX)) {
0998             err = devlink_fmsg_string_put(fmsg, "\n\tNIX1: alloc disabled RX");
0999             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     DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE,
1504                  "npc_exact_feature_disable", DEVLINK_PARAM_TYPE_STRING,
1505                  BIT(DEVLINK_PARAM_CMODE_RUNTIME),
1506                  rvu_af_npc_exact_feature_get,
1507                  rvu_af_npc_exact_feature_disable,
1508                  rvu_af_npc_exact_feature_validate),
1509 };
1510 
1511 /* Devlink switch mode */
1512 static int rvu_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode)
1513 {
1514     struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1515     struct rvu *rvu = rvu_dl->rvu;
1516     struct rvu_switch *rswitch;
1517 
1518     rswitch = &rvu->rswitch;
1519     *mode = rswitch->mode;
1520 
1521     return 0;
1522 }
1523 
1524 static int rvu_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
1525                     struct netlink_ext_ack *extack)
1526 {
1527     struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1528     struct rvu *rvu = rvu_dl->rvu;
1529     struct rvu_switch *rswitch;
1530 
1531     rswitch = &rvu->rswitch;
1532     switch (mode) {
1533     case DEVLINK_ESWITCH_MODE_LEGACY:
1534     case DEVLINK_ESWITCH_MODE_SWITCHDEV:
1535         if (rswitch->mode == mode)
1536             return 0;
1537         rswitch->mode = mode;
1538         if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV)
1539             rvu_switch_enable(rvu);
1540         else
1541             rvu_switch_disable(rvu);
1542         break;
1543     default:
1544         return -EINVAL;
1545     }
1546 
1547     return 0;
1548 }
1549 
1550 static int rvu_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
1551                 struct netlink_ext_ack *extack)
1552 {
1553     return devlink_info_driver_name_put(req, DRV_NAME);
1554 }
1555 
1556 static const struct devlink_ops rvu_devlink_ops = {
1557     .info_get = rvu_devlink_info_get,
1558     .eswitch_mode_get = rvu_devlink_eswitch_mode_get,
1559     .eswitch_mode_set = rvu_devlink_eswitch_mode_set,
1560 };
1561 
1562 int rvu_register_dl(struct rvu *rvu)
1563 {
1564     struct rvu_devlink *rvu_dl;
1565     struct devlink *dl;
1566     size_t size;
1567     int err;
1568 
1569     dl = devlink_alloc(&rvu_devlink_ops, sizeof(struct rvu_devlink),
1570                rvu->dev);
1571     if (!dl) {
1572         dev_warn(rvu->dev, "devlink_alloc failed\n");
1573         return -ENOMEM;
1574     }
1575 
1576     rvu_dl = devlink_priv(dl);
1577     rvu_dl->dl = dl;
1578     rvu_dl->rvu = rvu;
1579     rvu->rvu_dl = rvu_dl;
1580 
1581     err = rvu_health_reporters_create(rvu);
1582     if (err) {
1583         dev_err(rvu->dev,
1584             "devlink health reporter creation failed with error %d\n", err);
1585         goto err_dl_health;
1586     }
1587 
1588     /* Register exact match devlink only for CN10K-B */
1589     size = ARRAY_SIZE(rvu_af_dl_params);
1590     if (!rvu_npc_exact_has_match_table(rvu))
1591         size -= 1;
1592 
1593     err = devlink_params_register(dl, rvu_af_dl_params, size);
1594     if (err) {
1595         dev_err(rvu->dev,
1596             "devlink params register failed with error %d", err);
1597         goto err_dl_health;
1598     }
1599 
1600     devlink_register(dl);
1601     return 0;
1602 
1603 err_dl_health:
1604     rvu_health_reporters_destroy(rvu);
1605     devlink_free(dl);
1606     return err;
1607 }
1608 
1609 void rvu_unregister_dl(struct rvu *rvu)
1610 {
1611     struct rvu_devlink *rvu_dl = rvu->rvu_dl;
1612     struct devlink *dl = rvu_dl->dl;
1613 
1614     devlink_unregister(dl);
1615     devlink_params_unregister(dl, rvu_af_dl_params,
1616                   ARRAY_SIZE(rvu_af_dl_params));
1617     rvu_health_reporters_destroy(rvu);
1618     devlink_free(dl);
1619 }