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