1fae06da4SGeorge Cherian // SPDX-License-Identifier: GPL-2.0
2c7cd6c5aSSunil Goutham /* Marvell RVU Admin Function Devlink
3fae06da4SGeorge Cherian *
4fae06da4SGeorge Cherian * Copyright (C) 2020 Marvell.
5fae06da4SGeorge Cherian *
6fae06da4SGeorge Cherian */
7fae06da4SGeorge Cherian
8f1168d1eSGeorge Cherian #include<linux/bitfield.h>
9f1168d1eSGeorge Cherian
10fae06da4SGeorge Cherian #include "rvu.h"
11f1168d1eSGeorge Cherian #include "rvu_reg.h"
12f1168d1eSGeorge Cherian #include "rvu_struct.h"
13ef83e186SRatheesh Kannoth #include "rvu_npc_hash.h"
14fae06da4SGeorge Cherian
15fae06da4SGeorge Cherian #define DRV_NAME "octeontx2-af"
16fae06da4SGeorge Cherian
rvu_report_pair_start(struct devlink_fmsg * fmsg,const char * name)17f1168d1eSGeorge Cherian static int rvu_report_pair_start(struct devlink_fmsg *fmsg, const char *name)
18f1168d1eSGeorge Cherian {
19f1168d1eSGeorge Cherian int err;
20f1168d1eSGeorge Cherian
21f1168d1eSGeorge Cherian err = devlink_fmsg_pair_nest_start(fmsg, name);
22f1168d1eSGeorge Cherian if (err)
23f1168d1eSGeorge Cherian return err;
24f1168d1eSGeorge Cherian
25f1168d1eSGeorge Cherian return devlink_fmsg_obj_nest_start(fmsg);
26f1168d1eSGeorge Cherian }
27f1168d1eSGeorge Cherian
rvu_report_pair_end(struct devlink_fmsg * fmsg)28f1168d1eSGeorge Cherian static int rvu_report_pair_end(struct devlink_fmsg *fmsg)
29f1168d1eSGeorge Cherian {
30f1168d1eSGeorge Cherian int err;
31f1168d1eSGeorge Cherian
32f1168d1eSGeorge Cherian err = devlink_fmsg_obj_nest_end(fmsg);
33f1168d1eSGeorge Cherian if (err)
34f1168d1eSGeorge Cherian return err;
35f1168d1eSGeorge Cherian
36f1168d1eSGeorge Cherian return devlink_fmsg_pair_nest_end(fmsg);
37f1168d1eSGeorge Cherian }
38f1168d1eSGeorge Cherian
rvu_common_request_irq(struct rvu * rvu,int offset,const char * name,irq_handler_t fn)39f1168d1eSGeorge Cherian static bool rvu_common_request_irq(struct rvu *rvu, int offset,
40f1168d1eSGeorge Cherian const char *name, irq_handler_t fn)
41f1168d1eSGeorge Cherian {
42f1168d1eSGeorge Cherian struct rvu_devlink *rvu_dl = rvu->rvu_dl;
43f1168d1eSGeorge Cherian int rc;
44f1168d1eSGeorge Cherian
456dc9a23eSSunil Goutham sprintf(&rvu->irq_name[offset * NAME_SIZE], "%s", name);
46f1168d1eSGeorge Cherian rc = request_irq(pci_irq_vector(rvu->pdev, offset), fn, 0,
47f1168d1eSGeorge Cherian &rvu->irq_name[offset * NAME_SIZE], rvu_dl);
48f1168d1eSGeorge Cherian if (rc)
49f1168d1eSGeorge Cherian dev_warn(rvu->dev, "Failed to register %s irq\n", name);
50f1168d1eSGeorge Cherian else
51f1168d1eSGeorge Cherian rvu->irq_allocated[offset] = true;
52f1168d1eSGeorge Cherian
53f1168d1eSGeorge Cherian return rvu->irq_allocated[offset];
54f1168d1eSGeorge Cherian }
55f1168d1eSGeorge Cherian
rvu_nix_intr_work(struct work_struct * work)565ed66306SGeorge Cherian static void rvu_nix_intr_work(struct work_struct *work)
575ed66306SGeorge Cherian {
585ed66306SGeorge Cherian struct rvu_nix_health_reporters *rvu_nix_health_reporter;
595ed66306SGeorge Cherian
605ed66306SGeorge Cherian rvu_nix_health_reporter = container_of(work, struct rvu_nix_health_reporters, intr_work);
615ed66306SGeorge Cherian devlink_health_report(rvu_nix_health_reporter->rvu_hw_nix_intr_reporter,
625ed66306SGeorge Cherian "NIX_AF_RVU Error",
635ed66306SGeorge Cherian rvu_nix_health_reporter->nix_event_ctx);
645ed66306SGeorge Cherian }
655ed66306SGeorge Cherian
rvu_nix_af_rvu_intr_handler(int irq,void * rvu_irq)665ed66306SGeorge Cherian static irqreturn_t rvu_nix_af_rvu_intr_handler(int irq, void *rvu_irq)
675ed66306SGeorge Cherian {
685ed66306SGeorge Cherian struct rvu_nix_event_ctx *nix_event_context;
695ed66306SGeorge Cherian struct rvu_devlink *rvu_dl = rvu_irq;
705ed66306SGeorge Cherian struct rvu *rvu;
715ed66306SGeorge Cherian int blkaddr;
725ed66306SGeorge Cherian u64 intr;
735ed66306SGeorge Cherian
745ed66306SGeorge Cherian rvu = rvu_dl->rvu;
755ed66306SGeorge Cherian blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
765ed66306SGeorge Cherian if (blkaddr < 0)
775ed66306SGeorge Cherian return IRQ_NONE;
785ed66306SGeorge Cherian
795ed66306SGeorge Cherian nix_event_context = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
805ed66306SGeorge Cherian intr = rvu_read64(rvu, blkaddr, NIX_AF_RVU_INT);
815ed66306SGeorge Cherian nix_event_context->nix_af_rvu_int = intr;
825ed66306SGeorge Cherian
835ed66306SGeorge Cherian /* Clear interrupts */
845ed66306SGeorge Cherian rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT, intr);
855ed66306SGeorge Cherian rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT_ENA_W1C, ~0ULL);
865ed66306SGeorge Cherian queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_nix_health_reporter->intr_work);
875ed66306SGeorge Cherian
885ed66306SGeorge Cherian return IRQ_HANDLED;
895ed66306SGeorge Cherian }
905ed66306SGeorge Cherian
rvu_nix_gen_work(struct work_struct * work)915ed66306SGeorge Cherian static void rvu_nix_gen_work(struct work_struct *work)
925ed66306SGeorge Cherian {
935ed66306SGeorge Cherian struct rvu_nix_health_reporters *rvu_nix_health_reporter;
945ed66306SGeorge Cherian
955ed66306SGeorge Cherian rvu_nix_health_reporter = container_of(work, struct rvu_nix_health_reporters, gen_work);
965ed66306SGeorge Cherian devlink_health_report(rvu_nix_health_reporter->rvu_hw_nix_gen_reporter,
975ed66306SGeorge Cherian "NIX_AF_GEN Error",
985ed66306SGeorge Cherian rvu_nix_health_reporter->nix_event_ctx);
995ed66306SGeorge Cherian }
1005ed66306SGeorge Cherian
rvu_nix_af_rvu_gen_handler(int irq,void * rvu_irq)1015ed66306SGeorge Cherian static irqreturn_t rvu_nix_af_rvu_gen_handler(int irq, void *rvu_irq)
1025ed66306SGeorge Cherian {
1035ed66306SGeorge Cherian struct rvu_nix_event_ctx *nix_event_context;
1045ed66306SGeorge Cherian struct rvu_devlink *rvu_dl = rvu_irq;
1055ed66306SGeorge Cherian struct rvu *rvu;
1065ed66306SGeorge Cherian int blkaddr;
1075ed66306SGeorge Cherian u64 intr;
1085ed66306SGeorge Cherian
1095ed66306SGeorge Cherian rvu = rvu_dl->rvu;
1105ed66306SGeorge Cherian blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
1115ed66306SGeorge Cherian if (blkaddr < 0)
1125ed66306SGeorge Cherian return IRQ_NONE;
1135ed66306SGeorge Cherian
1145ed66306SGeorge Cherian nix_event_context = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
1155ed66306SGeorge Cherian intr = rvu_read64(rvu, blkaddr, NIX_AF_GEN_INT);
1165ed66306SGeorge Cherian nix_event_context->nix_af_rvu_gen = intr;
1175ed66306SGeorge Cherian
1185ed66306SGeorge Cherian /* Clear interrupts */
1195ed66306SGeorge Cherian rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT, intr);
1205ed66306SGeorge Cherian rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT_ENA_W1C, ~0ULL);
1215ed66306SGeorge Cherian queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_nix_health_reporter->gen_work);
1225ed66306SGeorge Cherian
1235ed66306SGeorge Cherian return IRQ_HANDLED;
1245ed66306SGeorge Cherian }
1255ed66306SGeorge Cherian
rvu_nix_err_work(struct work_struct * work)1265ed66306SGeorge Cherian static void rvu_nix_err_work(struct work_struct *work)
1275ed66306SGeorge Cherian {
1285ed66306SGeorge Cherian struct rvu_nix_health_reporters *rvu_nix_health_reporter;
1295ed66306SGeorge Cherian
1305ed66306SGeorge Cherian rvu_nix_health_reporter = container_of(work, struct rvu_nix_health_reporters, err_work);
1315ed66306SGeorge Cherian devlink_health_report(rvu_nix_health_reporter->rvu_hw_nix_err_reporter,
1325ed66306SGeorge Cherian "NIX_AF_ERR Error",
1335ed66306SGeorge Cherian rvu_nix_health_reporter->nix_event_ctx);
1345ed66306SGeorge Cherian }
1355ed66306SGeorge Cherian
rvu_nix_af_rvu_err_handler(int irq,void * rvu_irq)1365ed66306SGeorge Cherian static irqreturn_t rvu_nix_af_rvu_err_handler(int irq, void *rvu_irq)
1375ed66306SGeorge Cherian {
1385ed66306SGeorge Cherian struct rvu_nix_event_ctx *nix_event_context;
1395ed66306SGeorge Cherian struct rvu_devlink *rvu_dl = rvu_irq;
1405ed66306SGeorge Cherian struct rvu *rvu;
1415ed66306SGeorge Cherian int blkaddr;
1425ed66306SGeorge Cherian u64 intr;
1435ed66306SGeorge Cherian
1445ed66306SGeorge Cherian rvu = rvu_dl->rvu;
1455ed66306SGeorge Cherian blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
1465ed66306SGeorge Cherian if (blkaddr < 0)
1475ed66306SGeorge Cherian return IRQ_NONE;
1485ed66306SGeorge Cherian
1495ed66306SGeorge Cherian nix_event_context = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
1505ed66306SGeorge Cherian intr = rvu_read64(rvu, blkaddr, NIX_AF_ERR_INT);
1515ed66306SGeorge Cherian nix_event_context->nix_af_rvu_err = intr;
1525ed66306SGeorge Cherian
1535ed66306SGeorge Cherian /* Clear interrupts */
1545ed66306SGeorge Cherian rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT, intr);
1555ed66306SGeorge Cherian rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT_ENA_W1C, ~0ULL);
1565ed66306SGeorge Cherian queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_nix_health_reporter->err_work);
1575ed66306SGeorge Cherian
1585ed66306SGeorge Cherian return IRQ_HANDLED;
1595ed66306SGeorge Cherian }
1605ed66306SGeorge Cherian
rvu_nix_ras_work(struct work_struct * work)1615ed66306SGeorge Cherian static void rvu_nix_ras_work(struct work_struct *work)
1625ed66306SGeorge Cherian {
1635ed66306SGeorge Cherian struct rvu_nix_health_reporters *rvu_nix_health_reporter;
1645ed66306SGeorge Cherian
1655ed66306SGeorge Cherian rvu_nix_health_reporter = container_of(work, struct rvu_nix_health_reporters, ras_work);
1665ed66306SGeorge Cherian devlink_health_report(rvu_nix_health_reporter->rvu_hw_nix_ras_reporter,
1675ed66306SGeorge Cherian "NIX_AF_RAS Error",
1685ed66306SGeorge Cherian rvu_nix_health_reporter->nix_event_ctx);
1695ed66306SGeorge Cherian }
1705ed66306SGeorge Cherian
rvu_nix_af_rvu_ras_handler(int irq,void * rvu_irq)1715ed66306SGeorge Cherian static irqreturn_t rvu_nix_af_rvu_ras_handler(int irq, void *rvu_irq)
1725ed66306SGeorge Cherian {
1735ed66306SGeorge Cherian struct rvu_nix_event_ctx *nix_event_context;
1745ed66306SGeorge Cherian struct rvu_devlink *rvu_dl = rvu_irq;
1755ed66306SGeorge Cherian struct rvu *rvu;
1765ed66306SGeorge Cherian int blkaddr;
1775ed66306SGeorge Cherian u64 intr;
1785ed66306SGeorge Cherian
1795ed66306SGeorge Cherian rvu = rvu_dl->rvu;
1805ed66306SGeorge Cherian blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
1815ed66306SGeorge Cherian if (blkaddr < 0)
1825ed66306SGeorge Cherian return IRQ_NONE;
1835ed66306SGeorge Cherian
1845ed66306SGeorge Cherian nix_event_context = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
1855ed66306SGeorge Cherian intr = rvu_read64(rvu, blkaddr, NIX_AF_ERR_INT);
1865ed66306SGeorge Cherian nix_event_context->nix_af_rvu_ras = intr;
1875ed66306SGeorge Cherian
1885ed66306SGeorge Cherian /* Clear interrupts */
1895ed66306SGeorge Cherian rvu_write64(rvu, blkaddr, NIX_AF_RAS, intr);
1905ed66306SGeorge Cherian rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1C, ~0ULL);
1915ed66306SGeorge Cherian queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_nix_health_reporter->ras_work);
1925ed66306SGeorge Cherian
1935ed66306SGeorge Cherian return IRQ_HANDLED;
1945ed66306SGeorge Cherian }
1955ed66306SGeorge Cherian
rvu_nix_unregister_interrupts(struct rvu * rvu)1965ed66306SGeorge Cherian static void rvu_nix_unregister_interrupts(struct rvu *rvu)
1975ed66306SGeorge Cherian {
1985ed66306SGeorge Cherian struct rvu_devlink *rvu_dl = rvu->rvu_dl;
1995ed66306SGeorge Cherian int offs, i, blkaddr;
2005ed66306SGeorge Cherian
2015ed66306SGeorge Cherian blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
2025ed66306SGeorge Cherian if (blkaddr < 0)
2035ed66306SGeorge Cherian return;
2045ed66306SGeorge Cherian
2055ed66306SGeorge Cherian offs = rvu_read64(rvu, blkaddr, NIX_PRIV_AF_INT_CFG) & 0x3ff;
2065ed66306SGeorge Cherian if (!offs)
2075ed66306SGeorge Cherian return;
2085ed66306SGeorge Cherian
2095ed66306SGeorge Cherian rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT_ENA_W1C, ~0ULL);
2105ed66306SGeorge Cherian rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT_ENA_W1C, ~0ULL);
2115ed66306SGeorge Cherian rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT_ENA_W1C, ~0ULL);
2125ed66306SGeorge Cherian rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1C, ~0ULL);
2135ed66306SGeorge Cherian
2145ed66306SGeorge Cherian if (rvu->irq_allocated[offs + NIX_AF_INT_VEC_RVU]) {
2155ed66306SGeorge Cherian free_irq(pci_irq_vector(rvu->pdev, offs + NIX_AF_INT_VEC_RVU),
2165ed66306SGeorge Cherian rvu_dl);
2175ed66306SGeorge Cherian rvu->irq_allocated[offs + NIX_AF_INT_VEC_RVU] = false;
2185ed66306SGeorge Cherian }
2195ed66306SGeorge Cherian
220*08796bd2SGeetha sowjanya for (i = NIX_AF_INT_VEC_GEN; i < NIX_AF_INT_VEC_CNT; i++)
2215ed66306SGeorge Cherian if (rvu->irq_allocated[offs + i]) {
2225ed66306SGeorge Cherian free_irq(pci_irq_vector(rvu->pdev, offs + i), rvu_dl);
2235ed66306SGeorge Cherian rvu->irq_allocated[offs + i] = false;
2245ed66306SGeorge Cherian }
2255ed66306SGeorge Cherian }
2265ed66306SGeorge Cherian
rvu_nix_register_interrupts(struct rvu * rvu)2275ed66306SGeorge Cherian static int rvu_nix_register_interrupts(struct rvu *rvu)
2285ed66306SGeorge Cherian {
2295ed66306SGeorge Cherian int blkaddr, base;
2305ed66306SGeorge Cherian bool rc;
2315ed66306SGeorge Cherian
2325ed66306SGeorge Cherian blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
2335ed66306SGeorge Cherian if (blkaddr < 0)
2345ed66306SGeorge Cherian return blkaddr;
2355ed66306SGeorge Cherian
2365ed66306SGeorge Cherian /* Get NIX AF MSIX vectors offset. */
2375ed66306SGeorge Cherian base = rvu_read64(rvu, blkaddr, NIX_PRIV_AF_INT_CFG) & 0x3ff;
2385ed66306SGeorge Cherian if (!base) {
2395ed66306SGeorge Cherian dev_warn(rvu->dev,
2405ed66306SGeorge Cherian "Failed to get NIX%d NIX_AF_INT vector offsets\n",
2415ed66306SGeorge Cherian blkaddr - BLKADDR_NIX0);
2425ed66306SGeorge Cherian return 0;
2435ed66306SGeorge Cherian }
2445ed66306SGeorge Cherian /* Register and enable NIX_AF_RVU_INT interrupt */
2455ed66306SGeorge Cherian rc = rvu_common_request_irq(rvu, base + NIX_AF_INT_VEC_RVU,
2465ed66306SGeorge Cherian "NIX_AF_RVU_INT",
2475ed66306SGeorge Cherian rvu_nix_af_rvu_intr_handler);
2485ed66306SGeorge Cherian if (!rc)
2495ed66306SGeorge Cherian goto err;
2505ed66306SGeorge Cherian rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT_ENA_W1S, ~0ULL);
2515ed66306SGeorge Cherian
2525ed66306SGeorge Cherian /* Register and enable NIX_AF_GEN_INT interrupt */
2535ed66306SGeorge Cherian rc = rvu_common_request_irq(rvu, base + NIX_AF_INT_VEC_GEN,
2545ed66306SGeorge Cherian "NIX_AF_GEN_INT",
2555ed66306SGeorge Cherian rvu_nix_af_rvu_gen_handler);
2565ed66306SGeorge Cherian if (!rc)
2575ed66306SGeorge Cherian goto err;
2585ed66306SGeorge Cherian rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT_ENA_W1S, ~0ULL);
2595ed66306SGeorge Cherian
2605ed66306SGeorge Cherian /* Register and enable NIX_AF_ERR_INT interrupt */
2615ed66306SGeorge Cherian rc = rvu_common_request_irq(rvu, base + NIX_AF_INT_VEC_AF_ERR,
2625ed66306SGeorge Cherian "NIX_AF_ERR_INT",
2635ed66306SGeorge Cherian rvu_nix_af_rvu_err_handler);
2645ed66306SGeorge Cherian if (!rc)
2655ed66306SGeorge Cherian goto err;
2665ed66306SGeorge Cherian rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT_ENA_W1S, ~0ULL);
2675ed66306SGeorge Cherian
2685ed66306SGeorge Cherian /* Register and enable NIX_AF_RAS interrupt */
2695ed66306SGeorge Cherian rc = rvu_common_request_irq(rvu, base + NIX_AF_INT_VEC_POISON,
2705ed66306SGeorge Cherian "NIX_AF_RAS",
2715ed66306SGeorge Cherian rvu_nix_af_rvu_ras_handler);
2725ed66306SGeorge Cherian if (!rc)
2735ed66306SGeorge Cherian goto err;
2745ed66306SGeorge Cherian rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1S, ~0ULL);
2755ed66306SGeorge Cherian
2765ed66306SGeorge Cherian return 0;
2775ed66306SGeorge Cherian err:
2785ed66306SGeorge Cherian rvu_nix_unregister_interrupts(rvu);
2795ed66306SGeorge Cherian return rc;
2805ed66306SGeorge Cherian }
2815ed66306SGeorge Cherian
rvu_nix_report_show(struct devlink_fmsg * fmsg,void * ctx,enum nix_af_rvu_health health_reporter)2825ed66306SGeorge Cherian static int rvu_nix_report_show(struct devlink_fmsg *fmsg, void *ctx,
2835ed66306SGeorge Cherian enum nix_af_rvu_health health_reporter)
2845ed66306SGeorge Cherian {
2855ed66306SGeorge Cherian struct rvu_nix_event_ctx *nix_event_context;
2865ed66306SGeorge Cherian u64 intr_val;
2875ed66306SGeorge Cherian int err;
2885ed66306SGeorge Cherian
2895ed66306SGeorge Cherian nix_event_context = ctx;
2905ed66306SGeorge Cherian switch (health_reporter) {
2915ed66306SGeorge Cherian case NIX_AF_RVU_INTR:
2925ed66306SGeorge Cherian intr_val = nix_event_context->nix_af_rvu_int;
2935ed66306SGeorge Cherian err = rvu_report_pair_start(fmsg, "NIX_AF_RVU");
2945ed66306SGeorge Cherian if (err)
2955ed66306SGeorge Cherian return err;
2965ed66306SGeorge Cherian err = devlink_fmsg_u64_pair_put(fmsg, "\tNIX RVU Interrupt Reg ",
2975ed66306SGeorge Cherian nix_event_context->nix_af_rvu_int);
2985ed66306SGeorge Cherian if (err)
2995ed66306SGeorge Cherian return err;
3005ed66306SGeorge Cherian if (intr_val & BIT_ULL(0)) {
3015ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tUnmap Slot Error");
3025ed66306SGeorge Cherian if (err)
3035ed66306SGeorge Cherian return err;
3045ed66306SGeorge Cherian }
3055ed66306SGeorge Cherian err = rvu_report_pair_end(fmsg);
3065ed66306SGeorge Cherian if (err)
3075ed66306SGeorge Cherian return err;
3085ed66306SGeorge Cherian break;
3095ed66306SGeorge Cherian case NIX_AF_RVU_GEN:
3105ed66306SGeorge Cherian intr_val = nix_event_context->nix_af_rvu_gen;
3115ed66306SGeorge Cherian err = rvu_report_pair_start(fmsg, "NIX_AF_GENERAL");
3125ed66306SGeorge Cherian if (err)
3135ed66306SGeorge Cherian return err;
3145ed66306SGeorge Cherian err = devlink_fmsg_u64_pair_put(fmsg, "\tNIX General Interrupt Reg ",
3155ed66306SGeorge Cherian nix_event_context->nix_af_rvu_gen);
3165ed66306SGeorge Cherian if (err)
3175ed66306SGeorge Cherian return err;
3185ed66306SGeorge Cherian if (intr_val & BIT_ULL(0)) {
3195ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tRx multicast pkt drop");
3205ed66306SGeorge Cherian if (err)
3215ed66306SGeorge Cherian return err;
3225ed66306SGeorge Cherian }
3235ed66306SGeorge Cherian if (intr_val & BIT_ULL(1)) {
3245ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tRx mirror pkt drop");
3255ed66306SGeorge Cherian if (err)
3265ed66306SGeorge Cherian return err;
3275ed66306SGeorge Cherian }
3285ed66306SGeorge Cherian if (intr_val & BIT_ULL(4)) {
3295ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tSMQ flush done");
3305ed66306SGeorge Cherian if (err)
3315ed66306SGeorge Cherian return err;
3325ed66306SGeorge Cherian }
3335ed66306SGeorge Cherian err = rvu_report_pair_end(fmsg);
3345ed66306SGeorge Cherian if (err)
3355ed66306SGeorge Cherian return err;
3365ed66306SGeorge Cherian break;
3375ed66306SGeorge Cherian case NIX_AF_RVU_ERR:
3385ed66306SGeorge Cherian intr_val = nix_event_context->nix_af_rvu_err;
3395ed66306SGeorge Cherian err = rvu_report_pair_start(fmsg, "NIX_AF_ERR");
3405ed66306SGeorge Cherian if (err)
3415ed66306SGeorge Cherian return err;
3425ed66306SGeorge Cherian err = devlink_fmsg_u64_pair_put(fmsg, "\tNIX Error Interrupt Reg ",
3435ed66306SGeorge Cherian nix_event_context->nix_af_rvu_err);
3445ed66306SGeorge Cherian if (err)
3455ed66306SGeorge Cherian return err;
3465ed66306SGeorge Cherian if (intr_val & BIT_ULL(14)) {
3475ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tFault on NIX_AQ_INST_S read");
3485ed66306SGeorge Cherian if (err)
3495ed66306SGeorge Cherian return err;
3505ed66306SGeorge Cherian }
3515ed66306SGeorge Cherian if (intr_val & BIT_ULL(13)) {
3525ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tFault on NIX_AQ_RES_S write");
3535ed66306SGeorge Cherian if (err)
3545ed66306SGeorge Cherian return err;
3555ed66306SGeorge Cherian }
3565ed66306SGeorge Cherian if (intr_val & BIT_ULL(12)) {
3575ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tAQ Doorbell Error");
3585ed66306SGeorge Cherian if (err)
3595ed66306SGeorge Cherian return err;
3605ed66306SGeorge Cherian }
3615ed66306SGeorge Cherian if (intr_val & BIT_ULL(6)) {
3625ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tRx on unmapped PF_FUNC");
3635ed66306SGeorge Cherian if (err)
3645ed66306SGeorge Cherian return err;
3655ed66306SGeorge Cherian }
3665ed66306SGeorge Cherian if (intr_val & BIT_ULL(5)) {
3675ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tRx multicast replication error");
3685ed66306SGeorge Cherian if (err)
3695ed66306SGeorge Cherian return err;
3705ed66306SGeorge Cherian }
3715ed66306SGeorge Cherian if (intr_val & BIT_ULL(4)) {
3725ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tFault on NIX_RX_MCE_S read");
3735ed66306SGeorge Cherian if (err)
3745ed66306SGeorge Cherian return err;
3755ed66306SGeorge Cherian }
3765ed66306SGeorge Cherian if (intr_val & BIT_ULL(3)) {
3775ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tFault on multicast WQE read");
3785ed66306SGeorge Cherian if (err)
3795ed66306SGeorge Cherian return err;
3805ed66306SGeorge Cherian }
3815ed66306SGeorge Cherian if (intr_val & BIT_ULL(2)) {
3825ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tFault on mirror WQE read");
3835ed66306SGeorge Cherian if (err)
3845ed66306SGeorge Cherian return err;
3855ed66306SGeorge Cherian }
3865ed66306SGeorge Cherian if (intr_val & BIT_ULL(1)) {
3875ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tFault on mirror pkt write");
3885ed66306SGeorge Cherian if (err)
3895ed66306SGeorge Cherian return err;
3905ed66306SGeorge Cherian }
3915ed66306SGeorge Cherian if (intr_val & BIT_ULL(0)) {
3925ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tFault on multicast pkt write");
3935ed66306SGeorge Cherian if (err)
3945ed66306SGeorge Cherian return err;
3955ed66306SGeorge Cherian }
3965ed66306SGeorge Cherian err = rvu_report_pair_end(fmsg);
3975ed66306SGeorge Cherian if (err)
3985ed66306SGeorge Cherian return err;
3995ed66306SGeorge Cherian break;
4005ed66306SGeorge Cherian case NIX_AF_RVU_RAS:
4015ed66306SGeorge Cherian intr_val = nix_event_context->nix_af_rvu_err;
4025ed66306SGeorge Cherian err = rvu_report_pair_start(fmsg, "NIX_AF_RAS");
4035ed66306SGeorge Cherian if (err)
4045ed66306SGeorge Cherian return err;
4055ed66306SGeorge Cherian err = devlink_fmsg_u64_pair_put(fmsg, "\tNIX RAS Interrupt Reg ",
4065ed66306SGeorge Cherian nix_event_context->nix_af_rvu_err);
4075ed66306SGeorge Cherian if (err)
4085ed66306SGeorge Cherian return err;
4095ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tPoison Data on:");
4105ed66306SGeorge Cherian if (err)
4115ed66306SGeorge Cherian return err;
4125ed66306SGeorge Cherian if (intr_val & BIT_ULL(34)) {
4135ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tNIX_AQ_INST_S");
4145ed66306SGeorge Cherian if (err)
4155ed66306SGeorge Cherian return err;
4165ed66306SGeorge Cherian }
4175ed66306SGeorge Cherian if (intr_val & BIT_ULL(33)) {
4185ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tNIX_AQ_RES_S");
4195ed66306SGeorge Cherian if (err)
4205ed66306SGeorge Cherian return err;
4215ed66306SGeorge Cherian }
4225ed66306SGeorge Cherian if (intr_val & BIT_ULL(32)) {
4235ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tHW ctx");
4245ed66306SGeorge Cherian if (err)
4255ed66306SGeorge Cherian return err;
4265ed66306SGeorge Cherian }
4275ed66306SGeorge Cherian if (intr_val & BIT_ULL(4)) {
4285ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tPacket from mirror buffer");
4295ed66306SGeorge Cherian if (err)
4305ed66306SGeorge Cherian return err;
4315ed66306SGeorge Cherian }
4325ed66306SGeorge Cherian if (intr_val & BIT_ULL(3)) {
4335ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tPacket from multicast buffer");
4345ed66306SGeorge Cherian
4355ed66306SGeorge Cherian if (err)
4365ed66306SGeorge Cherian return err;
4375ed66306SGeorge Cherian }
4385ed66306SGeorge Cherian if (intr_val & BIT_ULL(2)) {
4395ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tWQE read from mirror buffer");
4405ed66306SGeorge Cherian if (err)
4415ed66306SGeorge Cherian return err;
4425ed66306SGeorge Cherian }
4435ed66306SGeorge Cherian if (intr_val & BIT_ULL(1)) {
4445ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tWQE read from multicast buffer");
4455ed66306SGeorge Cherian if (err)
4465ed66306SGeorge Cherian return err;
4475ed66306SGeorge Cherian }
4485ed66306SGeorge Cherian if (intr_val & BIT_ULL(0)) {
4495ed66306SGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tNIX_RX_MCE_S read");
4505ed66306SGeorge Cherian if (err)
4515ed66306SGeorge Cherian return err;
4525ed66306SGeorge Cherian }
4535ed66306SGeorge Cherian err = rvu_report_pair_end(fmsg);
4545ed66306SGeorge Cherian if (err)
4555ed66306SGeorge Cherian return err;
4565ed66306SGeorge Cherian break;
4575ed66306SGeorge Cherian default:
4585ed66306SGeorge Cherian return -EINVAL;
4595ed66306SGeorge Cherian }
4605ed66306SGeorge Cherian
4615ed66306SGeorge Cherian return 0;
4625ed66306SGeorge Cherian }
4635ed66306SGeorge Cherian
rvu_hw_nix_intr_dump(struct devlink_health_reporter * reporter,struct devlink_fmsg * fmsg,void * ctx,struct netlink_ext_ack * netlink_extack)4645ed66306SGeorge Cherian static int rvu_hw_nix_intr_dump(struct devlink_health_reporter *reporter,
4655ed66306SGeorge Cherian struct devlink_fmsg *fmsg, void *ctx,
4665ed66306SGeorge Cherian struct netlink_ext_ack *netlink_extack)
4675ed66306SGeorge Cherian {
4685ed66306SGeorge Cherian struct rvu *rvu = devlink_health_reporter_priv(reporter);
4695ed66306SGeorge Cherian struct rvu_devlink *rvu_dl = rvu->rvu_dl;
4705ed66306SGeorge Cherian struct rvu_nix_event_ctx *nix_ctx;
4715ed66306SGeorge Cherian
4725ed66306SGeorge Cherian nix_ctx = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
4735ed66306SGeorge Cherian
4745ed66306SGeorge Cherian return ctx ? rvu_nix_report_show(fmsg, ctx, NIX_AF_RVU_INTR) :
4755ed66306SGeorge Cherian rvu_nix_report_show(fmsg, nix_ctx, NIX_AF_RVU_INTR);
4765ed66306SGeorge Cherian }
4775ed66306SGeorge Cherian
rvu_hw_nix_intr_recover(struct devlink_health_reporter * reporter,void * ctx,struct netlink_ext_ack * netlink_extack)4785ed66306SGeorge Cherian static int rvu_hw_nix_intr_recover(struct devlink_health_reporter *reporter,
4795ed66306SGeorge Cherian void *ctx, struct netlink_ext_ack *netlink_extack)
4805ed66306SGeorge Cherian {
4815ed66306SGeorge Cherian struct rvu *rvu = devlink_health_reporter_priv(reporter);
4825ed66306SGeorge Cherian struct rvu_nix_event_ctx *nix_event_ctx = ctx;
4835ed66306SGeorge Cherian int blkaddr;
4845ed66306SGeorge Cherian
4855ed66306SGeorge Cherian blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
4865ed66306SGeorge Cherian if (blkaddr < 0)
4875ed66306SGeorge Cherian return blkaddr;
4885ed66306SGeorge Cherian
4895ed66306SGeorge Cherian if (nix_event_ctx->nix_af_rvu_int)
4905ed66306SGeorge Cherian rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT_ENA_W1S, ~0ULL);
4915ed66306SGeorge Cherian
4925ed66306SGeorge Cherian return 0;
4935ed66306SGeorge Cherian }
4945ed66306SGeorge Cherian
rvu_hw_nix_gen_dump(struct devlink_health_reporter * reporter,struct devlink_fmsg * fmsg,void * ctx,struct netlink_ext_ack * netlink_extack)4955ed66306SGeorge Cherian static int rvu_hw_nix_gen_dump(struct devlink_health_reporter *reporter,
4965ed66306SGeorge Cherian struct devlink_fmsg *fmsg, void *ctx,
4975ed66306SGeorge Cherian struct netlink_ext_ack *netlink_extack)
4985ed66306SGeorge Cherian {
4995ed66306SGeorge Cherian struct rvu *rvu = devlink_health_reporter_priv(reporter);
5005ed66306SGeorge Cherian struct rvu_devlink *rvu_dl = rvu->rvu_dl;
5015ed66306SGeorge Cherian struct rvu_nix_event_ctx *nix_ctx;
5025ed66306SGeorge Cherian
5035ed66306SGeorge Cherian nix_ctx = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
5045ed66306SGeorge Cherian
5055ed66306SGeorge Cherian return ctx ? rvu_nix_report_show(fmsg, ctx, NIX_AF_RVU_GEN) :
5065ed66306SGeorge Cherian rvu_nix_report_show(fmsg, nix_ctx, NIX_AF_RVU_GEN);
5075ed66306SGeorge Cherian }
5085ed66306SGeorge Cherian
rvu_hw_nix_gen_recover(struct devlink_health_reporter * reporter,void * ctx,struct netlink_ext_ack * netlink_extack)5095ed66306SGeorge Cherian static int rvu_hw_nix_gen_recover(struct devlink_health_reporter *reporter,
5105ed66306SGeorge Cherian void *ctx, struct netlink_ext_ack *netlink_extack)
5115ed66306SGeorge Cherian {
5125ed66306SGeorge Cherian struct rvu *rvu = devlink_health_reporter_priv(reporter);
5135ed66306SGeorge Cherian struct rvu_nix_event_ctx *nix_event_ctx = ctx;
5145ed66306SGeorge Cherian int blkaddr;
5155ed66306SGeorge Cherian
5165ed66306SGeorge Cherian blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
5175ed66306SGeorge Cherian if (blkaddr < 0)
5185ed66306SGeorge Cherian return blkaddr;
5195ed66306SGeorge Cherian
5205ed66306SGeorge Cherian if (nix_event_ctx->nix_af_rvu_gen)
5215ed66306SGeorge Cherian rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT_ENA_W1S, ~0ULL);
5225ed66306SGeorge Cherian
5235ed66306SGeorge Cherian return 0;
5245ed66306SGeorge Cherian }
5255ed66306SGeorge Cherian
rvu_hw_nix_err_dump(struct devlink_health_reporter * reporter,struct devlink_fmsg * fmsg,void * ctx,struct netlink_ext_ack * netlink_extack)5265ed66306SGeorge Cherian static int rvu_hw_nix_err_dump(struct devlink_health_reporter *reporter,
5275ed66306SGeorge Cherian struct devlink_fmsg *fmsg, void *ctx,
5285ed66306SGeorge Cherian struct netlink_ext_ack *netlink_extack)
5295ed66306SGeorge Cherian {
5305ed66306SGeorge Cherian struct rvu *rvu = devlink_health_reporter_priv(reporter);
5315ed66306SGeorge Cherian struct rvu_devlink *rvu_dl = rvu->rvu_dl;
5325ed66306SGeorge Cherian struct rvu_nix_event_ctx *nix_ctx;
5335ed66306SGeorge Cherian
5345ed66306SGeorge Cherian nix_ctx = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
5355ed66306SGeorge Cherian
5365ed66306SGeorge Cherian return ctx ? rvu_nix_report_show(fmsg, ctx, NIX_AF_RVU_ERR) :
5375ed66306SGeorge Cherian rvu_nix_report_show(fmsg, nix_ctx, NIX_AF_RVU_ERR);
5385ed66306SGeorge Cherian }
5395ed66306SGeorge Cherian
rvu_hw_nix_err_recover(struct devlink_health_reporter * reporter,void * ctx,struct netlink_ext_ack * netlink_extack)5405ed66306SGeorge Cherian static int rvu_hw_nix_err_recover(struct devlink_health_reporter *reporter,
5415ed66306SGeorge Cherian void *ctx, struct netlink_ext_ack *netlink_extack)
5425ed66306SGeorge Cherian {
5435ed66306SGeorge Cherian struct rvu *rvu = devlink_health_reporter_priv(reporter);
5445ed66306SGeorge Cherian struct rvu_nix_event_ctx *nix_event_ctx = ctx;
5455ed66306SGeorge Cherian int blkaddr;
5465ed66306SGeorge Cherian
5475ed66306SGeorge Cherian blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
5485ed66306SGeorge Cherian if (blkaddr < 0)
5495ed66306SGeorge Cherian return blkaddr;
5505ed66306SGeorge Cherian
5515ed66306SGeorge Cherian if (nix_event_ctx->nix_af_rvu_err)
5525ed66306SGeorge Cherian rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT_ENA_W1S, ~0ULL);
5535ed66306SGeorge Cherian
5545ed66306SGeorge Cherian return 0;
5555ed66306SGeorge Cherian }
5565ed66306SGeorge Cherian
rvu_hw_nix_ras_dump(struct devlink_health_reporter * reporter,struct devlink_fmsg * fmsg,void * ctx,struct netlink_ext_ack * netlink_extack)5575ed66306SGeorge Cherian static int rvu_hw_nix_ras_dump(struct devlink_health_reporter *reporter,
5585ed66306SGeorge Cherian struct devlink_fmsg *fmsg, void *ctx,
5595ed66306SGeorge Cherian struct netlink_ext_ack *netlink_extack)
5605ed66306SGeorge Cherian {
5615ed66306SGeorge Cherian struct rvu *rvu = devlink_health_reporter_priv(reporter);
5625ed66306SGeorge Cherian struct rvu_devlink *rvu_dl = rvu->rvu_dl;
5635ed66306SGeorge Cherian struct rvu_nix_event_ctx *nix_ctx;
5645ed66306SGeorge Cherian
5655ed66306SGeorge Cherian nix_ctx = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
5665ed66306SGeorge Cherian
5675ed66306SGeorge Cherian return ctx ? rvu_nix_report_show(fmsg, ctx, NIX_AF_RVU_RAS) :
5685ed66306SGeorge Cherian rvu_nix_report_show(fmsg, nix_ctx, NIX_AF_RVU_RAS);
5695ed66306SGeorge Cherian }
5705ed66306SGeorge Cherian
rvu_hw_nix_ras_recover(struct devlink_health_reporter * reporter,void * ctx,struct netlink_ext_ack * netlink_extack)5715ed66306SGeorge Cherian static int rvu_hw_nix_ras_recover(struct devlink_health_reporter *reporter,
5725ed66306SGeorge Cherian void *ctx, struct netlink_ext_ack *netlink_extack)
5735ed66306SGeorge Cherian {
5745ed66306SGeorge Cherian struct rvu *rvu = devlink_health_reporter_priv(reporter);
5755ed66306SGeorge Cherian struct rvu_nix_event_ctx *nix_event_ctx = ctx;
5765ed66306SGeorge Cherian int blkaddr;
5775ed66306SGeorge Cherian
5785ed66306SGeorge Cherian blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
5795ed66306SGeorge Cherian if (blkaddr < 0)
5805ed66306SGeorge Cherian return blkaddr;
5815ed66306SGeorge Cherian
5825ed66306SGeorge Cherian if (nix_event_ctx->nix_af_rvu_int)
5835ed66306SGeorge Cherian rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1S, ~0ULL);
5845ed66306SGeorge Cherian
5855ed66306SGeorge Cherian return 0;
5865ed66306SGeorge Cherian }
5875ed66306SGeorge Cherian
5885ed66306SGeorge Cherian RVU_REPORTERS(hw_nix_intr);
5895ed66306SGeorge Cherian RVU_REPORTERS(hw_nix_gen);
5905ed66306SGeorge Cherian RVU_REPORTERS(hw_nix_err);
5915ed66306SGeorge Cherian RVU_REPORTERS(hw_nix_ras);
5925ed66306SGeorge Cherian
5935ed66306SGeorge Cherian static void rvu_nix_health_reporters_destroy(struct rvu_devlink *rvu_dl);
5945ed66306SGeorge Cherian
rvu_nix_register_reporters(struct rvu_devlink * rvu_dl)5955ed66306SGeorge Cherian static int rvu_nix_register_reporters(struct rvu_devlink *rvu_dl)
5965ed66306SGeorge Cherian {
5975ed66306SGeorge Cherian struct rvu_nix_health_reporters *rvu_reporters;
5985ed66306SGeorge Cherian struct rvu_nix_event_ctx *nix_event_context;
5995ed66306SGeorge Cherian struct rvu *rvu = rvu_dl->rvu;
6005ed66306SGeorge Cherian
6015ed66306SGeorge Cherian rvu_reporters = kzalloc(sizeof(*rvu_reporters), GFP_KERNEL);
6025ed66306SGeorge Cherian if (!rvu_reporters)
6035ed66306SGeorge Cherian return -ENOMEM;
6045ed66306SGeorge Cherian
6055ed66306SGeorge Cherian rvu_dl->rvu_nix_health_reporter = rvu_reporters;
6065ed66306SGeorge Cherian nix_event_context = kzalloc(sizeof(*nix_event_context), GFP_KERNEL);
6075ed66306SGeorge Cherian if (!nix_event_context)
6085ed66306SGeorge Cherian return -ENOMEM;
6095ed66306SGeorge Cherian
6105ed66306SGeorge Cherian rvu_reporters->nix_event_ctx = nix_event_context;
6115ed66306SGeorge Cherian rvu_reporters->rvu_hw_nix_intr_reporter =
6125ed66306SGeorge Cherian devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_nix_intr_reporter_ops, 0, rvu);
6135ed66306SGeorge Cherian if (IS_ERR(rvu_reporters->rvu_hw_nix_intr_reporter)) {
6145ed66306SGeorge Cherian dev_warn(rvu->dev, "Failed to create hw_nix_intr reporter, err=%ld\n",
6155ed66306SGeorge Cherian PTR_ERR(rvu_reporters->rvu_hw_nix_intr_reporter));
6165ed66306SGeorge Cherian return PTR_ERR(rvu_reporters->rvu_hw_nix_intr_reporter);
6175ed66306SGeorge Cherian }
6185ed66306SGeorge Cherian
6195ed66306SGeorge Cherian rvu_reporters->rvu_hw_nix_gen_reporter =
6205ed66306SGeorge Cherian devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_nix_gen_reporter_ops, 0, rvu);
6215ed66306SGeorge Cherian if (IS_ERR(rvu_reporters->rvu_hw_nix_gen_reporter)) {
6225ed66306SGeorge Cherian dev_warn(rvu->dev, "Failed to create hw_nix_gen reporter, err=%ld\n",
6235ed66306SGeorge Cherian PTR_ERR(rvu_reporters->rvu_hw_nix_gen_reporter));
6245ed66306SGeorge Cherian return PTR_ERR(rvu_reporters->rvu_hw_nix_gen_reporter);
6255ed66306SGeorge Cherian }
6265ed66306SGeorge Cherian
6275ed66306SGeorge Cherian rvu_reporters->rvu_hw_nix_err_reporter =
6285ed66306SGeorge Cherian devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_nix_err_reporter_ops, 0, rvu);
6295ed66306SGeorge Cherian if (IS_ERR(rvu_reporters->rvu_hw_nix_err_reporter)) {
6305ed66306SGeorge Cherian dev_warn(rvu->dev, "Failed to create hw_nix_err reporter, err=%ld\n",
6315ed66306SGeorge Cherian PTR_ERR(rvu_reporters->rvu_hw_nix_err_reporter));
6325ed66306SGeorge Cherian return PTR_ERR(rvu_reporters->rvu_hw_nix_err_reporter);
6335ed66306SGeorge Cherian }
6345ed66306SGeorge Cherian
6355ed66306SGeorge Cherian rvu_reporters->rvu_hw_nix_ras_reporter =
6365ed66306SGeorge Cherian devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_nix_ras_reporter_ops, 0, rvu);
6375ed66306SGeorge Cherian if (IS_ERR(rvu_reporters->rvu_hw_nix_ras_reporter)) {
6385ed66306SGeorge Cherian dev_warn(rvu->dev, "Failed to create hw_nix_ras reporter, err=%ld\n",
6395ed66306SGeorge Cherian PTR_ERR(rvu_reporters->rvu_hw_nix_ras_reporter));
6405ed66306SGeorge Cherian return PTR_ERR(rvu_reporters->rvu_hw_nix_ras_reporter);
6415ed66306SGeorge Cherian }
6425ed66306SGeorge Cherian
6435ed66306SGeorge Cherian rvu_dl->devlink_wq = create_workqueue("rvu_devlink_wq");
6445ed66306SGeorge Cherian if (!rvu_dl->devlink_wq)
645dd75adfdSZhipeng Lu return -ENOMEM;
6465ed66306SGeorge Cherian
6475ed66306SGeorge Cherian INIT_WORK(&rvu_reporters->intr_work, rvu_nix_intr_work);
6485ed66306SGeorge Cherian INIT_WORK(&rvu_reporters->gen_work, rvu_nix_gen_work);
6495ed66306SGeorge Cherian INIT_WORK(&rvu_reporters->err_work, rvu_nix_err_work);
6505ed66306SGeorge Cherian INIT_WORK(&rvu_reporters->ras_work, rvu_nix_ras_work);
6515ed66306SGeorge Cherian
6525ed66306SGeorge Cherian return 0;
6535ed66306SGeorge Cherian }
6545ed66306SGeorge Cherian
rvu_nix_health_reporters_create(struct rvu_devlink * rvu_dl)6555ed66306SGeorge Cherian static int rvu_nix_health_reporters_create(struct rvu_devlink *rvu_dl)
6565ed66306SGeorge Cherian {
6575ed66306SGeorge Cherian struct rvu *rvu = rvu_dl->rvu;
6585ed66306SGeorge Cherian int err;
6595ed66306SGeorge Cherian
6605ed66306SGeorge Cherian err = rvu_nix_register_reporters(rvu_dl);
6615ed66306SGeorge Cherian if (err) {
6625ed66306SGeorge Cherian dev_warn(rvu->dev, "Failed to create nix reporter, err =%d\n",
6635ed66306SGeorge Cherian err);
6645ed66306SGeorge Cherian return err;
6655ed66306SGeorge Cherian }
6665ed66306SGeorge Cherian rvu_nix_register_interrupts(rvu);
6675ed66306SGeorge Cherian
6685ed66306SGeorge Cherian return 0;
6695ed66306SGeorge Cherian }
6705ed66306SGeorge Cherian
rvu_nix_health_reporters_destroy(struct rvu_devlink * rvu_dl)6715ed66306SGeorge Cherian static void rvu_nix_health_reporters_destroy(struct rvu_devlink *rvu_dl)
6725ed66306SGeorge Cherian {
6735ed66306SGeorge Cherian struct rvu_nix_health_reporters *nix_reporters;
6745ed66306SGeorge Cherian struct rvu *rvu = rvu_dl->rvu;
6755ed66306SGeorge Cherian
6765ed66306SGeorge Cherian nix_reporters = rvu_dl->rvu_nix_health_reporter;
6775ed66306SGeorge Cherian
6785ed66306SGeorge Cherian if (!nix_reporters->rvu_hw_nix_ras_reporter)
6795ed66306SGeorge Cherian return;
6805ed66306SGeorge Cherian if (!IS_ERR_OR_NULL(nix_reporters->rvu_hw_nix_intr_reporter))
6815ed66306SGeorge Cherian devlink_health_reporter_destroy(nix_reporters->rvu_hw_nix_intr_reporter);
6825ed66306SGeorge Cherian
6835ed66306SGeorge Cherian if (!IS_ERR_OR_NULL(nix_reporters->rvu_hw_nix_gen_reporter))
6845ed66306SGeorge Cherian devlink_health_reporter_destroy(nix_reporters->rvu_hw_nix_gen_reporter);
6855ed66306SGeorge Cherian
6865ed66306SGeorge Cherian if (!IS_ERR_OR_NULL(nix_reporters->rvu_hw_nix_err_reporter))
6875ed66306SGeorge Cherian devlink_health_reporter_destroy(nix_reporters->rvu_hw_nix_err_reporter);
6885ed66306SGeorge Cherian
6895ed66306SGeorge Cherian if (!IS_ERR_OR_NULL(nix_reporters->rvu_hw_nix_ras_reporter))
6905ed66306SGeorge Cherian devlink_health_reporter_destroy(nix_reporters->rvu_hw_nix_ras_reporter);
6915ed66306SGeorge Cherian
6925ed66306SGeorge Cherian rvu_nix_unregister_interrupts(rvu);
6935ed66306SGeorge Cherian kfree(rvu_dl->rvu_nix_health_reporter->nix_event_ctx);
6945ed66306SGeorge Cherian kfree(rvu_dl->rvu_nix_health_reporter);
6955ed66306SGeorge Cherian }
6965ed66306SGeorge Cherian
rvu_npa_intr_work(struct work_struct * work)697f1168d1eSGeorge Cherian static void rvu_npa_intr_work(struct work_struct *work)
698f1168d1eSGeorge Cherian {
699f1168d1eSGeorge Cherian struct rvu_npa_health_reporters *rvu_npa_health_reporter;
700f1168d1eSGeorge Cherian
701f1168d1eSGeorge Cherian rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, intr_work);
702f1168d1eSGeorge Cherian devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_intr_reporter,
703f1168d1eSGeorge Cherian "NPA_AF_RVU Error",
704f1168d1eSGeorge Cherian rvu_npa_health_reporter->npa_event_ctx);
705f1168d1eSGeorge Cherian }
706f1168d1eSGeorge Cherian
rvu_npa_af_rvu_intr_handler(int irq,void * rvu_irq)707f1168d1eSGeorge Cherian static irqreturn_t rvu_npa_af_rvu_intr_handler(int irq, void *rvu_irq)
708f1168d1eSGeorge Cherian {
709f1168d1eSGeorge Cherian struct rvu_npa_event_ctx *npa_event_context;
710f1168d1eSGeorge Cherian struct rvu_devlink *rvu_dl = rvu_irq;
711f1168d1eSGeorge Cherian struct rvu *rvu;
712f1168d1eSGeorge Cherian int blkaddr;
713f1168d1eSGeorge Cherian u64 intr;
714f1168d1eSGeorge Cherian
715f1168d1eSGeorge Cherian rvu = rvu_dl->rvu;
716f1168d1eSGeorge Cherian blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
717f1168d1eSGeorge Cherian if (blkaddr < 0)
718f1168d1eSGeorge Cherian return IRQ_NONE;
719f1168d1eSGeorge Cherian
720f1168d1eSGeorge Cherian npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
721f1168d1eSGeorge Cherian intr = rvu_read64(rvu, blkaddr, NPA_AF_RVU_INT);
722f1168d1eSGeorge Cherian npa_event_context->npa_af_rvu_int = intr;
723f1168d1eSGeorge Cherian
724f1168d1eSGeorge Cherian /* Clear interrupts */
725f1168d1eSGeorge Cherian rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT, intr);
726f1168d1eSGeorge Cherian rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1C, ~0ULL);
727f1168d1eSGeorge Cherian queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->intr_work);
728f1168d1eSGeorge Cherian
729f1168d1eSGeorge Cherian return IRQ_HANDLED;
730f1168d1eSGeorge Cherian }
731f1168d1eSGeorge Cherian
rvu_npa_gen_work(struct work_struct * work)732f1168d1eSGeorge Cherian static void rvu_npa_gen_work(struct work_struct *work)
733f1168d1eSGeorge Cherian {
734f1168d1eSGeorge Cherian struct rvu_npa_health_reporters *rvu_npa_health_reporter;
735f1168d1eSGeorge Cherian
736f1168d1eSGeorge Cherian rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, gen_work);
737f1168d1eSGeorge Cherian devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_gen_reporter,
738f1168d1eSGeorge Cherian "NPA_AF_GEN Error",
739f1168d1eSGeorge Cherian rvu_npa_health_reporter->npa_event_ctx);
740f1168d1eSGeorge Cherian }
741f1168d1eSGeorge Cherian
rvu_npa_af_gen_intr_handler(int irq,void * rvu_irq)742f1168d1eSGeorge Cherian static irqreturn_t rvu_npa_af_gen_intr_handler(int irq, void *rvu_irq)
743f1168d1eSGeorge Cherian {
744f1168d1eSGeorge Cherian struct rvu_npa_event_ctx *npa_event_context;
745f1168d1eSGeorge Cherian struct rvu_devlink *rvu_dl = rvu_irq;
746f1168d1eSGeorge Cherian struct rvu *rvu;
747f1168d1eSGeorge Cherian int blkaddr;
748f1168d1eSGeorge Cherian u64 intr;
749f1168d1eSGeorge Cherian
750f1168d1eSGeorge Cherian rvu = rvu_dl->rvu;
751f1168d1eSGeorge Cherian blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
752f1168d1eSGeorge Cherian if (blkaddr < 0)
753f1168d1eSGeorge Cherian return IRQ_NONE;
754f1168d1eSGeorge Cherian
755f1168d1eSGeorge Cherian npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
756f1168d1eSGeorge Cherian intr = rvu_read64(rvu, blkaddr, NPA_AF_GEN_INT);
757f1168d1eSGeorge Cherian npa_event_context->npa_af_rvu_gen = intr;
758f1168d1eSGeorge Cherian
759f1168d1eSGeorge Cherian /* Clear interrupts */
760f1168d1eSGeorge Cherian rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT, intr);
761f1168d1eSGeorge Cherian rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1C, ~0ULL);
762f1168d1eSGeorge Cherian queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->gen_work);
763f1168d1eSGeorge Cherian
764f1168d1eSGeorge Cherian return IRQ_HANDLED;
765f1168d1eSGeorge Cherian }
766f1168d1eSGeorge Cherian
rvu_npa_err_work(struct work_struct * work)767f1168d1eSGeorge Cherian static void rvu_npa_err_work(struct work_struct *work)
768f1168d1eSGeorge Cherian {
769f1168d1eSGeorge Cherian struct rvu_npa_health_reporters *rvu_npa_health_reporter;
770f1168d1eSGeorge Cherian
771f1168d1eSGeorge Cherian rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, err_work);
772f1168d1eSGeorge Cherian devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_err_reporter,
773f1168d1eSGeorge Cherian "NPA_AF_ERR Error",
774f1168d1eSGeorge Cherian rvu_npa_health_reporter->npa_event_ctx);
775f1168d1eSGeorge Cherian }
776f1168d1eSGeorge Cherian
rvu_npa_af_err_intr_handler(int irq,void * rvu_irq)777f1168d1eSGeorge Cherian static irqreturn_t rvu_npa_af_err_intr_handler(int irq, void *rvu_irq)
778f1168d1eSGeorge Cherian {
779f1168d1eSGeorge Cherian struct rvu_npa_event_ctx *npa_event_context;
780f1168d1eSGeorge Cherian struct rvu_devlink *rvu_dl = rvu_irq;
781f1168d1eSGeorge Cherian struct rvu *rvu;
782f1168d1eSGeorge Cherian int blkaddr;
783f1168d1eSGeorge Cherian u64 intr;
784f1168d1eSGeorge Cherian
785f1168d1eSGeorge Cherian rvu = rvu_dl->rvu;
786f1168d1eSGeorge Cherian blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
787f1168d1eSGeorge Cherian if (blkaddr < 0)
788f1168d1eSGeorge Cherian return IRQ_NONE;
789f1168d1eSGeorge Cherian npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
790f1168d1eSGeorge Cherian intr = rvu_read64(rvu, blkaddr, NPA_AF_ERR_INT);
791f1168d1eSGeorge Cherian npa_event_context->npa_af_rvu_err = intr;
792f1168d1eSGeorge Cherian
793f1168d1eSGeorge Cherian /* Clear interrupts */
794f1168d1eSGeorge Cherian rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT, intr);
795f1168d1eSGeorge Cherian rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1C, ~0ULL);
796f1168d1eSGeorge Cherian queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->err_work);
797f1168d1eSGeorge Cherian
798f1168d1eSGeorge Cherian return IRQ_HANDLED;
799f1168d1eSGeorge Cherian }
800f1168d1eSGeorge Cherian
rvu_npa_ras_work(struct work_struct * work)801f1168d1eSGeorge Cherian static void rvu_npa_ras_work(struct work_struct *work)
802f1168d1eSGeorge Cherian {
803f1168d1eSGeorge Cherian struct rvu_npa_health_reporters *rvu_npa_health_reporter;
804f1168d1eSGeorge Cherian
805f1168d1eSGeorge Cherian rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, ras_work);
806f1168d1eSGeorge Cherian devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_ras_reporter,
807f1168d1eSGeorge Cherian "HW NPA_AF_RAS Error reported",
808f1168d1eSGeorge Cherian rvu_npa_health_reporter->npa_event_ctx);
809f1168d1eSGeorge Cherian }
810f1168d1eSGeorge Cherian
rvu_npa_af_ras_intr_handler(int irq,void * rvu_irq)811f1168d1eSGeorge Cherian static irqreturn_t rvu_npa_af_ras_intr_handler(int irq, void *rvu_irq)
812f1168d1eSGeorge Cherian {
813f1168d1eSGeorge Cherian struct rvu_npa_event_ctx *npa_event_context;
814f1168d1eSGeorge Cherian struct rvu_devlink *rvu_dl = rvu_irq;
815f1168d1eSGeorge Cherian struct rvu *rvu;
816f1168d1eSGeorge Cherian int blkaddr;
817f1168d1eSGeorge Cherian u64 intr;
818f1168d1eSGeorge Cherian
819f1168d1eSGeorge Cherian rvu = rvu_dl->rvu;
820f1168d1eSGeorge Cherian blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
821f1168d1eSGeorge Cherian if (blkaddr < 0)
822f1168d1eSGeorge Cherian return IRQ_NONE;
823f1168d1eSGeorge Cherian
824f1168d1eSGeorge Cherian npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
825f1168d1eSGeorge Cherian intr = rvu_read64(rvu, blkaddr, NPA_AF_RAS);
826f1168d1eSGeorge Cherian npa_event_context->npa_af_rvu_ras = intr;
827f1168d1eSGeorge Cherian
828f1168d1eSGeorge Cherian /* Clear interrupts */
829f1168d1eSGeorge Cherian rvu_write64(rvu, blkaddr, NPA_AF_RAS, intr);
830f1168d1eSGeorge Cherian rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1C, ~0ULL);
831f1168d1eSGeorge Cherian queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->ras_work);
832f1168d1eSGeorge Cherian
833f1168d1eSGeorge Cherian return IRQ_HANDLED;
834f1168d1eSGeorge Cherian }
835f1168d1eSGeorge Cherian
rvu_npa_unregister_interrupts(struct rvu * rvu)836f1168d1eSGeorge Cherian static void rvu_npa_unregister_interrupts(struct rvu *rvu)
837f1168d1eSGeorge Cherian {
838f1168d1eSGeorge Cherian struct rvu_devlink *rvu_dl = rvu->rvu_dl;
839f1168d1eSGeorge Cherian int i, offs, blkaddr;
840f1168d1eSGeorge Cherian u64 reg;
841f1168d1eSGeorge Cherian
842f1168d1eSGeorge Cherian blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
843f1168d1eSGeorge Cherian if (blkaddr < 0)
844f1168d1eSGeorge Cherian return;
845f1168d1eSGeorge Cherian
846f1168d1eSGeorge Cherian reg = rvu_read64(rvu, blkaddr, NPA_PRIV_AF_INT_CFG);
847f1168d1eSGeorge Cherian offs = reg & 0x3FF;
848f1168d1eSGeorge Cherian
849f1168d1eSGeorge Cherian rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1C, ~0ULL);
850f1168d1eSGeorge Cherian rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1C, ~0ULL);
851f1168d1eSGeorge Cherian rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1C, ~0ULL);
852f1168d1eSGeorge Cherian rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1C, ~0ULL);
853f1168d1eSGeorge Cherian
854f1168d1eSGeorge Cherian for (i = 0; i < NPA_AF_INT_VEC_CNT; i++)
855f1168d1eSGeorge Cherian if (rvu->irq_allocated[offs + i]) {
856f1168d1eSGeorge Cherian free_irq(pci_irq_vector(rvu->pdev, offs + i), rvu_dl);
857f1168d1eSGeorge Cherian rvu->irq_allocated[offs + i] = false;
858f1168d1eSGeorge Cherian }
859f1168d1eSGeorge Cherian }
860f1168d1eSGeorge Cherian
rvu_npa_register_interrupts(struct rvu * rvu)861f1168d1eSGeorge Cherian static int rvu_npa_register_interrupts(struct rvu *rvu)
862f1168d1eSGeorge Cherian {
863f1168d1eSGeorge Cherian int blkaddr, base;
864f1168d1eSGeorge Cherian bool rc;
865f1168d1eSGeorge Cherian
866f1168d1eSGeorge Cherian blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
867f1168d1eSGeorge Cherian if (blkaddr < 0)
868f1168d1eSGeorge Cherian return blkaddr;
869f1168d1eSGeorge Cherian
870f1168d1eSGeorge Cherian /* Get NPA AF MSIX vectors offset. */
871f1168d1eSGeorge Cherian base = rvu_read64(rvu, blkaddr, NPA_PRIV_AF_INT_CFG) & 0x3ff;
872f1168d1eSGeorge Cherian if (!base) {
873f1168d1eSGeorge Cherian dev_warn(rvu->dev,
874f1168d1eSGeorge Cherian "Failed to get NPA_AF_INT vector offsets\n");
875f1168d1eSGeorge Cherian return 0;
876f1168d1eSGeorge Cherian }
877f1168d1eSGeorge Cherian
878f1168d1eSGeorge Cherian /* Register and enable NPA_AF_RVU_INT interrupt */
879f1168d1eSGeorge Cherian rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_RVU,
880f1168d1eSGeorge Cherian "NPA_AF_RVU_INT",
881f1168d1eSGeorge Cherian rvu_npa_af_rvu_intr_handler);
882f1168d1eSGeorge Cherian if (!rc)
883f1168d1eSGeorge Cherian goto err;
884f1168d1eSGeorge Cherian rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1S, ~0ULL);
885f1168d1eSGeorge Cherian
886f1168d1eSGeorge Cherian /* Register and enable NPA_AF_GEN_INT interrupt */
887f1168d1eSGeorge Cherian rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_GEN,
888f1168d1eSGeorge Cherian "NPA_AF_RVU_GEN",
889f1168d1eSGeorge Cherian rvu_npa_af_gen_intr_handler);
890f1168d1eSGeorge Cherian if (!rc)
891f1168d1eSGeorge Cherian goto err;
892f1168d1eSGeorge Cherian rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1S, ~0ULL);
893f1168d1eSGeorge Cherian
894f1168d1eSGeorge Cherian /* Register and enable NPA_AF_ERR_INT interrupt */
895f1168d1eSGeorge Cherian rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_AF_ERR,
896f1168d1eSGeorge Cherian "NPA_AF_ERR_INT",
897f1168d1eSGeorge Cherian rvu_npa_af_err_intr_handler);
898f1168d1eSGeorge Cherian if (!rc)
899f1168d1eSGeorge Cherian goto err;
900f1168d1eSGeorge Cherian rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1S, ~0ULL);
901f1168d1eSGeorge Cherian
902f1168d1eSGeorge Cherian /* Register and enable NPA_AF_RAS interrupt */
903f1168d1eSGeorge Cherian rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_POISON,
904f1168d1eSGeorge Cherian "NPA_AF_RAS",
905f1168d1eSGeorge Cherian rvu_npa_af_ras_intr_handler);
906f1168d1eSGeorge Cherian if (!rc)
907f1168d1eSGeorge Cherian goto err;
908f1168d1eSGeorge Cherian rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1S, ~0ULL);
909f1168d1eSGeorge Cherian
910f1168d1eSGeorge Cherian return 0;
911f1168d1eSGeorge Cherian err:
912f1168d1eSGeorge Cherian rvu_npa_unregister_interrupts(rvu);
913f1168d1eSGeorge Cherian return rc;
914f1168d1eSGeorge Cherian }
915f1168d1eSGeorge Cherian
rvu_npa_report_show(struct devlink_fmsg * fmsg,void * ctx,enum npa_af_rvu_health health_reporter)916f1168d1eSGeorge Cherian static int rvu_npa_report_show(struct devlink_fmsg *fmsg, void *ctx,
917f1168d1eSGeorge Cherian enum npa_af_rvu_health health_reporter)
918f1168d1eSGeorge Cherian {
919f1168d1eSGeorge Cherian struct rvu_npa_event_ctx *npa_event_context;
920d8a4ea35SColin Ian King unsigned int alloc_dis, free_dis;
921d8a4ea35SColin Ian King u64 intr_val;
922f1168d1eSGeorge Cherian int err;
923f1168d1eSGeorge Cherian
924f1168d1eSGeorge Cherian npa_event_context = ctx;
925f1168d1eSGeorge Cherian switch (health_reporter) {
926f1168d1eSGeorge Cherian case NPA_AF_RVU_GEN:
927f1168d1eSGeorge Cherian intr_val = npa_event_context->npa_af_rvu_gen;
928f1168d1eSGeorge Cherian err = rvu_report_pair_start(fmsg, "NPA_AF_GENERAL");
929f1168d1eSGeorge Cherian if (err)
930f1168d1eSGeorge Cherian return err;
931f1168d1eSGeorge Cherian err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA General Interrupt Reg ",
932f1168d1eSGeorge Cherian npa_event_context->npa_af_rvu_gen);
933f1168d1eSGeorge Cherian if (err)
934f1168d1eSGeorge Cherian return err;
935f1168d1eSGeorge Cherian if (intr_val & BIT_ULL(32)) {
936f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tUnmap PF Error");
937f1168d1eSGeorge Cherian if (err)
938f1168d1eSGeorge Cherian return err;
939f1168d1eSGeorge Cherian }
940f1168d1eSGeorge Cherian
941f1168d1eSGeorge Cherian free_dis = FIELD_GET(GENMASK(15, 0), intr_val);
942f1168d1eSGeorge Cherian if (free_dis & BIT(NPA_INPQ_NIX0_RX)) {
943f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tNIX0: free disabled RX");
944f1168d1eSGeorge Cherian if (err)
945f1168d1eSGeorge Cherian return err;
946f1168d1eSGeorge Cherian }
947f1168d1eSGeorge Cherian if (free_dis & BIT(NPA_INPQ_NIX0_TX)) {
948f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tNIX0:free disabled TX");
949f1168d1eSGeorge Cherian if (err)
950f1168d1eSGeorge Cherian return err;
951f1168d1eSGeorge Cherian }
952f1168d1eSGeorge Cherian if (free_dis & BIT(NPA_INPQ_NIX1_RX)) {
953f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tNIX1: free disabled RX");
954f1168d1eSGeorge Cherian if (err)
955f1168d1eSGeorge Cherian return err;
956f1168d1eSGeorge Cherian }
957f1168d1eSGeorge Cherian if (free_dis & BIT(NPA_INPQ_NIX1_TX)) {
958f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tNIX1:free disabled TX");
959f1168d1eSGeorge Cherian if (err)
960f1168d1eSGeorge Cherian return err;
961f1168d1eSGeorge Cherian }
962f1168d1eSGeorge Cherian if (free_dis & BIT(NPA_INPQ_SSO)) {
963f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for SSO");
964f1168d1eSGeorge Cherian if (err)
965f1168d1eSGeorge Cherian return err;
966f1168d1eSGeorge Cherian }
967f1168d1eSGeorge Cherian if (free_dis & BIT(NPA_INPQ_TIM)) {
968f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for TIM");
969f1168d1eSGeorge Cherian if (err)
970f1168d1eSGeorge Cherian return err;
971f1168d1eSGeorge Cherian }
972f1168d1eSGeorge Cherian if (free_dis & BIT(NPA_INPQ_DPI)) {
973f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for DPI");
974f1168d1eSGeorge Cherian if (err)
975f1168d1eSGeorge Cherian return err;
976f1168d1eSGeorge Cherian }
977f1168d1eSGeorge Cherian if (free_dis & BIT(NPA_INPQ_AURA_OP)) {
978f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for AURA");
979f1168d1eSGeorge Cherian if (err)
980f1168d1eSGeorge Cherian return err;
981f1168d1eSGeorge Cherian }
982f1168d1eSGeorge Cherian
983f1168d1eSGeorge Cherian alloc_dis = FIELD_GET(GENMASK(31, 16), intr_val);
984f1168d1eSGeorge Cherian if (alloc_dis & BIT(NPA_INPQ_NIX0_RX)) {
985f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tNIX0: alloc disabled RX");
986f1168d1eSGeorge Cherian if (err)
987f1168d1eSGeorge Cherian return err;
988f1168d1eSGeorge Cherian }
989f1168d1eSGeorge Cherian if (alloc_dis & BIT(NPA_INPQ_NIX0_TX)) {
990f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tNIX0:alloc disabled TX");
991f1168d1eSGeorge Cherian if (err)
992f1168d1eSGeorge Cherian return err;
993f1168d1eSGeorge Cherian }
994f1168d1eSGeorge Cherian if (alloc_dis & BIT(NPA_INPQ_NIX1_RX)) {
995f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tNIX1: alloc disabled RX");
996f1168d1eSGeorge Cherian if (err)
997f1168d1eSGeorge Cherian return err;
998f1168d1eSGeorge Cherian }
999f1168d1eSGeorge Cherian if (alloc_dis & BIT(NPA_INPQ_NIX1_TX)) {
1000f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tNIX1:alloc disabled TX");
1001f1168d1eSGeorge Cherian if (err)
1002f1168d1eSGeorge Cherian return err;
1003f1168d1eSGeorge Cherian }
1004f1168d1eSGeorge Cherian if (alloc_dis & BIT(NPA_INPQ_SSO)) {
1005f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for SSO");
1006f1168d1eSGeorge Cherian if (err)
1007f1168d1eSGeorge Cherian return err;
1008f1168d1eSGeorge Cherian }
1009f1168d1eSGeorge Cherian if (alloc_dis & BIT(NPA_INPQ_TIM)) {
1010f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for TIM");
1011f1168d1eSGeorge Cherian if (err)
1012f1168d1eSGeorge Cherian return err;
1013f1168d1eSGeorge Cherian }
1014f1168d1eSGeorge Cherian if (alloc_dis & BIT(NPA_INPQ_DPI)) {
1015f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for DPI");
1016f1168d1eSGeorge Cherian if (err)
1017f1168d1eSGeorge Cherian return err;
1018f1168d1eSGeorge Cherian }
1019f1168d1eSGeorge Cherian if (alloc_dis & BIT(NPA_INPQ_AURA_OP)) {
1020f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for AURA");
1021f1168d1eSGeorge Cherian if (err)
1022f1168d1eSGeorge Cherian return err;
1023f1168d1eSGeorge Cherian }
1024f1168d1eSGeorge Cherian err = rvu_report_pair_end(fmsg);
1025f1168d1eSGeorge Cherian if (err)
1026f1168d1eSGeorge Cherian return err;
1027f1168d1eSGeorge Cherian break;
1028f1168d1eSGeorge Cherian case NPA_AF_RVU_ERR:
1029f1168d1eSGeorge Cherian err = rvu_report_pair_start(fmsg, "NPA_AF_ERR");
1030f1168d1eSGeorge Cherian if (err)
1031f1168d1eSGeorge Cherian return err;
1032f1168d1eSGeorge Cherian err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA Error Interrupt Reg ",
1033f1168d1eSGeorge Cherian npa_event_context->npa_af_rvu_err);
1034f1168d1eSGeorge Cherian if (err)
1035f1168d1eSGeorge Cherian return err;
1036f1168d1eSGeorge Cherian
1037f1168d1eSGeorge Cherian if (npa_event_context->npa_af_rvu_err & BIT_ULL(14)) {
1038f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tFault on NPA_AQ_INST_S read");
1039f1168d1eSGeorge Cherian if (err)
1040f1168d1eSGeorge Cherian return err;
1041f1168d1eSGeorge Cherian }
1042f1168d1eSGeorge Cherian if (npa_event_context->npa_af_rvu_err & BIT_ULL(13)) {
1043f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tFault on NPA_AQ_RES_S write");
1044f1168d1eSGeorge Cherian if (err)
1045f1168d1eSGeorge Cherian return err;
1046f1168d1eSGeorge Cherian }
1047f1168d1eSGeorge Cherian if (npa_event_context->npa_af_rvu_err & BIT_ULL(12)) {
1048f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tAQ Doorbell Error");
1049f1168d1eSGeorge Cherian if (err)
1050f1168d1eSGeorge Cherian return err;
1051f1168d1eSGeorge Cherian }
1052f1168d1eSGeorge Cherian err = rvu_report_pair_end(fmsg);
1053f1168d1eSGeorge Cherian if (err)
1054f1168d1eSGeorge Cherian return err;
1055f1168d1eSGeorge Cherian break;
1056f1168d1eSGeorge Cherian case NPA_AF_RVU_RAS:
1057f1168d1eSGeorge Cherian err = rvu_report_pair_start(fmsg, "NPA_AF_RVU_RAS");
1058f1168d1eSGeorge Cherian if (err)
1059f1168d1eSGeorge Cherian return err;
1060f1168d1eSGeorge Cherian err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA RAS Interrupt Reg ",
1061f1168d1eSGeorge Cherian npa_event_context->npa_af_rvu_ras);
1062f1168d1eSGeorge Cherian if (err)
1063f1168d1eSGeorge Cherian return err;
1064f1168d1eSGeorge Cherian if (npa_event_context->npa_af_rvu_ras & BIT_ULL(34)) {
1065f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tPoison data on NPA_AQ_INST_S");
1066f1168d1eSGeorge Cherian if (err)
1067f1168d1eSGeorge Cherian return err;
1068f1168d1eSGeorge Cherian }
1069f1168d1eSGeorge Cherian if (npa_event_context->npa_af_rvu_ras & BIT_ULL(33)) {
1070f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tPoison data on NPA_AQ_RES_S");
1071f1168d1eSGeorge Cherian if (err)
1072f1168d1eSGeorge Cherian return err;
1073f1168d1eSGeorge Cherian }
1074f1168d1eSGeorge Cherian if (npa_event_context->npa_af_rvu_ras & BIT_ULL(32)) {
1075f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tPoison data on HW context");
1076f1168d1eSGeorge Cherian if (err)
1077f1168d1eSGeorge Cherian return err;
1078f1168d1eSGeorge Cherian }
1079f1168d1eSGeorge Cherian err = rvu_report_pair_end(fmsg);
1080f1168d1eSGeorge Cherian if (err)
1081f1168d1eSGeorge Cherian return err;
1082f1168d1eSGeorge Cherian break;
1083f1168d1eSGeorge Cherian case NPA_AF_RVU_INTR:
1084f1168d1eSGeorge Cherian err = rvu_report_pair_start(fmsg, "NPA_AF_RVU");
1085f1168d1eSGeorge Cherian if (err)
1086f1168d1eSGeorge Cherian return err;
1087f1168d1eSGeorge Cherian err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA RVU Interrupt Reg ",
1088f1168d1eSGeorge Cherian npa_event_context->npa_af_rvu_int);
1089f1168d1eSGeorge Cherian if (err)
1090f1168d1eSGeorge Cherian return err;
1091f1168d1eSGeorge Cherian if (npa_event_context->npa_af_rvu_int & BIT_ULL(0)) {
1092f1168d1eSGeorge Cherian err = devlink_fmsg_string_put(fmsg, "\n\tUnmap Slot Error");
1093f1168d1eSGeorge Cherian if (err)
1094f1168d1eSGeorge Cherian return err;
1095f1168d1eSGeorge Cherian }
1096f1168d1eSGeorge Cherian return rvu_report_pair_end(fmsg);
1097f1168d1eSGeorge Cherian default:
1098f1168d1eSGeorge Cherian return -EINVAL;
1099f1168d1eSGeorge Cherian }
1100f1168d1eSGeorge Cherian
1101f1168d1eSGeorge Cherian return 0;
1102f1168d1eSGeorge Cherian }
1103f1168d1eSGeorge Cherian
rvu_hw_npa_intr_dump(struct devlink_health_reporter * reporter,struct devlink_fmsg * fmsg,void * ctx,struct netlink_ext_ack * netlink_extack)1104f1168d1eSGeorge Cherian static int rvu_hw_npa_intr_dump(struct devlink_health_reporter *reporter,
1105f1168d1eSGeorge Cherian struct devlink_fmsg *fmsg, void *ctx,
1106f1168d1eSGeorge Cherian struct netlink_ext_ack *netlink_extack)
1107f1168d1eSGeorge Cherian {
1108f1168d1eSGeorge Cherian struct rvu *rvu = devlink_health_reporter_priv(reporter);
1109f1168d1eSGeorge Cherian struct rvu_devlink *rvu_dl = rvu->rvu_dl;
1110f1168d1eSGeorge Cherian struct rvu_npa_event_ctx *npa_ctx;
1111f1168d1eSGeorge Cherian
1112f1168d1eSGeorge Cherian npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
1113f1168d1eSGeorge Cherian
1114f1168d1eSGeorge Cherian return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_INTR) :
1115f1168d1eSGeorge Cherian rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_INTR);
1116f1168d1eSGeorge Cherian }
1117f1168d1eSGeorge Cherian
rvu_hw_npa_intr_recover(struct devlink_health_reporter * reporter,void * ctx,struct netlink_ext_ack * netlink_extack)1118f1168d1eSGeorge Cherian static int rvu_hw_npa_intr_recover(struct devlink_health_reporter *reporter,
1119f1168d1eSGeorge Cherian void *ctx, struct netlink_ext_ack *netlink_extack)
1120f1168d1eSGeorge Cherian {
1121f1168d1eSGeorge Cherian struct rvu *rvu = devlink_health_reporter_priv(reporter);
1122f1168d1eSGeorge Cherian struct rvu_npa_event_ctx *npa_event_ctx = ctx;
1123f1168d1eSGeorge Cherian int blkaddr;
1124f1168d1eSGeorge Cherian
1125f1168d1eSGeorge Cherian blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
1126f1168d1eSGeorge Cherian if (blkaddr < 0)
1127f1168d1eSGeorge Cherian return blkaddr;
1128f1168d1eSGeorge Cherian
1129f1168d1eSGeorge Cherian if (npa_event_ctx->npa_af_rvu_int)
1130f1168d1eSGeorge Cherian rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1S, ~0ULL);
1131f1168d1eSGeorge Cherian
1132f1168d1eSGeorge Cherian return 0;
1133f1168d1eSGeorge Cherian }
1134f1168d1eSGeorge Cherian
rvu_hw_npa_gen_dump(struct devlink_health_reporter * reporter,struct devlink_fmsg * fmsg,void * ctx,struct netlink_ext_ack * netlink_extack)1135f1168d1eSGeorge Cherian static int rvu_hw_npa_gen_dump(struct devlink_health_reporter *reporter,
1136f1168d1eSGeorge Cherian struct devlink_fmsg *fmsg, void *ctx,
1137f1168d1eSGeorge Cherian struct netlink_ext_ack *netlink_extack)
1138f1168d1eSGeorge Cherian {
1139f1168d1eSGeorge Cherian struct rvu *rvu = devlink_health_reporter_priv(reporter);
1140f1168d1eSGeorge Cherian struct rvu_devlink *rvu_dl = rvu->rvu_dl;
1141f1168d1eSGeorge Cherian struct rvu_npa_event_ctx *npa_ctx;
1142f1168d1eSGeorge Cherian
1143f1168d1eSGeorge Cherian npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
1144f1168d1eSGeorge Cherian
1145f1168d1eSGeorge Cherian return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_GEN) :
1146f1168d1eSGeorge Cherian rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_GEN);
1147f1168d1eSGeorge Cherian }
1148f1168d1eSGeorge Cherian
rvu_hw_npa_gen_recover(struct devlink_health_reporter * reporter,void * ctx,struct netlink_ext_ack * netlink_extack)1149f1168d1eSGeorge Cherian static int rvu_hw_npa_gen_recover(struct devlink_health_reporter *reporter,
1150f1168d1eSGeorge Cherian void *ctx, struct netlink_ext_ack *netlink_extack)
1151f1168d1eSGeorge Cherian {
1152f1168d1eSGeorge Cherian struct rvu *rvu = devlink_health_reporter_priv(reporter);
1153f1168d1eSGeorge Cherian struct rvu_npa_event_ctx *npa_event_ctx = ctx;
1154f1168d1eSGeorge Cherian int blkaddr;
1155f1168d1eSGeorge Cherian
1156f1168d1eSGeorge Cherian blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
1157f1168d1eSGeorge Cherian if (blkaddr < 0)
1158f1168d1eSGeorge Cherian return blkaddr;
1159f1168d1eSGeorge Cherian
1160f1168d1eSGeorge Cherian if (npa_event_ctx->npa_af_rvu_gen)
1161f1168d1eSGeorge Cherian rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1S, ~0ULL);
1162f1168d1eSGeorge Cherian
1163f1168d1eSGeorge Cherian return 0;
1164f1168d1eSGeorge Cherian }
1165f1168d1eSGeorge Cherian
rvu_hw_npa_err_dump(struct devlink_health_reporter * reporter,struct devlink_fmsg * fmsg,void * ctx,struct netlink_ext_ack * netlink_extack)1166f1168d1eSGeorge Cherian static int rvu_hw_npa_err_dump(struct devlink_health_reporter *reporter,
1167f1168d1eSGeorge Cherian struct devlink_fmsg *fmsg, void *ctx,
1168f1168d1eSGeorge Cherian struct netlink_ext_ack *netlink_extack)
1169f1168d1eSGeorge Cherian {
1170f1168d1eSGeorge Cherian struct rvu *rvu = devlink_health_reporter_priv(reporter);
1171f1168d1eSGeorge Cherian struct rvu_devlink *rvu_dl = rvu->rvu_dl;
1172f1168d1eSGeorge Cherian struct rvu_npa_event_ctx *npa_ctx;
1173f1168d1eSGeorge Cherian
1174f1168d1eSGeorge Cherian npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
1175f1168d1eSGeorge Cherian
1176f1168d1eSGeorge Cherian return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_ERR) :
1177f1168d1eSGeorge Cherian rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_ERR);
1178f1168d1eSGeorge Cherian }
1179f1168d1eSGeorge Cherian
rvu_hw_npa_err_recover(struct devlink_health_reporter * reporter,void * ctx,struct netlink_ext_ack * netlink_extack)1180f1168d1eSGeorge Cherian static int rvu_hw_npa_err_recover(struct devlink_health_reporter *reporter,
1181f1168d1eSGeorge Cherian void *ctx, struct netlink_ext_ack *netlink_extack)
1182f1168d1eSGeorge Cherian {
1183f1168d1eSGeorge Cherian struct rvu *rvu = devlink_health_reporter_priv(reporter);
1184f1168d1eSGeorge Cherian struct rvu_npa_event_ctx *npa_event_ctx = ctx;
1185f1168d1eSGeorge Cherian int blkaddr;
1186f1168d1eSGeorge Cherian
1187f1168d1eSGeorge Cherian blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
1188f1168d1eSGeorge Cherian if (blkaddr < 0)
1189f1168d1eSGeorge Cherian return blkaddr;
1190f1168d1eSGeorge Cherian
1191f1168d1eSGeorge Cherian if (npa_event_ctx->npa_af_rvu_err)
1192f1168d1eSGeorge Cherian rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1S, ~0ULL);
1193f1168d1eSGeorge Cherian
1194f1168d1eSGeorge Cherian return 0;
1195f1168d1eSGeorge Cherian }
1196f1168d1eSGeorge Cherian
rvu_hw_npa_ras_dump(struct devlink_health_reporter * reporter,struct devlink_fmsg * fmsg,void * ctx,struct netlink_ext_ack * netlink_extack)1197f1168d1eSGeorge Cherian static int rvu_hw_npa_ras_dump(struct devlink_health_reporter *reporter,
1198f1168d1eSGeorge Cherian struct devlink_fmsg *fmsg, void *ctx,
1199f1168d1eSGeorge Cherian struct netlink_ext_ack *netlink_extack)
1200f1168d1eSGeorge Cherian {
1201f1168d1eSGeorge Cherian struct rvu *rvu = devlink_health_reporter_priv(reporter);
1202f1168d1eSGeorge Cherian struct rvu_devlink *rvu_dl = rvu->rvu_dl;
1203f1168d1eSGeorge Cherian struct rvu_npa_event_ctx *npa_ctx;
1204f1168d1eSGeorge Cherian
1205f1168d1eSGeorge Cherian npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
1206f1168d1eSGeorge Cherian
1207f1168d1eSGeorge Cherian return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_RAS) :
1208f1168d1eSGeorge Cherian rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_RAS);
1209f1168d1eSGeorge Cherian }
1210f1168d1eSGeorge Cherian
rvu_hw_npa_ras_recover(struct devlink_health_reporter * reporter,void * ctx,struct netlink_ext_ack * netlink_extack)1211f1168d1eSGeorge Cherian static int rvu_hw_npa_ras_recover(struct devlink_health_reporter *reporter,
1212f1168d1eSGeorge Cherian void *ctx, struct netlink_ext_ack *netlink_extack)
1213f1168d1eSGeorge Cherian {
1214f1168d1eSGeorge Cherian struct rvu *rvu = devlink_health_reporter_priv(reporter);
1215f1168d1eSGeorge Cherian struct rvu_npa_event_ctx *npa_event_ctx = ctx;
1216f1168d1eSGeorge Cherian int blkaddr;
1217f1168d1eSGeorge Cherian
1218f1168d1eSGeorge Cherian blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
1219f1168d1eSGeorge Cherian if (blkaddr < 0)
1220f1168d1eSGeorge Cherian return blkaddr;
1221f1168d1eSGeorge Cherian
1222f1168d1eSGeorge Cherian if (npa_event_ctx->npa_af_rvu_ras)
1223f1168d1eSGeorge Cherian rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1S, ~0ULL);
1224f1168d1eSGeorge Cherian
1225f1168d1eSGeorge Cherian return 0;
1226f1168d1eSGeorge Cherian }
1227f1168d1eSGeorge Cherian
1228f1168d1eSGeorge Cherian RVU_REPORTERS(hw_npa_intr);
1229f1168d1eSGeorge Cherian RVU_REPORTERS(hw_npa_gen);
1230f1168d1eSGeorge Cherian RVU_REPORTERS(hw_npa_err);
1231f1168d1eSGeorge Cherian RVU_REPORTERS(hw_npa_ras);
1232f1168d1eSGeorge Cherian
1233f1168d1eSGeorge Cherian static void rvu_npa_health_reporters_destroy(struct rvu_devlink *rvu_dl);
1234f1168d1eSGeorge Cherian
rvu_npa_register_reporters(struct rvu_devlink * rvu_dl)1235f1168d1eSGeorge Cherian static int rvu_npa_register_reporters(struct rvu_devlink *rvu_dl)
1236f1168d1eSGeorge Cherian {
1237f1168d1eSGeorge Cherian struct rvu_npa_health_reporters *rvu_reporters;
1238f1168d1eSGeorge Cherian struct rvu_npa_event_ctx *npa_event_context;
1239f1168d1eSGeorge Cherian struct rvu *rvu = rvu_dl->rvu;
1240f1168d1eSGeorge Cherian
1241f1168d1eSGeorge Cherian rvu_reporters = kzalloc(sizeof(*rvu_reporters), GFP_KERNEL);
1242f1168d1eSGeorge Cherian if (!rvu_reporters)
1243f1168d1eSGeorge Cherian return -ENOMEM;
1244f1168d1eSGeorge Cherian
1245f1168d1eSGeorge Cherian rvu_dl->rvu_npa_health_reporter = rvu_reporters;
1246f1168d1eSGeorge Cherian npa_event_context = kzalloc(sizeof(*npa_event_context), GFP_KERNEL);
1247f1168d1eSGeorge Cherian if (!npa_event_context)
1248f1168d1eSGeorge Cherian return -ENOMEM;
1249f1168d1eSGeorge Cherian
1250f1168d1eSGeorge Cherian rvu_reporters->npa_event_ctx = npa_event_context;
1251f1168d1eSGeorge Cherian rvu_reporters->rvu_hw_npa_intr_reporter =
1252f1168d1eSGeorge Cherian devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_intr_reporter_ops, 0, rvu);
1253f1168d1eSGeorge Cherian if (IS_ERR(rvu_reporters->rvu_hw_npa_intr_reporter)) {
1254f1168d1eSGeorge Cherian dev_warn(rvu->dev, "Failed to create hw_npa_intr reporter, err=%ld\n",
1255f1168d1eSGeorge Cherian PTR_ERR(rvu_reporters->rvu_hw_npa_intr_reporter));
1256f1168d1eSGeorge Cherian return PTR_ERR(rvu_reporters->rvu_hw_npa_intr_reporter);
1257f1168d1eSGeorge Cherian }
1258f1168d1eSGeorge Cherian
1259f1168d1eSGeorge Cherian rvu_reporters->rvu_hw_npa_gen_reporter =
1260f1168d1eSGeorge Cherian devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_gen_reporter_ops, 0, rvu);
1261f1168d1eSGeorge Cherian if (IS_ERR(rvu_reporters->rvu_hw_npa_gen_reporter)) {
1262f1168d1eSGeorge Cherian dev_warn(rvu->dev, "Failed to create hw_npa_gen reporter, err=%ld\n",
1263f1168d1eSGeorge Cherian PTR_ERR(rvu_reporters->rvu_hw_npa_gen_reporter));
1264f1168d1eSGeorge Cherian return PTR_ERR(rvu_reporters->rvu_hw_npa_gen_reporter);
1265f1168d1eSGeorge Cherian }
1266f1168d1eSGeorge Cherian
1267f1168d1eSGeorge Cherian rvu_reporters->rvu_hw_npa_err_reporter =
1268f1168d1eSGeorge Cherian devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_err_reporter_ops, 0, rvu);
1269f1168d1eSGeorge Cherian if (IS_ERR(rvu_reporters->rvu_hw_npa_err_reporter)) {
1270f1168d1eSGeorge Cherian dev_warn(rvu->dev, "Failed to create hw_npa_err reporter, err=%ld\n",
1271f1168d1eSGeorge Cherian PTR_ERR(rvu_reporters->rvu_hw_npa_err_reporter));
1272f1168d1eSGeorge Cherian return PTR_ERR(rvu_reporters->rvu_hw_npa_err_reporter);
1273f1168d1eSGeorge Cherian }
1274f1168d1eSGeorge Cherian
1275f1168d1eSGeorge Cherian rvu_reporters->rvu_hw_npa_ras_reporter =
1276f1168d1eSGeorge Cherian devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_ras_reporter_ops, 0, rvu);
1277f1168d1eSGeorge Cherian if (IS_ERR(rvu_reporters->rvu_hw_npa_ras_reporter)) {
1278f1168d1eSGeorge Cherian dev_warn(rvu->dev, "Failed to create hw_npa_ras reporter, err=%ld\n",
1279f1168d1eSGeorge Cherian PTR_ERR(rvu_reporters->rvu_hw_npa_ras_reporter));
1280f1168d1eSGeorge Cherian return PTR_ERR(rvu_reporters->rvu_hw_npa_ras_reporter);
1281f1168d1eSGeorge Cherian }
1282f1168d1eSGeorge Cherian
1283f1168d1eSGeorge Cherian rvu_dl->devlink_wq = create_workqueue("rvu_devlink_wq");
1284f1168d1eSGeorge Cherian if (!rvu_dl->devlink_wq)
128533755da7SZhipeng Lu return -ENOMEM;
1286f1168d1eSGeorge Cherian
1287f1168d1eSGeorge Cherian INIT_WORK(&rvu_reporters->intr_work, rvu_npa_intr_work);
1288f1168d1eSGeorge Cherian INIT_WORK(&rvu_reporters->err_work, rvu_npa_err_work);
1289f1168d1eSGeorge Cherian INIT_WORK(&rvu_reporters->gen_work, rvu_npa_gen_work);
1290f1168d1eSGeorge Cherian INIT_WORK(&rvu_reporters->ras_work, rvu_npa_ras_work);
1291f1168d1eSGeorge Cherian
1292f1168d1eSGeorge Cherian return 0;
1293f1168d1eSGeorge Cherian }
1294f1168d1eSGeorge Cherian
rvu_npa_health_reporters_create(struct rvu_devlink * rvu_dl)1295f1168d1eSGeorge Cherian static int rvu_npa_health_reporters_create(struct rvu_devlink *rvu_dl)
1296f1168d1eSGeorge Cherian {
1297f1168d1eSGeorge Cherian struct rvu *rvu = rvu_dl->rvu;
1298f1168d1eSGeorge Cherian int err;
1299f1168d1eSGeorge Cherian
1300f1168d1eSGeorge Cherian err = rvu_npa_register_reporters(rvu_dl);
1301f1168d1eSGeorge Cherian if (err) {
1302f1168d1eSGeorge Cherian dev_warn(rvu->dev, "Failed to create npa reporter, err =%d\n",
1303f1168d1eSGeorge Cherian err);
1304f1168d1eSGeorge Cherian return err;
1305f1168d1eSGeorge Cherian }
1306f1168d1eSGeorge Cherian rvu_npa_register_interrupts(rvu);
1307f1168d1eSGeorge Cherian
1308f1168d1eSGeorge Cherian return 0;
1309f1168d1eSGeorge Cherian }
1310f1168d1eSGeorge Cherian
rvu_npa_health_reporters_destroy(struct rvu_devlink * rvu_dl)1311f1168d1eSGeorge Cherian static void rvu_npa_health_reporters_destroy(struct rvu_devlink *rvu_dl)
1312f1168d1eSGeorge Cherian {
1313f1168d1eSGeorge Cherian struct rvu_npa_health_reporters *npa_reporters;
1314f1168d1eSGeorge Cherian struct rvu *rvu = rvu_dl->rvu;
1315f1168d1eSGeorge Cherian
1316f1168d1eSGeorge Cherian npa_reporters = rvu_dl->rvu_npa_health_reporter;
1317f1168d1eSGeorge Cherian
1318f1168d1eSGeorge Cherian if (!npa_reporters->rvu_hw_npa_ras_reporter)
1319f1168d1eSGeorge Cherian return;
1320f1168d1eSGeorge Cherian if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_intr_reporter))
1321f1168d1eSGeorge Cherian devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_intr_reporter);
1322f1168d1eSGeorge Cherian
1323f1168d1eSGeorge Cherian if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_gen_reporter))
1324f1168d1eSGeorge Cherian devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_gen_reporter);
1325f1168d1eSGeorge Cherian
1326f1168d1eSGeorge Cherian if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_err_reporter))
1327f1168d1eSGeorge Cherian devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_err_reporter);
1328f1168d1eSGeorge Cherian
1329f1168d1eSGeorge Cherian if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_ras_reporter))
1330f1168d1eSGeorge Cherian devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_ras_reporter);
1331f1168d1eSGeorge Cherian
1332f1168d1eSGeorge Cherian rvu_npa_unregister_interrupts(rvu);
1333f1168d1eSGeorge Cherian kfree(rvu_dl->rvu_npa_health_reporter->npa_event_ctx);
1334f1168d1eSGeorge Cherian kfree(rvu_dl->rvu_npa_health_reporter);
1335f1168d1eSGeorge Cherian }
1336f1168d1eSGeorge Cherian
rvu_health_reporters_create(struct rvu * rvu)1337f1168d1eSGeorge Cherian static int rvu_health_reporters_create(struct rvu *rvu)
1338f1168d1eSGeorge Cherian {
1339f1168d1eSGeorge Cherian struct rvu_devlink *rvu_dl;
13405ed66306SGeorge Cherian int err;
1341f1168d1eSGeorge Cherian
1342f1168d1eSGeorge Cherian rvu_dl = rvu->rvu_dl;
13435ed66306SGeorge Cherian err = rvu_npa_health_reporters_create(rvu_dl);
13445ed66306SGeorge Cherian if (err)
13455ed66306SGeorge Cherian return err;
13465ed66306SGeorge Cherian
13475ed66306SGeorge Cherian return rvu_nix_health_reporters_create(rvu_dl);
1348f1168d1eSGeorge Cherian }
1349f1168d1eSGeorge Cherian
rvu_health_reporters_destroy(struct rvu * rvu)1350f1168d1eSGeorge Cherian static void rvu_health_reporters_destroy(struct rvu *rvu)
1351f1168d1eSGeorge Cherian {
1352f1168d1eSGeorge Cherian struct rvu_devlink *rvu_dl;
1353f1168d1eSGeorge Cherian
1354f1168d1eSGeorge Cherian if (!rvu->rvu_dl)
1355f1168d1eSGeorge Cherian return;
1356f1168d1eSGeorge Cherian
1357f1168d1eSGeorge Cherian rvu_dl = rvu->rvu_dl;
1358f1168d1eSGeorge Cherian rvu_npa_health_reporters_destroy(rvu_dl);
13595ed66306SGeorge Cherian rvu_nix_health_reporters_destroy(rvu_dl);
1360f1168d1eSGeorge Cherian }
1361f1168d1eSGeorge Cherian
136276660df2SSunil Goutham /* Devlink Params APIs */
rvu_af_dl_dwrr_mtu_validate(struct devlink * devlink,u32 id,union devlink_param_value val,struct netlink_ext_ack * extack)136376660df2SSunil Goutham static int rvu_af_dl_dwrr_mtu_validate(struct devlink *devlink, u32 id,
136476660df2SSunil Goutham union devlink_param_value val,
136576660df2SSunil Goutham struct netlink_ext_ack *extack)
136676660df2SSunil Goutham {
136776660df2SSunil Goutham struct rvu_devlink *rvu_dl = devlink_priv(devlink);
136876660df2SSunil Goutham struct rvu *rvu = rvu_dl->rvu;
136976660df2SSunil Goutham int dwrr_mtu = val.vu32;
137076660df2SSunil Goutham struct nix_txsch *txsch;
137176660df2SSunil Goutham struct nix_hw *nix_hw;
137276660df2SSunil Goutham
137376660df2SSunil Goutham if (!rvu->hw->cap.nix_common_dwrr_mtu) {
137476660df2SSunil Goutham NL_SET_ERR_MSG_MOD(extack,
137576660df2SSunil Goutham "Setting DWRR_MTU is not supported on this silicon");
137676660df2SSunil Goutham return -EOPNOTSUPP;
137776660df2SSunil Goutham }
137876660df2SSunil Goutham
137976660df2SSunil Goutham if ((dwrr_mtu > 65536 || !is_power_of_2(dwrr_mtu)) &&
138076660df2SSunil Goutham (dwrr_mtu != 9728 && dwrr_mtu != 10240)) {
138176660df2SSunil Goutham NL_SET_ERR_MSG_MOD(extack,
138276660df2SSunil Goutham "Invalid, supported MTUs are 0,2,4,8.16,32,64....4K,8K,32K,64K and 9728, 10240");
138376660df2SSunil Goutham return -EINVAL;
138476660df2SSunil Goutham }
138576660df2SSunil Goutham
138676660df2SSunil Goutham nix_hw = get_nix_hw(rvu->hw, BLKADDR_NIX0);
138776660df2SSunil Goutham if (!nix_hw)
138876660df2SSunil Goutham return -ENODEV;
138976660df2SSunil Goutham
139076660df2SSunil Goutham txsch = &nix_hw->txsch[NIX_TXSCH_LVL_SMQ];
139176660df2SSunil Goutham if (rvu_rsrc_free_count(&txsch->schq) != txsch->schq.max) {
139276660df2SSunil Goutham NL_SET_ERR_MSG_MOD(extack,
139376660df2SSunil Goutham "Changing DWRR MTU is not supported when there are active NIXLFs");
139476660df2SSunil Goutham NL_SET_ERR_MSG_MOD(extack,
139576660df2SSunil Goutham "Make sure none of the PF/VF interfaces are initialized and retry");
139676660df2SSunil Goutham return -EOPNOTSUPP;
139776660df2SSunil Goutham }
139876660df2SSunil Goutham
139976660df2SSunil Goutham return 0;
140076660df2SSunil Goutham }
140176660df2SSunil Goutham
rvu_af_dl_dwrr_mtu_set(struct devlink * devlink,u32 id,struct devlink_param_gset_ctx * ctx)140276660df2SSunil Goutham static int rvu_af_dl_dwrr_mtu_set(struct devlink *devlink, u32 id,
140376660df2SSunil Goutham struct devlink_param_gset_ctx *ctx)
140476660df2SSunil Goutham {
140576660df2SSunil Goutham struct rvu_devlink *rvu_dl = devlink_priv(devlink);
140676660df2SSunil Goutham struct rvu *rvu = rvu_dl->rvu;
140776660df2SSunil Goutham u64 dwrr_mtu;
140876660df2SSunil Goutham
140976660df2SSunil Goutham dwrr_mtu = convert_bytes_to_dwrr_mtu(ctx->val.vu32);
1410bbba125eSSunil Goutham rvu_write64(rvu, BLKADDR_NIX0,
1411bbba125eSSunil Goutham nix_get_dwrr_mtu_reg(rvu->hw, SMQ_LINK_TYPE_RPM), dwrr_mtu);
141276660df2SSunil Goutham
141376660df2SSunil Goutham return 0;
141476660df2SSunil Goutham }
141576660df2SSunil Goutham
rvu_af_dl_dwrr_mtu_get(struct devlink * devlink,u32 id,struct devlink_param_gset_ctx * ctx)141676660df2SSunil Goutham static int rvu_af_dl_dwrr_mtu_get(struct devlink *devlink, u32 id,
141776660df2SSunil Goutham struct devlink_param_gset_ctx *ctx)
141876660df2SSunil Goutham {
141976660df2SSunil Goutham struct rvu_devlink *rvu_dl = devlink_priv(devlink);
142076660df2SSunil Goutham struct rvu *rvu = rvu_dl->rvu;
142176660df2SSunil Goutham u64 dwrr_mtu;
142276660df2SSunil Goutham
142376660df2SSunil Goutham if (!rvu->hw->cap.nix_common_dwrr_mtu)
142476660df2SSunil Goutham return -EOPNOTSUPP;
142576660df2SSunil Goutham
1426bbba125eSSunil Goutham dwrr_mtu = rvu_read64(rvu, BLKADDR_NIX0,
1427bbba125eSSunil Goutham nix_get_dwrr_mtu_reg(rvu->hw, SMQ_LINK_TYPE_RPM));
142876660df2SSunil Goutham ctx->val.vu32 = convert_dwrr_mtu_to_bytes(dwrr_mtu);
142976660df2SSunil Goutham
143076660df2SSunil Goutham return 0;
143176660df2SSunil Goutham }
143276660df2SSunil Goutham
143376660df2SSunil Goutham enum rvu_af_dl_param_id {
143476660df2SSunil Goutham RVU_AF_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
143576660df2SSunil Goutham RVU_AF_DEVLINK_PARAM_ID_DWRR_MTU,
1436ef83e186SRatheesh Kannoth RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE,
143709de114cSNaveen Mamindlapalli RVU_AF_DEVLINK_PARAM_ID_NPC_MCAM_ZONE_PERCENT,
143876660df2SSunil Goutham };
143976660df2SSunil Goutham
rvu_af_npc_exact_feature_get(struct devlink * devlink,u32 id,struct devlink_param_gset_ctx * ctx)1440ef83e186SRatheesh Kannoth static int rvu_af_npc_exact_feature_get(struct devlink *devlink, u32 id,
1441ef83e186SRatheesh Kannoth struct devlink_param_gset_ctx *ctx)
1442ef83e186SRatheesh Kannoth {
1443ef83e186SRatheesh Kannoth struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1444ef83e186SRatheesh Kannoth struct rvu *rvu = rvu_dl->rvu;
1445ef83e186SRatheesh Kannoth bool enabled;
1446ef83e186SRatheesh Kannoth
1447ef83e186SRatheesh Kannoth enabled = rvu_npc_exact_has_match_table(rvu);
1448ef83e186SRatheesh Kannoth
1449ef83e186SRatheesh Kannoth snprintf(ctx->val.vstr, sizeof(ctx->val.vstr), "%s",
1450ef83e186SRatheesh Kannoth enabled ? "enabled" : "disabled");
1451ef83e186SRatheesh Kannoth
1452ef83e186SRatheesh Kannoth return 0;
1453ef83e186SRatheesh Kannoth }
1454ef83e186SRatheesh Kannoth
rvu_af_npc_exact_feature_disable(struct devlink * devlink,u32 id,struct devlink_param_gset_ctx * ctx)1455ef83e186SRatheesh Kannoth static int rvu_af_npc_exact_feature_disable(struct devlink *devlink, u32 id,
1456ef83e186SRatheesh Kannoth struct devlink_param_gset_ctx *ctx)
1457ef83e186SRatheesh Kannoth {
1458ef83e186SRatheesh Kannoth struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1459ef83e186SRatheesh Kannoth struct rvu *rvu = rvu_dl->rvu;
1460ef83e186SRatheesh Kannoth
1461ef83e186SRatheesh Kannoth rvu_npc_exact_disable_feature(rvu);
1462ef83e186SRatheesh Kannoth
1463ef83e186SRatheesh Kannoth return 0;
1464ef83e186SRatheesh Kannoth }
1465ef83e186SRatheesh Kannoth
rvu_af_npc_exact_feature_validate(struct devlink * devlink,u32 id,union devlink_param_value val,struct netlink_ext_ack * extack)1466ef83e186SRatheesh Kannoth static int rvu_af_npc_exact_feature_validate(struct devlink *devlink, u32 id,
1467ef83e186SRatheesh Kannoth union devlink_param_value val,
1468ef83e186SRatheesh Kannoth struct netlink_ext_ack *extack)
1469ef83e186SRatheesh Kannoth {
1470ef83e186SRatheesh Kannoth struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1471ef83e186SRatheesh Kannoth struct rvu *rvu = rvu_dl->rvu;
1472ef83e186SRatheesh Kannoth u64 enable;
1473ef83e186SRatheesh Kannoth
1474ef83e186SRatheesh Kannoth if (kstrtoull(val.vstr, 10, &enable)) {
1475ef83e186SRatheesh Kannoth NL_SET_ERR_MSG_MOD(extack,
1476ef83e186SRatheesh Kannoth "Only 1 value is supported");
1477ef83e186SRatheesh Kannoth return -EINVAL;
1478ef83e186SRatheesh Kannoth }
1479ef83e186SRatheesh Kannoth
1480ef83e186SRatheesh Kannoth if (enable != 1) {
1481ef83e186SRatheesh Kannoth NL_SET_ERR_MSG_MOD(extack,
1482ef83e186SRatheesh Kannoth "Only disabling exact match feature is supported");
1483ef83e186SRatheesh Kannoth return -EINVAL;
1484ef83e186SRatheesh Kannoth }
1485ef83e186SRatheesh Kannoth
1486ef83e186SRatheesh Kannoth if (rvu_npc_exact_can_disable_feature(rvu))
1487ef83e186SRatheesh Kannoth return 0;
1488ef83e186SRatheesh Kannoth
1489ef83e186SRatheesh Kannoth NL_SET_ERR_MSG_MOD(extack,
1490ef83e186SRatheesh Kannoth "Can't disable exact match feature; Please try before any configuration");
1491ef83e186SRatheesh Kannoth return -EFAULT;
1492ef83e186SRatheesh Kannoth }
1493ef83e186SRatheesh Kannoth
rvu_af_dl_npc_mcam_high_zone_percent_get(struct devlink * devlink,u32 id,struct devlink_param_gset_ctx * ctx)149409de114cSNaveen Mamindlapalli static int rvu_af_dl_npc_mcam_high_zone_percent_get(struct devlink *devlink, u32 id,
149509de114cSNaveen Mamindlapalli struct devlink_param_gset_ctx *ctx)
149609de114cSNaveen Mamindlapalli {
149709de114cSNaveen Mamindlapalli struct rvu_devlink *rvu_dl = devlink_priv(devlink);
149809de114cSNaveen Mamindlapalli struct rvu *rvu = rvu_dl->rvu;
149909de114cSNaveen Mamindlapalli struct npc_mcam *mcam;
150009de114cSNaveen Mamindlapalli u32 percent;
150109de114cSNaveen Mamindlapalli
150209de114cSNaveen Mamindlapalli mcam = &rvu->hw->mcam;
150309de114cSNaveen Mamindlapalli percent = (mcam->hprio_count * 100) / mcam->bmap_entries;
150409de114cSNaveen Mamindlapalli ctx->val.vu8 = (u8)percent;
150509de114cSNaveen Mamindlapalli
150609de114cSNaveen Mamindlapalli return 0;
150709de114cSNaveen Mamindlapalli }
150809de114cSNaveen Mamindlapalli
rvu_af_dl_npc_mcam_high_zone_percent_set(struct devlink * devlink,u32 id,struct devlink_param_gset_ctx * ctx)150909de114cSNaveen Mamindlapalli static int rvu_af_dl_npc_mcam_high_zone_percent_set(struct devlink *devlink, u32 id,
151009de114cSNaveen Mamindlapalli struct devlink_param_gset_ctx *ctx)
151109de114cSNaveen Mamindlapalli {
151209de114cSNaveen Mamindlapalli struct rvu_devlink *rvu_dl = devlink_priv(devlink);
151309de114cSNaveen Mamindlapalli struct rvu *rvu = rvu_dl->rvu;
151409de114cSNaveen Mamindlapalli struct npc_mcam *mcam;
151509de114cSNaveen Mamindlapalli u32 percent;
151609de114cSNaveen Mamindlapalli
151709de114cSNaveen Mamindlapalli percent = ctx->val.vu8;
151809de114cSNaveen Mamindlapalli mcam = &rvu->hw->mcam;
151909de114cSNaveen Mamindlapalli mcam->hprio_count = (mcam->bmap_entries * percent) / 100;
152009de114cSNaveen Mamindlapalli mcam->hprio_end = mcam->hprio_count;
152109de114cSNaveen Mamindlapalli mcam->lprio_count = (mcam->bmap_entries - mcam->hprio_count) / 2;
152209de114cSNaveen Mamindlapalli mcam->lprio_start = mcam->bmap_entries - mcam->lprio_count;
152309de114cSNaveen Mamindlapalli
152409de114cSNaveen Mamindlapalli return 0;
152509de114cSNaveen Mamindlapalli }
152609de114cSNaveen Mamindlapalli
rvu_af_dl_npc_mcam_high_zone_percent_validate(struct devlink * devlink,u32 id,union devlink_param_value val,struct netlink_ext_ack * extack)152709de114cSNaveen Mamindlapalli static int rvu_af_dl_npc_mcam_high_zone_percent_validate(struct devlink *devlink, u32 id,
152809de114cSNaveen Mamindlapalli union devlink_param_value val,
152909de114cSNaveen Mamindlapalli struct netlink_ext_ack *extack)
153009de114cSNaveen Mamindlapalli {
153109de114cSNaveen Mamindlapalli struct rvu_devlink *rvu_dl = devlink_priv(devlink);
153209de114cSNaveen Mamindlapalli struct rvu *rvu = rvu_dl->rvu;
153309de114cSNaveen Mamindlapalli struct npc_mcam *mcam;
153409de114cSNaveen Mamindlapalli
153509de114cSNaveen Mamindlapalli /* The percent of high prio zone must range from 12% to 100% of unreserved mcam space */
153609de114cSNaveen Mamindlapalli if (val.vu8 < 12 || val.vu8 > 100) {
153709de114cSNaveen Mamindlapalli NL_SET_ERR_MSG_MOD(extack,
153809de114cSNaveen Mamindlapalli "mcam high zone percent must be between 12% to 100%");
153909de114cSNaveen Mamindlapalli return -EINVAL;
154009de114cSNaveen Mamindlapalli }
154109de114cSNaveen Mamindlapalli
154209de114cSNaveen Mamindlapalli /* Do not allow user to modify the high priority zone entries while mcam entries
154309de114cSNaveen Mamindlapalli * have already been assigned.
154409de114cSNaveen Mamindlapalli */
154509de114cSNaveen Mamindlapalli mcam = &rvu->hw->mcam;
154609de114cSNaveen Mamindlapalli if (mcam->bmap_fcnt < mcam->bmap_entries) {
154709de114cSNaveen Mamindlapalli NL_SET_ERR_MSG_MOD(extack,
154809de114cSNaveen Mamindlapalli "mcam entries have already been assigned, can't resize");
154909de114cSNaveen Mamindlapalli return -EPERM;
155009de114cSNaveen Mamindlapalli }
155109de114cSNaveen Mamindlapalli
155209de114cSNaveen Mamindlapalli return 0;
155309de114cSNaveen Mamindlapalli }
155409de114cSNaveen Mamindlapalli
155576660df2SSunil Goutham static const struct devlink_param rvu_af_dl_params[] = {
155676660df2SSunil Goutham DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_DWRR_MTU,
155776660df2SSunil Goutham "dwrr_mtu", DEVLINK_PARAM_TYPE_U32,
155876660df2SSunil Goutham BIT(DEVLINK_PARAM_CMODE_RUNTIME),
155976660df2SSunil Goutham rvu_af_dl_dwrr_mtu_get, rvu_af_dl_dwrr_mtu_set,
156076660df2SSunil Goutham rvu_af_dl_dwrr_mtu_validate),
1561917d5e04SRatheesh Kannoth };
1562917d5e04SRatheesh Kannoth
1563917d5e04SRatheesh Kannoth static const struct devlink_param rvu_af_dl_param_exact_match[] = {
1564ef83e186SRatheesh Kannoth DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE,
1565ef83e186SRatheesh Kannoth "npc_exact_feature_disable", DEVLINK_PARAM_TYPE_STRING,
1566ef83e186SRatheesh Kannoth BIT(DEVLINK_PARAM_CMODE_RUNTIME),
1567ef83e186SRatheesh Kannoth rvu_af_npc_exact_feature_get,
1568ef83e186SRatheesh Kannoth rvu_af_npc_exact_feature_disable,
1569ef83e186SRatheesh Kannoth rvu_af_npc_exact_feature_validate),
157009de114cSNaveen Mamindlapalli DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NPC_MCAM_ZONE_PERCENT,
157109de114cSNaveen Mamindlapalli "npc_mcam_high_zone_percent", DEVLINK_PARAM_TYPE_U8,
157209de114cSNaveen Mamindlapalli BIT(DEVLINK_PARAM_CMODE_RUNTIME),
157309de114cSNaveen Mamindlapalli rvu_af_dl_npc_mcam_high_zone_percent_get,
157409de114cSNaveen Mamindlapalli rvu_af_dl_npc_mcam_high_zone_percent_set,
157509de114cSNaveen Mamindlapalli rvu_af_dl_npc_mcam_high_zone_percent_validate),
157676660df2SSunil Goutham };
157776660df2SSunil Goutham
157876660df2SSunil Goutham /* Devlink switch mode */
rvu_devlink_eswitch_mode_get(struct devlink * devlink,u16 * mode)157923109f8dSSubbaraya Sundeep static int rvu_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode)
158023109f8dSSubbaraya Sundeep {
158123109f8dSSubbaraya Sundeep struct rvu_devlink *rvu_dl = devlink_priv(devlink);
158223109f8dSSubbaraya Sundeep struct rvu *rvu = rvu_dl->rvu;
158323109f8dSSubbaraya Sundeep struct rvu_switch *rswitch;
158423109f8dSSubbaraya Sundeep
158523109f8dSSubbaraya Sundeep rswitch = &rvu->rswitch;
158623109f8dSSubbaraya Sundeep *mode = rswitch->mode;
158723109f8dSSubbaraya Sundeep
158823109f8dSSubbaraya Sundeep return 0;
158923109f8dSSubbaraya Sundeep }
159023109f8dSSubbaraya Sundeep
rvu_devlink_eswitch_mode_set(struct devlink * devlink,u16 mode,struct netlink_ext_ack * extack)159123109f8dSSubbaraya Sundeep static int rvu_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
159223109f8dSSubbaraya Sundeep struct netlink_ext_ack *extack)
159323109f8dSSubbaraya Sundeep {
159423109f8dSSubbaraya Sundeep struct rvu_devlink *rvu_dl = devlink_priv(devlink);
159523109f8dSSubbaraya Sundeep struct rvu *rvu = rvu_dl->rvu;
159623109f8dSSubbaraya Sundeep struct rvu_switch *rswitch;
159723109f8dSSubbaraya Sundeep
159823109f8dSSubbaraya Sundeep rswitch = &rvu->rswitch;
159923109f8dSSubbaraya Sundeep switch (mode) {
160023109f8dSSubbaraya Sundeep case DEVLINK_ESWITCH_MODE_LEGACY:
160123109f8dSSubbaraya Sundeep case DEVLINK_ESWITCH_MODE_SWITCHDEV:
160223109f8dSSubbaraya Sundeep if (rswitch->mode == mode)
160323109f8dSSubbaraya Sundeep return 0;
160423109f8dSSubbaraya Sundeep rswitch->mode = mode;
160523109f8dSSubbaraya Sundeep if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV)
160623109f8dSSubbaraya Sundeep rvu_switch_enable(rvu);
160723109f8dSSubbaraya Sundeep else
160823109f8dSSubbaraya Sundeep rvu_switch_disable(rvu);
160923109f8dSSubbaraya Sundeep break;
161023109f8dSSubbaraya Sundeep default:
161123109f8dSSubbaraya Sundeep return -EINVAL;
161223109f8dSSubbaraya Sundeep }
161323109f8dSSubbaraya Sundeep
161423109f8dSSubbaraya Sundeep return 0;
161523109f8dSSubbaraya Sundeep }
161623109f8dSSubbaraya Sundeep
1617fae06da4SGeorge Cherian static const struct devlink_ops rvu_devlink_ops = {
161823109f8dSSubbaraya Sundeep .eswitch_mode_get = rvu_devlink_eswitch_mode_get,
161923109f8dSSubbaraya Sundeep .eswitch_mode_set = rvu_devlink_eswitch_mode_set,
1620fae06da4SGeorge Cherian };
1621fae06da4SGeorge Cherian
rvu_register_dl(struct rvu * rvu)1622fae06da4SGeorge Cherian int rvu_register_dl(struct rvu *rvu)
1623fae06da4SGeorge Cherian {
1624fae06da4SGeorge Cherian struct rvu_devlink *rvu_dl;
1625fae06da4SGeorge Cherian struct devlink *dl;
1626fae06da4SGeorge Cherian int err;
1627fae06da4SGeorge Cherian
1628919d13a7SLeon Romanovsky dl = devlink_alloc(&rvu_devlink_ops, sizeof(struct rvu_devlink),
1629919d13a7SLeon Romanovsky rvu->dev);
1630fae06da4SGeorge Cherian if (!dl) {
1631fae06da4SGeorge Cherian dev_warn(rvu->dev, "devlink_alloc failed\n");
1632fae06da4SGeorge Cherian return -ENOMEM;
1633fae06da4SGeorge Cherian }
1634fae06da4SGeorge Cherian
163523109f8dSSubbaraya Sundeep rvu_dl = devlink_priv(dl);
1636fae06da4SGeorge Cherian rvu_dl->dl = dl;
1637fae06da4SGeorge Cherian rvu_dl->rvu = rvu;
1638fae06da4SGeorge Cherian rvu->rvu_dl = rvu_dl;
1639f1168d1eSGeorge Cherian
164076660df2SSunil Goutham err = rvu_health_reporters_create(rvu);
164176660df2SSunil Goutham if (err) {
164276660df2SSunil Goutham dev_err(rvu->dev,
164376660df2SSunil Goutham "devlink health reporter creation failed with error %d\n", err);
164476660df2SSunil Goutham goto err_dl_health;
164576660df2SSunil Goutham }
164676660df2SSunil Goutham
1647917d5e04SRatheesh Kannoth err = devlink_params_register(dl, rvu_af_dl_params, ARRAY_SIZE(rvu_af_dl_params));
164876660df2SSunil Goutham if (err) {
164976660df2SSunil Goutham dev_err(rvu->dev,
165076660df2SSunil Goutham "devlink params register failed with error %d", err);
165176660df2SSunil Goutham goto err_dl_health;
165276660df2SSunil Goutham }
165376660df2SSunil Goutham
1654917d5e04SRatheesh Kannoth /* Register exact match devlink only for CN10K-B */
1655917d5e04SRatheesh Kannoth if (!rvu_npc_exact_has_match_table(rvu))
1656917d5e04SRatheesh Kannoth goto done;
1657917d5e04SRatheesh Kannoth
1658917d5e04SRatheesh Kannoth err = devlink_params_register(dl, rvu_af_dl_param_exact_match,
1659917d5e04SRatheesh Kannoth ARRAY_SIZE(rvu_af_dl_param_exact_match));
1660917d5e04SRatheesh Kannoth if (err) {
1661917d5e04SRatheesh Kannoth dev_err(rvu->dev,
1662917d5e04SRatheesh Kannoth "devlink exact match params register failed with error %d", err);
1663917d5e04SRatheesh Kannoth goto err_dl_exact_match;
1664917d5e04SRatheesh Kannoth }
1665917d5e04SRatheesh Kannoth
1666917d5e04SRatheesh Kannoth done:
16671d264db4SLeon Romanovsky devlink_register(dl);
166876660df2SSunil Goutham return 0;
166976660df2SSunil Goutham
1670917d5e04SRatheesh Kannoth err_dl_exact_match:
1671917d5e04SRatheesh Kannoth devlink_params_unregister(dl, rvu_af_dl_params, ARRAY_SIZE(rvu_af_dl_params));
1672917d5e04SRatheesh Kannoth
167376660df2SSunil Goutham err_dl_health:
167476660df2SSunil Goutham rvu_health_reporters_destroy(rvu);
167576660df2SSunil Goutham devlink_free(dl);
167676660df2SSunil Goutham return err;
1677fae06da4SGeorge Cherian }
1678fae06da4SGeorge Cherian
rvu_unregister_dl(struct rvu * rvu)1679fae06da4SGeorge Cherian void rvu_unregister_dl(struct rvu *rvu)
1680fae06da4SGeorge Cherian {
1681fae06da4SGeorge Cherian struct rvu_devlink *rvu_dl = rvu->rvu_dl;
1682fae06da4SGeorge Cherian struct devlink *dl = rvu_dl->dl;
1683fae06da4SGeorge Cherian
16841d264db4SLeon Romanovsky devlink_unregister(dl);
1685917d5e04SRatheesh Kannoth
1686917d5e04SRatheesh Kannoth devlink_params_unregister(dl, rvu_af_dl_params, ARRAY_SIZE(rvu_af_dl_params));
1687917d5e04SRatheesh Kannoth
1688917d5e04SRatheesh Kannoth /* Unregister exact match devlink only for CN10K-B */
1689917d5e04SRatheesh Kannoth if (rvu_npc_exact_has_match_table(rvu))
1690917d5e04SRatheesh Kannoth devlink_params_unregister(dl, rvu_af_dl_param_exact_match,
1691917d5e04SRatheesh Kannoth ARRAY_SIZE(rvu_af_dl_param_exact_match));
1692917d5e04SRatheesh Kannoth
1693f1168d1eSGeorge Cherian rvu_health_reporters_destroy(rvu);
1694fae06da4SGeorge Cherian devlink_free(dl);
1695fae06da4SGeorge Cherian }
1696