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