Page MenuHomeFreeBSD

D31580.diff
No OneTemporary

D31580.diff

diff --git a/sys/arm64/conf/std.marvell b/sys/arm64/conf/std.marvell
--- a/sys/arm64/conf/std.marvell
+++ b/sys/arm64/conf/std.marvell
@@ -42,7 +42,6 @@
# Etherswitch devices
device etherswitch # Enable etherswitch support
device miiproxy # Required for etherswitch
-device e6000sw # Marvell mv88e6085 based switches
# USB support
device ehci_mv # Marvell EHCI USB interface
diff --git a/sys/dev/etherswitch/e6000sw/e6000sw.c b/sys/dev/etherswitch/e6000sw/e6000sw.c
--- a/sys/dev/etherswitch/e6000sw/e6000sw.c
+++ b/sys/dev/etherswitch/e6000sw/e6000sw.c
@@ -122,8 +122,6 @@
static int e6000sw_set_vlan_mode(e6000sw_softc_t *, uint32_t);
static int e6000sw_readreg_wrapper(device_t, int);
static int e6000sw_writereg_wrapper(device_t, int, int);
-static int e6000sw_readphy_wrapper(device_t, int, int);
-static int e6000sw_writephy_wrapper(device_t, int, int, int);
static int e6000sw_getvgroup_wrapper(device_t, etherswitch_vlangroup_t *);
static int e6000sw_setvgroup_wrapper(device_t, etherswitch_vlangroup_t *);
static int e6000sw_setvgroup(device_t, etherswitch_vlangroup_t *);
@@ -174,8 +172,8 @@
DEVMETHOD(etherswitch_setport, e6000sw_setport),
DEVMETHOD(etherswitch_readreg, e6000sw_readreg_wrapper),
DEVMETHOD(etherswitch_writereg, e6000sw_writereg_wrapper),
- DEVMETHOD(etherswitch_readphyreg, e6000sw_readphy_wrapper),
- DEVMETHOD(etherswitch_writephyreg, e6000sw_writephy_wrapper),
+ DEVMETHOD(etherswitch_readphyreg, e6000sw_readphy),
+ DEVMETHOD(etherswitch_writephyreg, e6000sw_writephy),
DEVMETHOD(etherswitch_setvgroup, e6000sw_setvgroup_wrapper),
DEVMETHOD(etherswitch_getvgroup, e6000sw_getvgroup_wrapper),
@@ -463,6 +461,7 @@
if (ports == 0) {
device_printf(dev, "failed to parse DTS: no ports found for "
"switch\n");
+ E6000SW_UNLOCK(sc);
return (ENXIO);
}
@@ -531,11 +530,20 @@
if (!e6000sw_is_phyport(sc, port))
continue;
+ /*
+ * It's necessary to unlock mutex, because e6000sw_attach_miibus
+ * calls functions, which try to lock mutex.That leads
+ * to recursive lock on non recursive mutex.
+ */
+ E6000SW_UNLOCK(sc);
+
err = e6000sw_attach_miibus(sc, port);
if (err != 0) {
device_printf(sc->dev, "failed to attach miibus\n");
goto out_fail;
}
+
+ E6000SW_LOCK(sc);
}
etherswitch_info.es_nports = sc->num_ports;
@@ -556,7 +564,6 @@
return (0);
out_fail:
- E6000SW_UNLOCK(sc);
e6000sw_detach(dev);
return (err);
@@ -661,14 +668,18 @@
uint32_t val;
sc = device_get_softc(dev);
+ E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED);
+
if (!e6000sw_is_phyport(sc, phy) || reg >= E6000SW_NUM_PHY_REGS) {
device_printf(dev, "Wrong register address.\n");
return (EINVAL);
}
- E6000SW_LOCK_ASSERT(sc, SA_XLOCKED);
+ E6000SW_LOCK(sc);
+
if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) {
device_printf(dev, "Timeout while waiting for switch\n");
+ E6000SW_UNLOCK(sc);
return (ETIMEDOUT);
}
@@ -677,11 +688,14 @@
((phy << SMI_CMD_DEV_ADDR) & SMI_CMD_DEV_ADDR_MASK));
if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) {
device_printf(dev, "Timeout while waiting for switch\n");
+ E6000SW_UNLOCK(sc);
return (ETIMEDOUT);
}
val = e6000sw_readreg(sc, REG_GLOBAL2, SMI_PHY_DATA_REG);
+ E6000SW_UNLOCK(sc);
+
return (val & PHY_DATA_MASK);
}
@@ -691,14 +705,18 @@
e6000sw_softc_t *sc;
sc = device_get_softc(dev);
+ E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED);
+
if (!e6000sw_is_phyport(sc, phy) || reg >= E6000SW_NUM_PHY_REGS) {
device_printf(dev, "Wrong register address.\n");
return (EINVAL);
}
- E6000SW_LOCK_ASSERT(sc, SA_XLOCKED);
+ E6000SW_LOCK(sc);
+
if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) {
device_printf(dev, "Timeout while waiting for switch\n");
+ E6000SW_UNLOCK(sc);
return (ETIMEDOUT);
}
@@ -708,6 +726,8 @@
SMI_CMD_OP_C22_WRITE | (reg & SMI_CMD_REG_ADDR_MASK) |
((phy << SMI_CMD_DEV_ADDR) & SMI_CMD_DEV_ADDR_MASK));
+ E6000SW_UNLOCK(sc);
+
return (0);
}
@@ -725,11 +745,10 @@
if (sc->sc_tq != NULL)
taskqueue_free(sc->sc_tq);
- bus_generic_detach(dev);
+ device_delete_children(dev);
+
sx_destroy(&sc->sx);
for (phy = 0; phy < sc->num_ports; phy++) {
- if (sc->miibus[phy] != NULL)
- device_delete_child(dev, sc->miibus[phy]);
if (sc->ifp[phy] != NULL)
if_free(sc->ifp[phy]);
if (sc->ifname[phy] != NULL)
@@ -1051,42 +1070,6 @@
return (0);
}
-/*
- * These wrappers are necessary because PHY accesses from etherswitchcfg
- * need to be synchronized with locks, while miibus PHY accesses do not.
- */
-static int
-e6000sw_readphy_wrapper(device_t dev, int phy, int reg)
-{
- e6000sw_softc_t *sc;
- int ret;
-
- sc = device_get_softc(dev);
- E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED);
-
- E6000SW_LOCK(sc);
- ret = e6000sw_readphy(dev, phy, reg);
- E6000SW_UNLOCK(sc);
-
- return (ret);
-}
-
-static int
-e6000sw_writephy_wrapper(device_t dev, int phy, int reg, int data)
-{
- e6000sw_softc_t *sc;
- int ret;
-
- sc = device_get_softc(dev);
- E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED);
-
- E6000SW_LOCK(sc);
- ret = e6000sw_writephy(dev, phy, reg, data);
- E6000SW_UNLOCK(sc);
-
- return (ret);
-}
-
/*
* setvgroup/getvgroup called from etherswitchfcg need to be locked,
* while internal calls do not.
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -108,6 +108,7 @@
${_dpms} \
dummynet \
${_dwwdt} \
+ ${_e6000sw} \
${_efirt} \
${_em} \
${_ena} \
@@ -624,6 +625,7 @@
.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm"
_sdhci_fdt= sdhci_fdt
+_e6000sw= e6000sw
.endif
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
diff --git a/sys/modules/e6000sw/Makefile b/sys/modules/e6000sw/Makefile
new file mode 100644
--- /dev/null
+++ b/sys/modules/e6000sw/Makefile
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+.PATH: ${SRCTOP}/sys/dev/etherswitch/e6000sw
+
+KMOD= e6000sw
+SRCS= e6000sw.c
+
+SRCS+= bus_if.h etherswitch_if.h mdio_if.h miibus_if.h ofw_bus_if.h
+
+.include <bsd.kmod.mk>

File Metadata

Mime Type
text/plain
Expires
Sun, Dec 22, 7:00 AM (20 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15551336
Default Alt Text
D31580.diff (5 KB)

Event Timeline