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 intr_val, alloc_dis, free_dis; 279 int err; 280 281 npa_event_context = ctx; 282 switch (health_reporter) { 283 case NPA_AF_RVU_GEN: 284 intr_val = npa_event_context->npa_af_rvu_gen; 285 err = rvu_report_pair_start(fmsg, "NPA_AF_GENERAL"); 286 if (err) 287 return err; 288 err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA General Interrupt Reg ", 289 npa_event_context->npa_af_rvu_gen); 290 if (err) 291 return err; 292 if (intr_val & BIT_ULL(32)) { 293 err = devlink_fmsg_string_put(fmsg, "\n\tUnmap PF Error"); 294 if (err) 295 return err; 296 } 297 298 free_dis = FIELD_GET(GENMASK(15, 0), intr_val); 299 if (free_dis & BIT(NPA_INPQ_NIX0_RX)) { 300 err = devlink_fmsg_string_put(fmsg, "\n\tNIX0: free disabled RX"); 301 if (err) 302 return err; 303 } 304 if (free_dis & BIT(NPA_INPQ_NIX0_TX)) { 305 err = devlink_fmsg_string_put(fmsg, "\n\tNIX0:free disabled TX"); 306 if (err) 307 return err; 308 } 309 if (free_dis & BIT(NPA_INPQ_NIX1_RX)) { 310 err = devlink_fmsg_string_put(fmsg, "\n\tNIX1: free disabled RX"); 311 if (err) 312 return err; 313 } 314 if (free_dis & BIT(NPA_INPQ_NIX1_TX)) { 315 err = devlink_fmsg_string_put(fmsg, "\n\tNIX1:free disabled TX"); 316 if (err) 317 return err; 318 } 319 if (free_dis & BIT(NPA_INPQ_SSO)) { 320 err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for SSO"); 321 if (err) 322 return err; 323 } 324 if (free_dis & BIT(NPA_INPQ_TIM)) { 325 err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for TIM"); 326 if (err) 327 return err; 328 } 329 if (free_dis & BIT(NPA_INPQ_DPI)) { 330 err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for DPI"); 331 if (err) 332 return err; 333 } 334 if (free_dis & BIT(NPA_INPQ_AURA_OP)) { 335 err = devlink_fmsg_string_put(fmsg, "\n\tFree Disabled for AURA"); 336 if (err) 337 return err; 338 } 339 340 alloc_dis = FIELD_GET(GENMASK(31, 16), intr_val); 341 if (alloc_dis & BIT(NPA_INPQ_NIX0_RX)) { 342 err = devlink_fmsg_string_put(fmsg, "\n\tNIX0: alloc disabled RX"); 343 if (err) 344 return err; 345 } 346 if (alloc_dis & BIT(NPA_INPQ_NIX0_TX)) { 347 err = devlink_fmsg_string_put(fmsg, "\n\tNIX0:alloc disabled TX"); 348 if (err) 349 return err; 350 } 351 if (alloc_dis & BIT(NPA_INPQ_NIX1_RX)) { 352 err = devlink_fmsg_string_put(fmsg, "\n\tNIX1: alloc disabled RX"); 353 if (err) 354 return err; 355 } 356 if (alloc_dis & BIT(NPA_INPQ_NIX1_TX)) { 357 err = devlink_fmsg_string_put(fmsg, "\n\tNIX1:alloc disabled TX"); 358 if (err) 359 return err; 360 } 361 if (alloc_dis & BIT(NPA_INPQ_SSO)) { 362 err = devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for SSO"); 363 if (err) 364 return err; 365 } 366 if (alloc_dis & BIT(NPA_INPQ_TIM)) { 367 err = devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for TIM"); 368 if (err) 369 return err; 370 } 371 if (alloc_dis & BIT(NPA_INPQ_DPI)) { 372 err = devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for DPI"); 373 if (err) 374 return err; 375 } 376 if (alloc_dis & BIT(NPA_INPQ_AURA_OP)) { 377 err = devlink_fmsg_string_put(fmsg, "\n\tAlloc Disabled for AURA"); 378 if (err) 379 return err; 380 } 381 err = rvu_report_pair_end(fmsg); 382 if (err) 383 return err; 384 break; 385 case NPA_AF_RVU_ERR: 386 err = rvu_report_pair_start(fmsg, "NPA_AF_ERR"); 387 if (err) 388 return err; 389 err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA Error Interrupt Reg ", 390 npa_event_context->npa_af_rvu_err); 391 if (err) 392 return err; 393 394 if (npa_event_context->npa_af_rvu_err & BIT_ULL(14)) { 395 err = devlink_fmsg_string_put(fmsg, "\n\tFault on NPA_AQ_INST_S read"); 396 if (err) 397 return err; 398 } 399 if (npa_event_context->npa_af_rvu_err & BIT_ULL(13)) { 400 err = devlink_fmsg_string_put(fmsg, "\n\tFault on NPA_AQ_RES_S write"); 401 if (err) 402 return err; 403 } 404 if (npa_event_context->npa_af_rvu_err & BIT_ULL(12)) { 405 err = devlink_fmsg_string_put(fmsg, "\n\tAQ Doorbell Error"); 406 if (err) 407 return err; 408 } 409 err = rvu_report_pair_end(fmsg); 410 if (err) 411 return err; 412 break; 413 case NPA_AF_RVU_RAS: 414 err = rvu_report_pair_start(fmsg, "NPA_AF_RVU_RAS"); 415 if (err) 416 return err; 417 err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA RAS Interrupt Reg ", 418 npa_event_context->npa_af_rvu_ras); 419 if (err) 420 return err; 421 if (npa_event_context->npa_af_rvu_ras & BIT_ULL(34)) { 422 err = devlink_fmsg_string_put(fmsg, "\n\tPoison data on NPA_AQ_INST_S"); 423 if (err) 424 return err; 425 } 426 if (npa_event_context->npa_af_rvu_ras & BIT_ULL(33)) { 427 err = devlink_fmsg_string_put(fmsg, "\n\tPoison data on NPA_AQ_RES_S"); 428 if (err) 429 return err; 430 } 431 if (npa_event_context->npa_af_rvu_ras & BIT_ULL(32)) { 432 err = devlink_fmsg_string_put(fmsg, "\n\tPoison data on HW context"); 433 if (err) 434 return err; 435 } 436 err = rvu_report_pair_end(fmsg); 437 if (err) 438 return err; 439 break; 440 case NPA_AF_RVU_INTR: 441 err = rvu_report_pair_start(fmsg, "NPA_AF_RVU"); 442 if (err) 443 return err; 444 err = devlink_fmsg_u64_pair_put(fmsg, "\tNPA RVU Interrupt Reg ", 445 npa_event_context->npa_af_rvu_int); 446 if (err) 447 return err; 448 if (npa_event_context->npa_af_rvu_int & BIT_ULL(0)) { 449 err = devlink_fmsg_string_put(fmsg, "\n\tUnmap Slot Error"); 450 if (err) 451 return err; 452 } 453 return rvu_report_pair_end(fmsg); 454 default: 455 return -EINVAL; 456 } 457 458 return 0; 459 } 460 461 static int rvu_hw_npa_intr_dump(struct devlink_health_reporter *reporter, 462 struct devlink_fmsg *fmsg, void *ctx, 463 struct netlink_ext_ack *netlink_extack) 464 { 465 struct rvu *rvu = devlink_health_reporter_priv(reporter); 466 struct rvu_devlink *rvu_dl = rvu->rvu_dl; 467 struct rvu_npa_event_ctx *npa_ctx; 468 469 npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx; 470 471 return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_INTR) : 472 rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_INTR); 473 } 474 475 static int rvu_hw_npa_intr_recover(struct devlink_health_reporter *reporter, 476 void *ctx, struct netlink_ext_ack *netlink_extack) 477 { 478 struct rvu *rvu = devlink_health_reporter_priv(reporter); 479 struct rvu_npa_event_ctx *npa_event_ctx = ctx; 480 int blkaddr; 481 482 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0); 483 if (blkaddr < 0) 484 return blkaddr; 485 486 if (npa_event_ctx->npa_af_rvu_int) 487 rvu_write64(rvu, blkaddr, NPA_AF_RVU_INT_ENA_W1S, ~0ULL); 488 489 return 0; 490 } 491 492 static int rvu_hw_npa_gen_dump(struct devlink_health_reporter *reporter, 493 struct devlink_fmsg *fmsg, void *ctx, 494 struct netlink_ext_ack *netlink_extack) 495 { 496 struct rvu *rvu = devlink_health_reporter_priv(reporter); 497 struct rvu_devlink *rvu_dl = rvu->rvu_dl; 498 struct rvu_npa_event_ctx *npa_ctx; 499 500 npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx; 501 502 return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_GEN) : 503 rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_GEN); 504 } 505 506 static int rvu_hw_npa_gen_recover(struct devlink_health_reporter *reporter, 507 void *ctx, struct netlink_ext_ack *netlink_extack) 508 { 509 struct rvu *rvu = devlink_health_reporter_priv(reporter); 510 struct rvu_npa_event_ctx *npa_event_ctx = ctx; 511 int blkaddr; 512 513 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0); 514 if (blkaddr < 0) 515 return blkaddr; 516 517 if (npa_event_ctx->npa_af_rvu_gen) 518 rvu_write64(rvu, blkaddr, NPA_AF_GEN_INT_ENA_W1S, ~0ULL); 519 520 return 0; 521 } 522 523 static int rvu_hw_npa_err_dump(struct devlink_health_reporter *reporter, 524 struct devlink_fmsg *fmsg, void *ctx, 525 struct netlink_ext_ack *netlink_extack) 526 { 527 struct rvu *rvu = devlink_health_reporter_priv(reporter); 528 struct rvu_devlink *rvu_dl = rvu->rvu_dl; 529 struct rvu_npa_event_ctx *npa_ctx; 530 531 npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx; 532 533 return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_ERR) : 534 rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_ERR); 535 } 536 537 static int rvu_hw_npa_err_recover(struct devlink_health_reporter *reporter, 538 void *ctx, struct netlink_ext_ack *netlink_extack) 539 { 540 struct rvu *rvu = devlink_health_reporter_priv(reporter); 541 struct rvu_npa_event_ctx *npa_event_ctx = ctx; 542 int blkaddr; 543 544 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0); 545 if (blkaddr < 0) 546 return blkaddr; 547 548 if (npa_event_ctx->npa_af_rvu_err) 549 rvu_write64(rvu, blkaddr, NPA_AF_ERR_INT_ENA_W1S, ~0ULL); 550 551 return 0; 552 } 553 554 static int rvu_hw_npa_ras_dump(struct devlink_health_reporter *reporter, 555 struct devlink_fmsg *fmsg, void *ctx, 556 struct netlink_ext_ack *netlink_extack) 557 { 558 struct rvu *rvu = devlink_health_reporter_priv(reporter); 559 struct rvu_devlink *rvu_dl = rvu->rvu_dl; 560 struct rvu_npa_event_ctx *npa_ctx; 561 562 npa_ctx = rvu_dl->rvu_npa_health_reporter->npa_event_ctx; 563 564 return ctx ? rvu_npa_report_show(fmsg, ctx, NPA_AF_RVU_RAS) : 565 rvu_npa_report_show(fmsg, npa_ctx, NPA_AF_RVU_RAS); 566 } 567 568 static int rvu_hw_npa_ras_recover(struct devlink_health_reporter *reporter, 569 void *ctx, struct netlink_ext_ack *netlink_extack) 570 { 571 struct rvu *rvu = devlink_health_reporter_priv(reporter); 572 struct rvu_npa_event_ctx *npa_event_ctx = ctx; 573 int blkaddr; 574 575 blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPA, 0); 576 if (blkaddr < 0) 577 return blkaddr; 578 579 if (npa_event_ctx->npa_af_rvu_ras) 580 rvu_write64(rvu, blkaddr, NPA_AF_RAS_ENA_W1S, ~0ULL); 581 582 return 0; 583 } 584 585 RVU_REPORTERS(hw_npa_intr); 586 RVU_REPORTERS(hw_npa_gen); 587 RVU_REPORTERS(hw_npa_err); 588 RVU_REPORTERS(hw_npa_ras); 589 590 static void rvu_npa_health_reporters_destroy(struct rvu_devlink *rvu_dl); 591 592 static int rvu_npa_register_reporters(struct rvu_devlink *rvu_dl) 593 { 594 struct rvu_npa_health_reporters *rvu_reporters; 595 struct rvu_npa_event_ctx *npa_event_context; 596 struct rvu *rvu = rvu_dl->rvu; 597 598 rvu_reporters = kzalloc(sizeof(*rvu_reporters), GFP_KERNEL); 599 if (!rvu_reporters) 600 return -ENOMEM; 601 602 rvu_dl->rvu_npa_health_reporter = rvu_reporters; 603 npa_event_context = kzalloc(sizeof(*npa_event_context), GFP_KERNEL); 604 if (!npa_event_context) 605 return -ENOMEM; 606 607 rvu_reporters->npa_event_ctx = npa_event_context; 608 rvu_reporters->rvu_hw_npa_intr_reporter = 609 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_intr_reporter_ops, 0, rvu); 610 if (IS_ERR(rvu_reporters->rvu_hw_npa_intr_reporter)) { 611 dev_warn(rvu->dev, "Failed to create hw_npa_intr reporter, err=%ld\n", 612 PTR_ERR(rvu_reporters->rvu_hw_npa_intr_reporter)); 613 return PTR_ERR(rvu_reporters->rvu_hw_npa_intr_reporter); 614 } 615 616 rvu_reporters->rvu_hw_npa_gen_reporter = 617 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_gen_reporter_ops, 0, rvu); 618 if (IS_ERR(rvu_reporters->rvu_hw_npa_gen_reporter)) { 619 dev_warn(rvu->dev, "Failed to create hw_npa_gen reporter, err=%ld\n", 620 PTR_ERR(rvu_reporters->rvu_hw_npa_gen_reporter)); 621 return PTR_ERR(rvu_reporters->rvu_hw_npa_gen_reporter); 622 } 623 624 rvu_reporters->rvu_hw_npa_err_reporter = 625 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_err_reporter_ops, 0, rvu); 626 if (IS_ERR(rvu_reporters->rvu_hw_npa_err_reporter)) { 627 dev_warn(rvu->dev, "Failed to create hw_npa_err reporter, err=%ld\n", 628 PTR_ERR(rvu_reporters->rvu_hw_npa_err_reporter)); 629 return PTR_ERR(rvu_reporters->rvu_hw_npa_err_reporter); 630 } 631 632 rvu_reporters->rvu_hw_npa_ras_reporter = 633 devlink_health_reporter_create(rvu_dl->dl, &rvu_hw_npa_ras_reporter_ops, 0, rvu); 634 if (IS_ERR(rvu_reporters->rvu_hw_npa_ras_reporter)) { 635 dev_warn(rvu->dev, "Failed to create hw_npa_ras reporter, err=%ld\n", 636 PTR_ERR(rvu_reporters->rvu_hw_npa_ras_reporter)); 637 return PTR_ERR(rvu_reporters->rvu_hw_npa_ras_reporter); 638 } 639 640 rvu_dl->devlink_wq = create_workqueue("rvu_devlink_wq"); 641 if (!rvu_dl->devlink_wq) 642 goto err; 643 644 INIT_WORK(&rvu_reporters->intr_work, rvu_npa_intr_work); 645 INIT_WORK(&rvu_reporters->err_work, rvu_npa_err_work); 646 INIT_WORK(&rvu_reporters->gen_work, rvu_npa_gen_work); 647 INIT_WORK(&rvu_reporters->ras_work, rvu_npa_ras_work); 648 649 return 0; 650 err: 651 rvu_npa_health_reporters_destroy(rvu_dl); 652 return -ENOMEM; 653 } 654 655 static int rvu_npa_health_reporters_create(struct rvu_devlink *rvu_dl) 656 { 657 struct rvu *rvu = rvu_dl->rvu; 658 int err; 659 660 err = rvu_npa_register_reporters(rvu_dl); 661 if (err) { 662 dev_warn(rvu->dev, "Failed to create npa reporter, err =%d\n", 663 err); 664 return err; 665 } 666 rvu_npa_register_interrupts(rvu); 667 668 return 0; 669 } 670 671 static void rvu_npa_health_reporters_destroy(struct rvu_devlink *rvu_dl) 672 { 673 struct rvu_npa_health_reporters *npa_reporters; 674 struct rvu *rvu = rvu_dl->rvu; 675 676 npa_reporters = rvu_dl->rvu_npa_health_reporter; 677 678 if (!npa_reporters->rvu_hw_npa_ras_reporter) 679 return; 680 if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_intr_reporter)) 681 devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_intr_reporter); 682 683 if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_gen_reporter)) 684 devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_gen_reporter); 685 686 if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_err_reporter)) 687 devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_err_reporter); 688 689 if (!IS_ERR_OR_NULL(npa_reporters->rvu_hw_npa_ras_reporter)) 690 devlink_health_reporter_destroy(npa_reporters->rvu_hw_npa_ras_reporter); 691 692 rvu_npa_unregister_interrupts(rvu); 693 kfree(rvu_dl->rvu_npa_health_reporter->npa_event_ctx); 694 kfree(rvu_dl->rvu_npa_health_reporter); 695 } 696 697 static int rvu_health_reporters_create(struct rvu *rvu) 698 { 699 struct rvu_devlink *rvu_dl; 700 701 rvu_dl = rvu->rvu_dl; 702 return rvu_npa_health_reporters_create(rvu_dl); 703 } 704 705 static void rvu_health_reporters_destroy(struct rvu *rvu) 706 { 707 struct rvu_devlink *rvu_dl; 708 709 if (!rvu->rvu_dl) 710 return; 711 712 rvu_dl = rvu->rvu_dl; 713 rvu_npa_health_reporters_destroy(rvu_dl); 714 } 715 716 static int rvu_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req, 717 struct netlink_ext_ack *extack) 718 { 719 return devlink_info_driver_name_put(req, DRV_NAME); 720 } 721 722 static const struct devlink_ops rvu_devlink_ops = { 723 .info_get = rvu_devlink_info_get, 724 }; 725 726 int rvu_register_dl(struct rvu *rvu) 727 { 728 struct rvu_devlink *rvu_dl; 729 struct devlink *dl; 730 int err; 731 732 rvu_dl = kzalloc(sizeof(*rvu_dl), GFP_KERNEL); 733 if (!rvu_dl) 734 return -ENOMEM; 735 736 dl = devlink_alloc(&rvu_devlink_ops, sizeof(struct rvu_devlink)); 737 if (!dl) { 738 dev_warn(rvu->dev, "devlink_alloc failed\n"); 739 kfree(rvu_dl); 740 return -ENOMEM; 741 } 742 743 err = devlink_register(dl, rvu->dev); 744 if (err) { 745 dev_err(rvu->dev, "devlink register failed with error %d\n", err); 746 devlink_free(dl); 747 kfree(rvu_dl); 748 return err; 749 } 750 751 rvu_dl->dl = dl; 752 rvu_dl->rvu = rvu; 753 rvu->rvu_dl = rvu_dl; 754 755 return rvu_health_reporters_create(rvu); 756 } 757 758 void rvu_unregister_dl(struct rvu *rvu) 759 { 760 struct rvu_devlink *rvu_dl = rvu->rvu_dl; 761 struct devlink *dl = rvu_dl->dl; 762 763 if (!dl) 764 return; 765 766 rvu_health_reporters_destroy(rvu); 767 devlink_unregister(dl); 768 devlink_free(dl); 769 kfree(rvu_dl); 770 } 771