svn commit: r186420 - head/sys/arm/xscale/ixp425

Sam Leffler sam at FreeBSD.org
Tue Dec 23 04:51:47 UTC 2008


Author: sam
Date: Tue Dec 23 04:51:46 2008
New Revision: 186420
URL: http://svn.freebsd.org/changeset/base/186420

Log:
  NPE cleanups needed for ancillary drivers (e.g. crypto acceleration):
  o check feature bits when probing NPE ethernet support
  o move firmware loading logic from if_npe to core npe support
  o allow multiple refs to core NPE driver
  o while here fix hw.npe.debug tunable path

Modified:
  head/sys/arm/xscale/ixp425/if_npe.c
  head/sys/arm/xscale/ixp425/ixp425_npe.c
  head/sys/arm/xscale/ixp425/ixp425_npevar.h

Modified: head/sys/arm/xscale/ixp425/if_npe.c
==============================================================================
--- head/sys/arm/xscale/ixp425/if_npe.c	Tue Dec 23 04:49:01 2008	(r186419)
+++ head/sys/arm/xscale/ixp425/if_npe.c	Tue Dec 23 04:51:46 2008	(r186420)
@@ -157,7 +157,6 @@ struct npe_softc {
  * assumptions probably need to be handled through hints.
  */
 static const struct {
-	uint32_t	imageid;	/* default fw image */
 	uint32_t	macbase;
 	uint32_t	miibase;
 	int		phy;		/* phy id */
@@ -167,7 +166,6 @@ static const struct {
 	uint8_t		tx_doneqid;
 } npeconfig[NPE_MAX] = {
 	[NPE_A] = {
-	  .imageid	= IXP425_NPE_A_IMAGEID,
 	  .macbase	= IXP435_MAC_A_HWBASE,
 	  .miibase	= IXP425_MAC_C_HWBASE,
 	  .phy		= 2,
@@ -177,7 +175,6 @@ static const struct {
 	  .tx_doneqid	= 31
 	},
 	[NPE_B] = {
-	  .imageid	= IXP425_NPE_B_IMAGEID,
 	  .macbase	= IXP425_MAC_B_HWBASE,
 	  .miibase	= IXP425_MAC_C_HWBASE,
 	  .phy		= 0,
@@ -187,7 +184,6 @@ static const struct {
 	  .tx_doneqid	= 31
 	},
 	[NPE_C] = {
-	  .imageid	= IXP425_NPE_C_IMAGEID,
 	  .macbase	= IXP425_MAC_C_HWBASE,
 	  .miibase	= IXP425_MAC_C_HWBASE,
 	  .phy		= 1,
@@ -258,7 +254,7 @@ SYSCTL_NODE(_hw, OID_AUTO, npe, CTLFLAG_
 static int npe_debug = 0;
 SYSCTL_INT(_hw_npe, OID_AUTO, debug, CTLFLAG_RW, &npe_debug,
 	   0, "IXP4XX NPE network interface debug msgs");
-TUNABLE_INT("hw.npe.npe", &npe_debug);
+TUNABLE_INT("hw.npe.debug", &npe_debug);
 #define	DPRINTF(sc, fmt, ...) do {					\
 	if (sc->sc_debug) device_printf(sc->sc_dev, fmt, __VA_ARGS__);	\
 } while (0)
@@ -301,16 +297,21 @@ npe_probe(device_t dev)
 		[NPE_B] = "IXP NPE-B",
 		[NPE_C] = "IXP NPE-C"
 	};
+	int unit = device_get_unit(dev);
 	int npeid;
 
+	if (unit > 2 || 
+	    (ixp4xx_read_feature_bits() &
+	     (unit == 0 ? EXP_FCTRL_ETH0 : EXP_FCTRL_ETH1)) == 0)
+		return EINVAL;
+
 	npeid = -1;
 	if (!override_npeid(dev, "npeid", &npeid))
-		npeid = unit2npeid(device_get_unit(dev));
+		npeid = unit2npeid(unit);
 	if (npeid == -1) {
-		device_printf(dev, "unit not supported\n");
+		device_printf(dev, "unit %d not supported\n", unit);
 		return EINVAL;
 	}
-	/* XXX check feature register to see if enabled */
 	device_set_desc(dev, desc[npeid]);
 	return 0;
 }
@@ -644,22 +645,6 @@ override_unit(device_t dev, const char *
 	return 1;
 }
 
-static int
-override_imageid(device_t dev, const char *resname, uint32_t *val)
-{
-	int unit = device_get_unit(dev);
-	int resval;
-
-	if (resource_int_value("npe", unit, resname, &resval) != 0)
-		return 0;
-	/* XXX validate */
-	if (bootverbose)
-		device_printf(dev, "using npe.%d.%s=0x%x override\n",
-		    unit, resname, resval);
-	*val = resval;
-	return 1;
-}
-
 static void
 npe_mac_reset(struct npe_softc *sc)
 {
@@ -677,7 +662,6 @@ npe_activate(device_t dev)
 {
 	struct npe_softc * sc = device_get_softc(dev);
 	int error, i, macbase, miibase;
-	uint32_t imageid, msg[2];
 
 	/*
 	 * Setup NEP ID, MAC, and MII bindings.  We allow override
@@ -722,35 +706,12 @@ npe_activate(device_t dev)
 		sc->sc_miih = sc->sc_ioh;
 
 	/*
-	 * Load NPE firmware and start it running.  We assume
-	 * that minor version bumps remain compatible so probe
-	 * the firmware image starting with the expected version
-	 * and then bump the minor version up to the max.
+	 * Load NPE firmware and start it running.
 	 */
-	if (!override_imageid(dev, "imageid", &imageid))
-		imageid = npeconfig[sc->sc_npeid].imageid;
-	for (;;) {
-		error = ixpnpe_init(sc->sc_npe, "npe_fw", imageid);
-		if (error == 0)
-			break;
-		/* ESRCH is returned when the requested image is not present */
-		if (error != ESRCH) {
-			device_printf(dev, "cannot init NPE (error %d)\n",
-			    error);
-			return error;
-		}
-		/* bump the minor version up to the max possible */
-		if (NPEIMAGE_MINOR(imageid) == 0xff) {
-			device_printf(dev, "cannot locate firmware "
-			    "(imageid 0x%08x)\n", imageid);
-			return error;
-		}
-		imageid++;
-	}
-	/* NB: firmware should respond with a status msg */
-	if (ixpnpe_recvmsg_sync(sc->sc_npe, msg) != 0) {
-		device_printf(dev, "firmware did not respond as expected\n");
-		return EIO;
+	error = ixpnpe_init(sc->sc_npe);
+	if (error != 0) {
+		device_printf(dev, "cannot init NPE (error %d)\n", error);
+		return error;
 	}
 
 	/* probe for PHY */
@@ -984,7 +945,6 @@ npe_setmac(struct npe_softc *sc, u_char 
 	WR4(sc, NPE_MAC_UNI_ADDR_4, eaddr[3]);
 	WR4(sc, NPE_MAC_UNI_ADDR_5, eaddr[4]);
 	WR4(sc, NPE_MAC_UNI_ADDR_6, eaddr[5]);
-
 }
 
 static void

Modified: head/sys/arm/xscale/ixp425/ixp425_npe.c
==============================================================================
--- head/sys/arm/xscale/ixp425/ixp425_npe.c	Tue Dec 23 04:49:01 2008	(r186419)
+++ head/sys/arm/xscale/ixp425/ixp425_npe.c	Tue Dec 23 04:51:46 2008	(r186420)
@@ -112,6 +112,8 @@ struct ixpnpe_softc {
 	struct mtx	sc_mtx;		/* mailbox lock */
 	uint32_t	sc_msg[2];	/* reply msg collected in ixpnpe_intr */
 	int		sc_msgwaiting;	/* sc_msg holds valid data */
+	int		sc_npeid;
+	int		sc_nrefs;	/* # of references */
 
 	int		validImage;	/* valid ucode image loaded */
 	int		started;	/* NPE is started */
@@ -121,6 +123,7 @@ struct ixpnpe_softc {
 	uint32_t	savedExecCount;
 	uint32_t	savedEcsDbgCtxtReg2;
 };
+static struct ixpnpe_softc *npes[NPE_MAX];
 
 #define	IX_NPEDL_NPEIMAGE_FIELD_MASK	0xff
 
@@ -287,6 +290,11 @@ ixpnpe_attach(device_t dev, int npeid)
 		device_printf(dev, "%s: bad npeid %d\n", __func__, npeid);
 		return NULL;
 	}
+	sc = npes[npeid];
+	if (sc != NULL) {
+		sc->sc_nrefs++;
+		return sc;
+	}
 	config = &npeconfigs[npeid];
 
 	/* XXX M_BUS */
@@ -294,6 +302,8 @@ ixpnpe_attach(device_t dev, int npeid)
 	sc->sc_dev = dev;
 	sc->sc_iot = sa->sc_iot;
 	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), "npe driver", MTX_DEF);
+	sc->sc_npeid = npeid;
+	sc->sc_nrefs = 1;
 
 	sc->sc_size = config->size;
 	sc->insMemSize = config->ins_memsize;	/* size of instruction memory */
@@ -320,20 +330,26 @@ ixpnpe_attach(device_t dev, int npeid)
 	npe_reg_write(sc, IX_NPECTL,
 	    npe_reg_read(sc, IX_NPECTL) | (IX_NPECTL_OFE | IX_NPECTL_OFWE));
 
+	npes[npeid] = sc;
+
 	return sc;
 }
 
 void
 ixpnpe_detach(struct ixpnpe_softc *sc)
 {
-	/* disable output fifo interrupts */ 
-	npe_reg_write(sc, IX_NPECTL,
-	    npe_reg_read(sc, IX_NPECTL) &~ (IX_NPECTL_OFE | IX_NPECTL_OFWE));
+	if (--sc->sc_nrefs == 0) {
+		npes[sc->sc_npeid] = NULL;
 
-	bus_teardown_intr(sc->sc_dev, sc->sc_irq, sc->sc_ih);
-	bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size);
-	mtx_destroy(&sc->sc_mtx);
-	free(sc, M_TEMP);
+		/* disable output fifo interrupts */ 
+		npe_reg_write(sc, IX_NPECTL,
+		    npe_reg_read(sc, IX_NPECTL) &~ (IX_NPECTL_OFE | IX_NPECTL_OFWE));
+
+		bus_teardown_intr(sc->sc_dev, sc->sc_irq, sc->sc_ih);
+		bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size);
+		mtx_destroy(&sc->sc_mtx);
+		free(sc, M_TEMP);
+	}
 }
 
 int
@@ -361,7 +377,7 @@ ixpnpe_start_locked(struct ixpnpe_softc 
 	if (!sc->started) {
 		error = npe_cpu_start(sc);
 		if (error == 0)
-		    sc->started = 1;
+			sc->started = 1;
 	} else
 		error = 0;
 
@@ -442,8 +458,9 @@ npe_findimage(struct ixpnpe_softc *sc,
 	return ESRCH;
 }
 
-int
-ixpnpe_init(struct ixpnpe_softc *sc, const char *imageName, uint32_t imageId)
+static int
+ixpnpe_load_firmware(struct ixpnpe_softc *sc, const char *imageName,
+    uint32_t imageId)
 {
 	static const char *devname[4] =
 	     { "IXP425", "IXP435/IXP465", "DeviceID#2", "DeviceID#3" };
@@ -504,6 +521,73 @@ done:
 	return error;
 }
 
+static int
+override_imageid(device_t dev, const char *resname, uint32_t *val)
+{
+	int unit = device_get_unit(dev);
+	int resval;
+
+	if (resource_int_value("npe", unit, resname, &resval) != 0)
+		return 0;
+	/* XXX validate */
+	if (bootverbose)
+		device_printf(dev, "using npe.%d.%s=0x%x override\n",
+		    unit, resname, resval);
+	*val = resval;
+	return 1;
+}
+
+int
+ixpnpe_init(struct ixpnpe_softc *sc)
+{
+	static const uint32_t npeconfig[NPE_MAX] = {
+		[NPE_A] = IXP425_NPE_A_IMAGEID,
+		[NPE_B] = IXP425_NPE_B_IMAGEID,
+		[NPE_C] = IXP425_NPE_C_IMAGEID,
+	};
+	uint32_t imageid, msg[2];
+	int error;
+
+	if (sc->started)
+		return 0;
+	/*
+	 * Load NPE firmware and start it running.  We assume
+	 * that minor version bumps remain compatible so probe
+	 * the firmware image starting with the expected version
+	 * and then bump the minor version up to the max.
+	 */
+	if (!override_imageid(sc->sc_dev, "imageid", &imageid))
+		imageid = npeconfig[sc->sc_npeid];
+	for (;;) {
+		error = ixpnpe_load_firmware(sc, "npe_fw", imageid);
+		if (error == 0)
+			break;
+		/*
+		 * ESRCH is returned when the requested image
+		 * is not present
+		 */
+		if (error != ESRCH) {
+			device_printf(sc->sc_dev,
+			    "cannot init NPE (error %d)\n", error);
+			return error;
+		}
+		/* bump the minor version up to the max possible */
+		if (NPEIMAGE_MINOR(imageid) == 0xff) {
+			device_printf(sc->sc_dev, "cannot locate firmware "
+			    "(imageid 0x%08x)\n", imageid);
+			return error;
+		}
+		imageid++;
+	}
+	/* NB: firmware should respond with a status msg */
+	if (ixpnpe_recvmsg_sync(sc, msg) != 0) {
+		device_printf(sc->sc_dev,
+		    "firmware did not respond as expected\n");
+		return EIO;
+	}
+	return 0;
+}
+
 int
 ixpnpe_getfunctionality(struct ixpnpe_softc *sc)
 {

Modified: head/sys/arm/xscale/ixp425/ixp425_npevar.h
==============================================================================
--- head/sys/arm/xscale/ixp425/ixp425_npevar.h	Tue Dec 23 04:49:01 2008	(r186419)
+++ head/sys/arm/xscale/ixp425/ixp425_npevar.h	Tue Dec 23 04:51:46 2008	(r186420)
@@ -111,8 +111,7 @@ void	ixpnpe_detach(struct ixpnpe_softc *
 int	ixpnpe_stopandreset(struct ixpnpe_softc *);
 int	ixpnpe_start(struct ixpnpe_softc *);
 int	ixpnpe_stop(struct ixpnpe_softc *);
-int	ixpnpe_init(struct ixpnpe_softc *,
-		const char *imageName, uint32_t imageId);
+int	ixpnpe_init(struct ixpnpe_softc *);
 int	ixpnpe_getfunctionality(struct ixpnpe_softc *sc);
 
 int	ixpnpe_sendmsg_async(struct ixpnpe_softc *, const uint32_t msg[2]);


More information about the svn-src-all mailing list