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_npa_intr_work(struct work_struct *work) 56 { 57 struct rvu_npa_health_reporters *rvu_npa_health_reporter; 58 59 rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, intr_work); 60 devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_intr_reporter, 61 "NPA_AF_RVU Error", 62 rvu_npa_health_reporter->npa_event_ctx); 63 } 64 65 static irqreturn_t rvu_npa_af_rvu_intr_handler(int irq, void *rvu_irq) 66 { 67 struct rvu_npa_event_ctx *npa_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_NPA, 0); 75 if (blkaddr < 0) 76 return IRQ_NONE; 77 78 npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx; 79 intr = rvu_read64(rvu, blkaddr, NPA_AF_RVU_INT); 80 npa_event_context->npa_af_rvu_int = intr; 81 82 /* Clear interrupts */ 83 rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT, intr); 84 rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1C, ~0ULL); 85 queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->intr_work); 86 87 return IRQ_HANDLED; 88 } 89 90 static void rvu_npa_gen_work(struct work_struct *work) 91 { 92 struct rvu_npa_health_reporters *rvu_npa_health_reporter; 93 94 rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, gen_work); 95 devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_gen_reporter, 96 "NPA_AF_GEN Error", 97 rvu_npa_health_reporter->npa_event_ctx); 98 } 99 100 static irqreturn_t rvu_npa_af_gen_intr_handler(int irq, void *rvu_irq) 101 { 102 struct rvu_npa_event_ctx *npa_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_NPA, 0); 110 if (blkaddr < 0) 111 return IRQ_NONE; 112 113 npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx; 114 intr = rvu_read64(rvu, blkaddr, NPA_AF_GEN_INT); 115 npa_event_context->npa_af_rvu_gen = intr; 116 117 /* Clear interrupts */ 118 rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT, intr); 119 rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1C, ~0ULL); 120 queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->gen_work); 121 122 return IRQ_HANDLED; 123 } 124 125 static void rvu_npa_err_work(struct work_struct *work) 126 { 127 struct rvu_npa_health_reporters *rvu_npa_health_reporter; 128 129 rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, err_work); 130 devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_err_reporter, 131 "NPA_AF_ERR Error", 132 rvu_npa_health_reporter->npa_event_ctx); 133 } 134 135 static irqreturn_t rvu_npa_af_err_intr_handler(int irq, void *rvu_irq) 136 { 137 struct rvu_npa_event_ctx *npa_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_NPA, 0); 145 if (blkaddr < 0) 146 return IRQ_NONE; 147 npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx; 148 intr = rvu_read64(rvu, blkaddr, NPA_AF_ERR_INT); 149 npa_event_context->npa_af_rvu_err = intr; 150 151 /* Clear interrupts */ 152 rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT, intr); 153 rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1C, ~0ULL); 154 queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->err_work); 155 156 return IRQ_HANDLED; 157 } 158 159 static void rvu_npa_ras_work(struct work_struct *work) 160 { 161 struct rvu_npa_health_reporters *rvu_npa_health_reporter; 162 163 rvu_npa_health_reporter = container_of(work, struct rvu_npa_health_reporters, ras_work); 164 devlink_health_report(rvu_npa_health_reporter->rvu_hw_npa_ras_reporter, 165 "HW NPA_AF_RAS Error reported", 166 rvu_npa_health_reporter->npa_event_ctx); 167 } 168 169 static irqreturn_t rvu_npa_af_ras_intr_handler(int irq, void *rvu_irq) 170 { 171 struct rvu_npa_event_ctx *npa_event_context; 172 struct rvu_devlink *rvu_dl = rvu_irq; 173 struct rvu *rvu; 174 int blkaddr; 175 u64 intr; 176 177 rvu = rvu_dl->rvu; 178 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0); 179 if (blkaddr < 0) 180 return IRQ_NONE; 181 182 npa_event_context = rvu_dl->rvu_npa_health_reporter->npa_event_ctx; 183 intr = rvu_read64(rvu, blkaddr, NPA_AF_RAS); 184 npa_event_context->npa_af_rvu_ras = intr; 185 186 /* Clear interrupts */ 187 rvu_write64(rvu, blkaddr, NPA_AF_RAS, intr); 188 rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1C, ~0ULL); 189 queue_work(rvu_dl->devlink_wq, &rvu_dl->rvu_npa_health_reporter->ras_work); 190 191 return IRQ_HANDLED; 192 } 193 194 static void rvu_npa_unregister_interrupts(struct rvu *rvu) 195 { 196 struct rvu_devlink *rvu_dl = rvu->rvu_dl; 197 int i, offs, blkaddr; 198 u64 reg; 199 200 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0); 201 if (blkaddr < 0) 202 return; 203 204 reg = rvu_read64(rvu, blkaddr, NPA_PRIV_AF_INT_CFG); 205 offs = reg & 0x3FF; 206 207 rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1C, ~0ULL); 208 rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1C, ~0ULL); 209 rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1C, ~0ULL); 210 rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1C, ~0ULL); 211 212 for (i = 0; i < NPA_AF_INT_VEC_CNT; i++) 213 if (rvu->irq_allocated[offs + i]) { 214 free_irq(pci_irq_vector(rvu->pdev, offs + i), rvu_dl); 215 rvu->irq_allocated[offs + i] = false; 216 } 217 } 218 219 static int rvu_npa_register_interrupts(struct rvu *rvu) 220 { 221 int blkaddr, base; 222 bool rc; 223 224 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0); 225 if (blkaddr < 0) 226 return blkaddr; 227 228 /* Get NPA AF MSIX vectors offset. */ 229 base = rvu_read64(rvu, blkaddr, NPA_PRIV_AF_INT_CFG) & 0x3ff; 230 if (!base) { 231 dev_warn(rvu->dev, 232 "Failed to get NPA_AF_INT vector offsets\n"); 233 return 0; 234 } 235 236 /* Register and enable NPA_AF_RVU_INT interrupt */ 237 rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_RVU, 238 "NPA_AF_RVU_INT", 239 rvu_npa_af_rvu_intr_handler); 240 if (!rc) 241 goto err; 242 rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1S, ~0ULL); 243 244 /* Register and enable NPA_AF_GEN_INT interrupt */ 245 rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_GEN, 246 "NPA_AF_RVU_GEN", 247 rvu_npa_af_gen_intr_handler); 248 if (!rc) 249 goto err; 250 rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1S, ~0ULL); 251 252 /* Register and enable NPA_AF_ERR_INT interrupt */ 253 rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_AF_ERR, 254 "NPA_AF_ERR_INT", 255 rvu_npa_af_err_intr_handler); 256 if (!rc) 257 goto err; 258 rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1S, ~0ULL); 259 260 /* Register and enable NPA_AF_RAS interrupt */ 261 rc = rvu_common_request_irq(rvu, base + NPA_AF_INT_VEC_POISON, 262 "NPA_AF_RAS", 263 rvu_npa_af_ras_intr_handler); 264 if (!rc) 265 goto err; 266 rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1S, ~0ULL); 267 268 return 0; 269 err: 270 rvu_npa_unregister_interrupts(rvu); 271 return rc; 272 } 273 274 static int rvu_npa_report_show(struct devlink_fmsg *fmsg, void *ctx, 275 enum npa_af_rvu_health health_reporter) 276 { 277 struct rvu_npa_event_ctx *npa_event_context; 278 unsigned int alloc_dis, free_dis; 279 u64 intr_val; 280 int err; 281 282 npa_event_context = ctx; 283 switch (health_reporter) { 284 case NPA_AF_RVU_GEN: 285 intr_val = npa_event_context->npa_af_rvu_gen; 286 err = rvu_report_pair_start(fmsg, "NPA_AF_GENERAL"); 287 if (err) 288 return err; 289 err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA General Interrupt Reg ", 290 npa_event_context->npa_af_rvu_gen); 291 if (err) 292 return err; 293 if (intr_val & BIT_ULL(32)) { 294 err = devlink_fmsg_string_put(fmsg, "\n\tUnmap PF Error"); 295 if (err) 296 return err; 297 } 298 299 free_dis = FIELD_GET(GENMASK(15, 0), intr_val); 300 if (free_dis & BIT(NPA_INPQ_NIX0_RX)) { 301 err = devlink_fmsg_string_put(fmsg, "\n\tNIX0: free disabled RX"); 302 if (err) 303 return err; 304 } 305 if (free_dis & BIT(NPA_INPQ_NIX0_TX)) { 306 err = devlink_fmsg_string_put(fmsg, "\n\tNIX0:free disabled TX"); 307 if (err) 308 return err; 309 } 310 if (free_dis & BIT(NPA_INPQ_NIX1_RX)) { 311 err = devlink_fmsg_string_put(fmsg, "\n\tNIX1: free disabled RX"); 312 if (err) 313 return err; 314 } 315 if (free_dis & BIT(NPA_INPQ_NIX1_TX)) { 316 err = devlink_fmsg_string_put(fmsg, "\n\tNIX1:free disabled TX"); 317 if (err) 318 return err; 319 } 320 if (free_dis & BIT(NPA_INPQ_SSO)) { 321 err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for SSO"); 322 if (err) 323 return err; 324 } 325 if (free_dis & BIT(NPA_INPQ_TIM)) { 326 err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for TIM"); 327 if (err) 328 return err; 329 } 330 if (free_dis & BIT(NPA_INPQ_DPI)) { 331 err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for DPI"); 332 if (err) 333 return err; 334 } 335 if (free_dis & BIT(NPA_INPQ_AURA_OP)) { 336 err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for AURA"); 337 if (err) 338 return err; 339 } 340 341 alloc_dis = FIELD_GET(GENMASK(31, 16), intr_val); 342 if (alloc_dis & BIT(NPA_INPQ_NIX0_RX)) { 343 err = devlink_fmsg_string_put(fmsg, "\n\tNIX0: alloc disabled RX"); 344 if (err) 345 return err; 346 } 347 if (alloc_dis & BIT(NPA_INPQ_NIX0_TX)) { 348 err = devlink_fmsg_string_put(fmsg, "\n\tNIX0:alloc disabled TX"); 349 if (err) 350 return err; 351 } 352 if (alloc_dis & BIT(NPA_INPQ_NIX1_RX)) { 353 err = devlink_fmsg_string_put(fmsg, "\n\tNIX1: alloc disabled RX"); 354 if (err) 355 return err; 356 } 357 if (alloc_dis & BIT(NPA_INPQ_NIX1_TX)) { 358 err = devlink_fmsg_string_put(fmsg, "\n\tNIX1:alloc disabled TX"); 359 if (err) 360 return err; 361 } 362 if (alloc_dis & BIT(NPA_INPQ_SSO)) { 363 err = devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for SSO"); 364 if (err) 365 return err; 366 } 367 if (alloc_dis & BIT(NPA_INPQ_TIM)) { 368 err = devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for TIM"); 369 if (err) 370 return err; 371 } 372 if (alloc_dis & BIT(NPA_INPQ_DPI)) { 373 err = devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for DPI"); 374 if (err) 375 return err; 376 } 377 if (alloc_dis & BIT(NPA_INPQ_AURA_OP)) { 378 err = devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for AURA"); 379 if (err) 380 return err; 381 } 382 err = rvu_report_pair_end(fmsg); 383 if (err) 384 return err; 385 break; 386 case NPA_AF_RVU_ERR: 387 err = rvu_report_pair_start(fmsg, "NPA_AF_ERR"); 388 if (err) 389 return err; 390 err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA Error Interrupt Reg ", 391 npa_event_context->npa_af_rvu_err); 392 if (err) 393 return err; 394 395 if (npa_event_context->npa_af_rvu_err & BIT_ULL(14)) { 396 err = devlink_fmsg_string_put(fmsg, "\n\tFault on NPA_AQ_INST_S read"); 397 if (err) 398 return err; 399 } 400 if (npa_event_context->npa_af_rvu_err & BIT_ULL(13)) { 401 err = devlink_fmsg_string_put(fmsg, "\n\tFault on NPA_AQ_RES_S write"); 402 if (err) 403 return err; 404 } 405 if (npa_event_context->npa_af_rvu_err & BIT_ULL(12)) { 406 err = devlink_fmsg_string_put(fmsg, "\n\tAQ Doorbell Error"); 407 if (err) 408 return err; 409 } 410 err = rvu_report_pair_end(fmsg); 411 if (err) 412 return err; 413 break; 414 case NPA_AF_RVU_RAS: 415 err = rvu_report_pair_start(fmsg, "NPA_AF_RVU_RAS"); 416 if (err) 417 return err; 418 err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA RAS Interrupt Reg ", 419 npa_event_context->npa_af_rvu_ras); 420 if (err) 421 return err; 422 if (npa_event_context->npa_af_rvu_ras & BIT_ULL(34)) { 423 err = devlink_fmsg_string_put(fmsg, "\n\tPoison data on NPA_AQ_INST_S"); 424 if (err) 425 return err; 426 } 427 if (npa_event_context->npa_af_rvu_ras & BIT_ULL(33)) { 428 err = devlink_fmsg_string_put(fmsg, "\n\tPoison data on NPA_AQ_RES_S"); 429 if (err) 430 return err; 431 } 432 if (npa_event_context->npa_af_rvu_ras & BIT_ULL(32)) { 433 err = devlink_fmsg_string_put(fmsg, "\n\tPoison data on HW context"); 434 if (err) 435 return err; 436 } 437 err = rvu_report_pair_end(fmsg); 438 if (err) 439 return err; 440 break; 441 case NPA_AF_RVU_INTR: 442 err = rvu_report_pair_start(fmsg, "NPA_AF_RVU"); 443 if (err) 444 return err; 445 err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA RVU Interrupt Reg ", 446 npa_event_context->npa_af_rvu_int); 447 if (err) 448 return err; 449 if (npa_event_context->npa_af_rvu_int & BIT_ULL(0)) { 450 err = devlink_fmsg_string_put(fmsg, "\n\tUnmap Slot Error"); 451 if (err) 452 return err; 453 } 454 return rvu_report_pair_end(fmsg); 455 default: 456 return -EINVAL; 457 } 458 459 return 0; 460 } 461 462 static int rvu_hw_npa_intr_dump(struct devlink_health_reporter *reporter, 463 struct devlink_fmsg *fmsg, void *ctx, 464 struct netlink_ext_ack *netlink_extack) 465 { 466 struct rvu *rvu = devlink_health_reporter_priv(reporter); 467 struct rvu_devlink *rvu_dl = rvu->rvu_dl; 468 struct rvu_npa_event_ctx *npa_ctx; 469 470 npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx; 471 472 return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_INTR) : 473 rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_INTR); 474 } 475 476 static int rvu_hw_npa_intr_recover(struct devlink_health_reporter *reporter, 477 void *ctx, struct netlink_ext_ack *netlink_extack) 478 { 479 struct rvu *rvu = devlink_health_reporter_priv(reporter); 480 struct rvu_npa_event_ctx *npa_event_ctx = ctx; 481 int blkaddr; 482 483 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0); 484 if (blkaddr < 0) 485 return blkaddr; 486 487 if (npa_event_ctx->npa_af_rvu_int) 488 rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1S, ~0ULL); 489 490 return 0; 491 } 492 493 static int rvu_hw_npa_gen_dump(struct devlink_health_reporter *reporter, 494 struct devlink_fmsg *fmsg, void *ctx, 495 struct netlink_ext_ack *netlink_extack) 496 { 497 struct rvu *rvu = devlink_health_reporter_priv(reporter); 498 struct rvu_devlink *rvu_dl = rvu->rvu_dl; 499 struct rvu_npa_event_ctx *npa_ctx; 500 501 npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx; 502 503 return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_GEN) : 504 rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_GEN); 505 } 506 507 static int rvu_hw_npa_gen_recover(struct devlink_health_reporter *reporter, 508 void *ctx, struct netlink_ext_ack *netlink_extack) 509 { 510 struct rvu *rvu = devlink_health_reporter_priv(reporter); 511 struct rvu_npa_event_ctx *npa_event_ctx = ctx; 512 int blkaddr; 513 514 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0); 515 if (blkaddr < 0) 516 return blkaddr; 517 518 if (npa_event_ctx->npa_af_rvu_gen) 519 rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1S, ~0ULL); 520 521 return 0; 522 } 523 524 static int rvu_hw_npa_err_dump(struct devlink_health_reporter *reporter, 525 struct devlink_fmsg *fmsg, void *ctx, 526 struct netlink_ext_ack *netlink_extack) 527 { 528 struct rvu *rvu = devlink_health_reporter_priv(reporter); 529 struct rvu_devlink *rvu_dl = rvu->rvu_dl; 530 struct rvu_npa_event_ctx *npa_ctx; 531 532 npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx; 533 534 return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_ERR) : 535 rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_ERR); 536 } 537 538 static int rvu_hw_npa_err_recover(struct devlink_health_reporter *reporter, 539 void *ctx, struct netlink_ext_ack *netlink_extack) 540 { 541 struct rvu *rvu = devlink_health_reporter_priv(reporter); 542 struct rvu_npa_event_ctx *npa_event_ctx = ctx; 543 int blkaddr; 544 545 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0); 546 if (blkaddr < 0) 547 return blkaddr; 548 549 if (npa_event_ctx->npa_af_rvu_err) 550 rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1S, ~0ULL); 551 552 return 0; 553 } 554 555 static int rvu_hw_npa_ras_dump(struct devlink_health_reporter *reporter, 556 struct devlink_fmsg *fmsg, void *ctx, 557 struct netlink_ext_ack *netlink_extack) 558 { 559 struct rvu *rvu = devlink_health_reporter_priv(reporter); 560 struct rvu_devlink *rvu_dl = rvu->rvu_dl; 561 struct rvu_npa_event_ctx *npa_ctx; 562 563 npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx; 564 565 return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_RAS) : 566 rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_RAS); 567 } 568 569 static int rvu_hw_npa_ras_recover(struct devlink_health_reporter *reporter, 570 void *ctx, struct netlink_ext_ack *netlink_extack) 571 { 572 struct rvu *rvu = devlink_health_reporter_priv(reporter); 573 struct rvu_npa_event_ctx *npa_event_ctx = ctx; 574 int blkaddr; 575 576 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0); 577 if (blkaddr < 0) 578 return blkaddr; 579 580 if (npa_event_ctx->npa_af_rvu_ras) 581 rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1S, ~0ULL); 582 583 return 0; 584 } 585 586 RVU_REPORTERS(hw_npa_intr); 587 RVU_REPORTERS(hw_npa_gen); 588 RVU_REPORTERS(hw_npa_err); 589 RVU_REPORTERS(hw_npa_ras); 590 591 static void rvu_npa_health_reporters_destroy(struct rvu_devlink *rvu_dl); 592 593 static int rvu_npa_register_reporters(struct rvu_devlink *rvu_dl) 594 { 595 struct rvu_npa_health_reporters *rvu_reporters; 596 struct rvu_npa_event_ctx *npa_event_context; 597 struct rvu *rvu = rvu_dl->rvu; 598 599 rvu_reporters = kzalloc(sizeof(*rvu_reporters), GFP_KERNEL); 600 if (!rvu_reporters) 601 return -ENOMEM; 602 603 rvu_dl->rvu_npa_health_reporter = rvu_reporters; 604 npa_event_context = kzalloc(sizeof(*npa_event_context), GFP_KERNEL); 605 if (!npa_event_context) 606 return -ENOMEM; 607 608 rvu_reporters->npa_event_ctx = npa_event_context; 609 rvu_reporters->rvu_hw_npa_intr_reporter = 610 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_intr_reporter_ops, 0, rvu); 611 if (IS_ERR(rvu_reporters->rvu_hw_npa_intr_reporter)) { 612 dev_warn(rvu->dev, "Failed to create hw_npa_intr reporter, err=%ld\n", 613 PTR_ERR(rvu_reporters->rvu_hw_npa_intr_reporter)); 614 return PTR_ERR(rvu_reporters->rvu_hw_npa_intr_reporter); 615 } 616 617 rvu_reporters->rvu_hw_npa_gen_reporter = 618 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_gen_reporter_ops, 0, rvu); 619 if (IS_ERR(rvu_reporters->rvu_hw_npa_gen_reporter)) { 620 dev_warn(rvu->dev, "Failed to create hw_npa_gen reporter, err=%ld\n", 621 PTR_ERR(rvu_reporters->rvu_hw_npa_gen_reporter)); 622 return PTR_ERR(rvu_reporters->rvu_hw_npa_gen_reporter); 623 } 624 625 rvu_reporters->rvu_hw_npa_err_reporter = 626 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_err_reporter_ops, 0, rvu); 627 if (IS_ERR(rvu_reporters->rvu_hw_npa_err_reporter)) { 628 dev_warn(rvu->dev, "Failed to create hw_npa_err reporter, err=%ld\n", 629 PTR_ERR(rvu_reporters->rvu_hw_npa_err_reporter)); 630 return PTR_ERR(rvu_reporters->rvu_hw_npa_err_reporter); 631 } 632 633 rvu_reporters->rvu_hw_npa_ras_reporter = 634 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_ras_reporter_ops, 0, rvu); 635 if (IS_ERR(rvu_reporters->rvu_hw_npa_ras_reporter)) { 636 dev_warn(rvu->dev, "Failed to create hw_npa_ras reporter, err=%ld\n", 637 PTR_ERR(rvu_reporters->rvu_hw_npa_ras_reporter)); 638 return PTR_ERR(rvu_reporters->rvu_hw_npa_ras_reporter); 639 } 640 641 rvu_dl->devlink_wq = create_workqueue("rvu_devlink_wq"); 642 if (!rvu_dl->devlink_wq) 643 goto err; 644 645 INIT_WORK(&rvu_reporters->intr_work, rvu_npa_intr_work); 646 INIT_WORK(&rvu_reporters->err_work, rvu_npa_err_work); 647 INIT_WORK(&rvu_reporters->gen_work, rvu_npa_gen_work); 648 INIT_WORK(&rvu_reporters->ras_work, rvu_npa_ras_work); 649 650 return 0; 651 err: 652 rvu_npa_health_reporters_destroy(rvu_dl); 653 return -ENOMEM; 654 } 655 656 static int rvu_npa_health_reporters_create(struct rvu_devlink *rvu_dl) 657 { 658 struct rvu *rvu = rvu_dl->rvu; 659 int err; 660 661 err = rvu_npa_register_reporters(rvu_dl); 662 if (err) { 663 dev_warn(rvu->dev, "Failed to create npa reporter, err =%d\n", 664 err); 665 return err; 666 } 667 rvu_npa_register_interrupts(rvu); 668 669 return 0; 670 } 671 672 static void rvu_npa_health_reporters_destroy(struct rvu_devlink *rvu_dl) 673 { 674 struct rvu_npa_health_reporters *npa_reporters; 675 struct rvu *rvu = rvu_dl->rvu; 676 677 npa_reporters = rvu_dl->rvu_npa_health_reporter; 678 679 if (!npa_reporters->rvu_hw_npa_ras_reporter) 680 return; 681 if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_intr_reporter)) 682 devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_intr_reporter); 683 684 if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_gen_reporter)) 685 devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_gen_reporter); 686 687 if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_err_reporter)) 688 devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_err_reporter); 689 690 if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_ras_reporter)) 691 devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_ras_reporter); 692 693 rvu_npa_unregister_interrupts(rvu); 694 kfree(rvu_dl->rvu_npa_health_reporter->npa_event_ctx); 695 kfree(rvu_dl->rvu_npa_health_reporter); 696 } 697 698 static int rvu_health_reporters_create(struct rvu *rvu) 699 { 700 struct rvu_devlink *rvu_dl; 701 702 rvu_dl = rvu->rvu_dl; 703 return rvu_npa_health_reporters_create(rvu_dl); 704 } 705 706 static void rvu_health_reporters_destroy(struct rvu *rvu) 707 { 708 struct rvu_devlink *rvu_dl; 709 710 if (!rvu->rvu_dl) 711 return; 712 713 rvu_dl = rvu->rvu_dl; 714 rvu_npa_health_reporters_destroy(rvu_dl); 715 } 716 717 static int rvu_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req, 718 struct netlink_ext_ack *extack) 719 { 720 return devlink_info_driver_name_put(req, DRV_NAME); 721 } 722 723 static const struct devlink_ops rvu_devlink_ops = { 724 .info_get = rvu_devlink_info_get, 725 }; 726 727 int rvu_register_dl(struct rvu *rvu) 728 { 729 struct rvu_devlink *rvu_dl; 730 struct devlink *dl; 731 int err; 732 733 rvu_dl = kzalloc(sizeof(*rvu_dl), GFP_KERNEL); 734 if (!rvu_dl) 735 return -ENOMEM; 736 737 dl = devlink_alloc(&rvu_devlink_ops, sizeof(struct rvu_devlink)); 738 if (!dl) { 739 dev_warn(rvu->dev, "devlink_alloc failed\n"); 740 kfree(rvu_dl); 741 return -ENOMEM; 742 } 743 744 err = devlink_register(dl, rvu->dev); 745 if (err) { 746 dev_err(rvu->dev, "devlink register failed with error %d\n", err); 747 devlink_free(dl); 748 kfree(rvu_dl); 749 return err; 750 } 751 752 rvu_dl->dl = dl; 753 rvu_dl->rvu = rvu; 754 rvu->rvu_dl = rvu_dl; 755 756 return rvu_health_reporters_create(rvu); 757 } 758 759 void rvu_unregister_dl(struct rvu *rvu) 760 { 761 struct rvu_devlink *rvu_dl = rvu->rvu_dl; 762 struct devlink *dl = rvu_dl->dl; 763 764 if (!dl) 765 return; 766 767 rvu_health_reporters_destroy(rvu); 768 devlink_unregister(dl); 769 devlink_free(dl); 770 kfree(rvu_dl); 771 } 772