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