git: ee1b7811a3e1 - main - e6000sw: Build the driver as a kernel module

Wojciech Macek wma at FreeBSD.org
Mon Sep 13 09:43:07 UTC 2021


The branch main has been updated by wma:

URL: https://cgit.FreeBSD.org/src/commit/?id=ee1b7811a3e19633aad02eab8bc81eae2ccbd8af

commit ee1b7811a3e19633aad02eab8bc81eae2ccbd8af
Author:     Hubert Mazur <hum at semihalf.com>
AuthorDate: 2021-09-13 09:42:16 +0000
Commit:     Wojciech Macek <wma at FreeBSD.org>
CommitDate: 2021-09-13 09:42:16 +0000

    e6000sw: Build the driver as a kernel module
    
    Fix detach routine.
    Driver was tested on EspressoBin.
    Remove it from GENERIC, since now it can be loaded automatically.
    
    Obtained from:          Semihalf
    Reviewed by:            manu
    Differential revision:  https://reviews.freebsd.org/D31580
---
 sys/arm64/conf/std.marvell            |  1 -
 sys/dev/etherswitch/e6000sw/e6000sw.c | 75 ++++++++++++++---------------------
 sys/modules/Makefile                  |  2 +
 sys/modules/e6000sw/Makefile          | 10 +++++
 4 files changed, 41 insertions(+), 47 deletions(-)

diff --git a/sys/arm64/conf/std.marvell b/sys/arm64/conf/std.marvell
index d6437a426d48..cb49d8aedc2b 100644
--- a/sys/arm64/conf/std.marvell
+++ b/sys/arm64/conf/std.marvell
@@ -42,7 +42,6 @@ device		neta			# Marvell Armada 370/38x/XP/3700 NIC
 # 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
index e6c76c578d14..68caf61f9358 100644
--- a/sys/dev/etherswitch/e6000sw/e6000sw.c
+++ b/sys/dev/etherswitch/e6000sw/e6000sw.c
@@ -122,8 +122,6 @@ static int e6000sw_setport(device_t, etherswitch_port_t *);
 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 @@ static device_method_t e6000sw_methods[] = {
 	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 @@ e6000sw_attach(device_t dev)
 	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 @@ e6000sw_attach(device_t dev)
 		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 @@ e6000sw_attach(device_t dev)
 	return (0);
 
 out_fail:
-	E6000SW_UNLOCK(sc);
 	e6000sw_detach(dev);
 
 	return (err);
@@ -661,14 +668,18 @@ e6000sw_readphy(device_t dev, int phy, int reg)
 	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 @@ e6000sw_readphy(device_t dev, int phy, int reg)
 	    ((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_writephy(device_t dev, int phy, int reg, int data)
 	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 @@ e6000sw_writephy(device_t dev, int phy, int reg, int data)
 	    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 @@ e6000sw_detach(device_t dev)
 	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 @@ e6000sw_writereg_wrapper(device_t dev, int addr_reg, int val)
 	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
index 030c64701de8..7ed2169445e4 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -108,6 +108,7 @@ SUBDIR=	\
 	${_dpms} \
 	dummynet \
 	${_dwwdt} \
+	${_e6000sw} \
 	${_efirt} \
 	${_em} \
 	${_ena} \
@@ -624,6 +625,7 @@ _rockchip=	rockchip
 
 .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
index 000000000000..51afb6d8f3a4
--- /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>


More information about the dev-commits-src-main mailing list