Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Dec 2008 17:44:40 GMT
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 154447 for review
Message-ID:  <200812101744.mBAHieHx083517@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=154447

Change 154447 by sam@sam_ebb on 2008/12/10 17:44:24

	Sync updates in the continued pursuit of a working NPE-A on ixp435:
	o track MAC address/naming changes
	o remove macsize and miisize from the static config tables; these
	  are always going to be 4K
	o fix NPE-A qid's (from clang@gateworks)
	o move phy probe to npe_activate so it can be done before hooking
	  up the qmgr (seems to be a noop)
	o simplify mac/mii address override from hints; no more size parameter
	o split out mac reset logic for possible reuse
	o rearrange activate work to be more like linux (doesn't seem to matter)
	o add printfs to show MAC and MII addresses (to go under bootverbose)
	o add DELAY(1) when polling for MII cmd completion and up max tries
	  to 1000 (~1ms total)
	
	Tested on Avila and Cambria boards w/o regression.

Affected files ...

.. //depot/projects/vap/sys/arm/xscale/ixp425/if_npe.c#11 edit

Differences ...

==== //depot/projects/vap/sys/arm/xscale/ixp425/if_npe.c#11 (text+ko) ====

@@ -159,9 +159,7 @@
 static const struct {
 	uint32_t	imageid;	/* default fw image */
 	uint32_t	macbase;
-	int		macsize;
 	uint32_t	miibase;
-	int		miisize;
 	int		phy;		/* phy id */
 	uint8_t		rx_qid;
 	uint8_t		rx_freeqid;
@@ -171,21 +169,17 @@
 	[NPE_A] = {
 	  .imageid	= IXP425_NPE_A_IMAGEID,
 	  .macbase	= IXP435_MAC_A_HWBASE,
-	  .macsize	= IXP435_MAC_A_SIZE,
-	  .miibase	= IXP435_MAC_A_HWBASE,
-	  .miisize	= IXP435_MAC_A_SIZE,
+	  .miibase	= IXP425_MAC_C_HWBASE,
 	  .phy		= 2,
 	  .rx_qid	= 4,
-	  .rx_freeqid	= 27,
-	  .tx_qid	= 24,
+	  .rx_freeqid	= 26,
+	  .tx_qid	= 23,
 	  .tx_doneqid	= 31
 	},
 	[NPE_B] = {
 	  .imageid	= IXP425_NPE_B_IMAGEID,
-	  .macbase	= IXP425_MAC_A_HWBASE,
-	  .macsize	= IXP425_MAC_A_SIZE,
-	  .miibase	= IXP425_MAC_A_HWBASE,
-	  .miisize	= IXP425_MAC_A_SIZE,
+	  .macbase	= IXP425_MAC_B_HWBASE,
+	  .miibase	= IXP425_MAC_C_HWBASE,
 	  .phy		= 0,
 	  .rx_qid	= 4,
 	  .rx_freeqid	= 27,
@@ -194,10 +188,8 @@
 	},
 	[NPE_C] = {
 	  .imageid	= IXP425_NPE_C_IMAGEID,
-	  .macbase	= IXP425_MAC_B_HWBASE,
-	  .macsize	= IXP425_MAC_B_SIZE,
-	  .miibase	= IXP425_MAC_A_HWBASE,
-	  .miisize	= IXP425_MAC_A_SIZE,
+	  .macbase	= IXP425_MAC_C_HWBASE,
+	  .miibase	= IXP425_MAC_C_HWBASE,
 	  .phy		= 1,
 	  .rx_qid	= 12,
 	  .rx_freeqid	= 28,
@@ -330,7 +322,7 @@
 	struct ixp425_softc *sa = device_get_softc(device_get_parent(dev));
 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
 	struct sysctl_oid *tree = device_get_sysctl_tree(dev);
-	struct ifnet *ifp = NULL;
+	struct ifnet *ifp;
 	int error;
 	u_char eaddr[6];
 
@@ -341,31 +333,23 @@
 	sc->sc_debug = npe_debug;
 	sc->sc_tickinterval = npe_tickinterval;
 
-	if (!override_npeid(dev, "npeid", &sc->sc_npeid))
-		sc->sc_npeid = unit2npeid(device_get_unit(dev));
-	sc->sc_npe = ixpnpe_attach(dev, sc->sc_npeid);
-	if (sc->sc_npe == NULL) {
-		device_printf(dev, "cannot attach ixpnpe.\n");
+	ifp = if_alloc(IFT_ETHER);
+	if (ifp == NULL) {
+		device_printf(dev, "cannot allocate ifnet\n");
 		error = EIO;		/* XXX */
 		goto out;
 	}
+	/* NB: must be setup prior to invoking mii code */
+	sc->sc_ifp = ifp;
 
 	error = npe_activate(dev);
 	if (error) {
-		device_printf(dev, "cannot activate npe.\n");
+		device_printf(dev, "cannot activate npe\n");
 		goto out;
 	}
 
 	npe_getmac(sc, eaddr);
 
-	/* NB: must be setup prior to invoking mii code */
-	sc->sc_ifp = ifp = if_alloc(IFT_ETHER);
-	if (mii_phy_probe(dev, &sc->sc_mii, npe_ifmedia_update, npe_ifmedia_status)) {
-		device_printf(dev, "cannot find my PHY.\n");
-		error = ENXIO;
-		goto out;
-	}
-
 	ifp->if_softc = sc;
 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
@@ -394,8 +378,6 @@
 		if_free(ifp);
 	NPE_LOCK_DESTROY(sc);
 	npe_deactivate(dev);
-	if (sc->sc_npe != NULL)
-		ixpnpe_detach(sc->sc_npe);
 	return error;
 }
 
@@ -416,8 +398,6 @@
 	}
 	NPE_LOCK_DESTROY(sc);
 	npe_deactivate(dev);
-	if (sc->sc_npe != NULL)
-		ixpnpe_detach(sc->sc_npe);
 	return 0;
 }
 
@@ -590,36 +570,8 @@
 }
 
 static int
