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