2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2021 Alstom Group.
5 * Copyright (c) 2021 Semihalf.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
31 #include <sys/param.h>
33 #include <sys/kernel.h>
34 #include <sys/module.h>
35 #include <sys/socket.h>
37 #include <sys/mutex.h>
39 #include <machine/bus.h>
42 #include <net/if_var.h>
43 #include <net/if_types.h>
44 #include <net/if_media.h>
46 #include <dev/enetc/enetc_hw.h>
47 #include <dev/enetc/enetc_mdio.h>
48 #include <dev/mii/mii.h>
49 #include <dev/mii/miivar.h>
50 #include <dev/ofw/ofw_bus.h>
51 #include <dev/ofw/ofw_bus_subr.h>
52 #include <dev/pci/pcireg.h>
53 #include <dev/pci/pcivar.h>
55 #include "miibus_if.h"
57 #define ENETC_MDIO_DEV_ID 0xee01
58 #define ENETC_MDIO_DEV_NAME "FSL PCIe IE Central MDIO"
60 static struct entec_mdio_pci_id {
64 } enetc_mdio_pci_ids[] = {
65 {PCI_VENDOR_FREESCALE, ENETC_MDIO_DEV_ID, ENETC_MDIO_DEV_NAME},
67 MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, enetc_mdio_pci,
68 enetc_mdio_pci_ids, nitems(enetc_mdio_pci_ids));
70 struct enetc_mdio_pci_softc {
73 struct resource *sc_regs;
76 static device_attach_t enetc_mdio_pci_attach;
77 static device_detach_t enetc_mdio_pci_detach;
78 static device_probe_t enetc_mdio_pci_probe;
81 enetc_mdio_pci_readreg(device_t dev, int phy, int reg)
83 struct enetc_mdio_pci_softc *sc;
86 sc = device_get_softc(dev);
88 mtx_lock(&sc->sc_lock);
89 ret = enetc_mdio_read(sc->sc_regs, ENETC_EMDIO_BASE, phy, reg);
90 mtx_unlock(&sc->sc_lock);
96 enetc_mdio_pci_writereg(device_t dev, int phy, int reg, int data)
98 struct enetc_mdio_pci_softc *sc;
101 sc = device_get_softc(dev);
103 mtx_lock(&sc->sc_lock);
104 err = enetc_mdio_write(sc->sc_regs, ENETC_EMDIO_BASE, phy, reg, data);
105 mtx_unlock(&sc->sc_lock);
113 enetc_mdio_pci_probe(device_t dev)
115 struct entec_mdio_pci_id *id;
117 for (id = enetc_mdio_pci_ids; id->vendor != 0; ++id) {
118 if (pci_get_device(dev) != id->device ||
119 pci_get_vendor(dev) != id->vendor)
122 device_set_desc(dev, id->desc);
124 return (BUS_PROBE_DEFAULT);
131 enetc_mdio_pci_attach(device_t dev)
133 struct enetc_mdio_pci_softc *sc;
136 sc = device_get_softc(dev);
140 mtx_init(&sc->sc_lock, device_get_nameunit(dev), "MDIO lock", MTX_DEF);
143 sc->sc_regs = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
145 if (sc->sc_regs == NULL) {
146 device_printf(dev, "can't allocate resources for PCI MDIO \n");
150 OF_device_register_xref(ofw_bus_get_node(dev), dev);
156 enetc_mdio_pci_detach(device_t dev)
158 struct enetc_mdio_pci_softc *sc;
160 sc = device_get_softc(dev);
162 bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), sc->sc_regs);
163 mtx_destroy(&sc->sc_lock);
168 static device_method_t enetc_mdio_pci_methods[] ={
169 DEVMETHOD(device_probe, enetc_mdio_pci_probe),
170 DEVMETHOD(device_attach, enetc_mdio_pci_attach),
171 DEVMETHOD(device_detach, enetc_mdio_pci_detach),
173 DEVMETHOD(miibus_readreg, enetc_mdio_pci_readreg),
174 DEVMETHOD(miibus_writereg, enetc_mdio_pci_writereg),
179 static driver_t enetc_mdio_pci_driver = {
181 enetc_mdio_pci_methods,
182 sizeof(struct enetc_mdio_pci_softc),
185 static devclass_t enetc_mdio_pci_devclass;
187 DRIVER_MODULE(enetc_mdio, pci, enetc_mdio_pci_driver,
188 enetc_mdio_pci_devclass, 0, 0);
189 DRIVER_MODULE(miibus, enetc_mdio, miibus_driver, miibus_devclass,
191 MODULE_VERSION(enetc_mdio, 1);