-npe_macaddr(int npeid, int *base, int *size)
+override_addr(device_t dev, const char *resname, int *base)
 {
-	if (npeid == NPE_A) {
-		if ((cpu_id() & CPU_ID_CPU_MASK) == CPU_ID_IXP435) {
-			*base = IXP435_MAC_A_HWBASE;
-			*size = IXP435_MAC_A_SIZE;
-		} else {
-			*base = IXP425_MAC_A_HWBASE;
-			*size = IXP425_MAC_A_SIZE;
-		}
-		return 0;
-	} else if (npeid == NPE_B) {
-		if ((cpu_id() & CPU_ID_CPU_MASK) != CPU_ID_IXP435) {
-			*base = IXP425_MAC_B_HWBASE;
-			*size = IXP425_MAC_B_SIZE;
-			return 0;
-		}
-	} else if (npeid == NPE_C) {
-		if ((cpu_id() & CPU_ID_CPU_MASK) == CPU_ID_IXP435) {
-			*base = IXP435_MAC_C_HWBASE;
-			*size = IXP435_MAC_C_SIZE;
-			return 0;
-		}
-	}
-	return EINVAL;
-}
-
-static int
-override_addr(device_t dev, const char *resname, int *base, int *size)
-{
 	int unit = device_get_unit(dev);
 	const char *resval;
 
@@ -628,18 +580,15 @@
 		return 0;
 	switch (resval[0]) {
 	case 'A':
-		npe_macaddr(NPE_A, base, size);
+		*base = IXP435_MAC_A_HWBASE;
 		break;
 	case 'B':
-		if (npe_macaddr(NPE_B, base, size) != 0)
-			goto bad;
+		*base = IXP425_MAC_B_HWBASE;
 		break;
 	case 'C':
-		if (npe_macaddr(NPE_C, base, size) != 0)
-			goto bad;
+		*base = IXP425_MAC_C_HWBASE;
 		break;
 	default:
-	bad:
 		device_printf(dev, "Warning, bad value %s for "
 		    "npe.%d.%s ignored\n", resval, unit, resname);
 		return 0;
@@ -711,14 +660,68 @@
 	return 1;
 }
 
+static void
+npe_mac_reset(struct npe_softc *sc)
+{
+	/*
+	 * Reset MAC core.
+	 */
+	WR4(sc, NPE_MAC_CORE_CNTRL, NPE_CORE_RESET);
+	DELAY(NPE_MAC_RESET_DELAY);
+	/* configure MAC to generate MDC clock */
+	WR4(sc, NPE_MAC_CORE_CNTRL, NPE_CORE_MDC_EN);
+}
+
 static int
 npe_activate(device_t dev)
 {
 	struct npe_softc * sc = device_get_softc(dev);
-	int error, i, macbase, macsize, miibase, miisize;
+	int error, i, macbase, miibase;
 	uint32_t imageid, msg[2];
 
 	/*
+	 * Setup NEP ID, MAC, and MII bindings.  We allow override
+	 * via hints to handle unexpected board configs.
+	 */
+	if (!override_npeid(dev, "npeid", &sc->sc_npeid))
+		sc->sc_npeid = unit2npeid(device_get_unit(dev));
+	sc->sc_npe = ixpnpe_attach(dev, sc->sc_npeid);
+	if (sc->sc_npe == NULL) {
+		device_printf(dev, "cannot attach ixpnpe\n");
+		return EIO;		/* XXX */
+	}
+
+	/* MAC */
+	if (!override_addr(dev, "mac", &macbase))
+		macbase = npeconfig[sc->sc_npeid].macbase;
+	device_printf(sc->sc_dev, "MAC at 0x%x\n", macbase);
+	if (bus_space_map(sc->sc_iot, macbase, IXP425_REG_SIZE, 0, &sc->sc_ioh)) {
+		device_printf(dev, "cannot map mac registers 0x%x:0x%x\n",
+		    macbase, IXP425_REG_SIZE);
+		return ENOMEM;
+	}
+
+	/* PHY */
+	if (!override_unit(dev, "phy", &sc->sc_phy, 0, MII_NPHY-1))
+		sc->sc_phy = npeconfig[sc->sc_npeid].phy;
+	if (!override_addr(dev, "mii", &miibase))
+		miibase = npeconfig[sc->sc_npeid].miibase;
+	device_printf(sc->sc_dev, "MII at 0x%x\n", miibase);
+	if (miibase != macbase) {
+		/*
+		 * PHY is mapped through a different MAC, setup an
+		 * additional mapping for frobbing the PHY registers.
+		 */
+		if (bus_space_map(sc->sc_iot, miibase, IXP425_REG_SIZE, 0, &sc->sc_miih)) {
+			device_printf(dev,
+			    "cannot map MII registers 0x%x:0x%x\n",
+			    miibase, IXP425_REG_SIZE);
+			return ENOMEM;
+		}
+	} else
+		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
@@ -744,38 +747,18 @@
 		}
 		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;
 	}
 
