cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rvu_devlink.c (44728B)


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