xref: /freebsd/sys/dev/dpaa2/dpaa2_mc_fdt.c (revision 723da5d92f40a413585107f8455280ea575fe410)
1ba7319e9SDmitry Salychev /*-
2ba7319e9SDmitry Salychev  * SPDX-License-Identifier: BSD-2-Clause
3ba7319e9SDmitry Salychev  *
4ba7319e9SDmitry Salychev  * Copyright © 2021-2022 Dmitry Salychev
5ba7319e9SDmitry Salychev  * Copyright © 2022 Bjoern A. Zeeb
6ba7319e9SDmitry Salychev  *
7ba7319e9SDmitry Salychev  * Redistribution and use in source and binary forms, with or without
8ba7319e9SDmitry Salychev  * modification, are permitted provided that the following conditions
9ba7319e9SDmitry Salychev  * are met:
10ba7319e9SDmitry Salychev  * 1. Redistributions of source code must retain the above copyright
11ba7319e9SDmitry Salychev  *    notice, this list of conditions and the following disclaimer.
12ba7319e9SDmitry Salychev  * 2. Redistributions in binary form must reproduce the above copyright
13ba7319e9SDmitry Salychev  *    notice, this list of conditions and the following disclaimer in the
14ba7319e9SDmitry Salychev  *    documentation and/or other materials provided with the distribution.
15ba7319e9SDmitry Salychev  *
16ba7319e9SDmitry Salychev  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17ba7319e9SDmitry Salychev  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18ba7319e9SDmitry Salychev  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19ba7319e9SDmitry Salychev  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20ba7319e9SDmitry Salychev  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21ba7319e9SDmitry Salychev  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22ba7319e9SDmitry Salychev  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23ba7319e9SDmitry Salychev  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24ba7319e9SDmitry Salychev  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25ba7319e9SDmitry Salychev  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26ba7319e9SDmitry Salychev  * SUCH DAMAGE.
27ba7319e9SDmitry Salychev  */
28ba7319e9SDmitry Salychev 
29ba7319e9SDmitry Salychev #include <sys/cdefs.h>
30ba7319e9SDmitry Salychev /*
31ba7319e9SDmitry Salychev  * The DPAA2 Management Complex (MC) Bus Driver (FDT-based).
32ba7319e9SDmitry Salychev  *
33ba7319e9SDmitry Salychev  * MC is a hardware resource manager which can be found in several NXP
34ba7319e9SDmitry Salychev  * SoCs (LX2160A, for example) and provides an access to the specialized
35ba7319e9SDmitry Salychev  * hardware objects used in network-oriented packet processing applications.
36ba7319e9SDmitry Salychev  */
37ba7319e9SDmitry Salychev 
38ba7319e9SDmitry Salychev #include <sys/param.h>
39ba7319e9SDmitry Salychev #include <sys/kernel.h>
40ba7319e9SDmitry Salychev #include <sys/bus.h>
41ba7319e9SDmitry Salychev #include <sys/rman.h>
42ba7319e9SDmitry Salychev #include <sys/module.h>
43ba7319e9SDmitry Salychev #include <sys/malloc.h>
44ba7319e9SDmitry Salychev #include <sys/mutex.h>
45ba7319e9SDmitry Salychev 
46ba7319e9SDmitry Salychev #include <machine/bus.h>
47ba7319e9SDmitry Salychev #include <machine/resource.h>
48ba7319e9SDmitry Salychev 
49ba7319e9SDmitry Salychev #include <dev/ofw/ofw_bus.h>
50ba7319e9SDmitry Salychev #include <dev/ofw/ofw_bus_subr.h>
51ba7319e9SDmitry Salychev #include <dev/fdt/simplebus.h>
52ba7319e9SDmitry Salychev 
53ba7319e9SDmitry Salychev #include "pcib_if.h"
54ba7319e9SDmitry Salychev #include "pci_if.h"
55ba7319e9SDmitry Salychev #include "ofw_bus_if.h"
56ba7319e9SDmitry Salychev 
57ba7319e9SDmitry Salychev #include "dpaa2_mcp.h"
58ba7319e9SDmitry Salychev #include "dpaa2_mc.h"
59ba7319e9SDmitry Salychev #include "dpaa2_mc_if.h"
60ba7319e9SDmitry Salychev 
61ba7319e9SDmitry Salychev struct dpaa2_mac_fdt_softc {
62ba7319e9SDmitry Salychev 	uint32_t			reg;
63ba7319e9SDmitry Salychev 	phandle_t			sfp;
64ba7319e9SDmitry Salychev 	phandle_t			pcs_handle;
65ba7319e9SDmitry Salychev 	phandle_t			phy_handle;
66ba7319e9SDmitry Salychev 	char				managed[64];
67ba7319e9SDmitry Salychev 	char				phy_conn_type[64];
68ba7319e9SDmitry Salychev };
69ba7319e9SDmitry Salychev 
70ba7319e9SDmitry Salychev #if 0
71ba7319e9SDmitry Salychev 	ethernet@1 {
72ba7319e9SDmitry Salychev 
73ba7319e9SDmitry Salychev 		compatible = "fsl,qoriq-mc-dpmac";
74ba7319e9SDmitry Salychev 		reg = <0x1>;
75ba7319e9SDmitry Salychev 		sfp = <0x14>;
76ba7319e9SDmitry Salychev 		pcs-handle = <0x15>;
77ba7319e9SDmitry Salychev 		phy-connection-type = "10gbase-r";
78ba7319e9SDmitry Salychev 		managed = "in-band-status";
79ba7319e9SDmitry Salychev 	};
80ba7319e9SDmitry Salychev 	ethernet@3 {
81ba7319e9SDmitry Salychev 
82ba7319e9SDmitry Salychev 		compatible = "fsl,qoriq-mc-dpmac";
83ba7319e9SDmitry Salychev 		reg = <0x3>;
84ba7319e9SDmitry Salychev 		phy-handle = <0x18>;
85ba7319e9SDmitry Salychev 		phy-connection-type = "qsgmii";
86ba7319e9SDmitry Salychev 		managed = "in-band-status";
87ba7319e9SDmitry Salychev 		pcs-handle = <0x19>;
88ba7319e9SDmitry Salychev 	};
89ba7319e9SDmitry Salychev #endif
90ba7319e9SDmitry Salychev 
91ba7319e9SDmitry Salychev static int
dpaa2_mac_dev_probe(device_t dev)92ba7319e9SDmitry Salychev dpaa2_mac_dev_probe(device_t dev)
93ba7319e9SDmitry Salychev {
94ba7319e9SDmitry Salychev 	phandle_t node;
95ba7319e9SDmitry Salychev 	uint64_t reg;
96ba7319e9SDmitry Salychev 	ssize_t s;
97ba7319e9SDmitry Salychev 
98ba7319e9SDmitry Salychev 	node = ofw_bus_get_node(dev);
99ba7319e9SDmitry Salychev 	if (!ofw_bus_node_is_compatible(node, "fsl,qoriq-mc-dpmac")) {
100ba7319e9SDmitry Salychev 		device_printf(dev, "'%s' not fsl,qoriq-mc-dpmac compatible\n",
101ba7319e9SDmitry Salychev 		    ofw_bus_get_name(dev));
102ba7319e9SDmitry Salychev 		return (ENXIO);
103ba7319e9SDmitry Salychev 	}
104ba7319e9SDmitry Salychev 
105ba7319e9SDmitry Salychev 	s = device_get_property(dev, "reg", &reg, sizeof(reg),
106ba7319e9SDmitry Salychev 	    DEVICE_PROP_UINT32);
107ba7319e9SDmitry Salychev 	if (s == -1) {
108ba7319e9SDmitry Salychev 		device_printf(dev, "%s: '%s' has no 'reg' property, s %zd\n",
109ba7319e9SDmitry Salychev 		    __func__, ofw_bus_get_name(dev), s);
110ba7319e9SDmitry Salychev 		return (ENXIO);
111ba7319e9SDmitry Salychev 	}
112ba7319e9SDmitry Salychev 
113ba7319e9SDmitry Salychev 	device_set_desc(dev, "DPAA2 MAC DEV");
114ba7319e9SDmitry Salychev 	return (BUS_PROBE_DEFAULT);
115ba7319e9SDmitry Salychev }
116ba7319e9SDmitry Salychev 
117ba7319e9SDmitry Salychev static int
dpaa2_mac_fdt_attach(device_t dev)118ba7319e9SDmitry Salychev dpaa2_mac_fdt_attach(device_t dev)
119ba7319e9SDmitry Salychev {
120ba7319e9SDmitry Salychev 	struct dpaa2_mac_fdt_softc *sc;
121ba7319e9SDmitry Salychev 	phandle_t node;
122ba7319e9SDmitry Salychev 	ssize_t s;
123ba7319e9SDmitry Salychev 
124ba7319e9SDmitry Salychev 	sc = device_get_softc(dev);
125ba7319e9SDmitry Salychev 	node = ofw_bus_get_node(dev);
126ba7319e9SDmitry Salychev 
127ba7319e9SDmitry Salychev 	s = device_get_property(dev, "reg", &sc->reg, sizeof(sc->reg),
128ba7319e9SDmitry Salychev 	    DEVICE_PROP_UINT32);
129ba7319e9SDmitry Salychev 	if (s == -1) {
130ba7319e9SDmitry Salychev 		device_printf(dev, "Cannot find 'reg' property: %zd\n", s);
131ba7319e9SDmitry Salychev 		return (ENXIO);
132ba7319e9SDmitry Salychev 	}
133ba7319e9SDmitry Salychev 
134ba7319e9SDmitry Salychev 	s = device_get_property(dev, "managed", sc->managed,
135ba7319e9SDmitry Salychev 	    sizeof(sc->managed), DEVICE_PROP_ANY);
136ba7319e9SDmitry Salychev 	s = device_get_property(dev, "phy-connection-type", sc->phy_conn_type,
137ba7319e9SDmitry Salychev 	    sizeof(sc->phy_conn_type), DEVICE_PROP_ANY);
138ba7319e9SDmitry Salychev 	s = device_get_property(dev, "pcs-handle", &sc->pcs_handle,
139ba7319e9SDmitry Salychev 	    sizeof(sc->pcs_handle), DEVICE_PROP_HANDLE);
140ba7319e9SDmitry Salychev 
141ba7319e9SDmitry Salychev 	/* 'sfp' and 'phy-handle' are optional but we need one or the other. */
142ba7319e9SDmitry Salychev 	s = device_get_property(dev, "sfp", &sc->sfp, sizeof(sc->sfp),
143ba7319e9SDmitry Salychev 	    DEVICE_PROP_HANDLE);
144ba7319e9SDmitry Salychev 	s = device_get_property(dev, "phy-handle", &sc->phy_handle,
145ba7319e9SDmitry Salychev 	    sizeof(sc->phy_handle), DEVICE_PROP_HANDLE);
146ba7319e9SDmitry Salychev 
147ba7319e9SDmitry Salychev 	if (bootverbose)
148ba7319e9SDmitry Salychev 		device_printf(dev, "node %#x '%s': reg %#x sfp %#x pcs-handle "
149ba7319e9SDmitry Salychev 		    "%#x phy-handle %#x managed '%s' phy-conn-type '%s'\n",
150ba7319e9SDmitry Salychev 		    node, ofw_bus_get_name(dev),
151ba7319e9SDmitry Salychev 		    sc->reg, sc->sfp, sc->pcs_handle, sc->phy_handle,
152ba7319e9SDmitry Salychev 		    sc->managed, sc->phy_conn_type);
153ba7319e9SDmitry Salychev 
154ba7319e9SDmitry Salychev 	return (0);
155ba7319e9SDmitry Salychev }
156ba7319e9SDmitry Salychev 
157ba7319e9SDmitry Salychev static bool
dpaa2_mac_fdt_match_id(device_t dev,uint32_t id)158ba7319e9SDmitry Salychev dpaa2_mac_fdt_match_id(device_t dev, uint32_t id)
159ba7319e9SDmitry Salychev {
160ba7319e9SDmitry Salychev 	struct dpaa2_mac_fdt_softc *sc;
161ba7319e9SDmitry Salychev 
162ba7319e9SDmitry Salychev 	if (dev == NULL)
163ba7319e9SDmitry Salychev 		return (false);
164ba7319e9SDmitry Salychev 
165ba7319e9SDmitry Salychev 	sc = device_get_softc(dev);
166ba7319e9SDmitry Salychev 	if (sc->reg == id)
167ba7319e9SDmitry Salychev 		return (true);
168ba7319e9SDmitry Salychev 
169ba7319e9SDmitry Salychev 	return (false);
170ba7319e9SDmitry Salychev }
171ba7319e9SDmitry Salychev 
172ba7319e9SDmitry Salychev static device_t
dpaa2_mac_fdt_get_phy_dev(device_t dev)173ba7319e9SDmitry Salychev dpaa2_mac_fdt_get_phy_dev(device_t dev)
174ba7319e9SDmitry Salychev {
175ba7319e9SDmitry Salychev 	struct dpaa2_mac_fdt_softc *sc;
176ba7319e9SDmitry Salychev 
177ba7319e9SDmitry Salychev 	if (dev == NULL)
178ba7319e9SDmitry Salychev 		return (NULL);
179ba7319e9SDmitry Salychev 
180ba7319e9SDmitry Salychev 	sc = device_get_softc(dev);
181ba7319e9SDmitry Salychev 	if (sc->phy_handle == 0 && sc->sfp == 0)
182ba7319e9SDmitry Salychev 		return (NULL);
183ba7319e9SDmitry Salychev 
184ba7319e9SDmitry Salychev #ifdef __not_yet__	/* No sff,sfp support yet. */
185ba7319e9SDmitry Salychev 	if (sc->sfp != 0) {
186ba7319e9SDmitry Salychev 		device_t xdev;
187ba7319e9SDmitry Salychev 
188ba7319e9SDmitry Salychev 		xdev = OF_device_from_xref(OF_xref_from_node(sc->sfp));
189ba7319e9SDmitry Salychev 		if (xdev != NULL)
190ba7319e9SDmitry Salychev 			return (xdev);
191ba7319e9SDmitry Salychev 	}
192ba7319e9SDmitry Salychev #endif
193ba7319e9SDmitry Salychev 	return (OF_device_from_xref(OF_xref_from_node(sc->phy_handle)));
194ba7319e9SDmitry Salychev }
195ba7319e9SDmitry Salychev 
196ba7319e9SDmitry Salychev static device_method_t dpaa2_mac_fdt_methods[] = {
197ba7319e9SDmitry Salychev 	/* Device interface */
198ba7319e9SDmitry Salychev 	DEVMETHOD(device_probe,		dpaa2_mac_dev_probe),
199ba7319e9SDmitry Salychev 	DEVMETHOD(device_attach,	dpaa2_mac_fdt_attach),
200ba7319e9SDmitry Salychev 	DEVMETHOD(device_detach,	bus_generic_detach),
201ba7319e9SDmitry Salychev 
202ba7319e9SDmitry Salychev 	DEVMETHOD_END
203ba7319e9SDmitry Salychev };
204ba7319e9SDmitry Salychev 
205ba7319e9SDmitry Salychev DEFINE_CLASS_0(dpaa2_mac_fdt, dpaa2_mac_fdt_driver, dpaa2_mac_fdt_methods,
206ba7319e9SDmitry Salychev     sizeof(struct dpaa2_mac_fdt_softc));
207ba7319e9SDmitry Salychev DRIVER_MODULE(dpaa2_mac_fdt, dpaa2_mc, dpaa2_mac_fdt_driver, 0, 0);
208ba7319e9SDmitry Salychev MODULE_DEPEND(dpaa2_mac_fdt, memac_mdio_fdt, 1, 1, 1);
209ba7319e9SDmitry Salychev 
210ba7319e9SDmitry Salychev /*
211ba7319e9SDmitry Salychev  * Device interface.
212ba7319e9SDmitry Salychev  */
213ba7319e9SDmitry Salychev 
214ba7319e9SDmitry Salychev static int
dpaa2_mc_fdt_probe(device_t dev)215ba7319e9SDmitry Salychev dpaa2_mc_fdt_probe(device_t dev)
216ba7319e9SDmitry Salychev {
217ba7319e9SDmitry Salychev 	if (!ofw_bus_status_okay(dev))
218ba7319e9SDmitry Salychev 		return (ENXIO);
219ba7319e9SDmitry Salychev 
220ba7319e9SDmitry Salychev 	if (!ofw_bus_is_compatible(dev, "fsl,qoriq-mc"))
221ba7319e9SDmitry Salychev 		return (ENXIO);
222ba7319e9SDmitry Salychev 
223ba7319e9SDmitry Salychev 	device_set_desc(dev, "DPAA2 Management Complex");
224ba7319e9SDmitry Salychev 	return (BUS_PROBE_DEFAULT);
225ba7319e9SDmitry Salychev }
226ba7319e9SDmitry Salychev 
227ba7319e9SDmitry Salychev static int
dpaa2_mc_fdt_probe_child(device_t bus,phandle_t child)228ba7319e9SDmitry Salychev dpaa2_mc_fdt_probe_child(device_t bus, phandle_t child)
229ba7319e9SDmitry Salychev {
230ba7319e9SDmitry Salychev 	device_t childdev;
231ba7319e9SDmitry Salychev 
232ba7319e9SDmitry Salychev 	/* make sure we do not aliready have a device. */
233ba7319e9SDmitry Salychev 	childdev = ofw_bus_find_child_device_by_phandle(bus, child);
234ba7319e9SDmitry Salychev 	if (childdev != NULL)
235ba7319e9SDmitry Salychev 		return (0);
236ba7319e9SDmitry Salychev 
237ba7319e9SDmitry Salychev 	childdev = simplebus_add_device(bus, child, 0, "dpaa2_mac_fdt", -1,
238ba7319e9SDmitry Salychev 	    NULL);
239ba7319e9SDmitry Salychev 	if (childdev == NULL)
240ba7319e9SDmitry Salychev 		return (ENXIO);
241ba7319e9SDmitry Salychev 
242ba7319e9SDmitry Salychev 	return (device_probe_and_attach(childdev));
243ba7319e9SDmitry Salychev }
244ba7319e9SDmitry Salychev 
245ba7319e9SDmitry Salychev static int
dpaa2_mc_fdt_attach(device_t dev)246ba7319e9SDmitry Salychev dpaa2_mc_fdt_attach(device_t dev)
247ba7319e9SDmitry Salychev {
248ba7319e9SDmitry Salychev 	struct dpaa2_mc_softc *sc;
249ba7319e9SDmitry Salychev 	phandle_t node;
250ba7319e9SDmitry Salychev 	phandle_t child;
251ba7319e9SDmitry Salychev 
252ba7319e9SDmitry Salychev 	sc = device_get_softc(dev);
253ba7319e9SDmitry Salychev 	sc->acpi_based = false;
254ba7319e9SDmitry Salychev 	sc->ofw_node = ofw_bus_get_node(dev);
255ba7319e9SDmitry Salychev 
256*723da5d9SJohn Baldwin 	bus_identify_children(dev);
257ba7319e9SDmitry Salychev 	bus_enumerate_hinted_children(dev);
258ba7319e9SDmitry Salychev 
259*723da5d9SJohn Baldwin 	bus_identify_children(dev);
260ba7319e9SDmitry Salychev 	bus_enumerate_hinted_children(dev);
261*723da5d9SJohn Baldwin 
262ba7319e9SDmitry Salychev 	/*
263ba7319e9SDmitry Salychev 	 * Attach the children represented in the device tree.
264ba7319e9SDmitry Salychev 	 */
265ba7319e9SDmitry Salychev 	/* fsl-mc -> dpamcs */
266ba7319e9SDmitry Salychev 	node = OF_child(sc->ofw_node);
267ba7319e9SDmitry Salychev 	simplebus_init(dev, node);
268ba7319e9SDmitry Salychev 
269ba7319e9SDmitry Salychev 	/* Attach the dpmac children represented in the device tree. */
270ba7319e9SDmitry Salychev 	child = ofw_bus_find_compatible(node, "fsl,qoriq-mc-dpmac");
271ba7319e9SDmitry Salychev 	for (; child > 0; child = OF_peer(child)) {
272ba7319e9SDmitry Salychev 		if (!ofw_bus_node_is_compatible(child, "fsl,qoriq-mc-dpmac"))
273ba7319e9SDmitry Salychev 			continue;
274ba7319e9SDmitry Salychev 		if (!OF_hasprop(child, "reg"))
275ba7319e9SDmitry Salychev 			continue;
276ba7319e9SDmitry Salychev 		if (dpaa2_mc_fdt_probe_child(dev, child) != 0)
277ba7319e9SDmitry Salychev 			continue;
278ba7319e9SDmitry Salychev 	}
279ba7319e9SDmitry Salychev 
280ba7319e9SDmitry Salychev 	return (dpaa2_mc_attach(dev));
281ba7319e9SDmitry Salychev }
282ba7319e9SDmitry Salychev 
283ba7319e9SDmitry Salychev /*
284ba7319e9SDmitry Salychev  * FDT compat layer.
285ba7319e9SDmitry Salychev  */
286ba7319e9SDmitry Salychev static device_t
dpaa2_mc_fdt_find_dpaa2_mac_dev(device_t dev,uint32_t id)287ba7319e9SDmitry Salychev dpaa2_mc_fdt_find_dpaa2_mac_dev(device_t dev, uint32_t id)
288ba7319e9SDmitry Salychev {
289ba7319e9SDmitry Salychev 	int devcount, error, i, len;
290ba7319e9SDmitry Salychev 	device_t *devlist, mdev;
291ba7319e9SDmitry Salychev 	const char *mdevname;
292ba7319e9SDmitry Salychev 
293ba7319e9SDmitry Salychev 	error = device_get_children(dev, &devlist, &devcount);
294ba7319e9SDmitry Salychev 	if (error != 0)
295ba7319e9SDmitry Salychev 		return (NULL);
296ba7319e9SDmitry Salychev 
297ba7319e9SDmitry Salychev 	for (i = 0; i < devcount; i++) {
298ba7319e9SDmitry Salychev 		mdev = devlist[i];
299ba7319e9SDmitry Salychev 		mdevname = device_get_name(mdev);
300ba7319e9SDmitry Salychev 		if (mdevname == NULL)
301ba7319e9SDmitry Salychev 			continue;
302ba7319e9SDmitry Salychev 		len = strlen(mdevname);
303ba7319e9SDmitry Salychev 		if (strncmp("dpaa2_mac_fdt", mdevname, len) != 0)
304ba7319e9SDmitry Salychev 			continue;
305ba7319e9SDmitry Salychev 		if (!device_is_attached(mdev))
306ba7319e9SDmitry Salychev 			continue;
307ba7319e9SDmitry Salychev 
308ba7319e9SDmitry Salychev 		if (dpaa2_mac_fdt_match_id(mdev, id))
309ba7319e9SDmitry Salychev 			return (mdev);
310ba7319e9SDmitry Salychev 	}
311ba7319e9SDmitry Salychev 
312ba7319e9SDmitry Salychev 	return (NULL);
313ba7319e9SDmitry Salychev }
314ba7319e9SDmitry Salychev 
315ba7319e9SDmitry Salychev static int
dpaa2_mc_fdt_get_phy_dev(device_t dev,device_t * phy_dev,uint32_t id)316ba7319e9SDmitry Salychev dpaa2_mc_fdt_get_phy_dev(device_t dev, device_t *phy_dev, uint32_t id)
317ba7319e9SDmitry Salychev {
318ba7319e9SDmitry Salychev 	device_t mdev, pdev;
319ba7319e9SDmitry Salychev 
320ba7319e9SDmitry Salychev 	mdev = dpaa2_mc_fdt_find_dpaa2_mac_dev(dev, id);
321ba7319e9SDmitry Salychev 	if (mdev == NULL) {
322ba7319e9SDmitry Salychev 		device_printf(dev, "%s: error finding dpmac device with id=%u\n",
323ba7319e9SDmitry Salychev 		    __func__, id);
324ba7319e9SDmitry Salychev 		return (ENXIO);
325ba7319e9SDmitry Salychev 	}
326ba7319e9SDmitry Salychev 
327ba7319e9SDmitry Salychev 	pdev = dpaa2_mac_fdt_get_phy_dev(mdev);
328ba7319e9SDmitry Salychev 	if (pdev == NULL) {
329ba7319e9SDmitry Salychev 		device_printf(dev, "%s: error getting MDIO device for dpamc %s "
330ba7319e9SDmitry Salychev 		    "(id=%u)\n", __func__, device_get_nameunit(mdev), id);
331ba7319e9SDmitry Salychev 		return (ENXIO);
332ba7319e9SDmitry Salychev 	}
333ba7319e9SDmitry Salychev 
334ba7319e9SDmitry Salychev 	if (phy_dev != NULL)
335ba7319e9SDmitry Salychev 		*phy_dev = pdev;
336ba7319e9SDmitry Salychev 
337ba7319e9SDmitry Salychev 	if (bootverbose)
338ba7319e9SDmitry Salychev 		device_printf(dev, "dpmac_id %u mdev %p (%s) pdev %p (%s)\n",
339ba7319e9SDmitry Salychev 		    id, mdev, device_get_nameunit(mdev),
340ba7319e9SDmitry Salychev 		    pdev, device_get_nameunit(pdev));
341ba7319e9SDmitry Salychev 
342ba7319e9SDmitry Salychev 	return (0);
343ba7319e9SDmitry Salychev }
344ba7319e9SDmitry Salychev 
345ba7319e9SDmitry Salychev static const struct ofw_bus_devinfo *
dpaa2_mc_simplebus_get_devinfo(device_t bus,device_t child)346ba7319e9SDmitry Salychev dpaa2_mc_simplebus_get_devinfo(device_t bus, device_t child)
347ba7319e9SDmitry Salychev {
348ba7319e9SDmitry Salychev 
349ba7319e9SDmitry Salychev 	return (OFW_BUS_GET_DEVINFO(device_get_parent(bus), child));
350ba7319e9SDmitry Salychev }
351ba7319e9SDmitry Salychev 
352ba7319e9SDmitry Salychev static device_method_t dpaa2_mc_fdt_methods[] = {
353ba7319e9SDmitry Salychev 	/* Device interface */
354ba7319e9SDmitry Salychev 	DEVMETHOD(device_probe,		dpaa2_mc_fdt_probe),
355ba7319e9SDmitry Salychev 	DEVMETHOD(device_attach,	dpaa2_mc_fdt_attach),
356ba7319e9SDmitry Salychev 	DEVMETHOD(device_detach,	dpaa2_mc_detach),
357ba7319e9SDmitry Salychev 
358ba7319e9SDmitry Salychev 	/* Bus interface */
3599b619f0eSJohn Baldwin 	DEVMETHOD(bus_get_rman,		dpaa2_mc_rman),
360ba7319e9SDmitry Salychev 	DEVMETHOD(bus_alloc_resource,	dpaa2_mc_alloc_resource),
361ba7319e9SDmitry Salychev 	DEVMETHOD(bus_adjust_resource,	dpaa2_mc_adjust_resource),
362ba7319e9SDmitry Salychev 	DEVMETHOD(bus_release_resource,	dpaa2_mc_release_resource),
363ba7319e9SDmitry Salychev 	DEVMETHOD(bus_activate_resource, dpaa2_mc_activate_resource),
364ba7319e9SDmitry Salychev 	DEVMETHOD(bus_deactivate_resource, dpaa2_mc_deactivate_resource),
365ba7319e9SDmitry Salychev 	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
366ba7319e9SDmitry Salychev 	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
367ba7319e9SDmitry Salychev 
368ba7319e9SDmitry Salychev 	/* Pseudo-PCIB interface */
369ba7319e9SDmitry Salychev 	DEVMETHOD(pcib_alloc_msi,	dpaa2_mc_alloc_msi),
370ba7319e9SDmitry Salychev 	DEVMETHOD(pcib_release_msi,	dpaa2_mc_release_msi),
371ba7319e9SDmitry Salychev 	DEVMETHOD(pcib_map_msi,		dpaa2_mc_map_msi),
372ba7319e9SDmitry Salychev 	DEVMETHOD(pcib_get_id,		dpaa2_mc_get_id),
373ba7319e9SDmitry Salychev 
374ba7319e9SDmitry Salychev 	/* DPAA2 MC bus interface */
375ba7319e9SDmitry Salychev 	DEVMETHOD(dpaa2_mc_manage_dev,	dpaa2_mc_manage_dev),
376ba7319e9SDmitry Salychev 	DEVMETHOD(dpaa2_mc_get_free_dev,dpaa2_mc_get_free_dev),
377ba7319e9SDmitry Salychev 	DEVMETHOD(dpaa2_mc_get_dev,	dpaa2_mc_get_dev),
378ba7319e9SDmitry Salychev 	DEVMETHOD(dpaa2_mc_get_shared_dev, dpaa2_mc_get_shared_dev),
379ba7319e9SDmitry Salychev 	DEVMETHOD(dpaa2_mc_reserve_dev,	dpaa2_mc_reserve_dev),
380ba7319e9SDmitry Salychev 	DEVMETHOD(dpaa2_mc_release_dev, dpaa2_mc_release_dev),
381ba7319e9SDmitry Salychev 	DEVMETHOD(dpaa2_mc_get_phy_dev,	dpaa2_mc_fdt_get_phy_dev),
382ba7319e9SDmitry Salychev 
383ba7319e9SDmitry Salychev 	/* OFW/simplebus */
384ba7319e9SDmitry Salychev 	DEVMETHOD(ofw_bus_get_devinfo,	dpaa2_mc_simplebus_get_devinfo),
385ba7319e9SDmitry Salychev 	DEVMETHOD(ofw_bus_get_compat,	ofw_bus_gen_get_compat),
386ba7319e9SDmitry Salychev 	DEVMETHOD(ofw_bus_get_model,	ofw_bus_gen_get_model),
387ba7319e9SDmitry Salychev 	DEVMETHOD(ofw_bus_get_name,	ofw_bus_gen_get_name),
388ba7319e9SDmitry Salychev 	DEVMETHOD(ofw_bus_get_node,	ofw_bus_gen_get_node),
389ba7319e9SDmitry Salychev 	DEVMETHOD(ofw_bus_get_type,	ofw_bus_gen_get_type),
390ba7319e9SDmitry Salychev 
391ba7319e9SDmitry Salychev 	DEVMETHOD_END
392ba7319e9SDmitry Salychev };
393ba7319e9SDmitry Salychev 
394ba7319e9SDmitry Salychev DEFINE_CLASS_1(dpaa2_mc, dpaa2_mc_fdt_driver, dpaa2_mc_fdt_methods,
395ba7319e9SDmitry Salychev     sizeof(struct dpaa2_mc_softc), dpaa2_mc_driver);
396ba7319e9SDmitry Salychev 
397ba7319e9SDmitry Salychev DRIVER_MODULE(dpaa2_mc, simplebus, dpaa2_mc_fdt_driver, 0, 0);
398