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