-	if (!override_addr(dev, "mac", &macbase, &macsize)) {
-		macbase = npeconfig[sc->sc_npeid].macbase;
-		macsize = npeconfig[sc->sc_npeid].macsize;
+	/* probe for PHY */
+	if (mii_phy_probe(dev, &sc->sc_mii, npe_ifmedia_update, npe_ifmedia_status)) {
+		device_printf(dev, "cannot find PHY %d.\n", sc->sc_phy);
+		return ENXIO;
 	}
-	if (bus_space_map(sc->sc_iot, macbase, macsize, 0, &sc->sc_ioh)) {
-		device_printf(dev, "cannot map mac registers 0x%x:0x%x\n",
-		    macbase, macsize);
-		return ENOMEM;
-	}
 
-	if (!override_addr(dev, "mii", &miibase, &miisize)) {
-		miibase = npeconfig[sc->sc_npeid].miibase;
-		miisize = npeconfig[sc->sc_npeid].miisize;
-	}
-	if (miibase != macbase) {
-		/*
-		 * PHY is mapped through a different MAC, setup an
-		 * additional mapping for frobbing the PHY registers.
-		 */
-		if (bus_space_map(sc->sc_iot, miibase, miisize, 0, &sc->sc_miih)) {
-			device_printf(dev,
-			    "cannot map MII registers 0x%x:0x%x\n",
-			    miibase, miisize);
-			return ENOMEM;
-		}
-	} else
-		sc->sc_miih = sc->sc_ioh;
 	error = npe_dma_setup(sc, &sc->txdma, "tx", npe_txbuf, NPE_MAXSEG);
 	if (error != 0)
 		return error;
@@ -809,8 +792,6 @@
 	}
 	sc->sc_stats_phys = sc->buf_phys;
 
-	/* XXX disable half-bridge LEARNING+FILTERING feature */
-
 	/*
 	 * Setup h/w rx/tx queues.  There are four q's:
 	 *   rx		inbound q of rx'd frames
@@ -840,7 +821,7 @@
 	for (i = 0; i < 8; i++)
 		npe_setrxqosentry(sc, i, 0, sc->rx_qid);
 
-	/* disable firewall mode just in case (should be off by default) */
+	/* disable firewall mode just in case (should be off) */
 	npe_setfirewallmode(sc, 0);
 
 	sc->tx_qid = npeconfig[sc->sc_npeid].tx_qid;
@@ -852,13 +833,6 @@
 		tx_doneqid = sc->tx_doneqid;
 	}
 
-	/*
-	 * Setup phy port number.  We allow override via hints
-	 * to handle different board configs.
-	 */
-	if (!override_unit(dev, "phy", &sc->sc_phy, 0, MII_NPHY-1))
-		sc->sc_phy = npeconfig[sc->sc_npeid].phy;
-
 	KASSERT(npes[sc->sc_npeid] == NULL,
 	    ("npe %u already setup", sc->sc_npeid));
 	npes[sc->sc_npeid] = sc;
@@ -874,8 +848,10 @@
 	npes[sc->sc_npeid] = NULL;
 
 	/* XXX disable q's */
