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