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
This commit is contained in:
parent
06e6ca6dd3
commit
29cf6a79ac
@ -44,6 +44,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <net/if_media.h>
|
||||
#include <net/if_types.h>
|
||||
|
||||
#include <dev/enetc/enetc_mdio.h>
|
||||
|
||||
#include <dev/etherswitch/etherswitch.h>
|
||||
#include <dev/mii/mii.h>
|
||||
#include <dev/mii/miivar.h>
|
||||
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 <bsd.kmod.mk>
|
||||
|
Loading…
Reference in New Issue
Block a user