xref: /linux/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c (revision 4f9786035f9e519db41375818e1d0b5f20da2f10)
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)17d8cf03fcSPrzemek Kitszel static void rvu_report_pair_start(struct devlink_fmsg *fmsg, const char *name)
18f1168d1eSGeorge Cherian {
19d8cf03fcSPrzemek Kitszel 	devlink_fmsg_pair_nest_start(fmsg, name);
20d8cf03fcSPrzemek Kitszel 	devlink_fmsg_obj_nest_start(fmsg);
21f1168d1eSGeorge Cherian }
22f1168d1eSGeorge Cherian 
rvu_report_pair_end(struct devlink_fmsg * fmsg)23d8cf03fcSPrzemek Kitszel static void rvu_report_pair_end(struct devlink_fmsg *fmsg)
24f1168d1eSGeorge Cherian {
25d8cf03fcSPrzemek Kitszel 	devlink_fmsg_obj_nest_end(fmsg);
26d8cf03fcSPrzemek Kitszel 	devlink_fmsg_pair_nest_end(fmsg);
27f1168d1eSGeorge Cherian }
28f1168d1eSGeorge Cherian 
rvu_common_request_irq(struct rvu * rvu,int offset,const char * name,irq_handler_t fn)29f1168d1eSGeorge Cherian static bool rvu_common_request_irq(struct rvu *rvu, int offset,
30f1168d1eSGeorge Cherian 				   const char *name, irq_handler_t fn)
31f1168d1eSGeorge Cherian {
32f1168d1eSGeorge Cherian 	struct rvu_devlink *rvu_dl = rvu->rvu_dl;
33f1168d1eSGeorge Cherian 	int rc;
34f1168d1eSGeorge Cherian 
356dc9a23eSSunil Goutham 	sprintf(&rvu->irq_name[offset * NAME_SIZE], "%s", name);
36f1168d1eSGeorge Cherian 	rc = request_irq(pci_irq_vector(rvu->pdev, offset), fn, 0,
37f1168d1eSGeorge Cherian 			 &rvu->irq_name[offset * NAME_SIZE], rvu_dl);
38f1168d1eSGeorge Cherian 	if (rc)
39f1168d1eSGeorge Cherian 		dev_warn(rvu->dev, "Failed to register %s irq\n", name);
40f1168d1eSGeorge Cherian 	else
41f1168d1eSGeorge Cherian 		rvu->irq_allocated[offset] = true;
42f1168d1eSGeorge Cherian 
43f1168d1eSGeorge Cherian 	return rvu->irq_allocated[offset];
44f1168d1eSGeorge Cherian }
45f1168d1eSGeorge Cherian 
rvu_nix_intr_work(struct work_struct * work)465ed66306SGeorge Cherian static void rvu_nix_intr_work(struct work_struct *work)
475ed66306SGeorge Cherian {
485ed66306SGeorge Cherian 	struct rvu_nix_health_reporters *rvu_nix_health_reporter;
495ed66306SGeorge Cherian 
505ed66306SGeorge Cherian 	rvu_nix_health_reporter = container_of(work, struct rvu_nix_health_reporters, intr_work);
515ed66306SGeorge Cherian 	devlink_health_report(rvu_nix_health_reporter->rvu_hw_nix_intr_reporter,
525ed66306SGeorge Cherian 			      "NIX_AF_RVU Error",
535ed66306SGeorge Cherian 			      rvu_nix_health_reporter->nix_event_ctx);
545ed66306SGeorge Cherian }
555ed66306SGeorge Cherian 
rvu_nix_af_rvu_intr_handler(int irq,void * rvu_irq)565ed66306SGeorge Cherian static irqreturn_t rvu_nix_af_rvu_intr_handler(int irq, void *rvu_irq)
575ed66306SGeorge Cherian {
585ed66306SGeorge Cherian 	struct rvu_nix_event_ctx *nix_event_context;
595ed66306SGeorge Cherian 	struct rvu_devlink *rvu_dl = rvu_irq;
605ed66306SGeorge Cherian 	struct rvu *rvu;
615ed66306SGeorge Cherian 	int blkaddr;
625ed66306SGeorge Cherian 	u64 intr;
635ed66306SGeorge Cherian 
645ed66306SGeorge Cherian 	rvu = rvu_dl->rvu;
655ed66306SGeorge Cherian 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
665ed66306SGeorge Cherian 	if (blkaddr < 0)
675ed66306SGeorge Cherian 		return IRQ_NONE;
685ed66306SGeorge Cherian 
695ed66306SGeorge Cherian 	nix_event_context = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
705ed66306SGeorge Cherian 	intr = rvu_read64(rvu, blkaddr, NIX_AF_RVU_INT);
715ed66306SGeorge Cherian 	nix_event_context->nix_af_rvu_int = intr;
725ed66306SGeorge Cherian 
735ed66306SGeorge Cherian 	/* Clear interrupts */
745ed66306SGeorge Cherian 	rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT, intr);
755ed66306SGeorge Cherian 	rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT_ENA_W1C, ~0ULL);
765ed66306SGeorge Cherian 	queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_nix_health_reporter->intr_work);
775ed66306SGeorge Cherian 
785ed66306SGeorge Cherian 	return IRQ_HANDLED;
795ed66306SGeorge Cherian }
805ed66306SGeorge Cherian 
rvu_nix_gen_work(struct work_struct * work)815ed66306SGeorge Cherian static void rvu_nix_gen_work(struct work_struct *work)
825ed66306SGeorge Cherian {
835ed66306SGeorge Cherian 	struct rvu_nix_health_reporters *rvu_nix_health_reporter;
845ed66306SGeorge Cherian 
855ed66306SGeorge Cherian 	rvu_nix_health_reporter = container_of(work, struct rvu_nix_health_reporters, gen_work);
865ed66306SGeorge Cherian 	devlink_health_report(rvu_nix_health_reporter->rvu_hw_nix_gen_reporter,
875ed66306SGeorge Cherian 			      "NIX_AF_GEN Error",
885ed66306SGeorge Cherian 			      rvu_nix_health_reporter->nix_event_ctx);
895ed66306SGeorge Cherian }
905ed66306SGeorge Cherian 
rvu_nix_af_rvu_gen_handler(int irq,void * rvu_irq)915ed66306SGeorge Cherian static irqreturn_t rvu_nix_af_rvu_gen_handler(int irq, void *rvu_irq)
925ed66306SGeorge Cherian {
935ed66306SGeorge Cherian 	struct rvu_nix_event_ctx *nix_event_context;
945ed66306SGeorge Cherian 	struct rvu_devlink *rvu_dl = rvu_irq;
955ed66306SGeorge Cherian 	struct rvu *rvu;
965ed66306SGeorge Cherian 	int blkaddr;
975ed66306SGeorge Cherian 	u64 intr;
985ed66306SGeorge Cherian 
995ed66306SGeorge Cherian 	rvu = rvu_dl->rvu;
1005ed66306SGeorge Cherian 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
1015ed66306SGeorge Cherian 	if (blkaddr < 0)
1025ed66306SGeorge Cherian 		return IRQ_NONE;
1035ed66306SGeorge Cherian 
1045ed66306SGeorge Cherian 	nix_event_context = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
1055ed66306SGeorge Cherian 	intr = rvu_read64(rvu, blkaddr, NIX_AF_GEN_INT);
1065ed66306SGeorge Cherian 	nix_event_context->nix_af_rvu_gen = intr;
1075ed66306SGeorge Cherian 
1085ed66306SGeorge Cherian 	/* Clear interrupts */
1095ed66306SGeorge Cherian 	rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT, intr);
1105ed66306SGeorge Cherian 	rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT_ENA_W1C, ~0ULL);
1115ed66306SGeorge Cherian 	queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_nix_health_reporter->gen_work);
1125ed66306SGeorge Cherian 
1135ed66306SGeorge Cherian 	return IRQ_HANDLED;
1145ed66306SGeorge Cherian }
1155ed66306SGeorge Cherian 
rvu_nix_err_work(struct work_struct * work)1165ed66306SGeorge Cherian static void rvu_nix_err_work(struct work_struct *work)
1175ed66306SGeorge Cherian {
1185ed66306SGeorge Cherian 	struct rvu_nix_health_reporters *rvu_nix_health_reporter;
1195ed66306SGeorge Cherian 
1205ed66306SGeorge Cherian 	rvu_nix_health_reporter = container_of(work, struct rvu_nix_health_reporters, err_work);
1215ed66306SGeorge Cherian 	devlink_health_report(rvu_nix_health_reporter->rvu_hw_nix_err_reporter,
1225ed66306SGeorge Cherian 			      "NIX_AF_ERR Error",
1235ed66306SGeorge Cherian 			      rvu_nix_health_reporter->nix_event_ctx);
1245ed66306SGeorge Cherian }
1255ed66306SGeorge Cherian 
rvu_nix_af_rvu_err_handler(int irq,void * rvu_irq)1265ed66306SGeorge Cherian static irqreturn_t rvu_nix_af_rvu_err_handler(int irq, void *rvu_irq)
1275ed66306SGeorge Cherian {
1285ed66306SGeorge Cherian 	struct rvu_nix_event_ctx *nix_event_context;
1295ed66306SGeorge Cherian 	struct rvu_devlink *rvu_dl = rvu_irq;
1305ed66306SGeorge Cherian 	struct rvu *rvu;
1315ed66306SGeorge Cherian 	int blkaddr;
1325ed66306SGeorge Cherian 	u64 intr;
1335ed66306SGeorge Cherian 
1345ed66306SGeorge Cherian 	rvu = rvu_dl->rvu;
1355ed66306SGeorge Cherian 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
1365ed66306SGeorge Cherian 	if (blkaddr < 0)
1375ed66306SGeorge Cherian 		return IRQ_NONE;
1385ed66306SGeorge Cherian 
1395ed66306SGeorge Cherian 	nix_event_context = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
1405ed66306SGeorge Cherian 	intr = rvu_read64(rvu, blkaddr, NIX_AF_ERR_INT);
1415ed66306SGeorge Cherian 	nix_event_context->nix_af_rvu_err = intr;
1425ed66306SGeorge Cherian 
1435ed66306SGeorge Cherian 	/* Clear interrupts */
1445ed66306SGeorge Cherian 	rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT, intr);
1455ed66306SGeorge Cherian 	rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT_ENA_W1C, ~0ULL);
1465ed66306SGeorge Cherian 	queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_nix_health_reporter->err_work);
1475ed66306SGeorge Cherian 
1485ed66306SGeorge Cherian 	return IRQ_HANDLED;
1495ed66306SGeorge Cherian }
1505ed66306SGeorge Cherian 
rvu_nix_ras_work(struct work_struct * work)1515ed66306SGeorge Cherian static void rvu_nix_ras_work(struct work_struct *work)
1525ed66306SGeorge Cherian {
1535ed66306SGeorge Cherian 	struct rvu_nix_health_reporters *rvu_nix_health_reporter;
1545ed66306SGeorge Cherian 
1555ed66306SGeorge Cherian 	rvu_nix_health_reporter = container_of(work, struct rvu_nix_health_reporters, ras_work);
1565ed66306SGeorge Cherian 	devlink_health_report(rvu_nix_health_reporter->rvu_hw_nix_ras_reporter,
1575ed66306SGeorge Cherian 			      "NIX_AF_RAS Error",
1585ed66306SGeorge Cherian 			      rvu_nix_health_reporter->nix_event_ctx);
1595ed66306SGeorge Cherian }
1605ed66306SGeorge Cherian 
rvu_nix_af_rvu_ras_handler(int irq,void * rvu_irq)1615ed66306SGeorge Cherian static irqreturn_t rvu_nix_af_rvu_ras_handler(int irq, void *rvu_irq)
1625ed66306SGeorge Cherian {
1635ed66306SGeorge Cherian 	struct rvu_nix_event_ctx *nix_event_context;
1645ed66306SGeorge Cherian 	struct rvu_devlink *rvu_dl = rvu_irq;
1655ed66306SGeorge Cherian 	struct rvu *rvu;
1665ed66306SGeorge Cherian 	int blkaddr;
1675ed66306SGeorge Cherian 	u64 intr;
1685ed66306SGeorge Cherian 
1695ed66306SGeorge Cherian 	rvu = rvu_dl->rvu;
1705ed66306SGeorge Cherian 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
1715ed66306SGeorge Cherian 	if (blkaddr < 0)
1725ed66306SGeorge Cherian 		return IRQ_NONE;
1735ed66306SGeorge Cherian 
1745ed66306SGeorge Cherian 	nix_event_context = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
1755ed66306SGeorge Cherian 	intr = rvu_read64(rvu, blkaddr, NIX_AF_ERR_INT);
1765ed66306SGeorge Cherian 	nix_event_context->nix_af_rvu_ras = intr;
1775ed66306SGeorge Cherian 
1785ed66306SGeorge Cherian 	/* Clear interrupts */
1795ed66306SGeorge Cherian 	rvu_write64(rvu, blkaddr, NIX_AF_RAS, intr);
1805ed66306SGeorge Cherian 	rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1C, ~0ULL);
1815ed66306SGeorge Cherian 	queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_nix_health_reporter->ras_work);
1825ed66306SGeorge Cherian 
1835ed66306SGeorge Cherian 	return IRQ_HANDLED;
1845ed66306SGeorge Cherian }
1855ed66306SGeorge Cherian 
rvu_nix_unregister_interrupts(struct rvu * rvu)1865ed66306SGeorge Cherian static void rvu_nix_unregister_interrupts(struct rvu *rvu)
1875ed66306SGeorge Cherian {
1885ed66306SGeorge Cherian 	struct rvu_devlink *rvu_dl = rvu->rvu_dl;
1895ed66306SGeorge Cherian 	int offs, i, blkaddr;
1905ed66306SGeorge Cherian 
1915ed66306SGeorge Cherian 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
1925ed66306SGeorge Cherian 	if (blkaddr < 0)
1935ed66306SGeorge Cherian 		return;
1945ed66306SGeorge Cherian 
1955ed66306SGeorge Cherian 	offs = rvu_read64(rvu, blkaddr, NIX_PRIV_AF_INT_CFG) & 0x3ff;
1965ed66306SGeorge Cherian 	if (!offs)
1975ed66306SGeorge Cherian 		return;
1985ed66306SGeorge Cherian 
1995ed66306SGeorge Cherian 	rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT_ENA_W1C, ~0ULL);
2005ed66306SGeorge Cherian 	rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT_ENA_W1C, ~0ULL);
2015ed66306SGeorge Cherian 	rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT_ENA_W1C, ~0ULL);
2025ed66306SGeorge Cherian 	rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1C, ~0ULL);
2035ed66306SGeorge Cherian 
2045ed66306SGeorge Cherian 	if (rvu->irq_allocated[offs + NIX_AF_INT_VEC_RVU]) {
2055ed66306SGeorge Cherian 		free_irq(pci_irq_vector(rvu->pdev, offs + NIX_AF_INT_VEC_RVU),
2065ed66306SGeorge Cherian 			 rvu_dl);
2075ed66306SGeorge Cherian 		rvu->irq_allocated[offs + NIX_AF_INT_VEC_RVU] = false;
2085ed66306SGeorge Cherian 	}
2095ed66306SGeorge Cherian 
210*323d6db6SGeetha sowjanya 	for (i = NIX_AF_INT_VEC_GEN; i < NIX_AF_INT_VEC_CNT; i++)
2115ed66306SGeorge Cherian 		if (rvu->irq_allocated[offs + i]) {
2125ed66306SGeorge Cherian 			free_irq(pci_irq_vector(rvu->pdev, offs + i), rvu_dl);
2135ed66306SGeorge Cherian 			rvu->irq_allocated[offs + i] = false;
2145ed66306SGeorge Cherian 		}
2155ed66306SGeorge Cherian }
2165ed66306SGeorge Cherian 
rvu_nix_register_interrupts(struct rvu * rvu)2175ed66306SGeorge Cherian static int rvu_nix_register_interrupts(struct rvu *rvu)
2185ed66306SGeorge Cherian {
2195ed66306SGeorge Cherian 	int blkaddr, base;
2205ed66306SGeorge Cherian 	bool rc;
2215ed66306SGeorge Cherian 
2225ed66306SGeorge Cherian 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
2235ed66306SGeorge Cherian 	if (blkaddr < 0)
2245ed66306SGeorge Cherian 		return blkaddr;
2255ed66306SGeorge Cherian 
2265ed66306SGeorge Cherian 	/* Get NIX AF MSIX vectors offset. */
2275ed66306SGeorge Cherian 	base = rvu_read64(rvu, blkaddr, NIX_PRIV_AF_INT_CFG) & 0x3ff;
2285ed66306SGeorge Cherian 	if (!base) {
2295ed66306SGeorge Cherian 		dev_warn(rvu->dev,
2305ed66306SGeorge Cherian 			 "Failed to get NIX%d NIX_AF_INT vector offsets\n",
2315ed66306SGeorge Cherian 			 blkaddr - BLKADDR_NIX0);
2325ed66306SGeorge Cherian 		return 0;
2335ed66306SGeorge Cherian 	}
2345ed66306SGeorge Cherian 	/* Register and enable NIX_AF_RVU_INT interrupt */
2355ed66306SGeorge Cherian 	rc = rvu_common_request_irq(rvu, base +  NIX_AF_INT_VEC_RVU,
2365ed66306SGeorge Cherian 				    "NIX_AF_RVU_INT",
2375ed66306SGeorge Cherian 				    rvu_nix_af_rvu_intr_handler);
2385ed66306SGeorge Cherian 	if (!rc)
2395ed66306SGeorge Cherian 		goto err;
2405ed66306SGeorge Cherian 	rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT_ENA_W1S, ~0ULL);
2415ed66306SGeorge Cherian 
2425ed66306SGeorge Cherian 	/* Register and enable NIX_AF_GEN_INT interrupt */
2435ed66306SGeorge Cherian 	rc = rvu_common_request_irq(rvu, base +  NIX_AF_INT_VEC_GEN,
2445ed66306SGeorge Cherian 				    "NIX_AF_GEN_INT",
2455ed66306SGeorge Cherian 				    rvu_nix_af_rvu_gen_handler);
2465ed66306SGeorge Cherian 	if (!rc)
2475ed66306SGeorge Cherian 		goto err;
2485ed66306SGeorge Cherian 	rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT_ENA_W1S, ~0ULL);
2495ed66306SGeorge Cherian 
2505ed66306SGeorge Cherian 	/* Register and enable NIX_AF_ERR_INT interrupt */
2515ed66306SGeorge Cherian 	rc = rvu_common_request_irq(rvu, base + NIX_AF_INT_VEC_AF_ERR,
2525ed66306SGeorge Cherian 				    "NIX_AF_ERR_INT",
2535ed66306SGeorge Cherian 				    rvu_nix_af_rvu_err_handler);
2545ed66306SGeorge Cherian 	if (!rc)
2555ed66306SGeorge Cherian 		goto err;
2565ed66306SGeorge Cherian 	rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT_ENA_W1S, ~0ULL);
2575ed66306SGeorge Cherian 
2585ed66306SGeorge Cherian 	/* Register and enable NIX_AF_RAS interrupt */
2595ed66306SGeorge Cherian 	rc = rvu_common_request_irq(rvu, base + NIX_AF_INT_VEC_POISON,
2605ed66306SGeorge Cherian 				    "NIX_AF_RAS",
2615ed66306SGeorge Cherian 				    rvu_nix_af_rvu_ras_handler);
2625ed66306SGeorge Cherian 	if (!rc)
2635ed66306SGeorge Cherian 		goto err;
2645ed66306SGeorge Cherian 	rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1S, ~0ULL);
2655ed66306SGeorge Cherian 
2665ed66306SGeorge Cherian 	return 0;
2675ed66306SGeorge Cherian err:
2685ed66306SGeorge Cherian 	rvu_nix_unregister_interrupts(rvu);
2695ed66306SGeorge Cherian 	return rc;
2705ed66306SGeorge Cherian }
2715ed66306SGeorge Cherian 
rvu_nix_report_show(struct devlink_fmsg * fmsg,void * ctx,enum nix_af_rvu_health health_reporter)2725ed66306SGeorge Cherian static int rvu_nix_report_show(struct devlink_fmsg *fmsg, void *ctx,
2735ed66306SGeorge Cherian 			       enum nix_af_rvu_health health_reporter)
2745ed66306SGeorge Cherian {
2755ed66306SGeorge Cherian 	struct rvu_nix_event_ctx *nix_event_context;
2765ed66306SGeorge Cherian 	u64 intr_val;
2775ed66306SGeorge Cherian 
2785ed66306SGeorge Cherian 	nix_event_context = ctx;
2795ed66306SGeorge Cherian 	switch (health_reporter) {
2805ed66306SGeorge Cherian 	case NIX_AF_RVU_INTR:
2815ed66306SGeorge Cherian 		intr_val = nix_event_context->nix_af_rvu_int;
282d8cf03fcSPrzemek Kitszel 		rvu_report_pair_start(fmsg, "NIX_AF_RVU");
283d8cf03fcSPrzemek Kitszel 		devlink_fmsg_u64_pair_put(fmsg, "\tNIX RVU Interrupt Reg ",
2845ed66306SGeorge Cherian 					  nix_event_context->nix_af_rvu_int);
285d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(0))
286d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tUnmap Slot Error");
287d8cf03fcSPrzemek Kitszel 		rvu_report_pair_end(fmsg);
2885ed66306SGeorge Cherian 		break;
2895ed66306SGeorge Cherian 	case NIX_AF_RVU_GEN:
2905ed66306SGeorge Cherian 		intr_val = nix_event_context->nix_af_rvu_gen;
291d8cf03fcSPrzemek Kitszel 		rvu_report_pair_start(fmsg, "NIX_AF_GENERAL");
292d8cf03fcSPrzemek Kitszel 		devlink_fmsg_u64_pair_put(fmsg, "\tNIX General Interrupt Reg ",
2935ed66306SGeorge Cherian 					  nix_event_context->nix_af_rvu_gen);
294d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(0))
295d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tRx multicast pkt drop");
296d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(1))
297d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tRx mirror pkt drop");
298d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(4))
299d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tSMQ flush done");
300d8cf03fcSPrzemek Kitszel 		rvu_report_pair_end(fmsg);
3015ed66306SGeorge Cherian 		break;
3025ed66306SGeorge Cherian 	case NIX_AF_RVU_ERR:
3035ed66306SGeorge Cherian 		intr_val = nix_event_context->nix_af_rvu_err;
304d8cf03fcSPrzemek Kitszel 		rvu_report_pair_start(fmsg, "NIX_AF_ERR");
305d8cf03fcSPrzemek Kitszel 		devlink_fmsg_u64_pair_put(fmsg, "\tNIX Error Interrupt Reg ",
3065ed66306SGeorge Cherian 					  nix_event_context->nix_af_rvu_err);
307d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(14))
308d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tFault on NIX_AQ_INST_S read");
309d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(13))
310d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tFault on NIX_AQ_RES_S write");
311d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(12))
312d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tAQ Doorbell Error");
313d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(6))
314d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tRx on unmapped PF_FUNC");
315d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(5))
316d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tRx multicast replication error");
317d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(4))
318d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tFault on NIX_RX_MCE_S read");
319d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(3))
320d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tFault on multicast WQE read");
321d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(2))
322d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tFault on mirror WQE read");
323d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(1))
324d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tFault on mirror pkt write");
325d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(0))
326d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tFault on multicast pkt write");
327d8cf03fcSPrzemek Kitszel 		rvu_report_pair_end(fmsg);
3285ed66306SGeorge Cherian 		break;
3295ed66306SGeorge Cherian 	case NIX_AF_RVU_RAS:
3305ed66306SGeorge Cherian 		intr_val = nix_event_context->nix_af_rvu_err;
331d8cf03fcSPrzemek Kitszel 		rvu_report_pair_start(fmsg, "NIX_AF_RAS");
332d8cf03fcSPrzemek Kitszel 		devlink_fmsg_u64_pair_put(fmsg, "\tNIX RAS Interrupt Reg ",
3335ed66306SGeorge Cherian 					  nix_event_context->nix_af_rvu_err);
334d8cf03fcSPrzemek Kitszel 		devlink_fmsg_string_put(fmsg, "\n\tPoison Data on:");
335d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(34))
336d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tNIX_AQ_INST_S");
337d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(33))
338d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tNIX_AQ_RES_S");
339d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(32))
340d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tHW ctx");
341d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(4))
342d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tPacket from mirror buffer");
343d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(3))
344d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tPacket from multicast buffer");
345d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(2))
346d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tWQE read from mirror buffer");
347d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(1))
348d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tWQE read from multicast buffer");
349d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(0))
350d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tNIX_RX_MCE_S read");
351d8cf03fcSPrzemek Kitszel 		rvu_report_pair_end(fmsg);
3525ed66306SGeorge Cherian 		break;
3535ed66306SGeorge Cherian 	default:
3545ed66306SGeorge Cherian 		return -EINVAL;
3555ed66306SGeorge Cherian 	}
3565ed66306SGeorge Cherian 
3575ed66306SGeorge Cherian 	return 0;
3585ed66306SGeorge Cherian }
3595ed66306SGeorge Cherian 
rvu_hw_nix_intr_dump(struct devlink_health_reporter * reporter,struct devlink_fmsg * fmsg,void * ctx,struct netlink_ext_ack * netlink_extack)3605ed66306SGeorge Cherian static int rvu_hw_nix_intr_dump(struct devlink_health_reporter *reporter,
3615ed66306SGeorge Cherian 				struct devlink_fmsg *fmsg, void *ctx,
3625ed66306SGeorge Cherian 				struct netlink_ext_ack *netlink_extack)
3635ed66306SGeorge Cherian {
3645ed66306SGeorge Cherian 	struct rvu *rvu = devlink_health_reporter_priv(reporter);
3655ed66306SGeorge Cherian 	struct rvu_devlink *rvu_dl = rvu->rvu_dl;
3665ed66306SGeorge Cherian 	struct rvu_nix_event_ctx *nix_ctx;
3675ed66306SGeorge Cherian 
3685ed66306SGeorge Cherian 	nix_ctx = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
3695ed66306SGeorge Cherian 
3705ed66306SGeorge Cherian 	return ctx ? rvu_nix_report_show(fmsg, ctx, NIX_AF_RVU_INTR) :
3715ed66306SGeorge Cherian 		     rvu_nix_report_show(fmsg, nix_ctx, NIX_AF_RVU_INTR);
3725ed66306SGeorge Cherian }
3735ed66306SGeorge Cherian 
rvu_hw_nix_intr_recover(struct devlink_health_reporter * reporter,void * ctx,struct netlink_ext_ack * netlink_extack)3745ed66306SGeorge Cherian static int rvu_hw_nix_intr_recover(struct devlink_health_reporter *reporter,
3755ed66306SGeorge Cherian 				   void *ctx, struct netlink_ext_ack *netlink_extack)
3765ed66306SGeorge Cherian {
3775ed66306SGeorge Cherian 	struct rvu *rvu = devlink_health_reporter_priv(reporter);
3785ed66306SGeorge Cherian 	struct rvu_nix_event_ctx *nix_event_ctx = ctx;
3795ed66306SGeorge Cherian 	int blkaddr;
3805ed66306SGeorge Cherian 
3815ed66306SGeorge Cherian 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
3825ed66306SGeorge Cherian 	if (blkaddr < 0)
3835ed66306SGeorge Cherian 		return blkaddr;
3845ed66306SGeorge Cherian 
3855ed66306SGeorge Cherian 	if (nix_event_ctx->nix_af_rvu_int)
3865ed66306SGeorge Cherian 		rvu_write64(rvu, blkaddr, NIX_AF_RVU_INT_ENA_W1S, ~0ULL);
3875ed66306SGeorge Cherian 
3885ed66306SGeorge Cherian 	return 0;
3895ed66306SGeorge Cherian }
3905ed66306SGeorge Cherian 
rvu_hw_nix_gen_dump(struct devlink_health_reporter * reporter,struct devlink_fmsg * fmsg,void * ctx,struct netlink_ext_ack * netlink_extack)3915ed66306SGeorge Cherian static int rvu_hw_nix_gen_dump(struct devlink_health_reporter *reporter,
3925ed66306SGeorge Cherian 			       struct devlink_fmsg *fmsg, void *ctx,
3935ed66306SGeorge Cherian 			       struct netlink_ext_ack *netlink_extack)
3945ed66306SGeorge Cherian {
3955ed66306SGeorge Cherian 	struct rvu *rvu = devlink_health_reporter_priv(reporter);
3965ed66306SGeorge Cherian 	struct rvu_devlink *rvu_dl = rvu->rvu_dl;
3975ed66306SGeorge Cherian 	struct rvu_nix_event_ctx *nix_ctx;
3985ed66306SGeorge Cherian 
3995ed66306SGeorge Cherian 	nix_ctx = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
4005ed66306SGeorge Cherian 
4015ed66306SGeorge Cherian 	return ctx ? rvu_nix_report_show(fmsg, ctx, NIX_AF_RVU_GEN) :
4025ed66306SGeorge Cherian 		     rvu_nix_report_show(fmsg, nix_ctx, NIX_AF_RVU_GEN);
4035ed66306SGeorge Cherian }
4045ed66306SGeorge Cherian 
rvu_hw_nix_gen_recover(struct devlink_health_reporter * reporter,void * ctx,struct netlink_ext_ack * netlink_extack)4055ed66306SGeorge Cherian static int rvu_hw_nix_gen_recover(struct devlink_health_reporter *reporter,
4065ed66306SGeorge Cherian 				  void *ctx, struct netlink_ext_ack *netlink_extack)
4075ed66306SGeorge Cherian {
4085ed66306SGeorge Cherian 	struct rvu *rvu = devlink_health_reporter_priv(reporter);
4095ed66306SGeorge Cherian 	struct rvu_nix_event_ctx *nix_event_ctx = ctx;
4105ed66306SGeorge Cherian 	int blkaddr;
4115ed66306SGeorge Cherian 
4125ed66306SGeorge Cherian 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
4135ed66306SGeorge Cherian 	if (blkaddr < 0)
4145ed66306SGeorge Cherian 		return blkaddr;
4155ed66306SGeorge Cherian 
4165ed66306SGeorge Cherian 	if (nix_event_ctx->nix_af_rvu_gen)
4175ed66306SGeorge Cherian 		rvu_write64(rvu, blkaddr, NIX_AF_GEN_INT_ENA_W1S, ~0ULL);
4185ed66306SGeorge Cherian 
4195ed66306SGeorge Cherian 	return 0;
4205ed66306SGeorge Cherian }
4215ed66306SGeorge Cherian 
rvu_hw_nix_err_dump(struct devlink_health_reporter * reporter,struct devlink_fmsg * fmsg,void * ctx,struct netlink_ext_ack * netlink_extack)4225ed66306SGeorge Cherian static int rvu_hw_nix_err_dump(struct devlink_health_reporter *reporter,
4235ed66306SGeorge Cherian 			       struct devlink_fmsg *fmsg, void *ctx,
4245ed66306SGeorge Cherian 			       struct netlink_ext_ack *netlink_extack)
4255ed66306SGeorge Cherian {
4265ed66306SGeorge Cherian 	struct rvu *rvu = devlink_health_reporter_priv(reporter);
4275ed66306SGeorge Cherian 	struct rvu_devlink *rvu_dl = rvu->rvu_dl;
4285ed66306SGeorge Cherian 	struct rvu_nix_event_ctx *nix_ctx;
4295ed66306SGeorge Cherian 
4305ed66306SGeorge Cherian 	nix_ctx = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
4315ed66306SGeorge Cherian 
4325ed66306SGeorge Cherian 	return ctx ? rvu_nix_report_show(fmsg, ctx, NIX_AF_RVU_ERR) :
4335ed66306SGeorge Cherian 		     rvu_nix_report_show(fmsg, nix_ctx, NIX_AF_RVU_ERR);
4345ed66306SGeorge Cherian }
4355ed66306SGeorge Cherian 
rvu_hw_nix_err_recover(struct devlink_health_reporter * reporter,void * ctx,struct netlink_ext_ack * netlink_extack)4365ed66306SGeorge Cherian static int rvu_hw_nix_err_recover(struct devlink_health_reporter *reporter,
4375ed66306SGeorge Cherian 				  void *ctx, struct netlink_ext_ack *netlink_extack)
4385ed66306SGeorge Cherian {
4395ed66306SGeorge Cherian 	struct rvu *rvu = devlink_health_reporter_priv(reporter);
4405ed66306SGeorge Cherian 	struct rvu_nix_event_ctx *nix_event_ctx = ctx;
4415ed66306SGeorge Cherian 	int blkaddr;
4425ed66306SGeorge Cherian 
4435ed66306SGeorge Cherian 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
4445ed66306SGeorge Cherian 	if (blkaddr < 0)
4455ed66306SGeorge Cherian 		return blkaddr;
4465ed66306SGeorge Cherian 
4475ed66306SGeorge Cherian 	if (nix_event_ctx->nix_af_rvu_err)
4485ed66306SGeorge Cherian 		rvu_write64(rvu, blkaddr, NIX_AF_ERR_INT_ENA_W1S, ~0ULL);
4495ed66306SGeorge Cherian 
4505ed66306SGeorge Cherian 	return 0;
4515ed66306SGeorge Cherian }
4525ed66306SGeorge Cherian 
rvu_hw_nix_ras_dump(struct devlink_health_reporter * reporter,struct devlink_fmsg * fmsg,void * ctx,struct netlink_ext_ack * netlink_extack)4535ed66306SGeorge Cherian static int rvu_hw_nix_ras_dump(struct devlink_health_reporter *reporter,
4545ed66306SGeorge Cherian 			       struct devlink_fmsg *fmsg, void *ctx,
4555ed66306SGeorge Cherian 			       struct netlink_ext_ack *netlink_extack)
4565ed66306SGeorge Cherian {
4575ed66306SGeorge Cherian 	struct rvu *rvu = devlink_health_reporter_priv(reporter);
4585ed66306SGeorge Cherian 	struct rvu_devlink *rvu_dl = rvu->rvu_dl;
4595ed66306SGeorge Cherian 	struct rvu_nix_event_ctx *nix_ctx;
4605ed66306SGeorge Cherian 
4615ed66306SGeorge Cherian 	nix_ctx = rvu_dl->rvu_nix_health_reporter->nix_event_ctx;
4625ed66306SGeorge Cherian 
4635ed66306SGeorge Cherian 	return ctx ? rvu_nix_report_show(fmsg, ctx, NIX_AF_RVU_RAS) :
4645ed66306SGeorge Cherian 		     rvu_nix_report_show(fmsg, nix_ctx, NIX_AF_RVU_RAS);
4655ed66306SGeorge Cherian }
4665ed66306SGeorge Cherian 
rvu_hw_nix_ras_recover(struct devlink_health_reporter * reporter,void * ctx,struct netlink_ext_ack * netlink_extack)4675ed66306SGeorge Cherian static int rvu_hw_nix_ras_recover(struct devlink_health_reporter *reporter,
4685ed66306SGeorge Cherian 				  void *ctx, struct netlink_ext_ack *netlink_extack)
4695ed66306SGeorge Cherian {
4705ed66306SGeorge Cherian 	struct rvu *rvu = devlink_health_reporter_priv(reporter);
4715ed66306SGeorge Cherian 	struct rvu_nix_event_ctx *nix_event_ctx = ctx;
4725ed66306SGeorge Cherian 	int blkaddr;
4735ed66306SGeorge Cherian 
4745ed66306SGeorge Cherian 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
4755ed66306SGeorge Cherian 	if (blkaddr < 0)
4765ed66306SGeorge Cherian 		return blkaddr;
4775ed66306SGeorge Cherian 
4785ed66306SGeorge Cherian 	if (nix_event_ctx->nix_af_rvu_int)
4795ed66306SGeorge Cherian 		rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1S, ~0ULL);
4805ed66306SGeorge Cherian 
4815ed66306SGeorge Cherian 	return 0;
4825ed66306SGeorge Cherian }
4835ed66306SGeorge Cherian 
4845ed66306SGeorge Cherian RVU_REPORTERS(hw_nix_intr);
4855ed66306SGeorge Cherian RVU_REPORTERS(hw_nix_gen);
4865ed66306SGeorge Cherian RVU_REPORTERS(hw_nix_err);
4875ed66306SGeorge Cherian RVU_REPORTERS(hw_nix_ras);
4885ed66306SGeorge Cherian 
4895ed66306SGeorge Cherian static void rvu_nix_health_reporters_destroy(struct rvu_devlink *rvu_dl);
4905ed66306SGeorge Cherian 
rvu_nix_register_reporters(struct rvu_devlink * rvu_dl)4915ed66306SGeorge Cherian static int rvu_nix_register_reporters(struct rvu_devlink *rvu_dl)
4925ed66306SGeorge Cherian {
4935ed66306SGeorge Cherian 	struct rvu_nix_health_reporters *rvu_reporters;
4945ed66306SGeorge Cherian 	struct rvu_nix_event_ctx *nix_event_context;
4955ed66306SGeorge Cherian 	struct rvu *rvu = rvu_dl->rvu;
4965ed66306SGeorge Cherian 
4975ed66306SGeorge Cherian 	rvu_reporters = kzalloc(sizeof(*rvu_reporters), GFP_KERNEL);
4985ed66306SGeorge Cherian 	if (!rvu_reporters)
4995ed66306SGeorge Cherian 		return -ENOMEM;
5005ed66306SGeorge Cherian 
5015ed66306SGeorge Cherian 	rvu_dl->rvu_nix_health_reporter = rvu_reporters;
5025ed66306SGeorge Cherian 	nix_event_context = kzalloc(sizeof(*nix_event_context), GFP_KERNEL);
5035ed66306SGeorge Cherian 	if (!nix_event_context)
5045ed66306SGeorge Cherian 		return -ENOMEM;
5055ed66306SGeorge Cherian 
5065ed66306SGeorge Cherian 	rvu_reporters->nix_event_ctx = nix_event_context;
5075ed66306SGeorge Cherian 	rvu_reporters->rvu_hw_nix_intr_reporter =
5085ed66306SGeorge Cherian 		devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_nix_intr_reporter_ops, 0, rvu);
5095ed66306SGeorge Cherian 	if (IS_ERR(rvu_reporters->rvu_hw_nix_intr_reporter)) {
5105ed66306SGeorge Cherian 		dev_warn(rvu->dev, "Failed to create hw_nix_intr reporter, err=%ld\n",
5115ed66306SGeorge Cherian 			 PTR_ERR(rvu_reporters->rvu_hw_nix_intr_reporter));
5125ed66306SGeorge Cherian 		return PTR_ERR(rvu_reporters->rvu_hw_nix_intr_reporter);
5135ed66306SGeorge Cherian 	}
5145ed66306SGeorge Cherian 
5155ed66306SGeorge Cherian 	rvu_reporters->rvu_hw_nix_gen_reporter =
5165ed66306SGeorge Cherian 		devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_nix_gen_reporter_ops, 0, rvu);
5175ed66306SGeorge Cherian 	if (IS_ERR(rvu_reporters->rvu_hw_nix_gen_reporter)) {
5185ed66306SGeorge Cherian 		dev_warn(rvu->dev, "Failed to create hw_nix_gen reporter, err=%ld\n",
5195ed66306SGeorge Cherian 			 PTR_ERR(rvu_reporters->rvu_hw_nix_gen_reporter));
5205ed66306SGeorge Cherian 		return PTR_ERR(rvu_reporters->rvu_hw_nix_gen_reporter);
5215ed66306SGeorge Cherian 	}
5225ed66306SGeorge Cherian 
5235ed66306SGeorge Cherian 	rvu_reporters->rvu_hw_nix_err_reporter =
5245ed66306SGeorge Cherian 		devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_nix_err_reporter_ops, 0, rvu);
5255ed66306SGeorge Cherian 	if (IS_ERR(rvu_reporters->rvu_hw_nix_err_reporter)) {
5265ed66306SGeorge Cherian 		dev_warn(rvu->dev, "Failed to create hw_nix_err reporter, err=%ld\n",
5275ed66306SGeorge Cherian 			 PTR_ERR(rvu_reporters->rvu_hw_nix_err_reporter));
5285ed66306SGeorge Cherian 		return PTR_ERR(rvu_reporters->rvu_hw_nix_err_reporter);
5295ed66306SGeorge Cherian 	}
5305ed66306SGeorge Cherian 
5315ed66306SGeorge Cherian 	rvu_reporters->rvu_hw_nix_ras_reporter =
5325ed66306SGeorge Cherian 		devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_nix_ras_reporter_ops, 0, rvu);
5335ed66306SGeorge Cherian 	if (IS_ERR(rvu_reporters->rvu_hw_nix_ras_reporter)) {
5345ed66306SGeorge Cherian 		dev_warn(rvu->dev, "Failed to create hw_nix_ras reporter, err=%ld\n",
5355ed66306SGeorge Cherian 			 PTR_ERR(rvu_reporters->rvu_hw_nix_ras_reporter));
5365ed66306SGeorge Cherian 		return PTR_ERR(rvu_reporters->rvu_hw_nix_ras_reporter);
5375ed66306SGeorge Cherian 	}
5385ed66306SGeorge Cherian 
5395ed66306SGeorge Cherian 	rvu_dl->devlink_wq = create_workqueue("rvu_devlink_wq");
5405ed66306SGeorge Cherian 	if (!rvu_dl->devlink_wq)
54128a7cb04SZhipeng Lu 		return -ENOMEM;
5425ed66306SGeorge Cherian 
5435ed66306SGeorge Cherian 	INIT_WORK(&rvu_reporters->intr_work, rvu_nix_intr_work);
5445ed66306SGeorge Cherian 	INIT_WORK(&rvu_reporters->gen_work, rvu_nix_gen_work);
5455ed66306SGeorge Cherian 	INIT_WORK(&rvu_reporters->err_work, rvu_nix_err_work);
5465ed66306SGeorge Cherian 	INIT_WORK(&rvu_reporters->ras_work, rvu_nix_ras_work);
5475ed66306SGeorge Cherian 
5485ed66306SGeorge Cherian 	return 0;
5495ed66306SGeorge Cherian }
5505ed66306SGeorge Cherian 
rvu_nix_health_reporters_create(struct rvu_devlink * rvu_dl)5515ed66306SGeorge Cherian static int rvu_nix_health_reporters_create(struct rvu_devlink *rvu_dl)
5525ed66306SGeorge Cherian {
5535ed66306SGeorge Cherian 	struct rvu *rvu = rvu_dl->rvu;
5545ed66306SGeorge Cherian 	int err;
5555ed66306SGeorge Cherian 
5565ed66306SGeorge Cherian 	err = rvu_nix_register_reporters(rvu_dl);
5575ed66306SGeorge Cherian 	if (err) {
5585ed66306SGeorge Cherian 		dev_warn(rvu->dev, "Failed to create nix reporter, err =%d\n",
5595ed66306SGeorge Cherian 			 err);
5605ed66306SGeorge Cherian 		return err;
5615ed66306SGeorge Cherian 	}
5625ed66306SGeorge Cherian 	rvu_nix_register_interrupts(rvu);
5635ed66306SGeorge Cherian 
5645ed66306SGeorge Cherian 	return 0;
5655ed66306SGeorge Cherian }
5665ed66306SGeorge Cherian 
rvu_nix_health_reporters_destroy(struct rvu_devlink * rvu_dl)5675ed66306SGeorge Cherian static void rvu_nix_health_reporters_destroy(struct rvu_devlink *rvu_dl)
5685ed66306SGeorge Cherian {
5695ed66306SGeorge Cherian 	struct rvu_nix_health_reporters *nix_reporters;
5705ed66306SGeorge Cherian 	struct rvu *rvu = rvu_dl->rvu;
5715ed66306SGeorge Cherian 
5725ed66306SGeorge Cherian 	nix_reporters = rvu_dl->rvu_nix_health_reporter;
5735ed66306SGeorge Cherian 
5745ed66306SGeorge Cherian 	if (!nix_reporters->rvu_hw_nix_ras_reporter)
5755ed66306SGeorge Cherian 		return;
5765ed66306SGeorge Cherian 	if (!IS_ERR_OR_NULL(nix_reporters->rvu_hw_nix_intr_reporter))
5775ed66306SGeorge Cherian 		devlink_health_reporter_destroy(nix_reporters->rvu_hw_nix_intr_reporter);
5785ed66306SGeorge Cherian 
5795ed66306SGeorge Cherian 	if (!IS_ERR_OR_NULL(nix_reporters->rvu_hw_nix_gen_reporter))
5805ed66306SGeorge Cherian 		devlink_health_reporter_destroy(nix_reporters->rvu_hw_nix_gen_reporter);
5815ed66306SGeorge Cherian 
5825ed66306SGeorge Cherian 	if (!IS_ERR_OR_NULL(nix_reporters->rvu_hw_nix_err_reporter))
5835ed66306SGeorge Cherian 		devlink_health_reporter_destroy(nix_reporters->rvu_hw_nix_err_reporter);
5845ed66306SGeorge Cherian 
5855ed66306SGeorge Cherian 	if (!IS_ERR_OR_NULL(nix_reporters->rvu_hw_nix_ras_reporter))
5865ed66306SGeorge Cherian 		devlink_health_reporter_destroy(nix_reporters->rvu_hw_nix_ras_reporter);
5875ed66306SGeorge Cherian 
5885ed66306SGeorge Cherian 	rvu_nix_unregister_interrupts(rvu);
5895ed66306SGeorge Cherian 	kfree(rvu_dl->rvu_nix_health_reporter->nix_event_ctx);
5905ed66306SGeorge Cherian 	kfree(rvu_dl->rvu_nix_health_reporter);
5915ed66306SGeorge Cherian }
5925ed66306SGeorge Cherian 
rvu_npa_intr_work(struct work_struct * work)593f1168d1eSGeorge Cherian static void rvu_npa_intr_work(struct work_struct *work)
594f1168d1eSGeorge Cherian {
595f1168d1eSGeorge Cherian 	struct rvu_npa_health_reporters *rvu_npa_health_reporter;
596f1168d1eSGeorge Cherian 
597f1168d1eSGeorge Cherian 	rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, intr_work);
598f1168d1eSGeorge Cherian 	devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_intr_reporter,
599f1168d1eSGeorge Cherian 			      "NPA_AF_RVU Error",
600f1168d1eSGeorge Cherian 			      rvu_npa_health_reporter->npa_event_ctx);
601f1168d1eSGeorge Cherian }
602f1168d1eSGeorge Cherian 
rvu_npa_af_rvu_intr_handler(int irq,void * rvu_irq)603f1168d1eSGeorge Cherian static irqreturn_t rvu_npa_af_rvu_intr_handler(int irq, void *rvu_irq)
604f1168d1eSGeorge Cherian {
605f1168d1eSGeorge Cherian 	struct rvu_npa_event_ctx *npa_event_context;
606f1168d1eSGeorge Cherian 	struct rvu_devlink *rvu_dl = rvu_irq;
607f1168d1eSGeorge Cherian 	struct rvu *rvu;
608f1168d1eSGeorge Cherian 	int blkaddr;
609f1168d1eSGeorge Cherian 	u64 intr;
610f1168d1eSGeorge Cherian 
611f1168d1eSGeorge Cherian 	rvu = rvu_dl->rvu;
612f1168d1eSGeorge Cherian 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
613f1168d1eSGeorge Cherian 	if (blkaddr < 0)
614f1168d1eSGeorge Cherian 		return IRQ_NONE;
615f1168d1eSGeorge Cherian 
616f1168d1eSGeorge Cherian 	npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
617f1168d1eSGeorge Cherian 	intr = rvu_read64(rvu, blkaddr, NPA_AF_RVU_INT);
618f1168d1eSGeorge Cherian 	npa_event_context->npa_af_rvu_int = intr;
619f1168d1eSGeorge Cherian 
620f1168d1eSGeorge Cherian 	/* Clear interrupts */
621f1168d1eSGeorge Cherian 	rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT, intr);
622f1168d1eSGeorge Cherian 	rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1C, ~0ULL);
623f1168d1eSGeorge Cherian 	queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->intr_work);
624f1168d1eSGeorge Cherian 
625f1168d1eSGeorge Cherian 	return IRQ_HANDLED;
626f1168d1eSGeorge Cherian }
627f1168d1eSGeorge Cherian 
rvu_npa_gen_work(struct work_struct * work)628f1168d1eSGeorge Cherian static void rvu_npa_gen_work(struct work_struct *work)
629f1168d1eSGeorge Cherian {
630f1168d1eSGeorge Cherian 	struct rvu_npa_health_reporters *rvu_npa_health_reporter;
631f1168d1eSGeorge Cherian 
632f1168d1eSGeorge Cherian 	rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, gen_work);
633f1168d1eSGeorge Cherian 	devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_gen_reporter,
634f1168d1eSGeorge Cherian 			      "NPA_AF_GEN Error",
635f1168d1eSGeorge Cherian 			      rvu_npa_health_reporter->npa_event_ctx);
636f1168d1eSGeorge Cherian }
637f1168d1eSGeorge Cherian 
rvu_npa_af_gen_intr_handler(int irq,void * rvu_irq)638f1168d1eSGeorge Cherian static irqreturn_t rvu_npa_af_gen_intr_handler(int irq, void *rvu_irq)
639f1168d1eSGeorge Cherian {
640f1168d1eSGeorge Cherian 	struct rvu_npa_event_ctx *npa_event_context;
641f1168d1eSGeorge Cherian 	struct rvu_devlink *rvu_dl = rvu_irq;
642f1168d1eSGeorge Cherian 	struct rvu *rvu;
643f1168d1eSGeorge Cherian 	int blkaddr;
644f1168d1eSGeorge Cherian 	u64 intr;
645f1168d1eSGeorge Cherian 
646f1168d1eSGeorge Cherian 	rvu = rvu_dl->rvu;
647f1168d1eSGeorge Cherian 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
648f1168d1eSGeorge Cherian 	if (blkaddr < 0)
649f1168d1eSGeorge Cherian 		return IRQ_NONE;
650f1168d1eSGeorge Cherian 
651f1168d1eSGeorge Cherian 	npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
652f1168d1eSGeorge Cherian 	intr = rvu_read64(rvu, blkaddr, NPA_AF_GEN_INT);
653f1168d1eSGeorge Cherian 	npa_event_context->npa_af_rvu_gen = intr;
654f1168d1eSGeorge Cherian 
655f1168d1eSGeorge Cherian 	/* Clear interrupts */
656f1168d1eSGeorge Cherian 	rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT, intr);
657f1168d1eSGeorge Cherian 	rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1C, ~0ULL);
658f1168d1eSGeorge Cherian 	queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->gen_work);
659f1168d1eSGeorge Cherian 
660f1168d1eSGeorge Cherian 	return IRQ_HANDLED;
661f1168d1eSGeorge Cherian }
662f1168d1eSGeorge Cherian 
rvu_npa_err_work(struct work_struct * work)663f1168d1eSGeorge Cherian static void rvu_npa_err_work(struct work_struct *work)
664f1168d1eSGeorge Cherian {
665f1168d1eSGeorge Cherian 	struct rvu_npa_health_reporters *rvu_npa_health_reporter;
666f1168d1eSGeorge Cherian 
667f1168d1eSGeorge Cherian 	rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, err_work);
668f1168d1eSGeorge Cherian 	devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_err_reporter,
669f1168d1eSGeorge Cherian 			      "NPA_AF_ERR Error",
670f1168d1eSGeorge Cherian 			      rvu_npa_health_reporter->npa_event_ctx);
671f1168d1eSGeorge Cherian }
672f1168d1eSGeorge Cherian 
rvu_npa_af_err_intr_handler(int irq,void * rvu_irq)673f1168d1eSGeorge Cherian static irqreturn_t rvu_npa_af_err_intr_handler(int irq, void *rvu_irq)
674f1168d1eSGeorge Cherian {
675f1168d1eSGeorge Cherian 	struct rvu_npa_event_ctx *npa_event_context;
676f1168d1eSGeorge Cherian 	struct rvu_devlink *rvu_dl = rvu_irq;
677f1168d1eSGeorge Cherian 	struct rvu *rvu;
678f1168d1eSGeorge Cherian 	int blkaddr;
679f1168d1eSGeorge Cherian 	u64 intr;
680f1168d1eSGeorge Cherian 
681f1168d1eSGeorge Cherian 	rvu = rvu_dl->rvu;
682f1168d1eSGeorge Cherian 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
683f1168d1eSGeorge Cherian 	if (blkaddr < 0)
684f1168d1eSGeorge Cherian 		return IRQ_NONE;
685f1168d1eSGeorge Cherian 	npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
686f1168d1eSGeorge Cherian 	intr = rvu_read64(rvu, blkaddr, NPA_AF_ERR_INT);
687f1168d1eSGeorge Cherian 	npa_event_context->npa_af_rvu_err = intr;
688f1168d1eSGeorge Cherian 
689f1168d1eSGeorge Cherian 	/* Clear interrupts */
690f1168d1eSGeorge Cherian 	rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT, intr);
691f1168d1eSGeorge Cherian 	rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1C, ~0ULL);
692f1168d1eSGeorge Cherian 	queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->err_work);
693f1168d1eSGeorge Cherian 
694f1168d1eSGeorge Cherian 	return IRQ_HANDLED;
695f1168d1eSGeorge Cherian }
696f1168d1eSGeorge Cherian 
rvu_npa_ras_work(struct work_struct * work)697f1168d1eSGeorge Cherian static void rvu_npa_ras_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, ras_work);
702f1168d1eSGeorge Cherian 	devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_ras_reporter,
703f1168d1eSGeorge Cherian 			      "HW NPA_AF_RAS Error reported",
704f1168d1eSGeorge Cherian 			      rvu_npa_health_reporter->npa_event_ctx);
705f1168d1eSGeorge Cherian }
706f1168d1eSGeorge Cherian 
rvu_npa_af_ras_intr_handler(int irq,void * rvu_irq)707f1168d1eSGeorge Cherian static irqreturn_t rvu_npa_af_ras_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_RAS);
722f1168d1eSGeorge Cherian 	npa_event_context->npa_af_rvu_ras = intr;
723f1168d1eSGeorge Cherian 
724f1168d1eSGeorge Cherian 	/* Clear interrupts */
725f1168d1eSGeorge Cherian 	rvu_write64(rvu, blkaddr, NPA_AF_RAS, intr);
726f1168d1eSGeorge Cherian 	rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1C, ~0ULL);
727f1168d1eSGeorge Cherian 	queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->ras_work);
728f1168d1eSGeorge Cherian 
729f1168d1eSGeorge Cherian 	return IRQ_HANDLED;
730f1168d1eSGeorge Cherian }
731f1168d1eSGeorge Cherian 
rvu_npa_unregister_interrupts(struct rvu * rvu)732f1168d1eSGeorge Cherian static void rvu_npa_unregister_interrupts(struct rvu *rvu)
733f1168d1eSGeorge Cherian {
734f1168d1eSGeorge Cherian 	struct rvu_devlink *rvu_dl = rvu->rvu_dl;
735f1168d1eSGeorge Cherian 	int i, offs, blkaddr;
736f1168d1eSGeorge Cherian 	u64 reg;
737f1168d1eSGeorge Cherian 
738f1168d1eSGeorge Cherian 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
739f1168d1eSGeorge Cherian 	if (blkaddr < 0)
740f1168d1eSGeorge Cherian 		return;
741f1168d1eSGeorge Cherian 
742f1168d1eSGeorge Cherian 	reg = rvu_read64(rvu, blkaddr, NPA_PRIV_AF_INT_CFG);
743f1168d1eSGeorge Cherian 	offs = reg & 0x3FF;
744f1168d1eSGeorge Cherian 
745f1168d1eSGeorge Cherian 	rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1C, ~0ULL);
746f1168d1eSGeorge Cherian 	rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1C, ~0ULL);
747f1168d1eSGeorge Cherian 	rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1C, ~0ULL);
748f1168d1eSGeorge Cherian 	rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1C, ~0ULL);
749f1168d1eSGeorge Cherian 
750f1168d1eSGeorge Cherian 	for (i = 0; i < NPA_AF_INT_VEC_CNT; i++)
751f1168d1eSGeorge Cherian 		if (rvu->irq_allocated[offs + i]) {
752f1168d1eSGeorge Cherian 			free_irq(pci_irq_vector(rvu->pdev, offs + i), rvu_dl);
753f1168d1eSGeorge Cherian 			rvu->irq_allocated[offs + i] = false;
754f1168d1eSGeorge Cherian 		}
755f1168d1eSGeorge Cherian }
756f1168d1eSGeorge Cherian 
rvu_npa_register_interrupts(struct rvu * rvu)757f1168d1eSGeorge Cherian static int rvu_npa_register_interrupts(struct rvu *rvu)
758f1168d1eSGeorge Cherian {
759f1168d1eSGeorge Cherian 	int blkaddr, base;
760f1168d1eSGeorge Cherian 	bool rc;
761f1168d1eSGeorge Cherian 
762f1168d1eSGeorge Cherian 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
763f1168d1eSGeorge Cherian 	if (blkaddr < 0)
764f1168d1eSGeorge Cherian 		return blkaddr;
765f1168d1eSGeorge Cherian 
766f1168d1eSGeorge Cherian 	/* Get NPA AF MSIX vectors offset. */
767f1168d1eSGeorge Cherian 	base = rvu_read64(rvu, blkaddr, NPA_PRIV_AF_INT_CFG) & 0x3ff;
768f1168d1eSGeorge Cherian 	if (!base) {
769f1168d1eSGeorge Cherian 		dev_warn(rvu->dev,
770f1168d1eSGeorge Cherian 			 "Failed to get NPA_AF_INT vector offsets\n");
771f1168d1eSGeorge Cherian 		return 0;
772f1168d1eSGeorge Cherian 	}
773f1168d1eSGeorge Cherian 
774f1168d1eSGeorge Cherian 	/* Register and enable NPA_AF_RVU_INT interrupt */
775f1168d1eSGeorge Cherian 	rc = rvu_common_request_irq(rvu, base +  NPA_AF_INT_VEC_RVU,
776f1168d1eSGeorge Cherian 				    "NPA_AF_RVU_INT",
777f1168d1eSGeorge Cherian 				    rvu_npa_af_rvu_intr_handler);
778f1168d1eSGeorge Cherian 	if (!rc)
779f1168d1eSGeorge Cherian 		goto err;
780f1168d1eSGeorge Cherian 	rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1S, ~0ULL);
781f1168d1eSGeorge Cherian 
782f1168d1eSGeorge Cherian 	/* Register and enable NPA_AF_GEN_INT interrupt */
783f1168d1eSGeorge Cherian 	rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_GEN,
784f1168d1eSGeorge Cherian 				    "NPA_AF_RVU_GEN",
785f1168d1eSGeorge Cherian 				    rvu_npa_af_gen_intr_handler);
786f1168d1eSGeorge Cherian 	if (!rc)
787f1168d1eSGeorge Cherian 		goto err;
788f1168d1eSGeorge Cherian 	rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1S, ~0ULL);
789f1168d1eSGeorge Cherian 
790f1168d1eSGeorge Cherian 	/* Register and enable NPA_AF_ERR_INT interrupt */
791f1168d1eSGeorge Cherian 	rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_AF_ERR,
792f1168d1eSGeorge Cherian 				    "NPA_AF_ERR_INT",
793f1168d1eSGeorge Cherian 				    rvu_npa_af_err_intr_handler);
794f1168d1eSGeorge Cherian 	if (!rc)
795f1168d1eSGeorge Cherian 		goto err;
796f1168d1eSGeorge Cherian 	rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1S, ~0ULL);
797f1168d1eSGeorge Cherian 
798f1168d1eSGeorge Cherian 	/* Register and enable NPA_AF_RAS interrupt */
799f1168d1eSGeorge Cherian 	rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_POISON,
800f1168d1eSGeorge Cherian 				    "NPA_AF_RAS",
801f1168d1eSGeorge Cherian 				    rvu_npa_af_ras_intr_handler);
802f1168d1eSGeorge Cherian 	if (!rc)
803f1168d1eSGeorge Cherian 		goto err;
804f1168d1eSGeorge Cherian 	rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1S, ~0ULL);
805f1168d1eSGeorge Cherian 
806f1168d1eSGeorge Cherian 	return 0;
807f1168d1eSGeorge Cherian err:
808f1168d1eSGeorge Cherian 	rvu_npa_unregister_interrupts(rvu);
809f1168d1eSGeorge Cherian 	return rc;
810f1168d1eSGeorge Cherian }
811f1168d1eSGeorge Cherian 
rvu_npa_report_show(struct devlink_fmsg * fmsg,void * ctx,enum npa_af_rvu_health health_reporter)812f1168d1eSGeorge Cherian static int rvu_npa_report_show(struct devlink_fmsg *fmsg, void *ctx,
813f1168d1eSGeorge Cherian 			       enum npa_af_rvu_health health_reporter)
814f1168d1eSGeorge Cherian {
815f1168d1eSGeorge Cherian 	struct rvu_npa_event_ctx *npa_event_context;
816d8a4ea35SColin Ian King 	unsigned int alloc_dis, free_dis;
817d8a4ea35SColin Ian King 	u64 intr_val;
818f1168d1eSGeorge Cherian 
819f1168d1eSGeorge Cherian 	npa_event_context = ctx;
820f1168d1eSGeorge Cherian 	switch (health_reporter) {
821f1168d1eSGeorge Cherian 	case NPA_AF_RVU_GEN:
822f1168d1eSGeorge Cherian 		intr_val = npa_event_context->npa_af_rvu_gen;
823d8cf03fcSPrzemek Kitszel 		rvu_report_pair_start(fmsg, "NPA_AF_GENERAL");
824d8cf03fcSPrzemek Kitszel 		devlink_fmsg_u64_pair_put(fmsg, "\tNPA General Interrupt Reg ",
825f1168d1eSGeorge Cherian 					  npa_event_context->npa_af_rvu_gen);
826d8cf03fcSPrzemek Kitszel 		if (intr_val & BIT_ULL(32))
827d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tUnmap PF Error");
828f1168d1eSGeorge Cherian 
829f1168d1eSGeorge Cherian 		free_dis = FIELD_GET(GENMASK(15, 0), intr_val);
830d8cf03fcSPrzemek Kitszel 		if (free_dis & BIT(NPA_INPQ_NIX0_RX))
831d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tNIX0: free disabled RX");
832d8cf03fcSPrzemek Kitszel 		if (free_dis & BIT(NPA_INPQ_NIX0_TX))
833d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tNIX0:free disabled TX");
834d8cf03fcSPrzemek Kitszel 		if (free_dis & BIT(NPA_INPQ_NIX1_RX))
835d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tNIX1: free disabled RX");
836d8cf03fcSPrzemek Kitszel 		if (free_dis & BIT(NPA_INPQ_NIX1_TX))
837d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tNIX1:free disabled TX");
838d8cf03fcSPrzemek Kitszel 		if (free_dis & BIT(NPA_INPQ_SSO))
839d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for SSO");
840d8cf03fcSPrzemek Kitszel 		if (free_dis & BIT(NPA_INPQ_TIM))
841d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for TIM");
842d8cf03fcSPrzemek Kitszel 		if (free_dis & BIT(NPA_INPQ_DPI))
843d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for DPI");
844d8cf03fcSPrzemek Kitszel 		if (free_dis & BIT(NPA_INPQ_AURA_OP))
845d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for AURA");
846f1168d1eSGeorge Cherian 
847f1168d1eSGeorge Cherian 		alloc_dis = FIELD_GET(GENMASK(31, 16), intr_val);
848d8cf03fcSPrzemek Kitszel 		if (alloc_dis & BIT(NPA_INPQ_NIX0_RX))
849d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tNIX0: alloc disabled RX");
850d8cf03fcSPrzemek Kitszel 		if (alloc_dis & BIT(NPA_INPQ_NIX0_TX))
851d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tNIX0:alloc disabled TX");
852d8cf03fcSPrzemek Kitszel 		if (alloc_dis & BIT(NPA_INPQ_NIX1_RX))
853d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tNIX1: alloc disabled RX");
854d8cf03fcSPrzemek Kitszel 		if (alloc_dis & BIT(NPA_INPQ_NIX1_TX))
855d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tNIX1:alloc disabled TX");
856d8cf03fcSPrzemek Kitszel 		if (alloc_dis & BIT(NPA_INPQ_SSO))
857d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for SSO");
858d8cf03fcSPrzemek Kitszel 		if (alloc_dis & BIT(NPA_INPQ_TIM))
859d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for TIM");
860d8cf03fcSPrzemek Kitszel 		if (alloc_dis & BIT(NPA_INPQ_DPI))
861d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for DPI");
862d8cf03fcSPrzemek Kitszel 		if (alloc_dis & BIT(NPA_INPQ_AURA_OP))
863d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for AURA");
864d8cf03fcSPrzemek Kitszel 
865d8cf03fcSPrzemek Kitszel 		rvu_report_pair_end(fmsg);
866f1168d1eSGeorge Cherian 		break;
867f1168d1eSGeorge Cherian 	case NPA_AF_RVU_ERR:
868d8cf03fcSPrzemek Kitszel 		rvu_report_pair_start(fmsg, "NPA_AF_ERR");
869d8cf03fcSPrzemek Kitszel 		devlink_fmsg_u64_pair_put(fmsg, "\tNPA Error Interrupt Reg ",
870f1168d1eSGeorge Cherian 					  npa_event_context->npa_af_rvu_err);
871d8cf03fcSPrzemek Kitszel 		if (npa_event_context->npa_af_rvu_err & BIT_ULL(14))
872d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tFault on NPA_AQ_INST_S read");
873d8cf03fcSPrzemek Kitszel 		if (npa_event_context->npa_af_rvu_err & BIT_ULL(13))
874d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tFault on NPA_AQ_RES_S write");
875d8cf03fcSPrzemek Kitszel 		if (npa_event_context->npa_af_rvu_err & BIT_ULL(12))
876d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tAQ Doorbell Error");
877d8cf03fcSPrzemek Kitszel 		rvu_report_pair_end(fmsg);
878f1168d1eSGeorge Cherian 		break;
879f1168d1eSGeorge Cherian 	case NPA_AF_RVU_RAS:
880d8cf03fcSPrzemek Kitszel 		rvu_report_pair_start(fmsg, "NPA_AF_RVU_RAS");
881d8cf03fcSPrzemek Kitszel 		devlink_fmsg_u64_pair_put(fmsg, "\tNPA RAS Interrupt Reg ",
882f1168d1eSGeorge Cherian 					  npa_event_context->npa_af_rvu_ras);
883d8cf03fcSPrzemek Kitszel 		if (npa_event_context->npa_af_rvu_ras & BIT_ULL(34))
884d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tPoison data on NPA_AQ_INST_S");
885d8cf03fcSPrzemek Kitszel 		if (npa_event_context->npa_af_rvu_ras & BIT_ULL(33))
886d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tPoison data on NPA_AQ_RES_S");
887d8cf03fcSPrzemek Kitszel 		if (npa_event_context->npa_af_rvu_ras & BIT_ULL(32))
888d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tPoison data on HW context");
889d8cf03fcSPrzemek Kitszel 		rvu_report_pair_end(fmsg);
890f1168d1eSGeorge Cherian 		break;
891f1168d1eSGeorge Cherian 	case NPA_AF_RVU_INTR:
892d8cf03fcSPrzemek Kitszel 		rvu_report_pair_start(fmsg, "NPA_AF_RVU");
893d8cf03fcSPrzemek Kitszel 		devlink_fmsg_u64_pair_put(fmsg, "\tNPA RVU Interrupt Reg ",
894f1168d1eSGeorge Cherian 					  npa_event_context->npa_af_rvu_int);
895d8cf03fcSPrzemek Kitszel 		if (npa_event_context->npa_af_rvu_int & BIT_ULL(0))
896d8cf03fcSPrzemek Kitszel 			devlink_fmsg_string_put(fmsg, "\n\tUnmap Slot Error");
897d8cf03fcSPrzemek Kitszel 		rvu_report_pair_end(fmsg);
898d8cf03fcSPrzemek Kitszel 		break;
899f1168d1eSGeorge Cherian 	default:
900f1168d1eSGeorge Cherian 		return -EINVAL;
901f1168d1eSGeorge Cherian 	}
902f1168d1eSGeorge Cherian 
903f1168d1eSGeorge Cherian 	return 0;
904f1168d1eSGeorge Cherian }
905f1168d1eSGeorge Cherian 
rvu_hw_npa_intr_dump(struct devlink_health_reporter * reporter,struct devlink_fmsg * fmsg,void * ctx,struct netlink_ext_ack * netlink_extack)906f1168d1eSGeorge Cherian static int rvu_hw_npa_intr_dump(struct devlink_health_reporter *reporter,
907f1168d1eSGeorge Cherian 				struct devlink_fmsg *fmsg, void *ctx,
908f1168d1eSGeorge Cherian 				struct netlink_ext_ack *netlink_extack)
909f1168d1eSGeorge Cherian {
910f1168d1eSGeorge Cherian 	struct rvu *rvu = devlink_health_reporter_priv(reporter);
911f1168d1eSGeorge Cherian 	struct rvu_devlink *rvu_dl = rvu->rvu_dl;
912f1168d1eSGeorge Cherian 	struct rvu_npa_event_ctx *npa_ctx;
913f1168d1eSGeorge Cherian 
914f1168d1eSGeorge Cherian 	npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
915f1168d1eSGeorge Cherian 
916f1168d1eSGeorge Cherian 	return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_INTR) :
917f1168d1eSGeorge Cherian 		     rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_INTR);
918f1168d1eSGeorge Cherian }
919f1168d1eSGeorge Cherian 
rvu_hw_npa_intr_recover(struct devlink_health_reporter * reporter,void * ctx,struct netlink_ext_ack * netlink_extack)920f1168d1eSGeorge Cherian static int rvu_hw_npa_intr_recover(struct devlink_health_reporter *reporter,
921f1168d1eSGeorge Cherian 				   void *ctx, struct netlink_ext_ack *netlink_extack)
922f1168d1eSGeorge Cherian {
923f1168d1eSGeorge Cherian 	struct rvu *rvu = devlink_health_reporter_priv(reporter);
924f1168d1eSGeorge Cherian 	struct rvu_npa_event_ctx *npa_event_ctx = ctx;
925f1168d1eSGeorge Cherian 	int blkaddr;
926f1168d1eSGeorge Cherian 
927f1168d1eSGeorge Cherian 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
928f1168d1eSGeorge Cherian 	if (blkaddr < 0)
929f1168d1eSGeorge Cherian 		return blkaddr;
930f1168d1eSGeorge Cherian 
931f1168d1eSGeorge Cherian 	if (npa_event_ctx->npa_af_rvu_int)
932f1168d1eSGeorge Cherian 		rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1S, ~0ULL);
933f1168d1eSGeorge Cherian 
934f1168d1eSGeorge Cherian 	return 0;
935f1168d1eSGeorge Cherian }
936f1168d1eSGeorge Cherian 
rvu_hw_npa_gen_dump(struct devlink_health_reporter * reporter,struct devlink_fmsg * fmsg,void * ctx,struct netlink_ext_ack * netlink_extack)937f1168d1eSGeorge Cherian static int rvu_hw_npa_gen_dump(struct devlink_health_reporter *reporter,
938f1168d1eSGeorge Cherian 			       struct devlink_fmsg *fmsg, void *ctx,
939f1168d1eSGeorge Cherian 			       struct netlink_ext_ack *netlink_extack)
940f1168d1eSGeorge Cherian {
941f1168d1eSGeorge Cherian 	struct rvu *rvu = devlink_health_reporter_priv(reporter);
942f1168d1eSGeorge Cherian 	struct rvu_devlink *rvu_dl = rvu->rvu_dl;
943f1168d1eSGeorge Cherian 	struct rvu_npa_event_ctx *npa_ctx;
944f1168d1eSGeorge Cherian 
945f1168d1eSGeorge Cherian 	npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
946f1168d1eSGeorge Cherian 
947f1168d1eSGeorge Cherian 	return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_GEN) :
948f1168d1eSGeorge Cherian 		     rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_GEN);
949f1168d1eSGeorge Cherian }
950f1168d1eSGeorge Cherian 
rvu_hw_npa_gen_recover(struct devlink_health_reporter * reporter,void * ctx,struct netlink_ext_ack * netlink_extack)951f1168d1eSGeorge Cherian static int rvu_hw_npa_gen_recover(struct devlink_health_reporter *reporter,
952f1168d1eSGeorge Cherian 				  void *ctx, struct netlink_ext_ack *netlink_extack)
953f1168d1eSGeorge Cherian {
954f1168d1eSGeorge Cherian 	struct rvu *rvu = devlink_health_reporter_priv(reporter);
955f1168d1eSGeorge Cherian 	struct rvu_npa_event_ctx *npa_event_ctx = ctx;
956f1168d1eSGeorge Cherian 	int blkaddr;
957f1168d1eSGeorge Cherian 
958f1168d1eSGeorge Cherian 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
959f1168d1eSGeorge Cherian 	if (blkaddr < 0)
960f1168d1eSGeorge Cherian 		return blkaddr;
961f1168d1eSGeorge Cherian 
962f1168d1eSGeorge Cherian 	if (npa_event_ctx->npa_af_rvu_gen)
963f1168d1eSGeorge Cherian 		rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1S, ~0ULL);
964f1168d1eSGeorge Cherian 
965f1168d1eSGeorge Cherian 	return 0;
966f1168d1eSGeorge Cherian }
967f1168d1eSGeorge Cherian 
rvu_hw_npa_err_dump(struct devlink_health_reporter * reporter,struct devlink_fmsg * fmsg,void * ctx,struct netlink_ext_ack * netlink_extack)968f1168d1eSGeorge Cherian static int rvu_hw_npa_err_dump(struct devlink_health_reporter *reporter,
969f1168d1eSGeorge Cherian 			       struct devlink_fmsg *fmsg, void *ctx,
970f1168d1eSGeorge Cherian 			       struct netlink_ext_ack *netlink_extack)
971f1168d1eSGeorge Cherian {
972f1168d1eSGeorge Cherian 	struct rvu *rvu = devlink_health_reporter_priv(reporter);
973f1168d1eSGeorge Cherian 	struct rvu_devlink *rvu_dl = rvu->rvu_dl;
974f1168d1eSGeorge Cherian 	struct rvu_npa_event_ctx *npa_ctx;
975f1168d1eSGeorge Cherian 
976f1168d1eSGeorge Cherian 	npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
977f1168d1eSGeorge Cherian 
978f1168d1eSGeorge Cherian 	return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_ERR) :
979f1168d1eSGeorge Cherian 		     rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_ERR);
980f1168d1eSGeorge Cherian }
981f1168d1eSGeorge Cherian 
rvu_hw_npa_err_recover(struct devlink_health_reporter * reporter,void * ctx,struct netlink_ext_ack * netlink_extack)982f1168d1eSGeorge Cherian static int rvu_hw_npa_err_recover(struct devlink_health_reporter *reporter,
983f1168d1eSGeorge Cherian 				  void *ctx, struct netlink_ext_ack *netlink_extack)
984f1168d1eSGeorge Cherian {
985f1168d1eSGeorge Cherian 	struct rvu *rvu = devlink_health_reporter_priv(reporter);
986f1168d1eSGeorge Cherian 	struct rvu_npa_event_ctx *npa_event_ctx = ctx;
987f1168d1eSGeorge Cherian 	int blkaddr;
988f1168d1eSGeorge Cherian 
989f1168d1eSGeorge Cherian 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
990f1168d1eSGeorge Cherian 	if (blkaddr < 0)
991f1168d1eSGeorge Cherian 		return blkaddr;
992f1168d1eSGeorge Cherian 
993f1168d1eSGeorge Cherian 	if (npa_event_ctx->npa_af_rvu_err)
994f1168d1eSGeorge Cherian 		rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1S, ~0ULL);
995f1168d1eSGeorge Cherian 
996f1168d1eSGeorge Cherian 	return 0;
997f1168d1eSGeorge Cherian }
998f1168d1eSGeorge Cherian 
rvu_hw_npa_ras_dump(struct devlink_health_reporter * reporter,struct devlink_fmsg * fmsg,void * ctx,struct netlink_ext_ack * netlink_extack)999f1168d1eSGeorge Cherian static int rvu_hw_npa_ras_dump(struct devlink_health_reporter *reporter,
1000f1168d1eSGeorge Cherian 			       struct devlink_fmsg *fmsg, void *ctx,
1001f1168d1eSGeorge Cherian 			       struct netlink_ext_ack *netlink_extack)
1002f1168d1eSGeorge Cherian {
1003f1168d1eSGeorge Cherian 	struct rvu *rvu = devlink_health_reporter_priv(reporter);
1004f1168d1eSGeorge Cherian 	struct rvu_devlink *rvu_dl = rvu->rvu_dl;
1005f1168d1eSGeorge Cherian 	struct rvu_npa_event_ctx *npa_ctx;
1006f1168d1eSGeorge Cherian 
1007f1168d1eSGeorge Cherian 	npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx;
1008f1168d1eSGeorge Cherian 
1009f1168d1eSGeorge Cherian 	return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_RAS) :
1010f1168d1eSGeorge Cherian 		     rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_RAS);
1011f1168d1eSGeorge Cherian }
1012f1168d1eSGeorge Cherian 
rvu_hw_npa_ras_recover(struct devlink_health_reporter * reporter,void * ctx,struct netlink_ext_ack * netlink_extack)1013f1168d1eSGeorge Cherian static int rvu_hw_npa_ras_recover(struct devlink_health_reporter *reporter,
1014f1168d1eSGeorge Cherian 				  void *ctx, struct netlink_ext_ack *netlink_extack)
1015f1168d1eSGeorge Cherian {
1016f1168d1eSGeorge Cherian 	struct rvu *rvu = devlink_health_reporter_priv(reporter);
1017f1168d1eSGeorge Cherian 	struct rvu_npa_event_ctx *npa_event_ctx = ctx;
1018f1168d1eSGeorge Cherian 	int blkaddr;
1019f1168d1eSGeorge Cherian 
1020f1168d1eSGeorge Cherian 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0);
1021f1168d1eSGeorge Cherian 	if (blkaddr < 0)
1022f1168d1eSGeorge Cherian 		return blkaddr;
1023f1168d1eSGeorge Cherian 
1024f1168d1eSGeorge Cherian 	if (npa_event_ctx->npa_af_rvu_ras)
1025f1168d1eSGeorge Cherian 		rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1S, ~0ULL);
1026f1168d1eSGeorge Cherian 
1027f1168d1eSGeorge Cherian 	return 0;
1028f1168d1eSGeorge Cherian }
1029f1168d1eSGeorge Cherian 
1030f1168d1eSGeorge Cherian RVU_REPORTERS(hw_npa_intr);
1031f1168d1eSGeorge Cherian RVU_REPORTERS(hw_npa_gen);
1032f1168d1eSGeorge Cherian RVU_REPORTERS(hw_npa_err);
1033f1168d1eSGeorge Cherian RVU_REPORTERS(hw_npa_ras);
1034f1168d1eSGeorge Cherian 
1035f1168d1eSGeorge Cherian static void rvu_npa_health_reporters_destroy(struct rvu_devlink *rvu_dl);
1036f1168d1eSGeorge Cherian 
rvu_npa_register_reporters(struct rvu_devlink * rvu_dl)1037f1168d1eSGeorge Cherian static int rvu_npa_register_reporters(struct rvu_devlink *rvu_dl)
1038f1168d1eSGeorge Cherian {
1039f1168d1eSGeorge Cherian 	struct rvu_npa_health_reporters *rvu_reporters;
1040f1168d1eSGeorge Cherian 	struct rvu_npa_event_ctx *npa_event_context;
1041f1168d1eSGeorge Cherian 	struct rvu *rvu = rvu_dl->rvu;
1042f1168d1eSGeorge Cherian 
1043f1168d1eSGeorge Cherian 	rvu_reporters = kzalloc(sizeof(*rvu_reporters), GFP_KERNEL);
1044f1168d1eSGeorge Cherian 	if (!rvu_reporters)
1045f1168d1eSGeorge Cherian 		return -ENOMEM;
1046f1168d1eSGeorge Cherian 
1047f1168d1eSGeorge Cherian 	rvu_dl->rvu_npa_health_reporter = rvu_reporters;
1048f1168d1eSGeorge Cherian 	npa_event_context = kzalloc(sizeof(*npa_event_context), GFP_KERNEL);
1049f1168d1eSGeorge Cherian 	if (!npa_event_context)
1050f1168d1eSGeorge Cherian 		return -ENOMEM;
1051f1168d1eSGeorge Cherian 
1052f1168d1eSGeorge Cherian 	rvu_reporters->npa_event_ctx = npa_event_context;
1053f1168d1eSGeorge Cherian 	rvu_reporters->rvu_hw_npa_intr_reporter =
1054f1168d1eSGeorge Cherian 		devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_intr_reporter_ops, 0, rvu);
1055f1168d1eSGeorge Cherian 	if (IS_ERR(rvu_reporters->rvu_hw_npa_intr_reporter)) {
1056f1168d1eSGeorge Cherian 		dev_warn(rvu->dev, "Failed to create hw_npa_intr reporter, err=%ld\n",
1057f1168d1eSGeorge Cherian 			 PTR_ERR(rvu_reporters->rvu_hw_npa_intr_reporter));
1058f1168d1eSGeorge Cherian 		return PTR_ERR(rvu_reporters->rvu_hw_npa_intr_reporter);
1059f1168d1eSGeorge Cherian 	}
1060f1168d1eSGeorge Cherian 
1061f1168d1eSGeorge Cherian 	rvu_reporters->rvu_hw_npa_gen_reporter =
1062f1168d1eSGeorge Cherian 		devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_gen_reporter_ops, 0, rvu);
1063f1168d1eSGeorge Cherian 	if (IS_ERR(rvu_reporters->rvu_hw_npa_gen_reporter)) {
1064f1168d1eSGeorge Cherian 		dev_warn(rvu->dev, "Failed to create hw_npa_gen reporter, err=%ld\n",
1065f1168d1eSGeorge Cherian 			 PTR_ERR(rvu_reporters->rvu_hw_npa_gen_reporter));
1066f1168d1eSGeorge Cherian 		return PTR_ERR(rvu_reporters->rvu_hw_npa_gen_reporter);
1067f1168d1eSGeorge Cherian 	}
1068f1168d1eSGeorge Cherian 
1069f1168d1eSGeorge Cherian 	rvu_reporters->rvu_hw_npa_err_reporter =
1070f1168d1eSGeorge Cherian 		devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_err_reporter_ops, 0, rvu);
1071f1168d1eSGeorge Cherian 	if (IS_ERR(rvu_reporters->rvu_hw_npa_err_reporter)) {
1072f1168d1eSGeorge Cherian 		dev_warn(rvu->dev, "Failed to create hw_npa_err reporter, err=%ld\n",
1073f1168d1eSGeorge Cherian 			 PTR_ERR(rvu_reporters->rvu_hw_npa_err_reporter));
1074f1168d1eSGeorge Cherian 		return PTR_ERR(rvu_reporters->rvu_hw_npa_err_reporter);
1075f1168d1eSGeorge Cherian 	}
1076f1168d1eSGeorge Cherian 
1077f1168d1eSGeorge Cherian 	rvu_reporters->rvu_hw_npa_ras_reporter =
1078f1168d1eSGeorge Cherian 		devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_ras_reporter_ops, 0, rvu);
1079f1168d1eSGeorge Cherian 	if (IS_ERR(rvu_reporters->rvu_hw_npa_ras_reporter)) {
1080f1168d1eSGeorge Cherian 		dev_warn(rvu->dev, "Failed to create hw_npa_ras reporter, err=%ld\n",
1081f1168d1eSGeorge Cherian 			 PTR_ERR(rvu_reporters->rvu_hw_npa_ras_reporter));
1082f1168d1eSGeorge Cherian 		return PTR_ERR(rvu_reporters->rvu_hw_npa_ras_reporter);
1083f1168d1eSGeorge Cherian 	}
1084f1168d1eSGeorge Cherian 
1085f1168d1eSGeorge Cherian 	rvu_dl->devlink_wq = create_workqueue("rvu_devlink_wq");
1086f1168d1eSGeorge Cherian 	if (!rvu_dl->devlink_wq)
10873c91c909SZhipeng Lu 		return -ENOMEM;
1088f1168d1eSGeorge Cherian 
1089f1168d1eSGeorge Cherian 	INIT_WORK(&rvu_reporters->intr_work, rvu_npa_intr_work);
1090f1168d1eSGeorge Cherian 	INIT_WORK(&rvu_reporters->err_work, rvu_npa_err_work);
1091f1168d1eSGeorge Cherian 	INIT_WORK(&rvu_reporters->gen_work, rvu_npa_gen_work);
1092f1168d1eSGeorge Cherian 	INIT_WORK(&rvu_reporters->ras_work, rvu_npa_ras_work);
1093f1168d1eSGeorge Cherian 
1094f1168d1eSGeorge Cherian 	return 0;
1095f1168d1eSGeorge Cherian }
1096f1168d1eSGeorge Cherian 
rvu_npa_health_reporters_create(struct rvu_devlink * rvu_dl)1097f1168d1eSGeorge Cherian static int rvu_npa_health_reporters_create(struct rvu_devlink *rvu_dl)
1098f1168d1eSGeorge Cherian {
1099f1168d1eSGeorge Cherian 	struct rvu *rvu = rvu_dl->rvu;
1100f1168d1eSGeorge Cherian 	int err;
1101f1168d1eSGeorge Cherian 
1102f1168d1eSGeorge Cherian 	err = rvu_npa_register_reporters(rvu_dl);
1103f1168d1eSGeorge Cherian 	if (err) {
1104f1168d1eSGeorge Cherian 		dev_warn(rvu->dev, "Failed to create npa reporter, err =%d\n",
1105f1168d1eSGeorge Cherian 			 err);
1106f1168d1eSGeorge Cherian 		return err;
1107f1168d1eSGeorge Cherian 	}
1108f1168d1eSGeorge Cherian 	rvu_npa_register_interrupts(rvu);
1109f1168d1eSGeorge Cherian 
1110f1168d1eSGeorge Cherian 	return 0;
1111f1168d1eSGeorge Cherian }
1112f1168d1eSGeorge Cherian 
rvu_npa_health_reporters_destroy(struct rvu_devlink * rvu_dl)1113f1168d1eSGeorge Cherian static void rvu_npa_health_reporters_destroy(struct rvu_devlink *rvu_dl)
1114f1168d1eSGeorge Cherian {
1115f1168d1eSGeorge Cherian 	struct rvu_npa_health_reporters *npa_reporters;
1116f1168d1eSGeorge Cherian 	struct rvu *rvu = rvu_dl->rvu;
1117f1168d1eSGeorge Cherian 
1118f1168d1eSGeorge Cherian 	npa_reporters = rvu_dl->rvu_npa_health_reporter;
1119f1168d1eSGeorge Cherian 
1120f1168d1eSGeorge Cherian 	if (!npa_reporters->rvu_hw_npa_ras_reporter)
1121f1168d1eSGeorge Cherian 		return;
1122f1168d1eSGeorge Cherian 	if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_intr_reporter))
1123f1168d1eSGeorge Cherian 		devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_intr_reporter);
1124f1168d1eSGeorge Cherian 
1125f1168d1eSGeorge Cherian 	if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_gen_reporter))
1126f1168d1eSGeorge Cherian 		devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_gen_reporter);
1127f1168d1eSGeorge Cherian 
1128f1168d1eSGeorge Cherian 	if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_err_reporter))
1129f1168d1eSGeorge Cherian 		devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_err_reporter);
1130f1168d1eSGeorge Cherian 
1131f1168d1eSGeorge Cherian 	if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_ras_reporter))
1132f1168d1eSGeorge Cherian 		devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_ras_reporter);
1133f1168d1eSGeorge Cherian 
1134f1168d1eSGeorge Cherian 	rvu_npa_unregister_interrupts(rvu);
1135f1168d1eSGeorge Cherian 	kfree(rvu_dl->rvu_npa_health_reporter->npa_event_ctx);
1136f1168d1eSGeorge Cherian 	kfree(rvu_dl->rvu_npa_health_reporter);
1137f1168d1eSGeorge Cherian }
1138f1168d1eSGeorge Cherian 
rvu_health_reporters_create(struct rvu * rvu)1139f1168d1eSGeorge Cherian static int rvu_health_reporters_create(struct rvu *rvu)
1140f1168d1eSGeorge Cherian {
1141f1168d1eSGeorge Cherian 	struct rvu_devlink *rvu_dl;
11425ed66306SGeorge Cherian 	int err;
1143f1168d1eSGeorge Cherian 
1144f1168d1eSGeorge Cherian 	rvu_dl = rvu->rvu_dl;
11455ed66306SGeorge Cherian 	err = rvu_npa_health_reporters_create(rvu_dl);
11465ed66306SGeorge Cherian 	if (err)
11475ed66306SGeorge Cherian 		return err;
11485ed66306SGeorge Cherian 
11495ed66306SGeorge Cherian 	return rvu_nix_health_reporters_create(rvu_dl);
1150f1168d1eSGeorge Cherian }
1151f1168d1eSGeorge Cherian 
rvu_health_reporters_destroy(struct rvu * rvu)1152f1168d1eSGeorge Cherian static void rvu_health_reporters_destroy(struct rvu *rvu)
1153f1168d1eSGeorge Cherian {
1154f1168d1eSGeorge Cherian 	struct rvu_devlink *rvu_dl;
1155f1168d1eSGeorge Cherian 
1156f1168d1eSGeorge Cherian 	if (!rvu->rvu_dl)
1157f1168d1eSGeorge Cherian 		return;
1158f1168d1eSGeorge Cherian 
1159f1168d1eSGeorge Cherian 	rvu_dl = rvu->rvu_dl;
1160f1168d1eSGeorge Cherian 	rvu_npa_health_reporters_destroy(rvu_dl);
11615ed66306SGeorge Cherian 	rvu_nix_health_reporters_destroy(rvu_dl);
1162f1168d1eSGeorge Cherian }
1163f1168d1eSGeorge Cherian 
116476660df2SSunil 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)116576660df2SSunil Goutham static int rvu_af_dl_dwrr_mtu_validate(struct devlink *devlink, u32 id,
116676660df2SSunil Goutham 				       union devlink_param_value val,
116776660df2SSunil Goutham 				       struct netlink_ext_ack *extack)
116876660df2SSunil Goutham {
116976660df2SSunil Goutham 	struct rvu_devlink *rvu_dl = devlink_priv(devlink);
117076660df2SSunil Goutham 	struct rvu *rvu = rvu_dl->rvu;
117176660df2SSunil Goutham 	int dwrr_mtu = val.vu32;
117276660df2SSunil Goutham 	struct nix_txsch *txsch;
117376660df2SSunil Goutham 	struct nix_hw *nix_hw;
117476660df2SSunil Goutham 
117576660df2SSunil Goutham 	if (!rvu->hw->cap.nix_common_dwrr_mtu) {
117676660df2SSunil Goutham 		NL_SET_ERR_MSG_MOD(extack,
117776660df2SSunil Goutham 				   "Setting DWRR_MTU is not supported on this silicon");
117876660df2SSunil Goutham 		return -EOPNOTSUPP;
117976660df2SSunil Goutham 	}
118076660df2SSunil Goutham 
118176660df2SSunil Goutham 	if ((dwrr_mtu > 65536 || !is_power_of_2(dwrr_mtu)) &&
118276660df2SSunil Goutham 	    (dwrr_mtu != 9728 && dwrr_mtu != 10240)) {
118376660df2SSunil Goutham 		NL_SET_ERR_MSG_MOD(extack,
118476660df2SSunil Goutham 				   "Invalid, supported MTUs are 0,2,4,8.16,32,64....4K,8K,32K,64K and 9728, 10240");
118576660df2SSunil Goutham 		return -EINVAL;
118676660df2SSunil Goutham 	}
118776660df2SSunil Goutham 
118876660df2SSunil Goutham 	nix_hw = get_nix_hw(rvu->hw, BLKADDR_NIX0);
118976660df2SSunil Goutham 	if (!nix_hw)
119076660df2SSunil Goutham 		return -ENODEV;
119176660df2SSunil Goutham 
119276660df2SSunil Goutham 	txsch = &nix_hw->txsch[NIX_TXSCH_LVL_SMQ];
119376660df2SSunil Goutham 	if (rvu_rsrc_free_count(&txsch->schq) != txsch->schq.max) {
119476660df2SSunil Goutham 		NL_SET_ERR_MSG_MOD(extack,
119576660df2SSunil Goutham 				   "Changing DWRR MTU is not supported when there are active NIXLFs");
119676660df2SSunil Goutham 		NL_SET_ERR_MSG_MOD(extack,
119776660df2SSunil Goutham 				   "Make sure none of the PF/VF interfaces are initialized and retry");
119876660df2SSunil Goutham 		return -EOPNOTSUPP;
119976660df2SSunil Goutham 	}
120076660df2SSunil Goutham 
120176660df2SSunil Goutham 	return 0;
120276660df2SSunil Goutham }
120376660df2SSunil Goutham 
rvu_af_dl_dwrr_mtu_set(struct devlink * devlink,u32 id,struct devlink_param_gset_ctx * ctx,struct netlink_ext_ack * extack)120476660df2SSunil Goutham static int rvu_af_dl_dwrr_mtu_set(struct devlink *devlink, u32 id,
12055625ca56SMateusz Polchlopek 				  struct devlink_param_gset_ctx *ctx,
12065625ca56SMateusz Polchlopek 				  struct netlink_ext_ack *extack)
120776660df2SSunil Goutham {
120876660df2SSunil Goutham 	struct rvu_devlink *rvu_dl = devlink_priv(devlink);
120976660df2SSunil Goutham 	struct rvu *rvu = rvu_dl->rvu;
121076660df2SSunil Goutham 	u64 dwrr_mtu;
121176660df2SSunil Goutham 
121276660df2SSunil Goutham 	dwrr_mtu = convert_bytes_to_dwrr_mtu(ctx->val.vu32);
1213bbba125eSSunil Goutham 	rvu_write64(rvu, BLKADDR_NIX0,
1214bbba125eSSunil Goutham 		    nix_get_dwrr_mtu_reg(rvu->hw, SMQ_LINK_TYPE_RPM), dwrr_mtu);
121576660df2SSunil Goutham 
121676660df2SSunil Goutham 	return 0;
121776660df2SSunil Goutham }
121876660df2SSunil Goutham 
rvu_af_dl_dwrr_mtu_get(struct devlink * devlink,u32 id,struct devlink_param_gset_ctx * ctx)121976660df2SSunil Goutham static int rvu_af_dl_dwrr_mtu_get(struct devlink *devlink, u32 id,
122076660df2SSunil Goutham 				  struct devlink_param_gset_ctx *ctx)
122176660df2SSunil Goutham {
122276660df2SSunil Goutham 	struct rvu_devlink *rvu_dl = devlink_priv(devlink);
122376660df2SSunil Goutham 	struct rvu *rvu = rvu_dl->rvu;
122476660df2SSunil Goutham 	u64 dwrr_mtu;
122576660df2SSunil Goutham 
122676660df2SSunil Goutham 	if (!rvu->hw->cap.nix_common_dwrr_mtu)
122776660df2SSunil Goutham 		return -EOPNOTSUPP;
122876660df2SSunil Goutham 
1229bbba125eSSunil Goutham 	dwrr_mtu = rvu_read64(rvu, BLKADDR_NIX0,
1230bbba125eSSunil Goutham 			      nix_get_dwrr_mtu_reg(rvu->hw, SMQ_LINK_TYPE_RPM));
123176660df2SSunil Goutham 	ctx->val.vu32 = convert_dwrr_mtu_to_bytes(dwrr_mtu);
123276660df2SSunil Goutham 
123376660df2SSunil Goutham 	return 0;
123476660df2SSunil Goutham }
123576660df2SSunil Goutham 
123676660df2SSunil Goutham enum rvu_af_dl_param_id {
123776660df2SSunil Goutham 	RVU_AF_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
123876660df2SSunil Goutham 	RVU_AF_DEVLINK_PARAM_ID_DWRR_MTU,
123909de114cSNaveen Mamindlapalli 	RVU_AF_DEVLINK_PARAM_ID_NPC_MCAM_ZONE_PERCENT,
1240fc1b2901SSunil Goutham 	RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE,
124170a7434bSLinu Cherian 	RVU_AF_DEVLINK_PARAM_ID_NPC_DEF_RULE_CNTR_ENABLE,
1242dd784287SSuman Ghosh 	RVU_AF_DEVLINK_PARAM_ID_NIX_MAXLF,
124376660df2SSunil Goutham };
124476660df2SSunil Goutham 
rvu_af_npc_exact_feature_get(struct devlink * devlink,u32 id,struct devlink_param_gset_ctx * ctx)1245ef83e186SRatheesh Kannoth static int rvu_af_npc_exact_feature_get(struct devlink *devlink, u32 id,
1246ef83e186SRatheesh Kannoth 					struct devlink_param_gset_ctx *ctx)
1247ef83e186SRatheesh Kannoth {
1248ef83e186SRatheesh Kannoth 	struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1249ef83e186SRatheesh Kannoth 	struct rvu *rvu = rvu_dl->rvu;
1250ef83e186SRatheesh Kannoth 	bool enabled;
1251ef83e186SRatheesh Kannoth 
1252ef83e186SRatheesh Kannoth 	enabled = rvu_npc_exact_has_match_table(rvu);
1253ef83e186SRatheesh Kannoth 
1254ef83e186SRatheesh Kannoth 	snprintf(ctx->val.vstr, sizeof(ctx->val.vstr), "%s",
1255ef83e186SRatheesh Kannoth 		 enabled ? "enabled" : "disabled");
1256ef83e186SRatheesh Kannoth 
1257ef83e186SRatheesh Kannoth 	return 0;
1258ef83e186SRatheesh Kannoth }
1259ef83e186SRatheesh Kannoth 
rvu_af_npc_exact_feature_disable(struct devlink * devlink,u32 id,struct devlink_param_gset_ctx * ctx,struct netlink_ext_ack * extack)1260ef83e186SRatheesh Kannoth static int rvu_af_npc_exact_feature_disable(struct devlink *devlink, u32 id,
12615625ca56SMateusz Polchlopek 					    struct devlink_param_gset_ctx *ctx,
12625625ca56SMateusz Polchlopek 					    struct netlink_ext_ack *extack)
1263ef83e186SRatheesh Kannoth {
1264ef83e186SRatheesh Kannoth 	struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1265ef83e186SRatheesh Kannoth 	struct rvu *rvu = rvu_dl->rvu;
1266ef83e186SRatheesh Kannoth 
1267ef83e186SRatheesh Kannoth 	rvu_npc_exact_disable_feature(rvu);
1268ef83e186SRatheesh Kannoth 
1269ef83e186SRatheesh Kannoth 	return 0;
1270ef83e186SRatheesh Kannoth }
1271ef83e186SRatheesh Kannoth 
rvu_af_npc_exact_feature_validate(struct devlink * devlink,u32 id,union devlink_param_value val,struct netlink_ext_ack * extack)1272ef83e186SRatheesh Kannoth static int rvu_af_npc_exact_feature_validate(struct devlink *devlink, u32 id,
1273ef83e186SRatheesh Kannoth 					     union devlink_param_value val,
1274ef83e186SRatheesh Kannoth 					     struct netlink_ext_ack *extack)
1275ef83e186SRatheesh Kannoth {
1276ef83e186SRatheesh Kannoth 	struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1277ef83e186SRatheesh Kannoth 	struct rvu *rvu = rvu_dl->rvu;
1278ef83e186SRatheesh Kannoth 	u64 enable;
1279ef83e186SRatheesh Kannoth 
1280ef83e186SRatheesh Kannoth 	if (kstrtoull(val.vstr, 10, &enable)) {
1281ef83e186SRatheesh Kannoth 		NL_SET_ERR_MSG_MOD(extack,
1282ef83e186SRatheesh Kannoth 				   "Only 1 value is supported");
1283ef83e186SRatheesh Kannoth 		return -EINVAL;
1284ef83e186SRatheesh Kannoth 	}
1285ef83e186SRatheesh Kannoth 
1286ef83e186SRatheesh Kannoth 	if (enable != 1) {
1287ef83e186SRatheesh Kannoth 		NL_SET_ERR_MSG_MOD(extack,
1288ef83e186SRatheesh Kannoth 				   "Only disabling exact match feature is supported");
1289ef83e186SRatheesh Kannoth 		return -EINVAL;
1290ef83e186SRatheesh Kannoth 	}
1291ef83e186SRatheesh Kannoth 
1292ef83e186SRatheesh Kannoth 	if (rvu_npc_exact_can_disable_feature(rvu))
1293ef83e186SRatheesh Kannoth 		return 0;
1294ef83e186SRatheesh Kannoth 
1295ef83e186SRatheesh Kannoth 	NL_SET_ERR_MSG_MOD(extack,
1296ef83e186SRatheesh Kannoth 			   "Can't disable exact match feature; Please try before any configuration");
1297ef83e186SRatheesh Kannoth 	return -EFAULT;
1298ef83e186SRatheesh Kannoth }
1299ef83e186SRatheesh Kannoth 
rvu_af_dl_npc_mcam_high_zone_percent_get(struct devlink * devlink,u32 id,struct devlink_param_gset_ctx * ctx)130009de114cSNaveen Mamindlapalli static int rvu_af_dl_npc_mcam_high_zone_percent_get(struct devlink *devlink, u32 id,
130109de114cSNaveen Mamindlapalli 						    struct devlink_param_gset_ctx *ctx)
130209de114cSNaveen Mamindlapalli {
130309de114cSNaveen Mamindlapalli 	struct rvu_devlink *rvu_dl = devlink_priv(devlink);
130409de114cSNaveen Mamindlapalli 	struct rvu *rvu = rvu_dl->rvu;
130509de114cSNaveen Mamindlapalli 	struct npc_mcam *mcam;
130609de114cSNaveen Mamindlapalli 	u32 percent;
130709de114cSNaveen Mamindlapalli 
130809de114cSNaveen Mamindlapalli 	mcam = &rvu->hw->mcam;
130909de114cSNaveen Mamindlapalli 	percent = (mcam->hprio_count * 100) / mcam->bmap_entries;
131009de114cSNaveen Mamindlapalli 	ctx->val.vu8 = (u8)percent;
131109de114cSNaveen Mamindlapalli 
131209de114cSNaveen Mamindlapalli 	return 0;
131309de114cSNaveen Mamindlapalli }
131409de114cSNaveen Mamindlapalli 
rvu_af_dl_npc_mcam_high_zone_percent_set(struct devlink * devlink,u32 id,struct devlink_param_gset_ctx * ctx,struct netlink_ext_ack * extack)131509de114cSNaveen Mamindlapalli static int rvu_af_dl_npc_mcam_high_zone_percent_set(struct devlink *devlink, u32 id,
13165625ca56SMateusz Polchlopek 						    struct devlink_param_gset_ctx *ctx,
13175625ca56SMateusz Polchlopek 						    struct netlink_ext_ack *extack)
131809de114cSNaveen Mamindlapalli {
131909de114cSNaveen Mamindlapalli 	struct rvu_devlink *rvu_dl = devlink_priv(devlink);
132009de114cSNaveen Mamindlapalli 	struct rvu *rvu = rvu_dl->rvu;
132109de114cSNaveen Mamindlapalli 	struct npc_mcam *mcam;
132209de114cSNaveen Mamindlapalli 	u32 percent;
132309de114cSNaveen Mamindlapalli 
132409de114cSNaveen Mamindlapalli 	percent = ctx->val.vu8;
132509de114cSNaveen Mamindlapalli 	mcam = &rvu->hw->mcam;
132609de114cSNaveen Mamindlapalli 	mcam->hprio_count = (mcam->bmap_entries * percent) / 100;
132709de114cSNaveen Mamindlapalli 	mcam->hprio_end = mcam->hprio_count;
132809de114cSNaveen Mamindlapalli 	mcam->lprio_count = (mcam->bmap_entries - mcam->hprio_count) / 2;
132909de114cSNaveen Mamindlapalli 	mcam->lprio_start = mcam->bmap_entries - mcam->lprio_count;
133009de114cSNaveen Mamindlapalli 
133109de114cSNaveen Mamindlapalli 	return 0;
133209de114cSNaveen Mamindlapalli }
133309de114cSNaveen 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)133409de114cSNaveen Mamindlapalli static int rvu_af_dl_npc_mcam_high_zone_percent_validate(struct devlink *devlink, u32 id,
133509de114cSNaveen Mamindlapalli 							 union devlink_param_value val,
133609de114cSNaveen Mamindlapalli 							 struct netlink_ext_ack *extack)
133709de114cSNaveen Mamindlapalli {
133809de114cSNaveen Mamindlapalli 	struct rvu_devlink *rvu_dl = devlink_priv(devlink);
133909de114cSNaveen Mamindlapalli 	struct rvu *rvu = rvu_dl->rvu;
134009de114cSNaveen Mamindlapalli 	struct npc_mcam *mcam;
134109de114cSNaveen Mamindlapalli 
134209de114cSNaveen Mamindlapalli 	/* The percent of high prio zone must range from 12% to 100% of unreserved mcam space */
134309de114cSNaveen Mamindlapalli 	if (val.vu8 < 12 || val.vu8 > 100) {
134409de114cSNaveen Mamindlapalli 		NL_SET_ERR_MSG_MOD(extack,
134509de114cSNaveen Mamindlapalli 				   "mcam high zone percent must be between 12% to 100%");
134609de114cSNaveen Mamindlapalli 		return -EINVAL;
134709de114cSNaveen Mamindlapalli 	}
134809de114cSNaveen Mamindlapalli 
134909de114cSNaveen Mamindlapalli 	/* Do not allow user to modify the high priority zone entries while mcam entries
135009de114cSNaveen Mamindlapalli 	 * have already been assigned.
135109de114cSNaveen Mamindlapalli 	 */
135209de114cSNaveen Mamindlapalli 	mcam = &rvu->hw->mcam;
135309de114cSNaveen Mamindlapalli 	if (mcam->bmap_fcnt < mcam->bmap_entries) {
135409de114cSNaveen Mamindlapalli 		NL_SET_ERR_MSG_MOD(extack,
135509de114cSNaveen Mamindlapalli 				   "mcam entries have already been assigned, can't resize");
135609de114cSNaveen Mamindlapalli 		return -EPERM;
135709de114cSNaveen Mamindlapalli 	}
135809de114cSNaveen Mamindlapalli 
135909de114cSNaveen Mamindlapalli 	return 0;
136009de114cSNaveen Mamindlapalli }
136109de114cSNaveen Mamindlapalli 
rvu_af_dl_npc_def_rule_cntr_get(struct devlink * devlink,u32 id,struct devlink_param_gset_ctx * ctx)136270a7434bSLinu Cherian static int rvu_af_dl_npc_def_rule_cntr_get(struct devlink *devlink, u32 id,
136370a7434bSLinu Cherian 					   struct devlink_param_gset_ctx *ctx)
136470a7434bSLinu Cherian {
136570a7434bSLinu Cherian 	struct rvu_devlink *rvu_dl = devlink_priv(devlink);
136670a7434bSLinu Cherian 	struct rvu *rvu = rvu_dl->rvu;
136770a7434bSLinu Cherian 
136870a7434bSLinu Cherian 	ctx->val.vbool = rvu->def_rule_cntr_en;
136970a7434bSLinu Cherian 
137070a7434bSLinu Cherian 	return 0;
137170a7434bSLinu Cherian }
137270a7434bSLinu Cherian 
rvu_af_dl_npc_def_rule_cntr_set(struct devlink * devlink,u32 id,struct devlink_param_gset_ctx * ctx,struct netlink_ext_ack * extack)137370a7434bSLinu Cherian static int rvu_af_dl_npc_def_rule_cntr_set(struct devlink *devlink, u32 id,
137470a7434bSLinu Cherian 					   struct devlink_param_gset_ctx *ctx,
137570a7434bSLinu Cherian 					   struct netlink_ext_ack *extack)
137670a7434bSLinu Cherian {
137770a7434bSLinu Cherian 	struct rvu_devlink *rvu_dl = devlink_priv(devlink);
137870a7434bSLinu Cherian 	struct rvu *rvu = rvu_dl->rvu;
137970a7434bSLinu Cherian 	int err;
138070a7434bSLinu Cherian 
138170a7434bSLinu Cherian 	err = npc_config_cntr_default_entries(rvu, ctx->val.vbool);
138270a7434bSLinu Cherian 	if (!err)
138370a7434bSLinu Cherian 		rvu->def_rule_cntr_en = ctx->val.vbool;
138470a7434bSLinu Cherian 
138570a7434bSLinu Cherian 	return err;
138670a7434bSLinu Cherian }
138770a7434bSLinu Cherian 
rvu_af_dl_nix_maxlf_get(struct devlink * devlink,u32 id,struct devlink_param_gset_ctx * ctx)1388dd784287SSuman Ghosh static int rvu_af_dl_nix_maxlf_get(struct devlink *devlink, u32 id,
1389dd784287SSuman Ghosh 				   struct devlink_param_gset_ctx *ctx)
1390dd784287SSuman Ghosh {
1391dd784287SSuman Ghosh 	struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1392dd784287SSuman Ghosh 	struct rvu *rvu = rvu_dl->rvu;
1393dd784287SSuman Ghosh 
1394dd784287SSuman Ghosh 	ctx->val.vu16 = (u16)rvu_get_nixlf_count(rvu);
1395dd784287SSuman Ghosh 
1396dd784287SSuman Ghosh 	return 0;
1397dd784287SSuman Ghosh }
1398dd784287SSuman Ghosh 
rvu_af_dl_nix_maxlf_set(struct devlink * devlink,u32 id,struct devlink_param_gset_ctx * ctx,struct netlink_ext_ack * extack)1399dd784287SSuman Ghosh static int rvu_af_dl_nix_maxlf_set(struct devlink *devlink, u32 id,
14005625ca56SMateusz Polchlopek 				   struct devlink_param_gset_ctx *ctx,
14015625ca56SMateusz Polchlopek 				   struct netlink_ext_ack *extack)
1402dd784287SSuman Ghosh {
1403dd784287SSuman Ghosh 	struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1404dd784287SSuman Ghosh 	struct rvu *rvu = rvu_dl->rvu;
1405dd784287SSuman Ghosh 	struct rvu_block *block;
1406dd784287SSuman Ghosh 	int blkaddr = 0;
1407dd784287SSuman Ghosh 
1408dd784287SSuman Ghosh 	npc_mcam_rsrcs_deinit(rvu);
1409dd784287SSuman Ghosh 	blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr);
1410dd784287SSuman Ghosh 	while (blkaddr) {
1411dd784287SSuman Ghosh 		block = &rvu->hw->block[blkaddr];
1412dd784287SSuman Ghosh 		block->lf.max = ctx->val.vu16;
1413dd784287SSuman Ghosh 		blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr);
1414dd784287SSuman Ghosh 	}
1415dd784287SSuman Ghosh 
1416dd784287SSuman Ghosh 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0);
1417dd784287SSuman Ghosh 	npc_mcam_rsrcs_init(rvu, blkaddr);
1418dd784287SSuman Ghosh 
1419dd784287SSuman Ghosh 	return 0;
1420dd784287SSuman Ghosh }
1421dd784287SSuman Ghosh 
rvu_af_dl_nix_maxlf_validate(struct devlink * devlink,u32 id,union devlink_param_value val,struct netlink_ext_ack * extack)1422dd784287SSuman Ghosh static int rvu_af_dl_nix_maxlf_validate(struct devlink *devlink, u32 id,
1423dd784287SSuman Ghosh 					union devlink_param_value val,
1424dd784287SSuman Ghosh 					struct netlink_ext_ack *extack)
1425dd784287SSuman Ghosh {
1426dd784287SSuman Ghosh 	struct rvu_devlink *rvu_dl = devlink_priv(devlink);
1427dd784287SSuman Ghosh 	struct rvu *rvu = rvu_dl->rvu;
1428dd784287SSuman Ghosh 	u16 max_nix0_lf, max_nix1_lf;
1429dd784287SSuman Ghosh 	struct npc_mcam *mcam;
1430dd784287SSuman Ghosh 	u64 cfg;
1431dd784287SSuman Ghosh 
1432dd784287SSuman Ghosh 	cfg = rvu_read64(rvu, BLKADDR_NIX0, NIX_AF_CONST2);
1433dd784287SSuman Ghosh 	max_nix0_lf = cfg & 0xFFF;
1434dd784287SSuman Ghosh 	cfg = rvu_read64(rvu, BLKADDR_NIX1, NIX_AF_CONST2);
1435dd784287SSuman Ghosh 	max_nix1_lf = cfg & 0xFFF;
1436dd784287SSuman Ghosh 
1437dd784287SSuman Ghosh 	/* Do not allow user to modify maximum NIX LFs while mcam entries
1438dd784287SSuman Ghosh 	 * have already been assigned.
1439dd784287SSuman Ghosh 	 */
1440dd784287SSuman Ghosh 	mcam = &rvu->hw->mcam;
1441dd784287SSuman Ghosh 	if (mcam->bmap_fcnt < mcam->bmap_entries) {
1442dd784287SSuman Ghosh 		NL_SET_ERR_MSG_MOD(extack,
1443dd784287SSuman Ghosh 				   "mcam entries have already been assigned, can't resize");
1444dd784287SSuman Ghosh 		return -EPERM;
1445dd784287SSuman Ghosh 	}
1446dd784287SSuman Ghosh 
1447dd784287SSuman Ghosh 	if (max_nix0_lf && val.vu16 > max_nix0_lf) {
1448dd784287SSuman Ghosh 		NL_SET_ERR_MSG_MOD(extack,
1449dd784287SSuman Ghosh 				   "requested nixlf is greater than the max supported nix0_lf");
1450dd784287SSuman Ghosh 		return -EPERM;
1451dd784287SSuman Ghosh 	}
1452dd784287SSuman Ghosh 
1453dd784287SSuman Ghosh 	if (max_nix1_lf && val.vu16 > max_nix1_lf) {
1454dd784287SSuman Ghosh 		NL_SET_ERR_MSG_MOD(extack,
1455dd784287SSuman Ghosh 				   "requested nixlf is greater than the max supported nix1_lf");
1456dd784287SSuman Ghosh 		return -EINVAL;
1457dd784287SSuman Ghosh 	}
1458dd784287SSuman Ghosh 
1459dd784287SSuman Ghosh 	return 0;
1460dd784287SSuman Ghosh }
1461dd784287SSuman Ghosh 
146276660df2SSunil Goutham static const struct devlink_param rvu_af_dl_params[] = {
146376660df2SSunil Goutham 	DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_DWRR_MTU,
146476660df2SSunil Goutham 			     "dwrr_mtu", DEVLINK_PARAM_TYPE_U32,
146576660df2SSunil Goutham 			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
146676660df2SSunil Goutham 			     rvu_af_dl_dwrr_mtu_get, rvu_af_dl_dwrr_mtu_set,
146776660df2SSunil Goutham 			     rvu_af_dl_dwrr_mtu_validate),
146809de114cSNaveen Mamindlapalli 	DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NPC_MCAM_ZONE_PERCENT,
146909de114cSNaveen Mamindlapalli 			     "npc_mcam_high_zone_percent", DEVLINK_PARAM_TYPE_U8,
147009de114cSNaveen Mamindlapalli 			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
147109de114cSNaveen Mamindlapalli 			     rvu_af_dl_npc_mcam_high_zone_percent_get,
147209de114cSNaveen Mamindlapalli 			     rvu_af_dl_npc_mcam_high_zone_percent_set,
147309de114cSNaveen Mamindlapalli 			     rvu_af_dl_npc_mcam_high_zone_percent_validate),
147470a7434bSLinu Cherian 	DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NPC_DEF_RULE_CNTR_ENABLE,
147570a7434bSLinu Cherian 			     "npc_def_rule_cntr", DEVLINK_PARAM_TYPE_BOOL,
147670a7434bSLinu Cherian 			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
147770a7434bSLinu Cherian 			     rvu_af_dl_npc_def_rule_cntr_get,
147870a7434bSLinu Cherian 			     rvu_af_dl_npc_def_rule_cntr_set, NULL),
1479dd784287SSuman Ghosh 	DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NIX_MAXLF,
1480dd784287SSuman Ghosh 			     "nix_maxlf", DEVLINK_PARAM_TYPE_U16,
1481dd784287SSuman Ghosh 			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
1482dd784287SSuman Ghosh 			     rvu_af_dl_nix_maxlf_get,
1483dd784287SSuman Ghosh 			     rvu_af_dl_nix_maxlf_set,
1484dd784287SSuman Ghosh 			     rvu_af_dl_nix_maxlf_validate),
148576660df2SSunil Goutham };
148676660df2SSunil Goutham 
1487fc1b2901SSunil Goutham static const struct devlink_param rvu_af_dl_param_exact_match[] = {
1488fc1b2901SSunil Goutham 	DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE,
1489fc1b2901SSunil Goutham 			     "npc_exact_feature_disable", DEVLINK_PARAM_TYPE_STRING,
1490fc1b2901SSunil Goutham 			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
1491fc1b2901SSunil Goutham 			     rvu_af_npc_exact_feature_get,
1492fc1b2901SSunil Goutham 			     rvu_af_npc_exact_feature_disable,
1493fc1b2901SSunil Goutham 			     rvu_af_npc_exact_feature_validate),
1494fc1b2901SSunil Goutham };
1495fc1b2901SSunil Goutham 
149676660df2SSunil Goutham /* Devlink switch mode */
rvu_devlink_eswitch_mode_get(struct devlink * devlink,u16 * mode)149723109f8dSSubbaraya Sundeep static int rvu_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode)
149823109f8dSSubbaraya Sundeep {
149923109f8dSSubbaraya Sundeep 	struct rvu_devlink *rvu_dl = devlink_priv(devlink);
150023109f8dSSubbaraya Sundeep 	struct rvu *rvu = rvu_dl->rvu;
150123109f8dSSubbaraya Sundeep 	struct rvu_switch *rswitch;
150223109f8dSSubbaraya Sundeep 
1503683645a2SGeetha sowjanya 	if (rvu->rep_mode)
1504683645a2SGeetha sowjanya 		return -EOPNOTSUPP;
1505683645a2SGeetha sowjanya 
150623109f8dSSubbaraya Sundeep 	rswitch = &rvu->rswitch;
150723109f8dSSubbaraya Sundeep 	*mode = rswitch->mode;
150823109f8dSSubbaraya Sundeep 
150923109f8dSSubbaraya Sundeep 	return 0;
151023109f8dSSubbaraya Sundeep }
151123109f8dSSubbaraya Sundeep 
rvu_devlink_eswitch_mode_set(struct devlink * devlink,u16 mode,struct netlink_ext_ack * extack)151223109f8dSSubbaraya Sundeep static int rvu_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode,
151323109f8dSSubbaraya Sundeep 					struct netlink_ext_ack *extack)
151423109f8dSSubbaraya Sundeep {
151523109f8dSSubbaraya Sundeep 	struct rvu_devlink *rvu_dl = devlink_priv(devlink);
151623109f8dSSubbaraya Sundeep 	struct rvu *rvu = rvu_dl->rvu;
151723109f8dSSubbaraya Sundeep 	struct rvu_switch *rswitch;
151823109f8dSSubbaraya Sundeep 
151923109f8dSSubbaraya Sundeep 	rswitch = &rvu->rswitch;
152023109f8dSSubbaraya Sundeep 	switch (mode) {
152123109f8dSSubbaraya Sundeep 	case DEVLINK_ESWITCH_MODE_LEGACY:
152223109f8dSSubbaraya Sundeep 	case DEVLINK_ESWITCH_MODE_SWITCHDEV:
152323109f8dSSubbaraya Sundeep 		if (rswitch->mode == mode)
152423109f8dSSubbaraya Sundeep 			return 0;
152523109f8dSSubbaraya Sundeep 		rswitch->mode = mode;
152623109f8dSSubbaraya Sundeep 		if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV)
152723109f8dSSubbaraya Sundeep 			rvu_switch_enable(rvu);
152823109f8dSSubbaraya Sundeep 		else
152923109f8dSSubbaraya Sundeep 			rvu_switch_disable(rvu);
153023109f8dSSubbaraya Sundeep 		break;
153123109f8dSSubbaraya Sundeep 	default:
153223109f8dSSubbaraya Sundeep 		return -EINVAL;
153323109f8dSSubbaraya Sundeep 	}
153423109f8dSSubbaraya Sundeep 
153523109f8dSSubbaraya Sundeep 	return 0;
153623109f8dSSubbaraya Sundeep }
153723109f8dSSubbaraya Sundeep 
1538fae06da4SGeorge Cherian static const struct devlink_ops rvu_devlink_ops = {
153923109f8dSSubbaraya Sundeep 	.eswitch_mode_get = rvu_devlink_eswitch_mode_get,
154023109f8dSSubbaraya Sundeep 	.eswitch_mode_set = rvu_devlink_eswitch_mode_set,
1541fae06da4SGeorge Cherian };
1542fae06da4SGeorge Cherian 
rvu_register_dl(struct rvu * rvu)1543fae06da4SGeorge Cherian int rvu_register_dl(struct rvu *rvu)
1544fae06da4SGeorge Cherian {
1545fae06da4SGeorge Cherian 	struct rvu_devlink *rvu_dl;
1546fae06da4SGeorge Cherian 	struct devlink *dl;
1547fae06da4SGeorge Cherian 	int err;
1548fae06da4SGeorge Cherian 
1549919d13a7SLeon Romanovsky 	dl = devlink_alloc(&rvu_devlink_ops, sizeof(struct rvu_devlink),
1550919d13a7SLeon Romanovsky 			   rvu->dev);
1551fae06da4SGeorge Cherian 	if (!dl) {
1552fae06da4SGeorge Cherian 		dev_warn(rvu->dev, "devlink_alloc failed\n");
1553fae06da4SGeorge Cherian 		return -ENOMEM;
1554fae06da4SGeorge Cherian 	}
1555fae06da4SGeorge Cherian 
155623109f8dSSubbaraya Sundeep 	rvu_dl = devlink_priv(dl);
1557fae06da4SGeorge Cherian 	rvu_dl->dl = dl;
1558fae06da4SGeorge Cherian 	rvu_dl->rvu = rvu;
1559fae06da4SGeorge Cherian 	rvu->rvu_dl = rvu_dl;
1560f1168d1eSGeorge Cherian 
156176660df2SSunil Goutham 	err = rvu_health_reporters_create(rvu);
156276660df2SSunil Goutham 	if (err) {
156376660df2SSunil Goutham 		dev_err(rvu->dev,
156476660df2SSunil Goutham 			"devlink health reporter creation failed with error %d\n", err);
156576660df2SSunil Goutham 		goto err_dl_health;
156676660df2SSunil Goutham 	}
156776660df2SSunil Goutham 
1568917d5e04SRatheesh Kannoth 	err = devlink_params_register(dl, rvu_af_dl_params, ARRAY_SIZE(rvu_af_dl_params));
156976660df2SSunil Goutham 	if (err) {
157076660df2SSunil Goutham 		dev_err(rvu->dev,
157176660df2SSunil Goutham 			"devlink params register failed with error %d", err);
157276660df2SSunil Goutham 		goto err_dl_health;
157376660df2SSunil Goutham 	}
157476660df2SSunil Goutham 
1575917d5e04SRatheesh Kannoth 	/* Register exact match devlink only for CN10K-B */
1576917d5e04SRatheesh Kannoth 	if (!rvu_npc_exact_has_match_table(rvu))
1577917d5e04SRatheesh Kannoth 		goto done;
1578917d5e04SRatheesh Kannoth 
1579917d5e04SRatheesh Kannoth 	err = devlink_params_register(dl, rvu_af_dl_param_exact_match,
1580917d5e04SRatheesh Kannoth 				      ARRAY_SIZE(rvu_af_dl_param_exact_match));
1581917d5e04SRatheesh Kannoth 	if (err) {
1582917d5e04SRatheesh Kannoth 		dev_err(rvu->dev,
1583917d5e04SRatheesh Kannoth 			"devlink exact match params register failed with error %d", err);
1584917d5e04SRatheesh Kannoth 		goto err_dl_exact_match;
1585917d5e04SRatheesh Kannoth 	}
1586917d5e04SRatheesh Kannoth 
1587917d5e04SRatheesh Kannoth done:
15881d264db4SLeon Romanovsky 	devlink_register(dl);
158976660df2SSunil Goutham 	return 0;
159076660df2SSunil Goutham 
1591917d5e04SRatheesh Kannoth err_dl_exact_match:
1592917d5e04SRatheesh Kannoth 	devlink_params_unregister(dl, rvu_af_dl_params, ARRAY_SIZE(rvu_af_dl_params));
1593917d5e04SRatheesh Kannoth 
159476660df2SSunil Goutham err_dl_health:
159576660df2SSunil Goutham 	rvu_health_reporters_destroy(rvu);
159676660df2SSunil Goutham 	devlink_free(dl);
159776660df2SSunil Goutham 	return err;
1598fae06da4SGeorge Cherian }
1599fae06da4SGeorge Cherian 
rvu_unregister_dl(struct rvu * rvu)1600fae06da4SGeorge Cherian void rvu_unregister_dl(struct rvu *rvu)
1601fae06da4SGeorge Cherian {
1602fae06da4SGeorge Cherian 	struct rvu_devlink *rvu_dl = rvu->rvu_dl;
1603fae06da4SGeorge Cherian 	struct devlink *dl = rvu_dl->dl;
1604fae06da4SGeorge Cherian 
16051d264db4SLeon Romanovsky 	devlink_unregister(dl);
1606917d5e04SRatheesh Kannoth 
1607917d5e04SRatheesh Kannoth 	devlink_params_unregister(dl, rvu_af_dl_params, ARRAY_SIZE(rvu_af_dl_params));
1608917d5e04SRatheesh Kannoth 
1609917d5e04SRatheesh Kannoth 	/* Unregister exact match devlink only for CN10K-B */
1610917d5e04SRatheesh Kannoth 	if (rvu_npc_exact_has_match_table(rvu))
1611917d5e04SRatheesh Kannoth 		devlink_params_unregister(dl, rvu_af_dl_param_exact_match,
1612917d5e04SRatheesh Kannoth 					  ARRAY_SIZE(rvu_af_dl_param_exact_match));
1613917d5e04SRatheesh Kannoth 
1614f1168d1eSGeorge Cherian 	rvu_health_reporters_destroy(rvu);
1615fae06da4SGeorge Cherian 	devlink_free(dl);
1616fae06da4SGeorge Cherian }
1617