-	if (sc->sc_npe != NULL)
+	if (sc->sc_npe != NULL) {
 		ixpnpe_stop(sc->sc_npe);
+		ixpnpe_detach(sc->sc_npe);
+	}
 	if (sc->sc_stats != NULL) {
 		bus_dmamap_unload(sc->sc_stats_tag, sc->sc_stats_map);
 		bus_dmamem_free(sc->sc_stats_tag, sc->sc_stats,
@@ -1256,10 +1232,7 @@
 	/*
 	 * Reset MAC core.
 	 */
-	WR4(sc, NPE_MAC_CORE_CNTRL, NPE_CORE_RESET);
-	DELAY(NPE_MAC_RESET_DELAY);
-	/* configure MAC to generate MDC clock */
-	WR4(sc, NPE_MAC_CORE_CNTRL, NPE_CORE_MDC_EN);
+	npe_mac_reset(sc);
 
 	/* disable transmitter and reciver in the MAC */
  	WR4(sc, NPE_MAC_RX_CNTRL1,
@@ -1672,10 +1645,13 @@
 /*
  * MII bus support routines.
  */
+#define	MII_RD4(sc, reg)	bus_space_read_4(sc->sc_iot, sc->sc_miih, reg)
+#define	MII_WR4(sc, reg, v) \
+	bus_space_write_4(sc->sc_iot, sc->sc_miih, reg, v)
+
 static uint32_t
 npe_mii_mdio_read(struct npe_softc *sc, int reg)
 {
-#define	MII_RD4(sc, reg)	bus_space_read_4(sc->sc_iot, sc->sc_miih, reg)
 	uint32_t v;
 
 	/* NB: registers are known to be sequential */
@@ -1684,37 +1660,34 @@
 	v |= (MII_RD4(sc, reg+8) & 0xff) << 16;
 	v |= (MII_RD4(sc, reg+12) & 0xff) << 24;
 	return v;
-#undef MII_RD4
 }
 
 static void
 npe_mii_mdio_write(struct npe_softc *sc, int reg, uint32_t cmd)
 {
-#define	MII_WR4(sc, reg, v) \
-	bus_space_write_4(sc->sc_iot, sc->sc_miih, reg, v)
-
 	/* NB: registers are known to be sequential */
 	MII_WR4(sc, reg+0, cmd & 0xff);
 	MII_WR4(sc, reg+4, (cmd >> 8) & 0xff);
 	MII_WR4(sc, reg+8, (cmd >> 16) & 0xff);
 	MII_WR4(sc, reg+12, (cmd >> 24) & 0xff);
-#undef MII_WR4
 }
 
 static int
 npe_mii_mdio_wait(struct npe_softc *sc)
 {
-#define	MAXTRIES	100	/* XXX */
 	uint32_t v;
 	int i;
 
-	for (i = 0; i < MAXTRIES; i++) {
+	/* NB: typically this takes 25-30 trips */
+	for (i = 0; i < 1000; i++) {
 		v = npe_mii_mdio_read(sc, NPE_MAC_MDIO_CMD);
 		if ((v & NPE_MII_GO) == 0)
 			return 1;
+		DELAY(1);
 	}
+	device_printf(sc->sc_dev, "%s: timeout after ~1ms, cmd 0x%x\n",
+	    __func__, v);
 	return 0;		/* NB: timeout */
-#undef MAXTRIES
 }
 
 static int
@@ -1725,15 +1698,13 @@
 
 	if (phy != sc->sc_phy)		/* XXX no auto-detect */
 		return 0xffff;
-	v = (phy << NPE_MII_ADDR_SHL) | (reg << NPE_MII_REG_SHL)
-	  | NPE_MII_GO;
+	v = (phy << NPE_MII_ADDR_SHL) | (reg << NPE_MII_REG_SHL) | NPE_MII_GO;
 	npe_mii_mdio_write(sc, NPE_MAC_MDIO_CMD, v);
 	if (npe_mii_mdio_wait(sc))
 		v = npe_mii_mdio_read(sc, NPE_MAC_MDIO_STS);
 	else
 		v = 0xffff | NPE_MII_READ_FAIL;
 	return (v & NPE_MII_READ_FAIL) ? 0xffff : (v & 0xffff);
-#undef MAXTRIES
 }
 
 static void
@@ -1742,7 +1713,7 @@
 	struct npe_softc *sc = device_get_softc(dev);
 	uint32_t v;
 
-	if (phy != sc->sc_phy)		/* XXX should not happen */
+	if (phy != sc->sc_phy)		/* XXX */
 		return;
 	v = (phy << NPE_MII_ADDR_SHL) | (reg << NPE_MII_REG_SHL)
 	  | data | NPE_MII_WRITE



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812101744.mBAHieHx083517>