xref: /freebsd/sys/dev/dpaa2/dpaa2_rc.c (revision ba7319e9091b4f6ef15a9c4be3d3d076f3047f72)
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, &reg);
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