1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright © 2021-2022 Dmitry Salychev 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 /* 30 * The DPAA2 Resource Container (DPRC) bus driver. 31 * 32 * DPRC holds all the resources and object information that a software context 33 * (kernel, virtual machine, etc.) can access or use. 34 */ 35 36 #include <sys/param.h> 37 #include <sys/kernel.h> 38 #include <sys/bus.h> 39 #include <sys/rman.h> 40 #include <sys/module.h> 41 #include <sys/malloc.h> 42 #include <sys/mutex.h> 43 #include <sys/condvar.h> 44 #include <sys/lock.h> 45 #include <sys/time.h> 46 #include <sys/types.h> 47 #include <sys/systm.h> 48 #include <sys/smp.h> 49 50 #include <machine/bus.h> 51 #include <machine/resource.h> 52 53 #include "pcib_if.h" 54 #include "pci_if.h" 55 56 #include "dpaa2_mcp.h" 57 #include "dpaa2_mc.h" 58 #include "dpaa2_ni.h" 59 #include "dpaa2_mc_if.h" 60 #include "dpaa2_cmd_if.h" 61 62 /* Timeouts to wait for a command response from MC. */ 63 #define CMD_SPIN_TIMEOUT 100u /* us */ 64 #define CMD_SPIN_ATTEMPTS 2000u /* max. 200 ms */ 65 66 #define TYPE_LEN_MAX 16u 67 #define LABEL_LEN_MAX 16u 68 69 MALLOC_DEFINE(M_DPAA2_RC, "dpaa2_rc", "DPAA2 Resource Container"); 70 71 /* Discover and add devices to the resource container. */ 72 static int dpaa2_rc_discover(struct dpaa2_rc_softc *); 73 static int dpaa2_rc_add_child(struct dpaa2_rc_softc *, struct dpaa2_cmd *, 74 struct dpaa2_obj *); 75 static int dpaa2_rc_add_managed_child(struct dpaa2_rc_softc *, 76 struct dpaa2_cmd *, struct dpaa2_obj *); 77 78 /* Helper routines. */ 79 static int dpaa2_rc_enable_irq(struct dpaa2_mcp *, struct dpaa2_cmd *, uint8_t, 80 bool, uint16_t); 81 static int dpaa2_rc_configure_irq(device_t, device_t, int, uint64_t, uint32_t); 82 static int dpaa2_rc_add_res(device_t, device_t, enum dpaa2_dev_type, int *, int); 83 static int dpaa2_rc_print_type(struct resource_list *, enum dpaa2_dev_type); 84 static struct dpaa2_mcp *dpaa2_rc_select_portal(device_t, device_t); 85 86 /* Routines to send commands to MC. */ 87 static int dpaa2_rc_exec_cmd(struct dpaa2_mcp *, struct dpaa2_cmd *, uint16_t); 88 static int dpaa2_rc_send_cmd(struct dpaa2_mcp *, struct dpaa2_cmd *); 89 static int dpaa2_rc_wait_for_cmd(struct dpaa2_mcp *, struct dpaa2_cmd *); 90 static int dpaa2_rc_reset_cmd_params(struct dpaa2_cmd *); 91 92 static int 93 dpaa2_rc_probe(device_t dev) 94 { 95 /* DPRC device will be added by the parent DPRC or MC bus itself. */ 96 device_set_desc(dev, "DPAA2 Resource Container"); 97 return (BUS_PROBE_DEFAULT); 98 } 99 100 static int 101 dpaa2_rc_detach(device_t dev) 102 { 103 struct dpaa2_devinfo *dinfo; 104 int error; 105 106 error = bus_generic_detach(dev); 107 if (error) 108 return (error); 109 110 dinfo = device_get_ivars(dev); 111 112 if (dinfo->portal) 113 dpaa2_mcp_free_portal(dinfo->portal); 114 if (dinfo) 115 free(dinfo, M_DPAA2_RC); 116 117 return (device_delete_children(dev)); 118 } 119 120 static int 121 dpaa2_rc_attach(device_t dev) 122 { 123 device_t pdev; 124 struct dpaa2_mc_softc *mcsc; 125 struct dpaa2_rc_softc *sc; 126 struct dpaa2_devinfo *dinfo = NULL; 127 int error; 128 129 sc = device_get_softc(dev); 130 sc->dev = dev; 131 sc->unit = device_get_unit(dev); 132 133 if (sc->unit == 0) { 134 /* Root DPRC should be attached directly to the MC bus. */ 135 pdev = device_get_parent(dev); 136 mcsc = device_get_softc(pdev); 137 138 KASSERT(strcmp(device_get_name(pdev), "dpaa2_mc") == 0, 139 ("root DPRC should be attached to the MC bus")); 140 141 /* 142 * Allocate devinfo to let the parent MC bus access ICID of the 143 * DPRC object. 144 */ 145 dinfo = malloc(sizeof(struct dpaa2_devinfo), M_DPAA2_RC, 146 M_WAITOK | M_ZERO); 147 if (!dinfo) { 148 device_printf(dev, "%s: failed to allocate " 149 "dpaa2_devinfo\n", __func__); 150 dpaa2_rc_detach(dev); 151 return (ENXIO); 152 } 153 device_set_ivars(dev, dinfo); 154 155 dinfo->pdev = pdev; 156 dinfo->dev = dev; 157 dinfo->dtype = DPAA2_DEV_RC; 158 dinfo->portal = NULL; 159 160 /* Prepare helper portal object to send commands to MC. */ 161 error = dpaa2_mcp_init_portal(&dinfo->portal, mcsc->res[0], 162 &mcsc->map[0], DPAA2_PORTAL_DEF); 163 if (error) { 164 device_printf(dev, "%s: failed to initialize dpaa2_mcp: " 165 "error=%d\n", __func__, error); 166 dpaa2_rc_detach(dev); 167 return (ENXIO); 168 } 169 } else { 170 /* TODO: Child DPRCs aren't supported yet. */ 171 return (ENXIO); 172 } 173 174 /* Create DPAA2 devices for objects in this container. */ 175 error = dpaa2_rc_discover(sc); 176 if (error) { 177 device_printf(dev, "%s: failed to discover objects in " 178 "container: error=%d\n", __func__, error); 179 dpaa2_rc_detach(dev); 180 return (error); 181 } 182 183 return (0); 184 } 185 186 /* 187 * Bus interface. 188 */ 189 190 static struct resource_list * 191 dpaa2_rc_get_resource_list(device_t rcdev, device_t child) 192 { 193 struct dpaa2_devinfo *dinfo = device_get_ivars(child); 194 195 return (&dinfo->resources); 196 } 197 198 static void 199 dpaa2_rc_delete_resource(device_t rcdev, device_t child, int type, int rid) 200 { 201 struct resource_list *rl; 202 struct resource_list_entry *rle; 203 struct dpaa2_devinfo *dinfo; 204 205 if (device_get_parent(child) != rcdev) 206 return; 207 208 dinfo = device_get_ivars(child); 209 rl = &dinfo->resources; 210 rle = resource_list_find(rl, type, rid); 211 if (rle == NULL) 212 return; 213 214 if (rle->res) { 215 if (rman_get_flags(rle->res) & RF_ACTIVE || 216 resource_list_busy(rl, type, rid)) { 217 device_printf(rcdev, "%s: resource still owned by " 218 "child: type=%d, rid=%d, start=%jx\n", __func__, 219 type, rid, rman_get_start(rle->res)); 220 return; 221 } 222 resource_list_unreserve(rl, rcdev, child, type, rid); 223 } 224 resource_list_delete(rl, type, rid); 225 } 226 227 static struct resource * 228 dpaa2_rc_alloc_multi_resource(device_t rcdev, device_t child, int type, int *rid, 229 rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) 230 { 231 struct resource_list *rl; 232 struct dpaa2_devinfo *dinfo; 233 234 dinfo = device_get_ivars(child); 235 rl = &dinfo->resources; 236 237 /* 238 * By default, software portal interrupts are message-based, that is, 239 * they are issued from QMan using a 4 byte write. 240 * 241 * TODO: However this default behavior can be changed by programming one 242 * or more software portals to issue their interrupts via a 243 * dedicated software portal interrupt wire. 244 * See registers SWP_INTW0_CFG to SWP_INTW3_CFG for details. 245 */ 246 if (type == SYS_RES_IRQ && *rid == 0) 247 return (NULL); 248 249 return (resource_list_alloc(rl, rcdev, child, type, rid, 250 start, end, count, flags)); 251 } 252 253 static struct resource * 254 dpaa2_rc_alloc_resource(device_t rcdev, device_t child, int type, int *rid, 255 rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) 256 { 257 if (device_get_parent(child) != rcdev) 258 return (BUS_ALLOC_RESOURCE(device_get_parent(rcdev), child, 259 type, rid, start, end, count, flags)); 260 261 return (dpaa2_rc_alloc_multi_resource(rcdev, child, type, rid, start, 262 end, count, flags)); 263 } 264 265 static int 266 dpaa2_rc_release_resource(device_t rcdev, device_t child, struct resource *r) 267 { 268 struct resource_list *rl; 269 struct dpaa2_devinfo *dinfo; 270 271 if (device_get_parent(child) != rcdev) 272 return (BUS_RELEASE_RESOURCE(device_get_parent(rcdev), child, 273 r)); 274 275 dinfo = device_get_ivars(child); 276 rl = &dinfo->resources; 277 return (resource_list_release(rl, rcdev, child, r)); 278 } 279 280 static void 281 dpaa2_rc_child_deleted(device_t rcdev, device_t child) 282 { 283 struct dpaa2_devinfo *dinfo; 284 struct resource_list *rl; 285 struct resource_list_entry *rle; 286 287 dinfo = device_get_ivars(child); 288 rl = &dinfo->resources; 289 290 /* Free all allocated resources */ 291 STAILQ_FOREACH(rle, rl, link) { 292 if (rle->res) { 293 if (rman_get_flags(rle->res) & RF_ACTIVE || 294 resource_list_busy(rl, rle->type, rle->rid)) { 295 device_printf(child, "%s: resource still owned: " 296 "type=%d, rid=%d, addr=%lx\n", __func__, 297 rle->type, rle->rid, 298 rman_get_start(rle->res)); 299 bus_release_resource(child, rle->type, rle->rid, 300 rle->res); 301 } 302 resource_list_unreserve(rl, rcdev, child, rle->type, 303 rle->rid); 304 } 305 } 306 resource_list_free(rl); 307 308 if (dinfo) 309 free(dinfo, M_DPAA2_RC); 310 } 311 312 static void 313 dpaa2_rc_child_detached(device_t rcdev, device_t child) 314 { 315 struct dpaa2_devinfo *dinfo; 316 struct resource_list *rl; 317 318 dinfo = device_get_ivars(child); 319 rl = &dinfo->resources; 320 321 if (resource_list_release_active(rl, rcdev, child, SYS_RES_IRQ) != 0) 322 device_printf(child, "%s: leaked IRQ resources!\n", __func__); 323 if (dinfo->msi.msi_alloc != 0) { 324 device_printf(child, "%s: leaked %d MSI vectors!\n", __func__, 325 dinfo->msi.msi_alloc); 326 PCI_RELEASE_MSI(rcdev, child); 327 } 328 if (resource_list_release_active(rl, rcdev, child, SYS_RES_MEMORY) != 0) 329 device_printf(child, "%s: leaked memory resources!\n", __func__); 330 } 331 332 static int 333 dpaa2_rc_setup_intr(device_t rcdev, device_t child, struct resource *irq, 334 int flags, driver_filter_t *filter, driver_intr_t *intr, void *arg, 335 void **cookiep) 336 { 337 struct dpaa2_devinfo *dinfo; 338 uint64_t addr; 339 uint32_t data; 340 void *cookie; 341 int error, rid; 342 343 error = bus_generic_setup_intr(rcdev, child, irq, flags, filter, intr, 344 arg, &cookie); 345 if (error) { 346 device_printf(rcdev, "%s: bus_generic_setup_intr() failed: " 347 "error=%d\n", __func__, error); 348 return (error); 349 } 350 351 /* If this is not a direct child, just bail out. */ 352 if (device_get_parent(child) != rcdev) { 353 *cookiep = cookie; 354 return (0); 355 } 356 357 rid = rman_get_rid(irq); 358 if (rid == 0) { 359 if (bootverbose) 360 device_printf(rcdev, "%s: cannot setup interrupt with " 361 "rid=0: INTx are not supported by DPAA2 objects " 362 "yet\n", __func__); 363 return (EINVAL); 364 } else { 365 dinfo = device_get_ivars(child); 366 KASSERT(dinfo->msi.msi_alloc > 0, 367 ("No MSI interrupts allocated")); 368 369 /* 370 * Ask our parent to map the MSI and give us the address and 371 * data register values. If we fail for some reason, teardown 372 * the interrupt handler. 373 */ 374 error = PCIB_MAP_MSI(device_get_parent(rcdev), child, 375 rman_get_start(irq), &addr, &data); 376 if (error) { 377 device_printf(rcdev, "%s: PCIB_MAP_MSI failed: " 378 "error=%d\n", __func__, error); 379 (void)bus_generic_teardown_intr(rcdev, child, irq, 380 cookie); 381 return (error); 382 } 383 384 /* Configure MSI for this DPAA2 object. */ 385 error = dpaa2_rc_configure_irq(rcdev, child, rid, addr, data); 386 if (error) { 387 device_printf(rcdev, "%s: failed to configure IRQ for " 388 "DPAA2 object: rid=%d, type=%s, unit=%d\n", __func__, 389 rid, dpaa2_ttos(dinfo->dtype), 390 device_get_unit(child)); 391 return (error); 392 } 393 dinfo->msi.msi_handlers++; 394 } 395 *cookiep = cookie; 396 return (0); 397 } 398 399 static int 400 dpaa2_rc_teardown_intr(device_t rcdev, device_t child, struct resource *irq, 401 void *cookie) 402 { 403 struct resource_list_entry *rle; 404 struct dpaa2_devinfo *dinfo; 405 int error, rid; 406 407 if (irq == NULL || !(rman_get_flags(irq) & RF_ACTIVE)) 408 return (EINVAL); 409 410 /* If this isn't a direct child, just bail out */ 411 if (device_get_parent(child) != rcdev) 412 return(bus_generic_teardown_intr(rcdev, child, irq, cookie)); 413 414 rid = rman_get_rid(irq); 415 if (rid == 0) { 416 if (bootverbose) 417 device_printf(rcdev, "%s: cannot teardown interrupt " 418 "with rid=0: INTx are not supported by DPAA2 " 419 "objects yet\n", __func__); 420 return (EINVAL); 421 } else { 422 dinfo = device_get_ivars(child); 423 rle = resource_list_find(&dinfo->resources, SYS_RES_IRQ, rid); 424 if (rle->res != irq) 425 return (EINVAL); 426 dinfo->msi.msi_handlers--; 427 } 428 429 error = bus_generic_teardown_intr(rcdev, child, irq, cookie); 430 if (rid > 0) 431 KASSERT(error == 0, 432 ("%s: generic teardown failed for MSI", __func__)); 433 return (error); 434 } 435 436 static int 437 dpaa2_rc_print_child(device_t rcdev, device_t child) 438 { 439 struct dpaa2_devinfo *dinfo = device_get_ivars(child); 440 struct resource_list *rl = &dinfo->resources; 441 int retval = 0; 442 443 retval += bus_print_child_header(rcdev, child); 444 445 retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#jx"); 446 retval += resource_list_print_type(rl, "iomem", SYS_RES_MEMORY, "%#jx"); 447 retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%jd"); 448 449 /* Print DPAA2-specific resources. */ 450 retval += dpaa2_rc_print_type(rl, DPAA2_DEV_IO); 451 retval += dpaa2_rc_print_type(rl, DPAA2_DEV_BP); 452 retval += dpaa2_rc_print_type(rl, DPAA2_DEV_CON); 453 retval += dpaa2_rc_print_type(rl, DPAA2_DEV_MCP); 454 455 retval += printf(" at %s (id=%u)", dpaa2_ttos(dinfo->dtype), dinfo->id); 456 457 retval += bus_print_child_domain(rcdev, child); 458 retval += bus_print_child_footer(rcdev, child); 459 460 return (retval); 461 } 462 463 /* 464 * Pseudo-PCI interface. 465 */ 466 467 /* 468 * Attempt to allocate *count MSI messages. The actual number allocated is 469 * returned in *count. After this function returns, each message will be 470 * available to the driver as SYS_RES_IRQ resources starting at a rid 1. 471 * 472 * NOTE: Implementation is similar to sys/dev/pci/pci.c. 473 */ 474 static int 475 dpaa2_rc_alloc_msi(device_t rcdev, device_t child, int *count) 476 { 477 struct dpaa2_devinfo *rcinfo = device_get_ivars(rcdev); 478 struct dpaa2_devinfo *dinfo = device_get_ivars(child); 479 int error, actual, i, run, irqs[32]; 480 481 /* Don't let count == 0 get us into trouble. */ 482 if (*count == 0) 483 return (EINVAL); 484 485 /* MSI should be allocated by the resource container. */ 486 if (rcinfo->dtype != DPAA2_DEV_RC) 487 return (ENODEV); 488 489 /* Already have allocated messages? */ 490 if (dinfo->msi.msi_alloc != 0) 491 return (ENXIO); 492 493 /* Don't ask for more than the device supports. */ 494 actual = min(*count, dinfo->msi.msi_msgnum); 495 496 /* Don't ask for more than 32 messages. */ 497 actual = min(actual, 32); 498 499 /* MSI requires power of 2 number of messages. */ 500 if (!powerof2(actual)) 501 return (EINVAL); 502 503 for (;;) { 504 /* Try to allocate N messages. */ 505 error = PCIB_ALLOC_MSI(device_get_parent(rcdev), child, actual, 506 actual, irqs); 507 if (error == 0) 508 break; 509 if (actual == 1) 510 return (error); 511 512 /* Try N / 2. */ 513 actual >>= 1; 514 } 515 516 /* 517 * We now have N actual messages mapped onto SYS_RES_IRQ resources in 518 * the irqs[] array, so add new resources starting at rid 1. 519 */ 520 for (i = 0; i < actual; i++) 521 resource_list_add(&dinfo->resources, SYS_RES_IRQ, i + 1, 522 irqs[i], irqs[i], 1); 523 524 if (bootverbose) { 525 if (actual == 1) { 526 device_printf(child, "using IRQ %d for MSI\n", irqs[0]); 527 } else { 528 /* 529 * Be fancy and try to print contiguous runs 530 * of IRQ values as ranges. 'run' is true if 531 * we are in a range. 532 */ 533 device_printf(child, "using IRQs %d", irqs[0]); 534 run = 0; 535 for (i = 1; i < actual; i++) { 536 /* Still in a run? */ 537 if (irqs[i] == irqs[i - 1] + 1) { 538 run = 1; 539 continue; 540 } 541 542 /* Finish previous range. */ 543 if (run) { 544 printf("-%d", irqs[i - 1]); 545 run = 0; 546 } 547 548 /* Start new range. */ 549 printf(",%d", irqs[i]); 550 } 551 552 /* Unfinished range? */ 553 if (run) 554 printf("-%d", irqs[actual - 1]); 555 printf(" for MSI\n"); 556 } 557 } 558 559 /* Update counts of alloc'd messages. */ 560 dinfo->msi.msi_alloc = actual; 561 dinfo->msi.msi_handlers = 0; 562 *count = actual; 563 return (0); 564 } 565 566 /* 567 * Release the MSI messages associated with this DPAA2 device. 568 * 569 * NOTE: Implementation is similar to sys/dev/pci/pci.c. 570 */ 571 static int 572 dpaa2_rc_release_msi(device_t rcdev, device_t child) 573 { 574 struct dpaa2_devinfo *rcinfo = device_get_ivars(rcdev); 575 struct dpaa2_devinfo *dinfo = device_get_ivars(child); 576 struct resource_list_entry *rle; 577 int i, irqs[32]; 578 579 /* MSI should be released by the resource container. */ 580 if (rcinfo->dtype != DPAA2_DEV_RC) 581 return (ENODEV); 582 583 /* Do we have any messages to release? */ 584 if (dinfo->msi.msi_alloc == 0) 585 return (ENODEV); 586 KASSERT(dinfo->msi.msi_alloc <= 32, 587 ("more than 32 alloc'd MSI messages")); 588 589 /* Make sure none of the resources are allocated. */ 590 if (dinfo->msi.msi_handlers > 0) 591 return (EBUSY); 592 for (i = 0; i < dinfo->msi.msi_alloc; i++) { 593 rle = resource_list_find(&dinfo->resources, SYS_RES_IRQ, i + 1); 594 KASSERT(rle != NULL, ("missing MSI resource")); 595 if (rle->res != NULL) 596 return (EBUSY); 597 irqs[i] = rle->start; 598 } 599 600 /* Release the messages. */ 601 PCIB_RELEASE_MSI(device_get_parent(rcdev), child, dinfo->msi.msi_alloc, 602 irqs); 603 for (i = 0; i < dinfo->msi.msi_alloc; i++) 604 resource_list_delete(&dinfo->resources, SYS_RES_IRQ, i + 1); 605 606 /* Update alloc count. */ 607 dinfo->msi.msi_alloc = 0; 608 return (0); 609 } 610 611 /** 612 * @brief Return the maximum number of the MSI supported by this DPAA2 device. 613 */ 614 static int 615 dpaa2_rc_msi_count(device_t rcdev, device_t child) 616 { 617 struct dpaa2_devinfo *dinfo = device_get_ivars(child); 618 619 return (dinfo->msi.msi_msgnum); 620 } 621 622 static int 623 dpaa2_rc_get_id(device_t rcdev, device_t child, enum pci_id_type type, 624 uintptr_t *id) 625 { 626 struct dpaa2_devinfo *rcinfo = device_get_ivars(rcdev); 627 628 if (rcinfo->dtype != DPAA2_DEV_RC) 629 return (ENODEV); 630 631 return (PCIB_GET_ID(device_get_parent(rcdev), child, type, id)); 632 } 633 634 /* 635 * DPAA2 MC command interface. 636 */ 637 638 static int 639 dpaa2_rc_mng_get_version(device_t dev, device_t child, struct dpaa2_cmd *cmd, 640 uint32_t *major, uint32_t *minor, uint32_t *rev) 641 { 642 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 643 int error; 644 645 if (portal == NULL || cmd == NULL || major == NULL || minor == NULL || 646 rev == NULL) 647 return (DPAA2_CMD_STAT_ERR); 648 649 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_MNG_GET_VER); 650 if (!error) { 651 *major = cmd->params[0] >> 32; 652 *minor = cmd->params[1] & 0xFFFFFFFF; 653 *rev = cmd->params[0] & 0xFFFFFFFF; 654 } 655 656 return (error); 657 } 658 659 static int 660 dpaa2_rc_mng_get_soc_version(device_t dev, device_t child, struct dpaa2_cmd *cmd, 661 uint32_t *pvr, uint32_t *svr) 662 { 663 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 664 int error; 665 666 if (portal == NULL || cmd == NULL || pvr == NULL || svr == NULL) 667 return (DPAA2_CMD_STAT_ERR); 668 669 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_MNG_GET_SOC_VER); 670 if (!error) { 671 *pvr = cmd->params[0] >> 32; 672 *svr = cmd->params[0] & 0xFFFFFFFF; 673 } 674 675 return (error); 676 } 677 678 static int 679 dpaa2_rc_mng_get_container_id(device_t dev, device_t child, 680 struct dpaa2_cmd *cmd, uint32_t *cont_id) 681 { 682 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 683 int error; 684 685 if (portal == NULL || cmd == NULL || cont_id == NULL) 686 return (DPAA2_CMD_STAT_ERR); 687 688 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_MNG_GET_CONT_ID); 689 if (!error) 690 *cont_id = cmd->params[0] & 0xFFFFFFFF; 691 692 return (error); 693 } 694 695 static int 696 dpaa2_rc_open(device_t dev, device_t child, struct dpaa2_cmd *cmd, 697 uint32_t cont_id, uint16_t *token) 698 { 699 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 700 struct dpaa2_cmd_header *hdr; 701 int error; 702 703 if (portal == NULL || cmd == NULL || token == NULL) 704 return (DPAA2_CMD_STAT_ERR); 705 706 cmd->params[0] = cont_id; 707 708 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_RC_OPEN); 709 if (!error) { 710 hdr = (struct dpaa2_cmd_header *) &cmd->header; 711 *token = hdr->token; 712 } 713 714 return (error); 715 } 716 717 static int 718 dpaa2_rc_close(device_t dev, device_t child, struct dpaa2_cmd *cmd) 719 { 720 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 721 722 if (portal == NULL || cmd == NULL) 723 return (DPAA2_CMD_STAT_ERR); 724 725 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_RC_CLOSE)); 726 } 727 728 static int 729 dpaa2_rc_get_obj_count(device_t dev, device_t child, struct dpaa2_cmd *cmd, 730 uint32_t *obj_count) 731 { 732 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 733 int error; 734 735 if (portal == NULL || cmd == NULL || obj_count == NULL) 736 return (DPAA2_CMD_STAT_ERR); 737 738 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_RC_GET_OBJ_COUNT); 739 if (!error) 740 *obj_count = (uint32_t)(cmd->params[0] >> 32); 741 742 return (error); 743 } 744 745 static int 746 dpaa2_rc_get_obj(device_t dev, device_t child, struct dpaa2_cmd *cmd, 747 uint32_t obj_idx, struct dpaa2_obj *obj) 748 { 749 struct __packed dpaa2_obj_resp { 750 uint32_t _reserved1; 751 uint32_t id; 752 uint16_t vendor; 753 uint8_t irq_count; 754 uint8_t reg_count; 755 uint32_t state; 756 uint16_t ver_major; 757 uint16_t ver_minor; 758 uint16_t flags; 759 uint16_t _reserved2; 760 uint8_t type[16]; 761 uint8_t label[16]; 762 } *pobj; 763 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 764 int error; 765 766 if (portal == NULL || cmd == NULL || obj == NULL) 767 return (DPAA2_CMD_STAT_ERR); 768 769 cmd->params[0] = obj_idx; 770 771 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_RC_GET_OBJ); 772 if (!error) { 773 pobj = (struct dpaa2_obj_resp *) &cmd->params[0]; 774 obj->id = pobj->id; 775 obj->vendor = pobj->vendor; 776 obj->irq_count = pobj->irq_count; 777 obj->reg_count = pobj->reg_count; 778 obj->state = pobj->state; 779 obj->ver_major = pobj->ver_major; 780 obj->ver_minor = pobj->ver_minor; 781 obj->flags = pobj->flags; 782 obj->type = dpaa2_stot((const char *) pobj->type); 783 memcpy(obj->label, pobj->label, sizeof(pobj->label)); 784 } 785 786 /* Some DPAA2 objects might not be supported by the driver yet. */ 787 if (obj->type == DPAA2_DEV_NOTYPE) 788 error = DPAA2_CMD_STAT_UNKNOWN_OBJ; 789 790 return (error); 791 } 792 793 static int 794 dpaa2_rc_get_obj_descriptor(device_t dev, device_t child, 795 struct dpaa2_cmd *cmd, uint32_t obj_id, enum dpaa2_dev_type dtype, 796 struct dpaa2_obj *obj) 797 { 798 struct __packed get_obj_desc_args { 799 uint32_t obj_id; 800 uint32_t _reserved1; 801 uint8_t type[16]; 802 } *args; 803 struct __packed dpaa2_obj_resp { 804 uint32_t _reserved1; 805 uint32_t id; 806 uint16_t vendor; 807 uint8_t irq_count; 808 uint8_t reg_count; 809 uint32_t state; 810 uint16_t ver_major; 811 uint16_t ver_minor; 812 uint16_t flags; 813 uint16_t _reserved2; 814 uint8_t type[16]; 815 uint8_t label[16]; 816 } *pobj; 817 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 818 const char *type = dpaa2_ttos(dtype); 819 int error; 820 821 if (portal == NULL || cmd == NULL || obj == NULL) 822 return (DPAA2_CMD_STAT_ERR); 823 824 args = (struct get_obj_desc_args *) &cmd->params[0]; 825 args->obj_id = obj_id; 826 memcpy(args->type, type, min(strlen(type) + 1, TYPE_LEN_MAX)); 827 828 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_RC_GET_OBJ_DESC); 829 if (!error) { 830 pobj = (struct dpaa2_obj_resp *) &cmd->params[0]; 831 obj->id = pobj->id; 832 obj->vendor = pobj->vendor; 833 obj->irq_count = pobj->irq_count; 834 obj->reg_count = pobj->reg_count; 835 obj->state = pobj->state; 836 obj->ver_major = pobj->ver_major; 837 obj->ver_minor = pobj->ver_minor; 838 obj->flags = pobj->flags; 839 obj->type = dpaa2_stot((const char *) pobj->type); 840 memcpy(obj->label, pobj->label, sizeof(pobj->label)); 841 } 842 843 /* Some DPAA2 objects might not be supported by the driver yet. */ 844 if (obj->type == DPAA2_DEV_NOTYPE) 845 error = DPAA2_CMD_STAT_UNKNOWN_OBJ; 846 847 return (error); 848 } 849 850 static int 851 dpaa2_rc_get_attributes(device_t dev, device_t child, struct dpaa2_cmd *cmd, 852 struct dpaa2_rc_attr *attr) 853 { 854 struct __packed dpaa2_rc_attr { 855 uint32_t cont_id; 856 uint32_t icid; 857 uint32_t options; 858 uint32_t portal_id; 859 } *pattr; 860 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 861 int error; 862 863 if (portal == NULL || cmd == NULL || attr == NULL) 864 return (DPAA2_CMD_STAT_ERR); 865 866 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_RC_GET_ATTR); 867 if (!error) { 868 pattr = (struct dpaa2_rc_attr *) &cmd->params[0]; 869 attr->cont_id = pattr->cont_id; 870 attr->portal_id = pattr->portal_id; 871 attr->options = pattr->options; 872 attr->icid = pattr->icid; 873 } 874 875 return (error); 876 } 877 878 static int 879 dpaa2_rc_get_obj_region(device_t dev, device_t child, struct dpaa2_cmd *cmd, 880 uint32_t obj_id, uint8_t reg_idx, enum dpaa2_dev_type dtype, 881 struct dpaa2_rc_obj_region *reg) 882 { 883 struct __packed obj_region_args { 884 uint32_t obj_id; 885 uint16_t _reserved1; 886 uint8_t reg_idx; 887 uint8_t _reserved2; 888 uint64_t _reserved3; 889 uint64_t _reserved4; 890 uint8_t type[16]; 891 } *args; 892 struct __packed obj_region { 893 uint64_t _reserved1; 894 uint64_t base_offset; 895 uint32_t size; 896 uint32_t type; 897 uint32_t flags; 898 uint32_t _reserved2; 899 uint64_t base_paddr; 900 } *resp; 901 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 902 uint16_t cmdid, api_major, api_minor; 903 const char *type = dpaa2_ttos(dtype); 904 int error; 905 906 if (portal == NULL || cmd == NULL || reg == NULL) 907 return (DPAA2_CMD_STAT_ERR); 908 909 /* 910 * If the DPRC object version was not yet cached, cache it now. 911 * Otherwise use the already cached value. 912 */ 913 if (!portal->rc_api_major && !portal->rc_api_minor) { 914 error = DPAA2_CMD_RC_GET_API_VERSION(dev, child, cmd, 915 &api_major, &api_minor); 916 if (error) 917 return (error); 918 portal->rc_api_major = api_major; 919 portal->rc_api_minor = api_minor; 920 } else { 921 api_major = portal->rc_api_major; 922 api_minor = portal->rc_api_minor; 923 } 924 925 /* TODO: Remove magic numbers. */ 926 if (api_major > 6u || (api_major == 6u && api_minor >= 6u)) 927 /* 928 * MC API version 6.6 changed the size of the MC portals and 929 * software portals to 64K (as implemented by hardware). 930 */ 931 cmdid = CMDID_RC_GET_OBJ_REG_V3; 932 else if (api_major == 6u && api_minor >= 3u) 933 /* 934 * MC API version 6.3 introduced a new field to the region 935 * descriptor: base_address. 936 */ 937 cmdid = CMDID_RC_GET_OBJ_REG_V2; 938 else 939 cmdid = CMDID_RC_GET_OBJ_REG; 940 941 args = (struct obj_region_args *) &cmd->params[0]; 942 args->obj_id = obj_id; 943 args->reg_idx = reg_idx; 944 memcpy(args->type, type, min(strlen(type) + 1, TYPE_LEN_MAX)); 945 946 error = dpaa2_rc_exec_cmd(portal, cmd, cmdid); 947 if (!error) { 948 resp = (struct obj_region *) &cmd->params[0]; 949 reg->base_paddr = resp->base_paddr; 950 reg->base_offset = resp->base_offset; 951 reg->size = resp->size; 952 reg->flags = resp->flags; 953 reg->type = resp->type & 0xFu; 954 } 955 956 return (error); 957 } 958 959 static int 960 dpaa2_rc_get_api_version(device_t dev, device_t child, struct dpaa2_cmd *cmd, 961 uint16_t *major, uint16_t *minor) 962 { 963 struct __packed rc_api_version { 964 uint16_t major; 965 uint16_t minor; 966 } *resp; 967 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 968 int error; 969 970 if (portal == NULL || cmd == NULL || major == NULL || minor == NULL) 971 return (DPAA2_CMD_STAT_ERR); 972 973 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_RC_GET_API_VERSION); 974 if (!error) { 975 resp = (struct rc_api_version *) &cmd->params[0]; 976 *major = resp->major; 977 *minor = resp->minor; 978 } 979 980 return (error); 981 } 982 983 static int 984 dpaa2_rc_set_irq_enable(device_t dev, device_t child, struct dpaa2_cmd *cmd, 985 uint8_t irq_idx, uint8_t enable) 986 { 987 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 988 989 if (portal == NULL || cmd == NULL) 990 return (DPAA2_CMD_STAT_ERR); 991 992 return (dpaa2_rc_enable_irq(portal, cmd, irq_idx, enable, 993 CMDID_RC_SET_IRQ_ENABLE)); 994 } 995 996 static int 997 dpaa2_rc_set_obj_irq(device_t dev, device_t child, struct dpaa2_cmd *cmd, 998 uint8_t irq_idx, uint64_t addr, uint32_t data, uint32_t irq_usr, 999 uint32_t obj_id, enum dpaa2_dev_type dtype) 1000 { 1001 struct __packed set_obj_irq_args { 1002 uint32_t data; 1003 uint8_t irq_idx; 1004 uint8_t _reserved1[3]; 1005 uint64_t addr; 1006 uint32_t irq_usr; 1007 uint32_t obj_id; 1008 uint8_t type[16]; 1009 } *args; 1010 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1011 const char *type = dpaa2_ttos(dtype); 1012 1013 if (portal == NULL || cmd == NULL) 1014 return (DPAA2_CMD_STAT_ERR); 1015 1016 args = (struct set_obj_irq_args *) &cmd->params[0]; 1017 args->irq_idx = irq_idx; 1018 args->addr = addr; 1019 args->data = data; 1020 args->irq_usr = irq_usr; 1021 args->obj_id = obj_id; 1022 memcpy(args->type, type, min(strlen(type) + 1, TYPE_LEN_MAX)); 1023 1024 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_RC_SET_OBJ_IRQ)); 1025 } 1026 1027 static int 1028 dpaa2_rc_get_conn(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1029 struct dpaa2_ep_desc *ep1_desc, struct dpaa2_ep_desc *ep2_desc, 1030 uint32_t *link_stat) 1031 { 1032 struct __packed get_conn_args { 1033 uint32_t ep1_id; 1034 uint32_t ep1_ifid; 1035 uint8_t ep1_type[16]; 1036 uint64_t _reserved[4]; 1037 } *args; 1038 struct __packed get_conn_resp { 1039 uint64_t _reserved1[3]; 1040 uint32_t ep2_id; 1041 uint32_t ep2_ifid; 1042 uint8_t ep2_type[16]; 1043 uint32_t link_stat; 1044 uint32_t _reserved2; 1045 } *resp; 1046 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1047 int error; 1048 1049 if (portal == NULL || cmd == NULL || ep1_desc == NULL || 1050 ep2_desc == NULL) 1051 return (DPAA2_CMD_STAT_ERR); 1052 1053 args = (struct get_conn_args *) &cmd->params[0]; 1054 args->ep1_id = ep1_desc->obj_id; 1055 args->ep1_ifid = ep1_desc->if_id; 1056 /* TODO: Remove magic number. */ 1057 strncpy(args->ep1_type, dpaa2_ttos(ep1_desc->type), 16); 1058 1059 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_RC_GET_CONN); 1060 if (!error) { 1061 resp = (struct get_conn_resp *) &cmd->params[0]; 1062 ep2_desc->obj_id = resp->ep2_id; 1063 ep2_desc->if_id = resp->ep2_ifid; 1064 ep2_desc->type = dpaa2_stot((const char *) resp->ep2_type); 1065 if (link_stat != NULL) 1066 *link_stat = resp->link_stat; 1067 } 1068 1069 return (error); 1070 } 1071 1072 static int 1073 dpaa2_rc_ni_open(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1074 uint32_t dpni_id, uint16_t *token) 1075 { 1076 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1077 struct dpaa2_cmd_header *hdr; 1078 int error; 1079 1080 if (portal == NULL || cmd == NULL || token == NULL) 1081 return (DPAA2_CMD_STAT_ERR); 1082 1083 cmd->params[0] = dpni_id; 1084 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_OPEN); 1085 if (!error) { 1086 hdr = (struct dpaa2_cmd_header *) &cmd->header; 1087 *token = hdr->token; 1088 } 1089 1090 return (error); 1091 } 1092 1093 static int 1094 dpaa2_rc_ni_close(device_t dev, device_t child, struct dpaa2_cmd *cmd) 1095 { 1096 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1097 1098 if (portal == NULL || cmd == NULL) 1099 return (DPAA2_CMD_STAT_ERR); 1100 1101 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_CLOSE)); 1102 } 1103 1104 static int 1105 dpaa2_rc_ni_enable(device_t dev, device_t child, struct dpaa2_cmd *cmd) 1106 { 1107 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1108 1109 if (portal == NULL || cmd == NULL) 1110 return (DPAA2_CMD_STAT_ERR); 1111 1112 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_ENABLE)); 1113 } 1114 1115 static int 1116 dpaa2_rc_ni_disable(device_t dev, device_t child, struct dpaa2_cmd *cmd) 1117 { 1118 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1119 1120 if (portal == NULL || cmd == NULL) 1121 return (DPAA2_CMD_STAT_ERR); 1122 1123 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_DISABLE)); 1124 } 1125 1126 static int 1127 dpaa2_rc_ni_get_api_version(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1128 uint16_t *major, uint16_t *minor) 1129 { 1130 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1131 int error; 1132 1133 if (portal == NULL || cmd == NULL || major == NULL || minor == NULL) 1134 return (DPAA2_CMD_STAT_ERR); 1135 1136 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_GET_API_VER); 1137 if (!error) { 1138 *major = cmd->params[0] & 0xFFFFU; 1139 *minor = (cmd->params[0] >> 16) & 0xFFFFU; 1140 } 1141 1142 return (error); 1143 } 1144 1145 static int 1146 dpaa2_rc_ni_reset(device_t dev, device_t child, struct dpaa2_cmd *cmd) 1147 { 1148 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1149 1150 if (portal == NULL || cmd == NULL) 1151 return (DPAA2_CMD_STAT_ERR); 1152 1153 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_RESET)); 1154 } 1155 1156 static int 1157 dpaa2_rc_ni_get_attributes(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1158 struct dpaa2_ni_attr *attr) 1159 { 1160 struct __packed ni_attr { 1161 uint32_t options; 1162 uint8_t num_queues; 1163 uint8_t num_rx_tcs; 1164 uint8_t mac_entries; 1165 uint8_t num_tx_tcs; 1166 uint8_t vlan_entries; 1167 uint8_t num_channels; 1168 uint8_t qos_entries; 1169 uint8_t _reserved1; 1170 uint16_t fs_entries; 1171 uint16_t _reserved2; 1172 uint8_t qos_key_size; 1173 uint8_t fs_key_size; 1174 uint16_t wriop_ver; 1175 uint8_t num_cgs; 1176 uint8_t _reserved3; 1177 uint16_t _reserved4; 1178 uint64_t _reserved5[4]; 1179 } *resp; 1180 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1181 int error; 1182 1183 if (portal == NULL || cmd == NULL || attr == NULL) 1184 return (DPAA2_CMD_STAT_ERR); 1185 1186 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_GET_ATTR); 1187 if (!error) { 1188 resp = (struct ni_attr *) &cmd->params[0]; 1189 1190 attr->options = resp->options; 1191 attr->wriop_ver = resp->wriop_ver; 1192 1193 attr->entries.fs = resp->fs_entries; 1194 attr->entries.mac = resp->mac_entries; 1195 attr->entries.vlan = resp->vlan_entries; 1196 attr->entries.qos = resp->qos_entries; 1197 1198 attr->num.queues = resp->num_queues; 1199 attr->num.rx_tcs = resp->num_rx_tcs; 1200 attr->num.tx_tcs = resp->num_tx_tcs; 1201 attr->num.channels = resp->num_channels; 1202 attr->num.cgs = resp->num_cgs; 1203 1204 attr->key_size.fs = resp->fs_key_size; 1205 attr->key_size.qos = resp->qos_key_size; 1206 } 1207 1208 return (error); 1209 } 1210 1211 static int 1212 dpaa2_rc_ni_set_buf_layout(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1213 struct dpaa2_ni_buf_layout *bl) 1214 { 1215 struct __packed set_buf_layout_args { 1216 uint8_t queue_type; 1217 uint8_t _reserved1; 1218 uint16_t _reserved2; 1219 uint16_t options; 1220 uint8_t params; 1221 uint8_t _reserved3; 1222 uint16_t priv_data_size; 1223 uint16_t data_align; 1224 uint16_t head_room; 1225 uint16_t tail_room; 1226 uint64_t _reserved4[5]; 1227 } *args; 1228 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1229 1230 if (portal == NULL || cmd == NULL || bl == NULL) 1231 return (DPAA2_CMD_STAT_ERR); 1232 1233 args = (struct set_buf_layout_args *) &cmd->params[0]; 1234 args->queue_type = (uint8_t) bl->queue_type; 1235 args->options = bl->options; 1236 args->params = 0; 1237 args->priv_data_size = bl->pd_size; 1238 args->data_align = bl->fd_align; 1239 args->head_room = bl->head_size; 1240 args->tail_room = bl->tail_size; 1241 1242 args->params |= bl->pass_timestamp ? 1U : 0U; 1243 args->params |= bl->pass_parser_result ? 2U : 0U; 1244 args->params |= bl->pass_frame_status ? 4U : 0U; 1245 args->params |= bl->pass_sw_opaque ? 8U : 0U; 1246 1247 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_SET_BUF_LAYOUT)); 1248 } 1249 1250 static int 1251 dpaa2_rc_ni_get_tx_data_offset(device_t dev, device_t child, 1252 struct dpaa2_cmd *cmd, uint16_t *offset) 1253 { 1254 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1255 int error; 1256 1257 if (portal == NULL || cmd == NULL || offset == NULL) 1258 return (DPAA2_CMD_STAT_ERR); 1259 1260 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_GET_TX_DATA_OFF); 1261 if (!error) 1262 *offset = cmd->params[0] & 0xFFFFU; 1263 1264 return (error); 1265 } 1266 1267 static int 1268 dpaa2_rc_ni_get_port_mac_addr(device_t dev, device_t child, 1269 struct dpaa2_cmd *cmd, uint8_t *mac) 1270 { 1271 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1272 int error; 1273 1274 if (portal == NULL || cmd == NULL || mac == NULL) 1275 return (DPAA2_CMD_STAT_ERR); 1276 1277 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_GET_PORT_MAC_ADDR); 1278 if (!error) { 1279 mac[0] = (cmd->params[0] >> 56) & 0xFFU; 1280 mac[1] = (cmd->params[0] >> 48) & 0xFFU; 1281 mac[2] = (cmd->params[0] >> 40) & 0xFFU; 1282 mac[3] = (cmd->params[0] >> 32) & 0xFFU; 1283 mac[4] = (cmd->params[0] >> 24) & 0xFFU; 1284 mac[5] = (cmd->params[0] >> 16) & 0xFFU; 1285 } 1286 1287 return (error); 1288 } 1289 1290 static int 1291 dpaa2_rc_ni_set_prim_mac_addr(device_t dev, device_t child, 1292 struct dpaa2_cmd *cmd, uint8_t *mac) 1293 { 1294 struct __packed set_prim_mac_args { 1295 uint8_t _reserved[2]; 1296 uint8_t mac[ETHER_ADDR_LEN]; 1297 } *args; 1298 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1299 1300 if (portal == NULL || cmd == NULL || mac == NULL) 1301 return (DPAA2_CMD_STAT_EINVAL); 1302 1303 args = (struct set_prim_mac_args *) &cmd->params[0]; 1304 for (int i = 1; i <= ETHER_ADDR_LEN; i++) 1305 args->mac[i - 1] = mac[ETHER_ADDR_LEN - i]; 1306 1307 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_SET_PRIM_MAC_ADDR)); 1308 } 1309 1310 static int 1311 dpaa2_rc_ni_get_prim_mac_addr(device_t dev, device_t child, 1312 struct dpaa2_cmd *cmd, uint8_t *mac) 1313 { 1314 struct __packed get_prim_mac_resp { 1315 uint8_t _reserved[2]; 1316 uint8_t mac[ETHER_ADDR_LEN]; 1317 } *resp; 1318 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1319 int error; 1320 1321 if (portal == NULL || cmd == NULL || mac == NULL) 1322 return (DPAA2_CMD_STAT_EINVAL); 1323 1324 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_GET_PRIM_MAC_ADDR); 1325 if (!error) { 1326 resp = (struct get_prim_mac_resp *) &cmd->params[0]; 1327 for (int i = 1; i <= ETHER_ADDR_LEN; i++) 1328 mac[ETHER_ADDR_LEN - i] = resp->mac[i - 1]; 1329 } 1330 1331 return (error); 1332 } 1333 1334 static int 1335 dpaa2_rc_ni_set_link_cfg(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1336 struct dpaa2_ni_link_cfg *cfg) 1337 { 1338 struct __packed link_cfg_args { 1339 uint64_t _reserved1; 1340 uint32_t rate; 1341 uint32_t _reserved2; 1342 uint64_t options; 1343 uint64_t adv_speeds; 1344 uint64_t _reserved3[3]; 1345 } *args; 1346 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1347 1348 if (portal == NULL || cmd == NULL || cfg == NULL) 1349 return (DPAA2_CMD_STAT_EINVAL); 1350 1351 args = (struct link_cfg_args *) &cmd->params[0]; 1352 args->rate = cfg->rate; 1353 args->options = cfg->options; 1354 args->adv_speeds = cfg->adv_speeds; 1355 1356 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_SET_LINK_CFG)); 1357 } 1358 1359 static int 1360 dpaa2_rc_ni_get_link_cfg(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1361 struct dpaa2_ni_link_cfg *cfg) 1362 { 1363 struct __packed link_cfg_resp { 1364 uint64_t _reserved1; 1365 uint32_t rate; 1366 uint32_t _reserved2; 1367 uint64_t options; 1368 uint64_t adv_speeds; 1369 uint64_t _reserved3[3]; 1370 } *resp; 1371 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1372 int error; 1373 1374 if (portal == NULL || cmd == NULL || cfg == NULL) 1375 return (DPAA2_CMD_STAT_EINVAL); 1376 1377 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_GET_LINK_CFG); 1378 if (!error) { 1379 resp = (struct link_cfg_resp *) &cmd->params[0]; 1380 cfg->rate = resp->rate; 1381 cfg->options = resp->options; 1382 cfg->adv_speeds = resp->adv_speeds; 1383 } 1384 1385 return (error); 1386 } 1387 1388 static int 1389 dpaa2_rc_ni_get_link_state(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1390 struct dpaa2_ni_link_state *state) 1391 { 1392 struct __packed link_state_resp { 1393 uint32_t _reserved1; 1394 uint32_t flags; 1395 uint32_t rate; 1396 uint32_t _reserved2; 1397 uint64_t options; 1398 uint64_t supported; 1399 uint64_t advert; 1400 } *resp; 1401 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1402 int error; 1403 1404 if (portal == NULL || cmd == NULL || state == NULL) 1405 return (DPAA2_CMD_STAT_EINVAL); 1406 1407 dpaa2_rc_reset_cmd_params(cmd); 1408 1409 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_GET_LINK_STATE); 1410 if (!error) { 1411 resp = (struct link_state_resp *) &cmd->params[0]; 1412 state->options = resp->options; 1413 state->adv_speeds = resp->advert; 1414 state->sup_speeds = resp->supported; 1415 state->rate = resp->rate; 1416 1417 state->link_up = resp->flags & 0x1u ? true : false; 1418 state->state_valid = resp->flags & 0x2u ? true : false; 1419 } 1420 1421 return (error); 1422 } 1423 1424 static int 1425 dpaa2_rc_ni_set_qos_table(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1426 struct dpaa2_ni_qos_table *tbl) 1427 { 1428 struct __packed qos_table_args { 1429 uint32_t _reserved1; 1430 uint8_t default_tc; 1431 uint8_t options; 1432 uint16_t _reserved2; 1433 uint64_t _reserved[5]; 1434 uint64_t kcfg_busaddr; 1435 } *args; 1436 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1437 1438 if (portal == NULL || cmd == NULL || tbl == NULL) 1439 return (DPAA2_CMD_STAT_EINVAL); 1440 1441 dpaa2_rc_reset_cmd_params(cmd); 1442 1443 args = (struct qos_table_args *) &cmd->params[0]; 1444 args->default_tc = tbl->default_tc; 1445 args->kcfg_busaddr = tbl->kcfg_busaddr; 1446 1447 args->options |= tbl->discard_on_miss ? 1U : 0U; 1448 args->options |= tbl->keep_entries ? 2U : 0U; 1449 1450 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_SET_QOS_TABLE)); 1451 } 1452 1453 static int 1454 dpaa2_rc_ni_clear_qos_table(device_t dev, device_t child, struct dpaa2_cmd *cmd) 1455 { 1456 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1457 1458 if (portal == NULL || cmd == NULL) 1459 return (DPAA2_CMD_STAT_EINVAL); 1460 1461 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_CLEAR_QOS_TABLE)); 1462 } 1463 1464 static int 1465 dpaa2_rc_ni_set_pools(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1466 struct dpaa2_ni_pools_cfg *cfg) 1467 { 1468 struct __packed set_pools_args { 1469 uint8_t pools_num; 1470 uint8_t backup_pool_mask; 1471 uint8_t _reserved1; 1472 uint8_t pool_as; /* assigning: 0 - QPRI, 1 - QDBIN */ 1473 uint32_t bp_obj_id[DPAA2_NI_MAX_POOLS]; 1474 uint16_t buf_sz[DPAA2_NI_MAX_POOLS]; 1475 uint32_t _reserved2; 1476 } *args; 1477 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1478 1479 if (portal == NULL || cmd == NULL || cfg == NULL) 1480 return (DPAA2_CMD_STAT_EINVAL); 1481 1482 dpaa2_rc_reset_cmd_params(cmd); 1483 1484 args = (struct set_pools_args *) &cmd->params[0]; 1485 args->pools_num = cfg->pools_num < DPAA2_NI_MAX_POOLS 1486 ? cfg->pools_num : DPAA2_NI_MAX_POOLS; 1487 for (uint32_t i = 0; i < args->pools_num; i++) { 1488 args->bp_obj_id[i] = cfg->pools[i].bp_obj_id; 1489 args->buf_sz[i] = cfg->pools[i].buf_sz; 1490 args->backup_pool_mask |= (cfg->pools[i].backup_flag & 1) << i; 1491 } 1492 1493 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_SET_POOLS)); 1494 } 1495 1496 static int 1497 dpaa2_rc_ni_set_err_behavior(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1498 struct dpaa2_ni_err_cfg *cfg) 1499 { 1500 struct __packed err_behavior_args { 1501 uint32_t err_mask; 1502 uint8_t flags; 1503 } *args; 1504 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1505 1506 if (portal == NULL || cmd == NULL || cfg == NULL) 1507 return (DPAA2_CMD_STAT_EINVAL); 1508 1509 dpaa2_rc_reset_cmd_params(cmd); 1510 1511 args = (struct err_behavior_args *) &cmd->params[0]; 1512 args->err_mask = cfg->err_mask; 1513 1514 args->flags |= cfg->set_err_fas ? 0x10u : 0u; 1515 args->flags |= ((uint8_t) cfg->action) & 0x0Fu; 1516 1517 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_SET_ERR_BEHAVIOR)); 1518 } 1519 1520 static int 1521 dpaa2_rc_ni_get_queue(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1522 struct dpaa2_ni_queue_cfg *cfg) 1523 { 1524 struct __packed get_queue_args { 1525 uint8_t queue_type; 1526 uint8_t tc; 1527 uint8_t idx; 1528 uint8_t chan_id; 1529 } *args; 1530 struct __packed get_queue_resp { 1531 uint64_t _reserved1; 1532 uint32_t dest_id; 1533 uint16_t _reserved2; 1534 uint8_t priority; 1535 uint8_t flags; 1536 uint64_t flc; 1537 uint64_t user_ctx; 1538 uint32_t fqid; 1539 uint16_t qdbin; 1540 uint16_t _reserved3; 1541 uint8_t cgid; 1542 uint8_t _reserved[15]; 1543 } *resp; 1544 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1545 int error; 1546 1547 if (portal == NULL || cmd == NULL || cfg == NULL) 1548 return (DPAA2_CMD_STAT_EINVAL); 1549 1550 dpaa2_rc_reset_cmd_params(cmd); 1551 1552 args = (struct get_queue_args *) &cmd->params[0]; 1553 args->queue_type = (uint8_t) cfg->type; 1554 args->tc = cfg->tc; 1555 args->idx = cfg->idx; 1556 args->chan_id = cfg->chan_id; 1557 1558 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_GET_QUEUE); 1559 if (!error) { 1560 resp = (struct get_queue_resp *) &cmd->params[0]; 1561 1562 cfg->dest_id = resp->dest_id; 1563 cfg->priority = resp->priority; 1564 cfg->flow_ctx = resp->flc; 1565 cfg->user_ctx = resp->user_ctx; 1566 cfg->fqid = resp->fqid; 1567 cfg->qdbin = resp->qdbin; 1568 cfg->cgid = resp->cgid; 1569 1570 cfg->dest_type = (enum dpaa2_ni_dest_type) resp->flags & 0x0Fu; 1571 cfg->cgid_valid = (resp->flags & 0x20u) > 0u ? true : false; 1572 cfg->stash_control = (resp->flags & 0x40u) > 0u ? true : false; 1573 cfg->hold_active = (resp->flags & 0x80u) > 0u ? true : false; 1574 } 1575 1576 return (error); 1577 } 1578 1579 static int 1580 dpaa2_rc_ni_set_queue(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1581 struct dpaa2_ni_queue_cfg *cfg) 1582 { 1583 struct __packed set_queue_args { 1584 uint8_t queue_type; 1585 uint8_t tc; 1586 uint8_t idx; 1587 uint8_t options; 1588 uint32_t _reserved1; 1589 uint32_t dest_id; 1590 uint16_t _reserved2; 1591 uint8_t priority; 1592 uint8_t flags; 1593 uint64_t flc; 1594 uint64_t user_ctx; 1595 uint8_t cgid; 1596 uint8_t chan_id; 1597 uint8_t _reserved[23]; 1598 } *args; 1599 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1600 1601 if (portal == NULL || cmd == NULL || cfg == NULL) 1602 return (DPAA2_CMD_STAT_EINVAL); 1603 1604 dpaa2_rc_reset_cmd_params(cmd); 1605 1606 args = (struct set_queue_args *) &cmd->params[0]; 1607 args->queue_type = (uint8_t) cfg->type; 1608 args->tc = cfg->tc; 1609 args->idx = cfg->idx; 1610 args->options = cfg->options; 1611 args->dest_id = cfg->dest_id; 1612 args->priority = cfg->priority; 1613 args->flc = cfg->flow_ctx; 1614 args->user_ctx = cfg->user_ctx; 1615 args->cgid = cfg->cgid; 1616 args->chan_id = cfg->chan_id; 1617 1618 args->flags |= (uint8_t)(cfg->dest_type & 0x0Fu); 1619 args->flags |= cfg->stash_control ? 0x40u : 0u; 1620 args->flags |= cfg->hold_active ? 0x80u : 0u; 1621 1622 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_SET_QUEUE)); 1623 } 1624 1625 static int 1626 dpaa2_rc_ni_get_qdid(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1627 enum dpaa2_ni_queue_type type, uint16_t *qdid) 1628 { 1629 struct __packed get_qdid_args { 1630 uint8_t queue_type; 1631 } *args; 1632 struct __packed get_qdid_resp { 1633 uint16_t qdid; 1634 } *resp; 1635 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1636 int error; 1637 1638 if (portal == NULL || cmd == NULL || qdid == NULL) 1639 return (DPAA2_CMD_STAT_EINVAL); 1640 1641 dpaa2_rc_reset_cmd_params(cmd); 1642 1643 args = (struct get_qdid_args *) &cmd->params[0]; 1644 args->queue_type = (uint8_t) type; 1645 1646 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_GET_QDID); 1647 if (!error) { 1648 resp = (struct get_qdid_resp *) &cmd->params[0]; 1649 *qdid = resp->qdid; 1650 } 1651 1652 return (error); 1653 } 1654 1655 static int 1656 dpaa2_rc_ni_add_mac_addr(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1657 uint8_t *mac) 1658 { 1659 struct __packed add_mac_args { 1660 uint8_t flags; 1661 uint8_t _reserved; 1662 uint8_t mac[ETHER_ADDR_LEN]; 1663 uint8_t tc_id; 1664 uint8_t fq_id; 1665 } *args; 1666 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1667 1668 if (portal == NULL || cmd == NULL || mac == NULL) 1669 return (DPAA2_CMD_STAT_EINVAL); 1670 1671 dpaa2_rc_reset_cmd_params(cmd); 1672 1673 args = (struct add_mac_args *) &cmd->params[0]; 1674 for (int i = 1; i <= ETHER_ADDR_LEN; i++) 1675 args->mac[i - 1] = mac[ETHER_ADDR_LEN - i]; 1676 1677 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_ADD_MAC_ADDR)); 1678 } 1679 1680 static int 1681 dpaa2_rc_ni_remove_mac_addr(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1682 uint8_t *mac) 1683 { 1684 struct __packed rem_mac_args { 1685 uint16_t _reserved; 1686 uint8_t mac[ETHER_ADDR_LEN]; 1687 uint64_t _reserved1[6]; 1688 } *args; 1689 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1690 1691 if (portal == NULL || cmd == NULL || mac == NULL) 1692 return (DPAA2_CMD_STAT_EINVAL); 1693 1694 dpaa2_rc_reset_cmd_params(cmd); 1695 1696 args = (struct rem_mac_args *) &cmd->params[0]; 1697 for (int i = 1; i <= ETHER_ADDR_LEN; i++) 1698 args->mac[i - 1] = mac[ETHER_ADDR_LEN - i]; 1699 1700 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_REMOVE_MAC_ADDR)); 1701 } 1702 1703 static int 1704 dpaa2_rc_ni_clear_mac_filters(device_t dev, device_t child, 1705 struct dpaa2_cmd *cmd, bool rm_uni, bool rm_multi) 1706 { 1707 struct __packed clear_mac_filters_args { 1708 uint8_t flags; 1709 } *args; 1710 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1711 1712 if (portal == NULL || cmd == NULL) 1713 return (DPAA2_CMD_STAT_EINVAL); 1714 1715 dpaa2_rc_reset_cmd_params(cmd); 1716 1717 args = (struct clear_mac_filters_args *) &cmd->params[0]; 1718 args->flags |= rm_uni ? 0x1 : 0x0; 1719 args->flags |= rm_multi ? 0x2 : 0x0; 1720 1721 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_CLEAR_MAC_FILTERS)); 1722 } 1723 1724 static int 1725 dpaa2_rc_ni_set_mfl(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1726 uint16_t length) 1727 { 1728 struct __packed set_mfl_args { 1729 uint16_t length; 1730 } *args; 1731 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1732 1733 if (portal == NULL || cmd == NULL) 1734 return (DPAA2_CMD_STAT_EINVAL); 1735 1736 dpaa2_rc_reset_cmd_params(cmd); 1737 1738 args = (struct set_mfl_args *) &cmd->params[0]; 1739 args->length = length; 1740 1741 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_SET_MFL)); 1742 } 1743 1744 static int 1745 dpaa2_rc_ni_set_offload(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1746 enum dpaa2_ni_ofl_type ofl_type, bool en) 1747 { 1748 struct __packed set_ofl_args { 1749 uint8_t _reserved[3]; 1750 uint8_t ofl_type; 1751 uint32_t config; 1752 } *args; 1753 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1754 1755 if (portal == NULL || cmd == NULL) 1756 return (DPAA2_CMD_STAT_EINVAL); 1757 1758 dpaa2_rc_reset_cmd_params(cmd); 1759 1760 args = (struct set_ofl_args *) &cmd->params[0]; 1761 args->ofl_type = (uint8_t) ofl_type; 1762 args->config = en ? 1u : 0u; 1763 1764 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_SET_OFFLOAD)); 1765 } 1766 1767 static int 1768 dpaa2_rc_ni_set_irq_mask(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1769 uint8_t irq_idx, uint32_t mask) 1770 { 1771 struct __packed set_irq_mask_args { 1772 uint32_t mask; 1773 uint8_t irq_idx; 1774 } *args; 1775 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1776 1777 if (portal == NULL || cmd == NULL) 1778 return (DPAA2_CMD_STAT_EINVAL); 1779 1780 dpaa2_rc_reset_cmd_params(cmd); 1781 1782 args = (struct set_irq_mask_args *) &cmd->params[0]; 1783 args->mask = mask; 1784 args->irq_idx = irq_idx; 1785 1786 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_SET_IRQ_MASK)); 1787 } 1788 1789 static int 1790 dpaa2_rc_ni_set_irq_enable(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1791 uint8_t irq_idx, bool en) 1792 { 1793 struct __packed set_irq_enable_args { 1794 uint32_t en; 1795 uint8_t irq_idx; 1796 } *args; 1797 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1798 1799 if (portal == NULL || cmd == NULL) 1800 return (DPAA2_CMD_STAT_EINVAL); 1801 1802 dpaa2_rc_reset_cmd_params(cmd); 1803 1804 args = (struct set_irq_enable_args *) &cmd->params[0]; 1805 args->en = en ? 1u : 0u; 1806 args->irq_idx = irq_idx; 1807 1808 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_SET_IRQ_ENABLE)); 1809 } 1810 1811 static int 1812 dpaa2_rc_ni_get_irq_status(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1813 uint8_t irq_idx, uint32_t *status) 1814 { 1815 struct __packed get_irq_stat_args { 1816 uint32_t status; 1817 uint8_t irq_idx; 1818 } *args; 1819 struct __packed get_irq_stat_resp { 1820 uint32_t status; 1821 } *resp; 1822 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1823 int error; 1824 1825 if (portal == NULL || cmd == NULL || status == NULL) 1826 return (DPAA2_CMD_STAT_EINVAL); 1827 1828 dpaa2_rc_reset_cmd_params(cmd); 1829 1830 args = (struct get_irq_stat_args *) &cmd->params[0]; 1831 args->status = *status; 1832 args->irq_idx = irq_idx; 1833 1834 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_GET_IRQ_STATUS); 1835 if (!error) { 1836 resp = (struct get_irq_stat_resp *) &cmd->params[0]; 1837 *status = resp->status; 1838 } 1839 1840 return (error); 1841 } 1842 1843 static int 1844 dpaa2_rc_ni_set_uni_promisc(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1845 bool en) 1846 { 1847 struct __packed set_uni_promisc_args { 1848 uint8_t en; 1849 } *args; 1850 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1851 1852 if (portal == NULL || cmd == NULL) 1853 return (DPAA2_CMD_STAT_EINVAL); 1854 1855 dpaa2_rc_reset_cmd_params(cmd); 1856 1857 args = (struct set_uni_promisc_args *) &cmd->params[0]; 1858 args->en = en ? 1u : 0u; 1859 1860 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_SET_UNI_PROMISC)); 1861 } 1862 1863 static int 1864 dpaa2_rc_ni_set_multi_promisc(device_t dev, device_t child, 1865 struct dpaa2_cmd *cmd, bool en) 1866 { 1867 /* TODO: Implementation is the same as for ni_set_uni_promisc(). */ 1868 struct __packed set_multi_promisc_args { 1869 uint8_t en; 1870 } *args; 1871 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1872 1873 if (portal == NULL || cmd == NULL) 1874 return (DPAA2_CMD_STAT_EINVAL); 1875 1876 dpaa2_rc_reset_cmd_params(cmd); 1877 1878 args = (struct set_multi_promisc_args *) &cmd->params[0]; 1879 args->en = en ? 1u : 0u; 1880 1881 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_SET_MULTI_PROMISC)); 1882 } 1883 1884 static int 1885 dpaa2_rc_ni_get_statistics(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1886 uint8_t page, uint16_t param, uint64_t *cnt) 1887 { 1888 struct __packed get_statistics_args { 1889 uint8_t page; 1890 uint16_t param; 1891 } *args; 1892 struct __packed get_statistics_resp { 1893 uint64_t cnt[7]; 1894 } *resp; 1895 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1896 int error; 1897 1898 if (portal == NULL || cmd == NULL || cnt == NULL) 1899 return (DPAA2_CMD_STAT_EINVAL); 1900 1901 dpaa2_rc_reset_cmd_params(cmd); 1902 1903 args = (struct get_statistics_args *) &cmd->params[0]; 1904 args->page = page; 1905 args->param = param; 1906 1907 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_GET_STATISTICS); 1908 if (!error) { 1909 resp = (struct get_statistics_resp *) &cmd->params[0]; 1910 for (int i = 0; i < DPAA2_NI_STAT_COUNTERS; i++) 1911 cnt[i] = resp->cnt[i]; 1912 } 1913 1914 return (error); 1915 } 1916 1917 static int 1918 dpaa2_rc_ni_set_rx_tc_dist(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1919 uint16_t dist_size, uint8_t tc, enum dpaa2_ni_dist_mode dist_mode, 1920 bus_addr_t key_cfg_buf) 1921 { 1922 struct __packed set_rx_tc_dist_args { 1923 uint16_t dist_size; 1924 uint8_t tc; 1925 uint8_t ma_dm; /* miss action + dist. mode */ 1926 uint32_t _reserved1; 1927 uint64_t _reserved2[5]; 1928 uint64_t key_cfg_iova; 1929 } *args; 1930 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1931 1932 if (portal == NULL || cmd == NULL) 1933 return (DPAA2_CMD_STAT_EINVAL); 1934 1935 dpaa2_rc_reset_cmd_params(cmd); 1936 1937 args = (struct set_rx_tc_dist_args *) &cmd->params[0]; 1938 args->dist_size = dist_size; 1939 args->tc = tc; 1940 args->ma_dm = ((uint8_t) dist_mode) & 0x0Fu; 1941 args->key_cfg_iova = key_cfg_buf; 1942 1943 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_NI_SET_RX_TC_DIST)); 1944 } 1945 1946 static int 1947 dpaa2_rc_io_open(device_t dev, device_t child, struct dpaa2_cmd *cmd, 1948 uint32_t dpio_id, uint16_t *token) 1949 { 1950 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1951 struct dpaa2_cmd_header *hdr; 1952 int error; 1953 1954 if (portal == NULL || cmd == NULL || token == NULL) 1955 return (DPAA2_CMD_STAT_ERR); 1956 1957 cmd->params[0] = dpio_id; 1958 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_IO_OPEN); 1959 if (!error) { 1960 hdr = (struct dpaa2_cmd_header *) &cmd->header; 1961 *token = hdr->token; 1962 } 1963 1964 return (error); 1965 } 1966 1967 static int 1968 dpaa2_rc_io_close(device_t dev, device_t child, struct dpaa2_cmd *cmd) 1969 { 1970 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1971 1972 if (portal == NULL || cmd == NULL) 1973 return (DPAA2_CMD_STAT_ERR); 1974 1975 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_IO_CLOSE)); 1976 } 1977 1978 static int 1979 dpaa2_rc_io_enable(device_t dev, device_t child, struct dpaa2_cmd *cmd) 1980 { 1981 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1982 1983 if (portal == NULL || cmd == NULL) 1984 return (DPAA2_CMD_STAT_ERR); 1985 1986 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_IO_ENABLE)); 1987 } 1988 1989 static int 1990 dpaa2_rc_io_disable(device_t dev, device_t child, struct dpaa2_cmd *cmd) 1991 { 1992 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 1993 1994 if (portal == NULL || cmd == NULL) 1995 return (DPAA2_CMD_STAT_ERR); 1996 1997 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_IO_DISABLE)); 1998 } 1999 2000 static int 2001 dpaa2_rc_io_reset(device_t dev, device_t child, struct dpaa2_cmd *cmd) 2002 { 2003 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2004 2005 if (portal == NULL || cmd == NULL) 2006 return (DPAA2_CMD_STAT_ERR); 2007 2008 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_IO_RESET)); 2009 } 2010 2011 static int 2012 dpaa2_rc_io_get_attributes(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2013 struct dpaa2_io_attr *attr) 2014 { 2015 struct __packed dpaa2_io_attr { 2016 uint32_t id; 2017 uint16_t swp_id; 2018 uint8_t priors_num; 2019 uint8_t chan_mode; 2020 uint64_t swp_ce_paddr; 2021 uint64_t swp_ci_paddr; 2022 uint32_t swp_version; 2023 uint32_t _reserved1; 2024 uint32_t swp_clk; 2025 uint32_t _reserved2[5]; 2026 } *pattr; 2027 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2028 int error; 2029 2030 if (portal == NULL || cmd == NULL || attr == NULL) 2031 return (DPAA2_CMD_STAT_ERR); 2032 2033 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_IO_GET_ATTR); 2034 if (!error) { 2035 pattr = (struct dpaa2_io_attr *) &cmd->params[0]; 2036 2037 attr->swp_ce_paddr = pattr->swp_ce_paddr; 2038 attr->swp_ci_paddr = pattr->swp_ci_paddr; 2039 attr->swp_version = pattr->swp_version; 2040 attr->swp_clk = pattr->swp_clk; 2041 attr->id = pattr->id; 2042 attr->swp_id = pattr->swp_id; 2043 attr->priors_num = pattr->priors_num; 2044 attr->chan_mode = (enum dpaa2_io_chan_mode) 2045 pattr->chan_mode; 2046 } 2047 2048 return (error); 2049 } 2050 2051 static int 2052 dpaa2_rc_io_set_irq_mask(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2053 uint8_t irq_idx, uint32_t mask) 2054 { 2055 /* TODO: Extract similar *_set_irq_mask() into one function. */ 2056 struct __packed set_irq_mask_args { 2057 uint32_t mask; 2058 uint8_t irq_idx; 2059 } *args; 2060 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2061 2062 if (portal == NULL || cmd == NULL) 2063 return (DPAA2_CMD_STAT_EINVAL); 2064 2065 dpaa2_rc_reset_cmd_params(cmd); 2066 2067 args = (struct set_irq_mask_args *) &cmd->params[0]; 2068 args->mask = mask; 2069 args->irq_idx = irq_idx; 2070 2071 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_IO_SET_IRQ_MASK)); 2072 } 2073 2074 static int 2075 dpaa2_rc_io_get_irq_status(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2076 uint8_t irq_idx, uint32_t *status) 2077 { 2078 /* TODO: Extract similar *_get_irq_status() into one function. */ 2079 struct __packed get_irq_stat_args { 2080 uint32_t status; 2081 uint8_t irq_idx; 2082 } *args; 2083 struct __packed get_irq_stat_resp { 2084 uint32_t status; 2085 } *resp; 2086 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2087 int error; 2088 2089 if (portal == NULL || cmd == NULL || status == NULL) 2090 return (DPAA2_CMD_STAT_EINVAL); 2091 2092 dpaa2_rc_reset_cmd_params(cmd); 2093 2094 args = (struct get_irq_stat_args *) &cmd->params[0]; 2095 args->status = *status; 2096 args->irq_idx = irq_idx; 2097 2098 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_IO_GET_IRQ_STATUS); 2099 if (!error) { 2100 resp = (struct get_irq_stat_resp *) &cmd->params[0]; 2101 *status = resp->status; 2102 } 2103 2104 return (error); 2105 } 2106 2107 static int 2108 dpaa2_rc_io_set_irq_enable(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2109 uint8_t irq_idx, bool en) 2110 { 2111 /* TODO: Extract similar *_set_irq_enable() into one function. */ 2112 struct __packed set_irq_enable_args { 2113 uint32_t en; 2114 uint8_t irq_idx; 2115 } *args; 2116 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2117 2118 if (portal == NULL || cmd == NULL) 2119 return (DPAA2_CMD_STAT_EINVAL); 2120 2121 dpaa2_rc_reset_cmd_params(cmd); 2122 2123 args = (struct set_irq_enable_args *) &cmd->params[0]; 2124 args->en = en ? 1u : 0u; 2125 args->irq_idx = irq_idx; 2126 2127 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_IO_SET_IRQ_ENABLE)); 2128 } 2129 2130 static int 2131 dpaa2_rc_io_add_static_dq_chan(device_t dev, device_t child, 2132 struct dpaa2_cmd *cmd, uint32_t dpcon_id, uint8_t *chan_idx) 2133 { 2134 struct __packed add_static_dq_chan_args { 2135 uint32_t dpcon_id; 2136 } *args; 2137 struct __packed add_static_dq_chan_resp { 2138 uint8_t chan_idx; 2139 } *resp; 2140 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2141 int error; 2142 2143 if (portal == NULL || cmd == NULL || chan_idx == NULL) 2144 return (DPAA2_CMD_STAT_EINVAL); 2145 2146 dpaa2_rc_reset_cmd_params(cmd); 2147 2148 args = (struct add_static_dq_chan_args *) &cmd->params[0]; 2149 args->dpcon_id = dpcon_id; 2150 2151 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_IO_ADD_STATIC_DQ_CHAN); 2152 if (!error) { 2153 resp = (struct add_static_dq_chan_resp *) &cmd->params[0]; 2154 *chan_idx = resp->chan_idx; 2155 } 2156 2157 return (error); 2158 } 2159 2160 static int 2161 dpaa2_rc_bp_open(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2162 uint32_t dpbp_id, uint16_t *token) 2163 { 2164 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2165 struct dpaa2_cmd_header *hdr; 2166 int error; 2167 2168 if (portal == NULL || cmd == NULL || token == NULL) 2169 return (DPAA2_CMD_STAT_ERR); 2170 2171 cmd->params[0] = dpbp_id; 2172 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_BP_OPEN); 2173 if (!error) { 2174 hdr = (struct dpaa2_cmd_header *) &cmd->header; 2175 *token = hdr->token; 2176 } 2177 2178 return (error); 2179 } 2180 2181 static int 2182 dpaa2_rc_bp_close(device_t dev, device_t child, struct dpaa2_cmd *cmd) 2183 { 2184 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2185 2186 if (portal == NULL || cmd == NULL) 2187 return (DPAA2_CMD_STAT_ERR); 2188 2189 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_BP_CLOSE)); 2190 } 2191 2192 static int 2193 dpaa2_rc_bp_enable(device_t dev, device_t child, struct dpaa2_cmd *cmd) 2194 { 2195 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2196 2197 if (portal == NULL || cmd == NULL) 2198 return (DPAA2_CMD_STAT_ERR); 2199 2200 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_BP_ENABLE)); 2201 } 2202 2203 static int 2204 dpaa2_rc_bp_disable(device_t dev, device_t child, struct dpaa2_cmd *cmd) 2205 { 2206 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2207 2208 if (portal == NULL || cmd == NULL) 2209 return (DPAA2_CMD_STAT_ERR); 2210 2211 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_BP_DISABLE)); 2212 } 2213 2214 static int 2215 dpaa2_rc_bp_reset(device_t dev, device_t child, struct dpaa2_cmd *cmd) 2216 { 2217 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2218 2219 if (portal == NULL || cmd == NULL) 2220 return (DPAA2_CMD_STAT_ERR); 2221 2222 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_BP_RESET)); 2223 } 2224 2225 static int 2226 dpaa2_rc_bp_get_attributes(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2227 struct dpaa2_bp_attr *attr) 2228 { 2229 struct __packed dpaa2_bp_attr { 2230 uint16_t _reserved1; 2231 uint16_t bpid; 2232 uint32_t id; 2233 } *pattr; 2234 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2235 int error; 2236 2237 if (portal == NULL || cmd == NULL || attr == NULL) 2238 return (DPAA2_CMD_STAT_ERR); 2239 2240 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_BP_GET_ATTR); 2241 if (!error) { 2242 pattr = (struct dpaa2_bp_attr *) &cmd->params[0]; 2243 attr->id = pattr->id; 2244 attr->bpid = pattr->bpid; 2245 } 2246 2247 return (error); 2248 } 2249 2250 static int 2251 dpaa2_rc_mac_open(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2252 uint32_t dpmac_id, uint16_t *token) 2253 { 2254 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2255 struct dpaa2_cmd_header *hdr; 2256 int error; 2257 2258 if (portal == NULL || cmd == NULL || token == NULL) 2259 return (DPAA2_CMD_STAT_ERR); 2260 2261 cmd->params[0] = dpmac_id; 2262 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_MAC_OPEN); 2263 if (!error) { 2264 hdr = (struct dpaa2_cmd_header *) &cmd->header; 2265 *token = hdr->token; 2266 } 2267 2268 return (error); 2269 } 2270 2271 static int 2272 dpaa2_rc_mac_close(device_t dev, device_t child, struct dpaa2_cmd *cmd) 2273 { 2274 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2275 2276 if (portal == NULL || cmd == NULL) 2277 return (DPAA2_CMD_STAT_ERR); 2278 2279 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_MAC_CLOSE)); 2280 } 2281 2282 static int 2283 dpaa2_rc_mac_reset(device_t dev, device_t child, struct dpaa2_cmd *cmd) 2284 { 2285 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2286 2287 if (portal == NULL || cmd == NULL) 2288 return (DPAA2_CMD_STAT_ERR); 2289 2290 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_MAC_RESET)); 2291 } 2292 2293 static int 2294 dpaa2_rc_mac_mdio_read(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2295 uint8_t phy, uint16_t reg, uint16_t *val) 2296 { 2297 struct __packed mdio_read_args { 2298 uint8_t clause; /* set to 0 by default */ 2299 uint8_t phy; 2300 uint16_t reg; 2301 uint32_t _reserved1; 2302 uint64_t _reserved2[6]; 2303 } *args; 2304 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2305 int error; 2306 2307 if (portal == NULL || cmd == NULL || val == NULL) 2308 return (DPAA2_CMD_STAT_ERR); 2309 2310 args = (struct mdio_read_args *) &cmd->params[0]; 2311 args->phy = phy; 2312 args->reg = reg; 2313 args->clause = 0; 2314 2315 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_MAC_MDIO_READ); 2316 if (!error) 2317 *val = cmd->params[0] & 0xFFFF; 2318 2319 return (error); 2320 } 2321 2322 static int 2323 dpaa2_rc_mac_mdio_write(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2324 uint8_t phy, uint16_t reg, uint16_t val) 2325 { 2326 struct __packed mdio_write_args { 2327 uint8_t clause; /* set to 0 by default */ 2328 uint8_t phy; 2329 uint16_t reg; 2330 uint16_t val; 2331 uint16_t _reserved1; 2332 uint64_t _reserved2[6]; 2333 } *args; 2334 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2335 2336 if (portal == NULL || cmd == NULL) 2337 return (DPAA2_CMD_STAT_ERR); 2338 2339 args = (struct mdio_write_args *) &cmd->params[0]; 2340 args->phy = phy; 2341 args->reg = reg; 2342 args->val = val; 2343 args->clause = 0; 2344 2345 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_MAC_MDIO_WRITE)); 2346 } 2347 2348 static int 2349 dpaa2_rc_mac_get_addr(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2350 uint8_t *mac) 2351 { 2352 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2353 int error; 2354 2355 if (portal == NULL || cmd == NULL || mac == NULL) 2356 return (DPAA2_CMD_STAT_ERR); 2357 2358 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_MAC_GET_ADDR); 2359 if (!error) { 2360 mac[0] = (cmd->params[0] >> 56) & 0xFFU; 2361 mac[1] = (cmd->params[0] >> 48) & 0xFFU; 2362 mac[2] = (cmd->params[0] >> 40) & 0xFFU; 2363 mac[3] = (cmd->params[0] >> 32) & 0xFFU; 2364 mac[4] = (cmd->params[0] >> 24) & 0xFFU; 2365 mac[5] = (cmd->params[0] >> 16) & 0xFFU; 2366 } 2367 2368 return (error); 2369 } 2370 2371 static int 2372 dpaa2_rc_mac_get_attributes(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2373 struct dpaa2_mac_attr *attr) 2374 { 2375 struct __packed mac_attr_resp { 2376 uint8_t eth_if; 2377 uint8_t link_type; 2378 uint16_t id; 2379 uint32_t max_rate; 2380 2381 uint8_t fec_mode; 2382 uint8_t ifg_mode; 2383 uint8_t ifg_len; 2384 uint8_t _reserved1; 2385 uint32_t _reserved2; 2386 2387 uint8_t sgn_post_pre; 2388 uint8_t serdes_cfg_mode; 2389 uint8_t eq_amp_red; 2390 uint8_t eq_post1q; 2391 uint8_t eq_preq; 2392 uint8_t eq_type; 2393 uint16_t _reserved3; 2394 2395 uint64_t _reserved[4]; 2396 } *resp; 2397 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2398 int error; 2399 2400 if (portal == NULL || cmd == NULL || attr == NULL) 2401 return (DPAA2_CMD_STAT_EINVAL); 2402 2403 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_MAC_GET_ATTR); 2404 if (!error) { 2405 resp = (struct mac_attr_resp *) &cmd->params[0]; 2406 attr->id = resp->id; 2407 attr->max_rate = resp->max_rate; 2408 attr->eth_if = resp->eth_if; 2409 attr->link_type = resp->link_type; 2410 } 2411 2412 return (error); 2413 } 2414 2415 static int 2416 dpaa2_rc_mac_set_link_state(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2417 struct dpaa2_mac_link_state *state) 2418 { 2419 struct __packed mac_set_link_args { 2420 uint64_t options; 2421 uint32_t rate; 2422 uint32_t _reserved1; 2423 uint32_t flags; 2424 uint32_t _reserved2; 2425 uint64_t supported; 2426 uint64_t advert; 2427 } *args; 2428 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2429 2430 if (portal == NULL || cmd == NULL || state == NULL) 2431 return (DPAA2_CMD_STAT_EINVAL); 2432 2433 dpaa2_rc_reset_cmd_params(cmd); 2434 2435 args = (struct mac_set_link_args *) &cmd->params[0]; 2436 args->options = state->options; 2437 args->rate = state->rate; 2438 args->supported = state->supported; 2439 args->advert = state->advert; 2440 2441 args->flags |= state->up ? 0x1u : 0u; 2442 args->flags |= state->state_valid ? 0x2u : 0u; 2443 2444 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_MAC_SET_LINK_STATE)); 2445 } 2446 2447 static int 2448 dpaa2_rc_mac_set_irq_mask(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2449 uint8_t irq_idx, uint32_t mask) 2450 { 2451 /* TODO: Implementation is the same as for ni_set_irq_mask(). */ 2452 struct __packed set_irq_mask_args { 2453 uint32_t mask; 2454 uint8_t irq_idx; 2455 } *args; 2456 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2457 2458 if (portal == NULL || cmd == NULL) 2459 return (DPAA2_CMD_STAT_EINVAL); 2460 2461 dpaa2_rc_reset_cmd_params(cmd); 2462 2463 args = (struct set_irq_mask_args *) &cmd->params[0]; 2464 args->mask = mask; 2465 args->irq_idx = irq_idx; 2466 2467 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_MAC_SET_IRQ_MASK)); 2468 } 2469 2470 static int 2471 dpaa2_rc_mac_set_irq_enable(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2472 uint8_t irq_idx, bool en) 2473 { 2474 /* TODO: Implementation is the same as for ni_set_irq_enable(). */ 2475 struct __packed set_irq_enable_args { 2476 uint32_t en; 2477 uint8_t irq_idx; 2478 } *args; 2479 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2480 2481 if (portal == NULL || cmd == NULL) 2482 return (DPAA2_CMD_STAT_EINVAL); 2483 2484 dpaa2_rc_reset_cmd_params(cmd); 2485 2486 args = (struct set_irq_enable_args *) &cmd->params[0]; 2487 args->en = en ? 1u : 0u; 2488 args->irq_idx = irq_idx; 2489 2490 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_MAC_SET_IRQ_ENABLE)); 2491 } 2492 2493 static int 2494 dpaa2_rc_mac_get_irq_status(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2495 uint8_t irq_idx, uint32_t *status) 2496 { 2497 /* TODO: Implementation is the same as ni_get_irq_status(). */ 2498 struct __packed get_irq_stat_args { 2499 uint32_t status; 2500 uint8_t irq_idx; 2501 } *args; 2502 struct __packed get_irq_stat_resp { 2503 uint32_t status; 2504 } *resp; 2505 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2506 int error; 2507 2508 if (portal == NULL || cmd == NULL || status == NULL) 2509 return (DPAA2_CMD_STAT_EINVAL); 2510 2511 dpaa2_rc_reset_cmd_params(cmd); 2512 2513 args = (struct get_irq_stat_args *) &cmd->params[0]; 2514 args->status = *status; 2515 args->irq_idx = irq_idx; 2516 2517 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_MAC_GET_IRQ_STATUS); 2518 if (!error) { 2519 resp = (struct get_irq_stat_resp *) &cmd->params[0]; 2520 *status = resp->status; 2521 } 2522 2523 return (error); 2524 } 2525 2526 static int 2527 dpaa2_rc_con_open(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2528 uint32_t dpcon_id, uint16_t *token) 2529 { 2530 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2531 struct dpaa2_cmd_header *hdr; 2532 int error; 2533 2534 if (portal == NULL || cmd == NULL || token == NULL) 2535 return (DPAA2_CMD_STAT_ERR); 2536 2537 cmd->params[0] = dpcon_id; 2538 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_CON_OPEN); 2539 if (!error) { 2540 hdr = (struct dpaa2_cmd_header *) &cmd->header; 2541 *token = hdr->token; 2542 } 2543 2544 return (error); 2545 } 2546 2547 2548 static int 2549 dpaa2_rc_con_close(device_t dev, device_t child, struct dpaa2_cmd *cmd) 2550 { 2551 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2552 2553 if (portal == NULL || cmd == NULL) 2554 return (DPAA2_CMD_STAT_ERR); 2555 2556 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_CON_CLOSE)); 2557 } 2558 2559 static int 2560 dpaa2_rc_con_reset(device_t dev, device_t child, struct dpaa2_cmd *cmd) 2561 { 2562 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2563 2564 if (portal == NULL || cmd == NULL) 2565 return (DPAA2_CMD_STAT_ERR); 2566 2567 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_CON_RESET)); 2568 } 2569 2570 static int 2571 dpaa2_rc_con_enable(device_t dev, device_t child, struct dpaa2_cmd *cmd) 2572 { 2573 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2574 2575 if (portal == NULL || cmd == NULL) 2576 return (DPAA2_CMD_STAT_ERR); 2577 2578 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_CON_ENABLE)); 2579 } 2580 2581 static int 2582 dpaa2_rc_con_disable(device_t dev, device_t child, struct dpaa2_cmd *cmd) 2583 { 2584 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2585 2586 if (portal == NULL || cmd == NULL) 2587 return (DPAA2_CMD_STAT_ERR); 2588 2589 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_CON_DISABLE)); 2590 } 2591 2592 static int 2593 dpaa2_rc_con_get_attributes(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2594 struct dpaa2_con_attr *attr) 2595 { 2596 struct __packed con_attr_resp { 2597 uint32_t id; 2598 uint16_t chan_id; 2599 uint8_t prior_num; 2600 uint8_t _reserved1; 2601 uint64_t _reserved2[6]; 2602 } *resp; 2603 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2604 int error; 2605 2606 if (portal == NULL || cmd == NULL || attr == NULL) 2607 return (DPAA2_CMD_STAT_EINVAL); 2608 2609 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_CON_GET_ATTR); 2610 if (!error) { 2611 resp = (struct con_attr_resp *) &cmd->params[0]; 2612 attr->id = resp->id; 2613 attr->chan_id = resp->chan_id; 2614 attr->prior_num = resp->prior_num; 2615 } 2616 2617 return (error); 2618 } 2619 2620 static int 2621 dpaa2_rc_con_set_notif(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2622 struct dpaa2_con_notif_cfg *cfg) 2623 { 2624 struct __packed set_notif_args { 2625 uint32_t dpio_id; 2626 uint8_t prior; 2627 uint8_t _reserved1; 2628 uint16_t _reserved2; 2629 uint64_t ctx; 2630 uint64_t _reserved3[5]; 2631 } *args; 2632 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2633 2634 if (portal == NULL || cmd == NULL || cfg == NULL) 2635 return (DPAA2_CMD_STAT_ERR); 2636 2637 args = (struct set_notif_args *) &cmd->params[0]; 2638 args->dpio_id = cfg->dpio_id; 2639 args->prior = cfg->prior; 2640 args->ctx = cfg->qman_ctx; 2641 2642 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_CON_SET_NOTIF)); 2643 } 2644 2645 static int 2646 dpaa2_rc_mcp_create(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2647 uint32_t portal_id, uint32_t options, uint32_t *dpmcp_id) 2648 { 2649 struct __packed mcp_create_args { 2650 uint32_t portal_id; 2651 uint32_t options; 2652 uint64_t _reserved[6]; 2653 } *args; 2654 struct __packed mcp_create_resp { 2655 uint32_t dpmcp_id; 2656 } *resp; 2657 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2658 int error; 2659 2660 if (portal == NULL || cmd == NULL || dpmcp_id == NULL) 2661 return (DPAA2_CMD_STAT_ERR); 2662 2663 args = (struct mcp_create_args *) &cmd->params[0]; 2664 args->portal_id = portal_id; 2665 args->options = options; 2666 2667 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_MCP_CREATE); 2668 if (!error) { 2669 resp = (struct mcp_create_resp *) &cmd->params[0]; 2670 *dpmcp_id = resp->dpmcp_id; 2671 } 2672 2673 return (error); 2674 } 2675 2676 static int 2677 dpaa2_rc_mcp_destroy(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2678 uint32_t dpmcp_id) 2679 { 2680 struct __packed mcp_destroy_args { 2681 uint32_t dpmcp_id; 2682 } *args; 2683 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2684 2685 if (portal == NULL || cmd == NULL) 2686 return (DPAA2_CMD_STAT_ERR); 2687 2688 args = (struct mcp_destroy_args *) &cmd->params[0]; 2689 args->dpmcp_id = dpmcp_id; 2690 2691 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_MCP_DESTROY)); 2692 } 2693 2694 static int 2695 dpaa2_rc_mcp_open(device_t dev, device_t child, struct dpaa2_cmd *cmd, 2696 uint32_t dpmcp_id, uint16_t *token) 2697 { 2698 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2699 struct dpaa2_cmd_header *hdr; 2700 int error; 2701 2702 if (portal == NULL || cmd == NULL || token == NULL) 2703 return (DPAA2_CMD_STAT_ERR); 2704 2705 cmd->params[0] = dpmcp_id; 2706 error = dpaa2_rc_exec_cmd(portal, cmd, CMDID_MCP_OPEN); 2707 if (!error) { 2708 hdr = (struct dpaa2_cmd_header *) &cmd->header; 2709 *token = hdr->token; 2710 } 2711 2712 return (error); 2713 } 2714 2715 static int 2716 dpaa2_rc_mcp_close(device_t dev, device_t child, struct dpaa2_cmd *cmd) 2717 { 2718 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2719 2720 if (portal == NULL || cmd == NULL) 2721 return (DPAA2_CMD_STAT_ERR); 2722 2723 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_MCP_CLOSE)); 2724 } 2725 2726 static int 2727 dpaa2_rc_mcp_reset(device_t dev, device_t child, struct dpaa2_cmd *cmd) 2728 { 2729 struct dpaa2_mcp *portal = dpaa2_rc_select_portal(dev, child); 2730 2731 if (portal == NULL || cmd == NULL) 2732 return (DPAA2_CMD_STAT_ERR); 2733 2734 return (dpaa2_rc_exec_cmd(portal, cmd, CMDID_MCP_RESET)); 2735 } 2736 2737 /** 2738 * @brief Create and add devices for DPAA2 objects in this resource container. 2739 */ 2740 static int 2741 dpaa2_rc_discover(struct dpaa2_rc_softc *sc) 2742 { 2743 device_t rcdev = sc->dev; 2744 device_t child = sc->dev; 2745 struct dpaa2_devinfo *rcinfo = device_get_ivars(rcdev); 2746 struct dpaa2_cmd cmd; 2747 struct dpaa2_rc_attr dprc_attr; 2748 struct dpaa2_obj obj; 2749 uint32_t major, minor, rev, obj_count; 2750 uint16_t rc_token; 2751 int rc; 2752 2753 DPAA2_CMD_INIT(&cmd); 2754 2755 /* Print MC firmware version. */ 2756 rc = DPAA2_CMD_MNG_GET_VERSION(rcdev, child, &cmd, &major, &minor, &rev); 2757 if (rc) { 2758 device_printf(rcdev, "%s: failed to get MC firmware version: " 2759 "error=%d\n", __func__, rc); 2760 return (ENXIO); 2761 } 2762 device_printf(rcdev, "MC firmware version: %u.%u.%u\n", major, minor, 2763 rev); 2764 2765 /* Obtain container ID associated with a given MC portal. */ 2766 rc = DPAA2_CMD_MNG_GET_CONTAINER_ID(rcdev, child, &cmd, &sc->cont_id); 2767 if (rc) { 2768 device_printf(rcdev, "%s: failed to get container id: " 2769 "error=%d\n", __func__, rc); 2770 return (ENXIO); 2771 } 2772 if (bootverbose) { 2773 device_printf(rcdev, "Resource container ID: %u\n", sc->cont_id); 2774 } 2775 2776 /* Open the resource container. */ 2777 rc = DPAA2_CMD_RC_OPEN(rcdev, child, &cmd, sc->cont_id, &rc_token); 2778 if (rc) { 2779 device_printf(rcdev, "%s: failed to open container: cont_id=%u, " 2780 "error=%d\n", __func__, sc->cont_id, rc); 2781 return (ENXIO); 2782 } 2783 2784 /* Obtain a number of objects in this container. */ 2785 rc = DPAA2_CMD_RC_GET_OBJ_COUNT(rcdev, child, &cmd, &obj_count); 2786 if (rc) { 2787 device_printf(rcdev, "%s: failed to count objects in container: " 2788 "cont_id=%u, error=%d\n", __func__, sc->cont_id, rc); 2789 (void)DPAA2_CMD_RC_CLOSE(rcdev, child, &cmd); 2790 return (ENXIO); 2791 } 2792 if (bootverbose) { 2793 device_printf(rcdev, "Objects in container: %u\n", obj_count); 2794 } 2795 2796 rc = DPAA2_CMD_RC_GET_ATTRIBUTES(rcdev, child, &cmd, &dprc_attr); 2797 if (rc) { 2798 device_printf(rcdev, "%s: failed to get attributes of the " 2799 "container: cont_id=%u, error=%d\n", __func__, sc->cont_id, 2800 rc); 2801 DPAA2_CMD_RC_CLOSE(rcdev, child, &cmd); 2802 return (ENXIO); 2803 } 2804 if (bootverbose) { 2805 device_printf(rcdev, "Isolation context ID: %u\n", 2806 dprc_attr.icid); 2807 } 2808 if (rcinfo) { 2809 rcinfo->id = dprc_attr.cont_id; 2810 rcinfo->portal_id = dprc_attr.portal_id; 2811 rcinfo->icid = dprc_attr.icid; 2812 } 2813 2814 /* 2815 * Add MC portals before everything else. 2816 * TODO: Discover DPAA2 objects on-demand. 2817 */ 2818 for (uint32_t i = 0; i < obj_count; i++) { 2819 rc = DPAA2_CMD_RC_GET_OBJ(rcdev, child, &cmd, i, &obj); 2820 if (rc) { 2821 continue; /* Skip silently for now. */ 2822 } 2823 if (obj.type != DPAA2_DEV_MCP) { 2824 continue; 2825 } 2826 dpaa2_rc_add_managed_child(sc, &cmd, &obj); 2827 } 2828 /* Probe and attach MC portals. */ 2829 bus_identify_children(rcdev); 2830 bus_attach_children(rcdev); 2831 2832 /* Add managed devices (except DPMCPs) to the resource container. */ 2833 for (uint32_t i = 0; i < obj_count; i++) { 2834 rc = DPAA2_CMD_RC_GET_OBJ(rcdev, child, &cmd, i, &obj); 2835 if (rc && bootverbose) { 2836 if (rc == DPAA2_CMD_STAT_UNKNOWN_OBJ) { 2837 device_printf(rcdev, "%s: skip unsupported " 2838 "DPAA2 object: idx=%u\n", __func__, i); 2839 continue; 2840 } else { 2841 device_printf(rcdev, "%s: failed to get " 2842 "information about DPAA2 object: idx=%u, " 2843 "error=%d\n", __func__, i, rc); 2844 continue; 2845 } 2846 } 2847 if (obj.type == DPAA2_DEV_MCP) { 2848 continue; /* Already added. */ 2849 } 2850 dpaa2_rc_add_managed_child(sc, &cmd, &obj); 2851 } 2852 /* Probe and attach managed devices properly. */ 2853 bus_identify_children(rcdev); 2854 bus_attach_children(rcdev); 2855 2856 /* Add other devices to the resource container. */ 2857 for (uint32_t i = 0; i < obj_count; i++) { 2858 rc = DPAA2_CMD_RC_GET_OBJ(rcdev, child, &cmd, i, &obj); 2859 if (rc == DPAA2_CMD_STAT_UNKNOWN_OBJ && bootverbose) { 2860 device_printf(rcdev, "%s: skip unsupported DPAA2 " 2861 "object: idx=%u\n", __func__, i); 2862 continue; 2863 } else if (rc) { 2864 device_printf(rcdev, "%s: failed to get object: " 2865 "idx=%u, error=%d\n", __func__, i, rc); 2866 continue; 2867 } 2868 dpaa2_rc_add_child(sc, &cmd, &obj); 2869 } 2870 2871 DPAA2_CMD_RC_CLOSE(rcdev, child, &cmd); 2872 2873 /* Probe and attach the rest of devices. */ 2874 bus_identify_children(rcdev); 2875 bus_attach_children(rcdev); 2876 return (0); 2877 } 2878 2879 /** 2880 * @brief Add a new DPAA2 device to the resource container bus. 2881 */ 2882 static int 2883 dpaa2_rc_add_child(struct dpaa2_rc_softc *sc, struct dpaa2_cmd *cmd, 2884 struct dpaa2_obj *obj) 2885 { 2886 device_t rcdev, dev; 2887 struct dpaa2_devinfo *rcinfo; 2888 struct dpaa2_devinfo *dinfo; 2889 struct resource_spec *res_spec; 2890 const char *devclass; 2891 int dpio_n = 0; /* to limit DPIOs by # of CPUs */ 2892 int dpcon_n = 0; /* to limit DPCONs by # of CPUs */ 2893 int rid, error; 2894 2895 rcdev = sc->dev; 2896 rcinfo = device_get_ivars(rcdev); 2897 2898 switch (obj->type) { 2899 case DPAA2_DEV_NI: 2900 devclass = "dpaa2_ni"; 2901 res_spec = dpaa2_ni_spec; 2902 break; 2903 default: 2904 return (ENXIO); 2905 } 2906 2907 /* Add a device for the DPAA2 object. */ 2908 dev = device_add_child(rcdev, devclass, -1); 2909 if (dev == NULL) { 2910 device_printf(rcdev, "%s: failed to add a device for DPAA2 " 2911 "object: type=%s, id=%u\n", __func__, dpaa2_ttos(obj->type), 2912 obj->id); 2913 return (ENXIO); 2914 } 2915 2916 /* Allocate devinfo for a child. */ 2917 dinfo = malloc(sizeof(struct dpaa2_devinfo), M_DPAA2_RC, 2918 M_WAITOK | M_ZERO); 2919 if (!dinfo) { 2920 device_printf(rcdev, "%s: failed to allocate dpaa2_devinfo " 2921 "for: type=%s, id=%u\n", __func__, dpaa2_ttos(obj->type), 2922 obj->id); 2923 return (ENXIO); 2924 } 2925 device_set_ivars(dev, dinfo); 2926 2927 dinfo->pdev = rcdev; 2928 dinfo->dev = dev; 2929 dinfo->id = obj->id; 2930 dinfo->dtype = obj->type; 2931 dinfo->portal = NULL; 2932 /* Children share their parent container's ICID and portal ID. */ 2933 dinfo->icid = rcinfo->icid; 2934 dinfo->portal_id = rcinfo->portal_id; 2935 /* MSI configuration */ 2936 dinfo->msi.msi_msgnum = obj->irq_count; 2937 dinfo->msi.msi_alloc = 0; 2938 dinfo->msi.msi_handlers = 0; 2939 2940 /* Initialize a resource list for the child. */ 2941 resource_list_init(&dinfo->resources); 2942 2943 /* Add DPAA2-specific resources to the resource list. */ 2944 for (; res_spec && res_spec->type != -1; res_spec++) { 2945 if (res_spec->type < DPAA2_DEV_MC) 2946 continue; /* Skip non-DPAA2 resource. */ 2947 rid = res_spec->rid; 2948 2949 /* Limit DPIOs and DPCONs by number of CPUs. */ 2950 if (res_spec->type == DPAA2_DEV_IO && dpio_n >= mp_ncpus) { 2951 dpio_n++; 2952 continue; 2953 } 2954 if (res_spec->type == DPAA2_DEV_CON && dpcon_n >= mp_ncpus) { 2955 dpcon_n++; 2956 continue; 2957 } 2958 2959 error = dpaa2_rc_add_res(rcdev, dev, res_spec->type, &rid, 2960 res_spec->flags); 2961 if (error) 2962 device_printf(rcdev, "%s: dpaa2_rc_add_res() failed: " 2963 "error=%d\n", __func__, error); 2964 2965 if (res_spec->type == DPAA2_DEV_IO) 2966 dpio_n++; 2967 if (res_spec->type == DPAA2_DEV_CON) 2968 dpcon_n++; 2969 } 2970 2971 return (0); 2972 } 2973 2974 /** 2975 * @brief Add a new managed DPAA2 device to the resource container bus. 2976 * 2977 * There are DPAA2 objects (DPIO, DPBP) which have their own drivers and can be 2978 * allocated as resources or associated with the other DPAA2 objects. This 2979 * function is supposed to discover such managed objects in the resource 2980 * container and add them as children to perform a proper initialization. 2981 * 2982 * NOTE: It must be called together with bus_identify_children() and 2983 * bus_attach_children() before dpaa2_rc_add_child(). 2984 */ 2985 static int 2986 dpaa2_rc_add_managed_child(struct dpaa2_rc_softc *sc, struct dpaa2_cmd *cmd, 2987 struct dpaa2_obj *obj) 2988 { 2989 device_t rcdev, dev, child; 2990 struct dpaa2_devinfo *rcinfo, *dinfo; 2991 struct dpaa2_rc_obj_region reg; 2992 struct resource_spec *res_spec; 2993 const char *devclass; 2994 uint64_t start, end, count; 2995 uint32_t flags = 0; 2996 int rid, error; 2997 2998 rcdev = sc->dev; 2999 child = sc->dev; 3000 rcinfo = device_get_ivars(rcdev); 3001 3002 switch (obj->type) { 3003 case DPAA2_DEV_IO: 3004 devclass = "dpaa2_io"; 3005 res_spec = dpaa2_io_spec; 3006 flags = DPAA2_MC_DEV_ALLOCATABLE | DPAA2_MC_DEV_SHAREABLE; 3007 break; 3008 case DPAA2_DEV_BP: 3009 devclass = "dpaa2_bp"; 3010 res_spec = dpaa2_bp_spec; 3011 flags = DPAA2_MC_DEV_ALLOCATABLE; 3012 break; 3013 case DPAA2_DEV_CON: 3014 devclass = "dpaa2_con"; 3015 res_spec = dpaa2_con_spec; 3016 flags = DPAA2_MC_DEV_ALLOCATABLE; 3017 break; 3018 case DPAA2_DEV_MAC: 3019 devclass = "dpaa2_mac"; 3020 res_spec = dpaa2_mac_spec; 3021 flags = DPAA2_MC_DEV_ASSOCIATED; 3022 break; 3023 case DPAA2_DEV_MCP: 3024 devclass = "dpaa2_mcp"; 3025 res_spec = NULL; 3026 flags = DPAA2_MC_DEV_ALLOCATABLE | DPAA2_MC_DEV_SHAREABLE; 3027 break; 3028 default: 3029 /* Only managed devices above are supported. */ 3030 return (EINVAL); 3031 } 3032 3033 /* Add a device for the DPAA2 object. */ 3034 dev = device_add_child(rcdev, devclass, -1); 3035 if (dev == NULL) { 3036 device_printf(rcdev, "%s: failed to add a device for DPAA2 " 3037 "object: type=%s, id=%u\n", __func__, dpaa2_ttos(obj->type), 3038 obj->id); 3039 return (ENXIO); 3040 } 3041 3042 /* Allocate devinfo for the child. */ 3043 dinfo = malloc(sizeof(struct dpaa2_devinfo), M_DPAA2_RC, 3044 M_WAITOK | M_ZERO); 3045 if (!dinfo) { 3046 device_printf(rcdev, "%s: failed to allocate dpaa2_devinfo " 3047 "for: type=%s, id=%u\n", __func__, dpaa2_ttos(obj->type), 3048 obj->id); 3049 return (ENXIO); 3050 } 3051 device_set_ivars(dev, dinfo); 3052 3053 dinfo->pdev = rcdev; 3054 dinfo->dev = dev; 3055 dinfo->id = obj->id; 3056 dinfo->dtype = obj->type; 3057 dinfo->portal = NULL; 3058 /* Children share their parent container's ICID and portal ID. */ 3059 dinfo->icid = rcinfo->icid; 3060 dinfo->portal_id = rcinfo->portal_id; 3061 /* MSI configuration */ 3062 dinfo->msi.msi_msgnum = obj->irq_count; 3063 dinfo->msi.msi_alloc = 0; 3064 dinfo->msi.msi_handlers = 0; 3065 3066 /* Initialize a resource list for the child. */ 3067 resource_list_init(&dinfo->resources); 3068 3069 /* Add memory regions to the resource list. */ 3070 for (uint8_t i = 0; i < obj->reg_count; i++) { 3071 error = DPAA2_CMD_RC_GET_OBJ_REGION(rcdev, child, cmd, obj->id, 3072 i, obj->type, ®); 3073 if (error) { 3074 device_printf(rcdev, "%s: failed to obtain memory " 3075 "region for type=%s, id=%u, reg_idx=%u: error=%d\n", 3076 __func__, dpaa2_ttos(obj->type), obj->id, i, error); 3077 continue; 3078 } 3079 count = reg.size; 3080 start = reg.base_paddr + reg.base_offset; 3081 end = reg.base_paddr + reg.base_offset + reg.size - 1; 3082 3083 resource_list_add(&dinfo->resources, SYS_RES_MEMORY, i, start, 3084 end, count); 3085 } 3086 3087 /* Add DPAA2-specific resources to the resource list. */ 3088 for (; res_spec && res_spec->type != -1; res_spec++) { 3089 if (res_spec->type < DPAA2_DEV_MC) 3090 continue; /* Skip non-DPAA2 resource. */ 3091 rid = res_spec->rid; 3092 3093 error = dpaa2_rc_add_res(rcdev, dev, res_spec->type, &rid, 3094 res_spec->flags); 3095 if (error) 3096 device_printf(rcdev, "%s: dpaa2_rc_add_res() failed: " 3097 "error=%d\n", __func__, error); 3098 } 3099 3100 /* Inform MC about a new managed device. */ 3101 error = DPAA2_MC_MANAGE_DEV(rcdev, dev, flags); 3102 if (error) { 3103 device_printf(rcdev, "%s: failed to add a managed DPAA2 device: " 3104 "type=%s, id=%u, error=%d\n", __func__, 3105 dpaa2_ttos(obj->type), obj->id, error); 3106 return (ENXIO); 3107 } 3108 3109 return (0); 3110 } 3111 3112 /** 3113 * @brief Configure given IRQ using MC command interface. 3114 */ 3115 static int 3116 dpaa2_rc_configure_irq(device_t rcdev, device_t child, int rid, uint64_t addr, 3117 uint32_t data) 3118 { 3119 struct dpaa2_devinfo *rcinfo; 3120 struct dpaa2_devinfo *dinfo; 3121 struct dpaa2_cmd cmd; 3122 uint16_t rc_token; 3123 int rc = EINVAL; 3124 3125 DPAA2_CMD_INIT(&cmd); 3126 3127 if (device_get_parent(child) == rcdev && rid >= 1) { 3128 rcinfo = device_get_ivars(rcdev); 3129 dinfo = device_get_ivars(child); 3130 3131 rc = DPAA2_CMD_RC_OPEN(rcdev, child, &cmd, rcinfo->id, 3132 &rc_token); 3133 if (rc) { 3134 device_printf(rcdev, "%s: failed to open DPRC: " 3135 "error=%d\n", __func__, rc); 3136 return (ENODEV); 3137 } 3138 /* Set MSI address and value. */ 3139 rc = DPAA2_CMD_RC_SET_OBJ_IRQ(rcdev, child, &cmd, rid - 1, addr, 3140 data, rid, dinfo->id, dinfo->dtype); 3141 if (rc) { 3142 device_printf(rcdev, "%s: failed to setup IRQ: " 3143 "rid=%d, addr=%jx, data=%x, error=%d\n", __func__, 3144 rid, addr, data, rc); 3145 return (ENODEV); 3146 } 3147 rc = DPAA2_CMD_RC_CLOSE(rcdev, child, &cmd); 3148 if (rc) { 3149 device_printf(rcdev, "%s: failed to close DPRC: " 3150 "error=%d\n", __func__, rc); 3151 return (ENODEV); 3152 } 3153 rc = 0; 3154 } 3155 3156 return (rc); 3157 } 3158 3159 /** 3160 * @brief General implementation of the MC command to enable IRQ. 3161 */ 3162 static int 3163 dpaa2_rc_enable_irq(struct dpaa2_mcp *mcp, struct dpaa2_cmd *cmd, 3164 uint8_t irq_idx, bool enable, uint16_t cmdid) 3165 { 3166 struct __packed enable_irq_args { 3167 uint8_t enable; 3168 uint8_t _reserved1; 3169 uint16_t _reserved2; 3170 uint8_t irq_idx; 3171 uint8_t _reserved3; 3172 uint16_t _reserved4; 3173 uint64_t _reserved5[6]; 3174 } *args; 3175 3176 if (!mcp || !cmd) 3177 return (DPAA2_CMD_STAT_ERR); 3178 3179 args = (struct enable_irq_args *) &cmd->params[0]; 3180 args->irq_idx = irq_idx; 3181 args->enable = enable == 0u ? 0u : 1u; 3182 3183 return (dpaa2_rc_exec_cmd(mcp, cmd, cmdid)); 3184 } 3185 3186 /** 3187 * @brief Sends a command to MC and waits for response. 3188 */ 3189 static int 3190 dpaa2_rc_exec_cmd(struct dpaa2_mcp *mcp, struct dpaa2_cmd *cmd, uint16_t cmdid) 3191 { 3192 struct dpaa2_cmd_header *hdr; 3193 uint16_t flags; 3194 int error; 3195 3196 if (!mcp || !cmd) 3197 return (DPAA2_CMD_STAT_ERR); 3198 3199 /* Prepare a command for the MC hardware. */ 3200 hdr = (struct dpaa2_cmd_header *) &cmd->header; 3201 hdr->cmdid = cmdid; 3202 hdr->status = DPAA2_CMD_STAT_READY; 3203 3204 DPAA2_MCP_LOCK(mcp, &flags); 3205 if (flags & DPAA2_PORTAL_DESTROYED) { 3206 /* Terminate operation if portal is destroyed. */ 3207 DPAA2_MCP_UNLOCK(mcp); 3208 return (DPAA2_CMD_STAT_INVALID_STATE); 3209 } 3210 3211 /* Send a command to MC and wait for the result. */ 3212 dpaa2_rc_send_cmd(mcp, cmd); 3213 error = dpaa2_rc_wait_for_cmd(mcp, cmd); 3214 if (error) { 3215 DPAA2_MCP_UNLOCK(mcp); 3216 return (DPAA2_CMD_STAT_ERR); 3217 } 3218 if (hdr->status != DPAA2_CMD_STAT_OK) { 3219 DPAA2_MCP_UNLOCK(mcp); 3220 return (int)(hdr->status); 3221 } 3222 3223 DPAA2_MCP_UNLOCK(mcp); 3224 3225 return (DPAA2_CMD_STAT_OK); 3226 } 3227 3228 /** 3229 * @brief Writes a command to the MC command portal. 3230 */ 3231 static int 3232 dpaa2_rc_send_cmd(struct dpaa2_mcp *mcp, struct dpaa2_cmd *cmd) 3233 { 3234 /* Write command parameters. */ 3235 for (uint32_t i = 1; i <= DPAA2_CMD_PARAMS_N; i++) 3236 bus_write_8(mcp->map, sizeof(uint64_t) * i, cmd->params[i-1]); 3237 3238 bus_barrier(mcp->map, 0, sizeof(struct dpaa2_cmd), 3239 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 3240 3241 /* Write command header to trigger execution. */ 3242 bus_write_8(mcp->map, 0, cmd->header); 3243 3244 return (0); 3245 } 3246 3247 /** 3248 * @brief Polls the MC command portal in order to receive a result of the 3249 * command execution. 3250 */ 3251 static int 3252 dpaa2_rc_wait_for_cmd(struct dpaa2_mcp *mcp, struct dpaa2_cmd *cmd) 3253 { 3254 struct dpaa2_cmd_header *hdr; 3255 uint64_t val; 3256 uint32_t i; 3257 3258 /* Wait for a command execution result from the MC hardware. */ 3259 for (i = 1; i <= CMD_SPIN_ATTEMPTS; i++) { 3260 val = bus_read_8(mcp->map, 0); 3261 hdr = (struct dpaa2_cmd_header *) &val; 3262 if (hdr->status != DPAA2_CMD_STAT_READY) { 3263 break; 3264 } 3265 DELAY(CMD_SPIN_TIMEOUT); 3266 } 3267 3268 if (i > CMD_SPIN_ATTEMPTS) { 3269 /* Return an error on expired timeout. */ 3270 return (DPAA2_CMD_STAT_TIMEOUT); 3271 } else { 3272 /* Read command response. */ 3273 cmd->header = val; 3274 for (i = 1; i <= DPAA2_CMD_PARAMS_N; i++) { 3275 cmd->params[i-1] = 3276 bus_read_8(mcp->map, i * sizeof(uint64_t)); 3277 } 3278 } 3279 3280 return (DPAA2_CMD_STAT_OK); 3281 } 3282 3283 /** 3284 * @brief Reserve a DPAA2-specific device of the given devtype for the child. 3285 */ 3286 static int 3287 dpaa2_rc_add_res(device_t rcdev, device_t child, enum dpaa2_dev_type devtype, 3288 int *rid, int flags) 3289 { 3290 device_t dpaa2_dev; 3291 struct dpaa2_devinfo *dinfo = device_get_ivars(child); 3292 struct resource *res; 3293 bool shared = false; 3294 int error; 3295 3296 /* Request a free DPAA2 device of the given type from MC. */ 3297 error = DPAA2_MC_GET_FREE_DEV(rcdev, &dpaa2_dev, devtype); 3298 if (error && !(flags & RF_SHAREABLE)) { 3299 device_printf(rcdev, "%s: failed to obtain a free %s (rid=%d) " 3300 "for: %s (id=%u)\n", __func__, dpaa2_ttos(devtype), *rid, 3301 dpaa2_ttos(dinfo->dtype), dinfo->id); 3302 return (error); 3303 } 3304 3305 /* Request a shared DPAA2 device of the given type from MC. */ 3306 if (error) { 3307 error = DPAA2_MC_GET_SHARED_DEV(rcdev, &dpaa2_dev, devtype); 3308 if (error) { 3309 device_printf(rcdev, "%s: failed to obtain a shared " 3310 "%s (rid=%d) for: %s (id=%u)\n", __func__, 3311 dpaa2_ttos(devtype), *rid, dpaa2_ttos(dinfo->dtype), 3312 dinfo->id); 3313 return (error); 3314 } 3315 shared = true; 3316 } 3317 3318 /* Add DPAA2 device to the resource list of the child device. */ 3319 resource_list_add(&dinfo->resources, devtype, *rid, 3320 (rman_res_t) dpaa2_dev, (rman_res_t) dpaa2_dev, 1); 3321 3322 /* Reserve a newly added DPAA2 resource. */ 3323 res = resource_list_reserve(&dinfo->resources, rcdev, child, devtype, 3324 rid, (rman_res_t) dpaa2_dev, (rman_res_t) dpaa2_dev, 1, 3325 flags & ~RF_ACTIVE); 3326 if (!res) { 3327 device_printf(rcdev, "%s: failed to reserve %s (rid=%d) for: %s " 3328 "(id=%u)\n", __func__, dpaa2_ttos(devtype), *rid, 3329 dpaa2_ttos(dinfo->dtype), dinfo->id); 3330 return (EBUSY); 3331 } 3332 3333 /* Reserve a shared DPAA2 device of the given type. */ 3334 if (shared) { 3335 error = DPAA2_MC_RESERVE_DEV(rcdev, dpaa2_dev, devtype); 3336 if (error) { 3337 device_printf(rcdev, "%s: failed to reserve a shared " 3338 "%s (rid=%d) for: %s (id=%u)\n", __func__, 3339 dpaa2_ttos(devtype), *rid, dpaa2_ttos(dinfo->dtype), 3340 dinfo->id); 3341 return (error); 3342 } 3343 } 3344 3345 return (0); 3346 } 3347 3348 static int 3349 dpaa2_rc_print_type(struct resource_list *rl, enum dpaa2_dev_type type) 3350 { 3351 struct dpaa2_devinfo *dinfo; 3352 struct resource_list_entry *rle; 3353 uint32_t prev_id; 3354 int printed = 0, series = 0; 3355 int retval = 0; 3356 3357 STAILQ_FOREACH(rle, rl, link) { 3358 if (rle->type == type) { 3359 dinfo = device_get_ivars((device_t) rle->start); 3360 3361 if (printed == 0) { 3362 retval += printf(" %s (id=", 3363 dpaa2_ttos(dinfo->dtype)); 3364 } else { 3365 if (dinfo->id == prev_id + 1) { 3366 if (series == 0) { 3367 series = 1; 3368 retval += printf("-"); 3369 } 3370 } else { 3371 if (series == 1) { 3372 retval += printf("%u", prev_id); 3373 series = 0; 3374 } 3375 retval += printf(","); 3376 } 3377 } 3378 printed++; 3379 3380 if (series == 0) 3381 retval += printf("%u", dinfo->id); 3382 prev_id = dinfo->id; 3383 } 3384 } 3385 if (printed) { 3386 if (series == 1) 3387 retval += printf("%u", prev_id); 3388 retval += printf(")"); 3389 } 3390 3391 return (retval); 3392 } 3393 3394 static int 3395 dpaa2_rc_reset_cmd_params(struct dpaa2_cmd *cmd) 3396 { 3397 if (cmd != NULL) { 3398 memset(cmd->params, 0, sizeof(cmd->params[0]) * 3399 DPAA2_CMD_PARAMS_N); 3400 } 3401 return (0); 3402 } 3403 3404 static struct dpaa2_mcp * 3405 dpaa2_rc_select_portal(device_t dev, device_t child) 3406 { 3407 struct dpaa2_devinfo *dinfo = device_get_ivars(dev); 3408 struct dpaa2_devinfo *cinfo = device_get_ivars(child); 3409 3410 if (cinfo == NULL || dinfo == NULL || dinfo->dtype != DPAA2_DEV_RC) 3411 return (NULL); 3412 return (cinfo->portal != NULL ? cinfo->portal : dinfo->portal); 3413 } 3414 3415 static device_method_t dpaa2_rc_methods[] = { 3416 /* Device interface */ 3417 DEVMETHOD(device_probe, dpaa2_rc_probe), 3418 DEVMETHOD(device_attach, dpaa2_rc_attach), 3419 DEVMETHOD(device_detach, dpaa2_rc_detach), 3420 3421 /* Bus interface */ 3422 DEVMETHOD(bus_get_resource_list, dpaa2_rc_get_resource_list), 3423 DEVMETHOD(bus_delete_resource, dpaa2_rc_delete_resource), 3424 DEVMETHOD(bus_alloc_resource, dpaa2_rc_alloc_resource), 3425 DEVMETHOD(bus_release_resource, dpaa2_rc_release_resource), 3426 DEVMETHOD(bus_child_deleted, dpaa2_rc_child_deleted), 3427 DEVMETHOD(bus_child_detached, dpaa2_rc_child_detached), 3428 DEVMETHOD(bus_setup_intr, dpaa2_rc_setup_intr), 3429 DEVMETHOD(bus_teardown_intr, dpaa2_rc_teardown_intr), 3430 DEVMETHOD(bus_print_child, dpaa2_rc_print_child), 3431 DEVMETHOD(bus_add_child, device_add_child_ordered), 3432 DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), 3433 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), 3434 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 3435 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 3436 DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), 3437 3438 /* Pseudo-PCI interface */ 3439 DEVMETHOD(pci_alloc_msi, dpaa2_rc_alloc_msi), 3440 DEVMETHOD(pci_release_msi, dpaa2_rc_release_msi), 3441 DEVMETHOD(pci_msi_count, dpaa2_rc_msi_count), 3442 DEVMETHOD(pci_get_id, dpaa2_rc_get_id), 3443 3444 /* DPAA2 MC command interface */ 3445 DEVMETHOD(dpaa2_cmd_mng_get_version, dpaa2_rc_mng_get_version), 3446 DEVMETHOD(dpaa2_cmd_mng_get_soc_version, dpaa2_rc_mng_get_soc_version), 3447 DEVMETHOD(dpaa2_cmd_mng_get_container_id, dpaa2_rc_mng_get_container_id), 3448 /* DPRC commands */ 3449 DEVMETHOD(dpaa2_cmd_rc_open, dpaa2_rc_open), 3450 DEVMETHOD(dpaa2_cmd_rc_close, dpaa2_rc_close), 3451 DEVMETHOD(dpaa2_cmd_rc_get_obj_count, dpaa2_rc_get_obj_count), 3452 DEVMETHOD(dpaa2_cmd_rc_get_obj, dpaa2_rc_get_obj), 3453 DEVMETHOD(dpaa2_cmd_rc_get_obj_descriptor, dpaa2_rc_get_obj_descriptor), 3454 DEVMETHOD(dpaa2_cmd_rc_get_attributes, dpaa2_rc_get_attributes), 3455 DEVMETHOD(dpaa2_cmd_rc_get_obj_region, dpaa2_rc_get_obj_region), 3456 DEVMETHOD(dpaa2_cmd_rc_get_api_version, dpaa2_rc_get_api_version), 3457 DEVMETHOD(dpaa2_cmd_rc_set_irq_enable, dpaa2_rc_set_irq_enable), 3458 DEVMETHOD(dpaa2_cmd_rc_set_obj_irq, dpaa2_rc_set_obj_irq), 3459 DEVMETHOD(dpaa2_cmd_rc_get_conn, dpaa2_rc_get_conn), 3460 /* DPNI commands */ 3461 DEVMETHOD(dpaa2_cmd_ni_open, dpaa2_rc_ni_open), 3462 DEVMETHOD(dpaa2_cmd_ni_close, dpaa2_rc_ni_close), 3463 DEVMETHOD(dpaa2_cmd_ni_enable, dpaa2_rc_ni_enable), 3464 DEVMETHOD(dpaa2_cmd_ni_disable, dpaa2_rc_ni_disable), 3465 DEVMETHOD(dpaa2_cmd_ni_get_api_version, dpaa2_rc_ni_get_api_version), 3466 DEVMETHOD(dpaa2_cmd_ni_reset, dpaa2_rc_ni_reset), 3467 DEVMETHOD(dpaa2_cmd_ni_get_attributes, dpaa2_rc_ni_get_attributes), 3468 DEVMETHOD(dpaa2_cmd_ni_set_buf_layout, dpaa2_rc_ni_set_buf_layout), 3469 DEVMETHOD(dpaa2_cmd_ni_get_tx_data_off, dpaa2_rc_ni_get_tx_data_offset), 3470 DEVMETHOD(dpaa2_cmd_ni_get_port_mac_addr, dpaa2_rc_ni_get_port_mac_addr), 3471 DEVMETHOD(dpaa2_cmd_ni_set_prim_mac_addr, dpaa2_rc_ni_set_prim_mac_addr), 3472 DEVMETHOD(dpaa2_cmd_ni_get_prim_mac_addr, dpaa2_rc_ni_get_prim_mac_addr), 3473 DEVMETHOD(dpaa2_cmd_ni_set_link_cfg, dpaa2_rc_ni_set_link_cfg), 3474 DEVMETHOD(dpaa2_cmd_ni_get_link_cfg, dpaa2_rc_ni_get_link_cfg), 3475 DEVMETHOD(dpaa2_cmd_ni_get_link_state, dpaa2_rc_ni_get_link_state), 3476 DEVMETHOD(dpaa2_cmd_ni_set_qos_table, dpaa2_rc_ni_set_qos_table), 3477 DEVMETHOD(dpaa2_cmd_ni_clear_qos_table, dpaa2_rc_ni_clear_qos_table), 3478 DEVMETHOD(dpaa2_cmd_ni_set_pools, dpaa2_rc_ni_set_pools), 3479 DEVMETHOD(dpaa2_cmd_ni_set_err_behavior,dpaa2_rc_ni_set_err_behavior), 3480 DEVMETHOD(dpaa2_cmd_ni_get_queue, dpaa2_rc_ni_get_queue), 3481 DEVMETHOD(dpaa2_cmd_ni_set_queue, dpaa2_rc_ni_set_queue), 3482 DEVMETHOD(dpaa2_cmd_ni_get_qdid, dpaa2_rc_ni_get_qdid), 3483 DEVMETHOD(dpaa2_cmd_ni_add_mac_addr, dpaa2_rc_ni_add_mac_addr), 3484 DEVMETHOD(dpaa2_cmd_ni_remove_mac_addr, dpaa2_rc_ni_remove_mac_addr), 3485 DEVMETHOD(dpaa2_cmd_ni_clear_mac_filters, dpaa2_rc_ni_clear_mac_filters), 3486 DEVMETHOD(dpaa2_cmd_ni_set_mfl, dpaa2_rc_ni_set_mfl), 3487 DEVMETHOD(dpaa2_cmd_ni_set_offload, dpaa2_rc_ni_set_offload), 3488 DEVMETHOD(dpaa2_cmd_ni_set_irq_mask, dpaa2_rc_ni_set_irq_mask), 3489 DEVMETHOD(dpaa2_cmd_ni_set_irq_enable, dpaa2_rc_ni_set_irq_enable), 3490 DEVMETHOD(dpaa2_cmd_ni_get_irq_status, dpaa2_rc_ni_get_irq_status), 3491 DEVMETHOD(dpaa2_cmd_ni_set_uni_promisc, dpaa2_rc_ni_set_uni_promisc), 3492 DEVMETHOD(dpaa2_cmd_ni_set_multi_promisc, dpaa2_rc_ni_set_multi_promisc), 3493 DEVMETHOD(dpaa2_cmd_ni_get_statistics, dpaa2_rc_ni_get_statistics), 3494 DEVMETHOD(dpaa2_cmd_ni_set_rx_tc_dist, dpaa2_rc_ni_set_rx_tc_dist), 3495 /* DPIO commands */ 3496 DEVMETHOD(dpaa2_cmd_io_open, dpaa2_rc_io_open), 3497 DEVMETHOD(dpaa2_cmd_io_close, dpaa2_rc_io_close), 3498 DEVMETHOD(dpaa2_cmd_io_enable, dpaa2_rc_io_enable), 3499 DEVMETHOD(dpaa2_cmd_io_disable, dpaa2_rc_io_disable), 3500 DEVMETHOD(dpaa2_cmd_io_reset, dpaa2_rc_io_reset), 3501 DEVMETHOD(dpaa2_cmd_io_get_attributes, dpaa2_rc_io_get_attributes), 3502 DEVMETHOD(dpaa2_cmd_io_set_irq_mask, dpaa2_rc_io_set_irq_mask), 3503 DEVMETHOD(dpaa2_cmd_io_get_irq_status, dpaa2_rc_io_get_irq_status), 3504 DEVMETHOD(dpaa2_cmd_io_set_irq_enable, dpaa2_rc_io_set_irq_enable), 3505 DEVMETHOD(dpaa2_cmd_io_add_static_dq_chan, dpaa2_rc_io_add_static_dq_chan), 3506 /* DPBP commands */ 3507 DEVMETHOD(dpaa2_cmd_bp_open, dpaa2_rc_bp_open), 3508 DEVMETHOD(dpaa2_cmd_bp_close, dpaa2_rc_bp_close), 3509 DEVMETHOD(dpaa2_cmd_bp_enable, dpaa2_rc_bp_enable), 3510 DEVMETHOD(dpaa2_cmd_bp_disable, dpaa2_rc_bp_disable), 3511 DEVMETHOD(dpaa2_cmd_bp_reset, dpaa2_rc_bp_reset), 3512 DEVMETHOD(dpaa2_cmd_bp_get_attributes, dpaa2_rc_bp_get_attributes), 3513 /* DPMAC commands */ 3514 DEVMETHOD(dpaa2_cmd_mac_open, dpaa2_rc_mac_open), 3515 DEVMETHOD(dpaa2_cmd_mac_close, dpaa2_rc_mac_close), 3516 DEVMETHOD(dpaa2_cmd_mac_reset, dpaa2_rc_mac_reset), 3517 DEVMETHOD(dpaa2_cmd_mac_mdio_read, dpaa2_rc_mac_mdio_read), 3518 DEVMETHOD(dpaa2_cmd_mac_mdio_write, dpaa2_rc_mac_mdio_write), 3519 DEVMETHOD(dpaa2_cmd_mac_get_addr, dpaa2_rc_mac_get_addr), 3520 DEVMETHOD(dpaa2_cmd_mac_get_attributes, dpaa2_rc_mac_get_attributes), 3521 DEVMETHOD(dpaa2_cmd_mac_set_link_state, dpaa2_rc_mac_set_link_state), 3522 DEVMETHOD(dpaa2_cmd_mac_set_irq_mask, dpaa2_rc_mac_set_irq_mask), 3523 DEVMETHOD(dpaa2_cmd_mac_set_irq_enable, dpaa2_rc_mac_set_irq_enable), 3524 DEVMETHOD(dpaa2_cmd_mac_get_irq_status, dpaa2_rc_mac_get_irq_status), 3525 /* DPCON commands */ 3526 DEVMETHOD(dpaa2_cmd_con_open, dpaa2_rc_con_open), 3527 DEVMETHOD(dpaa2_cmd_con_close, dpaa2_rc_con_close), 3528 DEVMETHOD(dpaa2_cmd_con_reset, dpaa2_rc_con_reset), 3529 DEVMETHOD(dpaa2_cmd_con_enable, dpaa2_rc_con_enable), 3530 DEVMETHOD(dpaa2_cmd_con_disable, dpaa2_rc_con_disable), 3531 DEVMETHOD(dpaa2_cmd_con_get_attributes, dpaa2_rc_con_get_attributes), 3532 DEVMETHOD(dpaa2_cmd_con_set_notif, dpaa2_rc_con_set_notif), 3533 /* DPMCP commands */ 3534 DEVMETHOD(dpaa2_cmd_mcp_create, dpaa2_rc_mcp_create), 3535 DEVMETHOD(dpaa2_cmd_mcp_destroy, dpaa2_rc_mcp_destroy), 3536 DEVMETHOD(dpaa2_cmd_mcp_open, dpaa2_rc_mcp_open), 3537 DEVMETHOD(dpaa2_cmd_mcp_close, dpaa2_rc_mcp_close), 3538 DEVMETHOD(dpaa2_cmd_mcp_reset, dpaa2_rc_mcp_reset), 3539 3540 DEVMETHOD_END 3541 }; 3542 3543 static driver_t dpaa2_rc_driver = { 3544 "dpaa2_rc", 3545 dpaa2_rc_methods, 3546 sizeof(struct dpaa2_rc_softc), 3547 }; 3548 3549 /* For root container */ 3550 DRIVER_MODULE(dpaa2_rc, dpaa2_mc, dpaa2_rc_driver, 0, 0); 3551 /* For child containers */ 3552 DRIVER_MODULE(dpaa2_rc, dpaa2_rc, dpaa2_rc_driver, 0, 0); 3553