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