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