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