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