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