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