svn commit: r305040 - head/sys/dev/tsec

Justin Hibbits jhibbits at FreeBSD.org
Tue Aug 30 01:58:50 UTC 2016


Author: jhibbits
Date: Tue Aug 30 01:58:49 2016
New Revision: 305040
URL: https://svnweb.freebsd.org/changeset/base/305040

Log:
  Add support for NXP/Freescale etsec2 ethernet controller
  
  Adding the compatible property check isn't enough.  Device trees for eTSEC2
  devices are missing a 'reg' property on the eTSEC node itself, relegating it to
  the queue group child nodes.
  
  Still left to do: add Multigroup mode support (see QorIQ reference manuals s for
  SoCs with eTSEC2).
  
  MFC after:	2 weeks
  Relnotes:	Yes

Modified:
  head/sys/dev/tsec/if_tsec.h
  head/sys/dev/tsec/if_tsec_fdt.c

Modified: head/sys/dev/tsec/if_tsec.h
==============================================================================
--- head/sys/dev/tsec/if_tsec.h	Tue Aug 30 01:31:03 2016	(r305039)
+++ head/sys/dev/tsec/if_tsec.h	Tue Aug 30 01:58:49 2016	(r305040)
@@ -135,6 +135,7 @@ struct tsec_softc {
 	int		phyaddr;
 	bus_space_tag_t phy_bst;
 	bus_space_handle_t phy_bsh;
+	int		phy_regoff;
 };
 
 /* interface to get/put generic objects */
@@ -258,9 +259,11 @@ extern struct mtx tsec_phy_mtx;
 #define TSEC_PHY_LOCK(sc)	mtx_lock(&tsec_phy_mtx)
 #define TSEC_PHY_UNLOCK(sc)	mtx_unlock(&tsec_phy_mtx)
 #define TSEC_PHY_READ(sc, reg)		\
-		bus_space_read_4((sc)->phy_bst, (sc)->phy_bsh, (reg))
+		bus_space_read_4((sc)->phy_bst, (sc)->phy_bsh, \
+			(reg) + (sc)->phy_regoff)
 #define TSEC_PHY_WRITE(sc, reg, val)	\
-		bus_space_write_4((sc)->phy_bst, (sc)->phy_bsh, (reg), (val))
+		bus_space_write_4((sc)->phy_bst, (sc)->phy_bsh, \
+			(reg) + (sc)->phy_regoff, (val))
 
 /* Lock for transmitter */
 #define TSEC_TRANSMIT_LOCK(sc) do {					\

Modified: head/sys/dev/tsec/if_tsec_fdt.c
==============================================================================
--- head/sys/dev/tsec/if_tsec_fdt.c	Tue Aug 30 01:31:03 2016	(r305039)
+++ head/sys/dev/tsec/if_tsec_fdt.c	Tue Aug 30 01:58:49 2016	(r305040)
@@ -121,25 +121,33 @@ tsec_fdt_probe(device_t dev)
 
 	sc = device_get_softc(dev);
 
-	sc->sc_rrid = 0;
-	sc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rrid,
-	    RF_ACTIVE);
-	if (sc->sc_rres == NULL)
-		return (ENXIO);
-
-	sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres);
-	sc->sc_bas.bst = rman_get_bustag(sc->sc_rres);
-
-	/* Check if we are eTSEC (enhanced TSEC) */
-	id = TSEC_READ(sc, TSEC_REG_ID);
-	sc->is_etsec = ((id >> 16) == TSEC_ETSEC_ID) ? 1 : 0;
-	id |= TSEC_READ(sc, TSEC_REG_ID2);
-
-	bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rrid, sc->sc_rres);
-
-	if (id == 0) {
-		device_printf(dev, "could not identify TSEC type\n");
-		return (ENXIO);
+	/*
+	 * Device trees with "fsl,etsec2" compatible nodes don't have a reg
+	 * property, as it's been relegated to the queue-group children.
+	 */
+	if (ofw_bus_is_compatible(dev, "fsl,etsec2"))
+		sc->is_etsec = 1;
+	else {
+		sc->sc_rrid = 0;
+		sc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rrid,
+		    RF_ACTIVE);
+		if (sc->sc_rres == NULL)
+			return (ENXIO);
+
+		sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres);
+		sc->sc_bas.bst = rman_get_bustag(sc->sc_rres);
+
+		/* Check if we are eTSEC (enhanced TSEC) */
+		id = TSEC_READ(sc, TSEC_REG_ID);
+		sc->is_etsec = ((id >> 16) == TSEC_ETSEC_ID) ? 1 : 0;
+		id |= TSEC_READ(sc, TSEC_REG_ID2);
+
+		bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rrid, sc->sc_rres);
+
+		if (id == 0) {
+			device_printf(dev, "could not identify TSEC type\n");
+			return (ENXIO);
+		}
 	}
 
 	if (sc->is_etsec)
@@ -154,13 +162,31 @@ static int
 tsec_fdt_attach(device_t dev)
 {
 	struct tsec_softc *sc;
-	phandle_t phy;
+	struct resource_list *rl;
+	phandle_t child, mdio, phy;
+	int acells, scells;
 	int error = 0;
 
 	sc = device_get_softc(dev);
 	sc->dev = dev;
 	sc->node = ofw_bus_get_node(dev);
 
+	if (fdt_addrsize_cells(sc->node, &acells, &scells) != 0) {
+		acells = 1;
+		scells = 1;
+	}
+	if (ofw_bus_is_compatible(dev, "fsl,etsec2")) {
+		rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev);
+
+		/*
+		 * TODO: Add all children resources to the list.  Will be
+		 * required to support multigroup mode.
+		 */
+		child = OF_child(sc->node);
+		ofw_bus_reg_to_rl(dev, child, acells, scells, rl);
+		ofw_bus_intr_to_rl(dev, child, rl, NULL);
+	}
+
 	/* Get phy address from fdt */
 	if (OF_getencprop(sc->node, "phy-handle", &phy, sizeof(phy)) <= 0) {
 		device_printf(dev, "PHY not found in device tree");
@@ -168,9 +194,17 @@ tsec_fdt_attach(device_t dev)
 	}
 
 	phy = OF_node_from_xref(phy);
-	OF_decode_addr(OF_parent(phy), 0, &sc->phy_bst, &sc->phy_bsh, NULL);
+	mdio = OF_parent(phy);
+	OF_decode_addr(mdio, 0, &sc->phy_bst, &sc->phy_bsh, NULL);
 	OF_getencprop(phy, "reg", &sc->phyaddr, sizeof(sc->phyaddr));
 
+	/*
+	 * etsec2 MDIO nodes are given the MDIO module base address, so we need
+	 * to add the MII offset to get the PHY registers.
+	 */
+	if (ofw_bus_node_is_compatible(mdio, "fsl,etsec2-mdio"))
+		sc->phy_regoff = TSEC_REG_MIIBASE;
+
 	/* Init timer */
 	callout_init(&sc->tsec_callout, 1);
 


More information about the svn-src-head mailing list