From 29cf6a79acb7c28586ce39473e9ea1f2f1cd1ed4 Mon Sep 17 00:00:00 2001 From: Kornel Duleba Date: Tue, 26 Oct 2021 10:36:35 +0200 Subject: [PATCH] felix: Use internal MDIO regs for PHY communication Previously we would use an external MDIO device found on the PCI bus. Switch to using MDIO mapped in a separate BAR of the switch device. It is much easier this way since we don't have to depend on another driver anymore. Obtained from: Semihalf Sponsored by: Alstom Group --- sys/dev/etherswitch/felix/felix.c | 70 +++++++++++---------------- sys/dev/etherswitch/felix/felix_reg.h | 2 + sys/dev/etherswitch/felix/felix_var.h | 2 + sys/modules/felix/Makefile | 3 +- 4 files changed, 35 insertions(+), 42 deletions(-) diff --git a/sys/dev/etherswitch/felix/felix.c b/sys/dev/etherswitch/felix/felix.c index 1cd1e0e29ca7..f57a6e1daa0c 100644 --- a/sys/dev/etherswitch/felix/felix.c +++ b/sys/dev/etherswitch/felix/felix.c @@ -44,6 +44,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include #include #include @@ -124,6 +126,10 @@ static device_method_t felix_methods[] = { DEVMETHOD(etherswitch_setvgroup, felix_setvgroup), DEVMETHOD(etherswitch_getvgroup, felix_getvgroup), + /* miibus interface */ + DEVMETHOD(miibus_readreg, felix_readphy), + DEVMETHOD(miibus_writereg, felix_writephy), + DEVMETHOD_END }; @@ -131,15 +137,16 @@ static devclass_t felix_devclass; DEFINE_CLASS_0(felix, felix_driver, felix_methods, sizeof(struct felix_softc)); -DRIVER_MODULE(felix, pci, felix_driver, felix_devclass, NULL, NULL); +DRIVER_MODULE_ORDERED(felix, pci, felix_driver, felix_devclass, + NULL, NULL, SI_ORDER_ANY); +DRIVER_MODULE(miibus, felix, miibus_driver, miibus_devclass, + NULL, NULL); DRIVER_MODULE(etherswitch, felix, etherswitch_driver, etherswitch_devclass, NULL, NULL); MODULE_VERSION(felix, 1); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, felix, felix_pci_ids, nitems(felix_pci_ids) - 1); -MODULE_DEPEND(felix, enetc_mdio, 1, 1, 1); - static int felix_probe(device_t dev) { @@ -324,7 +331,6 @@ felix_attach(device_t dev) phandle_t child, ports, node; int error, port, rid; felix_softc_t sc; - device_t mdio_dev; uint32_t phy_addr; ssize_t size; @@ -333,12 +339,21 @@ felix_attach(device_t dev) sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q; strlcpy(sc->info.es_name, "Felix TSN Switch", sizeof(sc->info.es_name)); + rid = PCIR_BAR(FELIX_BAR_MDIO); + sc->mdio = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->mdio == NULL) { + device_printf(dev, "Failed to allocate MDIO registers.\n"); + return (ENXIO); + } + rid = PCIR_BAR(FELIX_BAR_REGS); sc->regs = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (sc->regs == NULL) { device_printf(dev, "Failed to allocate registers BAR.\n"); - return (ENXIO); + error = ENXIO; + goto out_fail; } mtx_init(&sc->mtx, "felix lock", NULL, MTX_DEF); @@ -396,25 +411,9 @@ felix_attach(device_t dev) goto out_fail; } - node = OF_parent(node); - if (node <= 0) { - device_printf(sc->dev, - "Failed to obtain MDIO node.\n"); - error = ENXIO; - goto out_fail; - } - - mdio_dev = OF_device_from_xref(node); - if (mdio_dev == NULL) { - device_printf(sc->dev, - "Failed to obtain MDIO driver handle.\n"); - error = ENXIO; - goto out_fail; - } - sc->ports[port].phyaddr = phy_addr; sc->ports[port].miibus = NULL; - error = mii_attach(mdio_dev, &sc->ports[port].miibus, sc->ports[port].ifp, + error = mii_attach(dev, &sc->ports[port].miibus, sc->ports[port].ifp, felix_ifmedia_upd, felix_ifmedia_sts, BMSR_DEFCAPMASK, phy_addr, MII_OFFSET_ANY, 0); if (error != 0) @@ -447,7 +446,6 @@ static int felix_detach(device_t dev) { felix_softc_t sc; - device_t mdio_dev; int error; int i; @@ -468,10 +466,8 @@ felix_detach(device_t dev) felix_setup(sc); for (i = 0; i < sc->info.es_nports; i++) { - if (sc->ports[i].miibus != NULL) { - mdio_dev = device_get_parent(sc->ports[i].miibus); - device_delete_child(mdio_dev, sc->ports[i].miibus); - } + if (sc->ports[i].miibus != NULL) + device_delete_child(dev, sc->ports[i].miibus); if (sc->ports[i].ifp != NULL) if_free(sc->ports[i].ifp); if (sc->ports[i].ifname != NULL) @@ -482,6 +478,10 @@ felix_detach(device_t dev) error = bus_release_resource(sc->dev, SYS_RES_MEMORY, rman_get_rid(sc->regs), sc->regs); + if (sc->mdio != NULL) + error = bus_release_resource(sc->dev, SYS_RES_MEMORY, + rman_get_rid(sc->mdio), sc->mdio); + return (error); } @@ -759,32 +759,20 @@ static int felix_readphy(device_t dev, int phy, int reg) { felix_softc_t sc; - device_t mdio_dev; - int port; sc = device_get_softc(dev); - port = felix_phyforport(sc, phy); - if (port < 0) - return (UINT32_MAX); /* Can't return errors here. */ - mdio_dev = device_get_parent(sc->ports[port].miibus); - return (MIIBUS_READREG(mdio_dev, phy, reg)); + return (enetc_mdio_read(sc->mdio, FELIX_MDIO_BASE, phy, reg)); } static int felix_writephy(device_t dev, int phy, int reg, int data) { felix_softc_t sc; - device_t mdio_dev; - int port; sc = device_get_softc(dev); - port = felix_phyforport(sc, phy); - if (port < 0) - return (ENXIO); - mdio_dev = device_get_parent(sc->ports[port].miibus); - return (MIIBUS_WRITEREG(mdio_dev, phy, reg, data)); + return (enetc_mdio_write(sc->mdio, FELIX_MDIO_BASE, phy, reg, data)); } static int diff --git a/sys/dev/etherswitch/felix/felix_reg.h b/sys/dev/etherswitch/felix/felix_reg.h index 3474da72a456..eae3ebc135eb 100644 --- a/sys/dev/etherswitch/felix/felix_reg.h +++ b/sys/dev/etherswitch/felix/felix_reg.h @@ -31,6 +31,8 @@ #define BIT(x) (1UL << (x)) +#define FELIX_MDIO_BASE 0x1C00 + #define FELIX_DEVCPU_GCB_RST 0x70004 #define FELIX_DEVCPU_GCB_RST_EN BIT(0) diff --git a/sys/dev/etherswitch/felix/felix_var.h b/sys/dev/etherswitch/felix/felix_var.h index 1bdbc35e6116..d891419793b7 100644 --- a/sys/dev/etherswitch/felix/felix_var.h +++ b/sys/dev/etherswitch/felix/felix_var.h @@ -38,6 +38,7 @@ #define PCI_VENDOR_FREESCALE 0x1957 #define FELIX_DEV_ID 0xEEF0 +#define FELIX_BAR_MDIO 0 #define FELIX_BAR_REGS 4 #define FELIX_LOCK(_sc) mtx_lock(&(_sc)->mtx) @@ -92,6 +93,7 @@ struct felix_port { typedef struct felix_softc { device_t dev; struct resource *regs; + struct resource *mdio; etherswitch_info_t info; struct callout tick_callout; diff --git a/sys/modules/felix/Makefile b/sys/modules/felix/Makefile index 8f30a0e72a45..4bbca5046e0a 100644 --- a/sys/modules/felix/Makefile +++ b/sys/modules/felix/Makefile @@ -27,9 +27,10 @@ # .PATH: ${SRCTOP}/sys/dev/etherswitch/felix +.PATH: ${SRCTOP}/sys/dev/enetc KMOD = felix -SRCS = felix.c +SRCS = felix.c enetc_mdio.c SRCS += bus_if.h device_if.h etherswitch_if.h miibus_if.h ofw_bus_if.h pci_if.h .include