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