1 // SPDX-License-Identifier: GPL-2.0 2 /* Marvell OcteonTx2 RVU 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 static int rvu_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req, 1368 struct netlink_ext_ack *extack) 1369 { 1370 return devlink_info_driver_name_put(req, DRV_NAME); 1371 } 1372 1373 static const struct devlink_ops rvu_devlink_ops = { 1374 .info_get = rvu_devlink_info_get, 1375 }; 1376 1377 int rvu_register_dl(struct rvu *rvu) 1378 { 1379 struct rvu_devlink *rvu_dl; 1380 struct devlink *dl; 1381 int err; 1382 1383 rvu_dl = kzalloc(sizeof(*rvu_dl), GFP_KERNEL); 1384 if (!rvu_dl) 1385 return -ENOMEM; 1386 1387 dl = devlink_alloc(&rvu_devlink_ops, sizeof(struct rvu_devlink)); 1388 if (!dl) { 1389 dev_warn(rvu->dev, "devlink_alloc failed\n"); 1390 kfree(rvu_dl); 1391 return -ENOMEM; 1392 } 1393 1394 err = devlink_register(dl, rvu->dev); 1395 if (err) { 1396 dev_err(rvu->dev, "devlink register failed with error %d\n", err); 1397 devlink_free(dl); 1398 kfree(rvu_dl); 1399 return err; 1400 } 1401 1402 rvu_dl->dl = dl; 1403 rvu_dl->rvu = rvu; 1404 rvu->rvu_dl = rvu_dl; 1405 1406 return rvu_health_reporters_create(rvu); 1407 } 1408 1409 void rvu_unregister_dl(struct rvu *rvu) 1410 { 1411 struct rvu_devlink *rvu_dl = rvu->rvu_dl; 1412 struct devlink *dl = rvu_dl->dl; 1413 1414 if (!dl) 1415 return; 1416 1417 rvu_health_reporters_destroy(rvu); 1418 devlink_unregister(dl); 1419 devlink_free(dl); 1420 kfree(rvu_dl); 1421 } 1422