Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 6 Nov 2006 22:39:48 GMT
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 109395 for review
Message-ID:  <200611062239.kA6Mdmg1028695@repoman.freebsd.org>

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

Change 109395 by sam@sam_ebb on 2006/11/06 22:39:06

	minor cleanups:
	o fetch npe stats every second and update mib and ifnet stats
	o eliminate #defines for static q assignments; they did nothing
	  but obscure what was going on
	o add some npe msg wrappers that will eventually get used but
	  are dead code right now

Affected files ...

.. //depot/projects/arm/src/sys/arm/xscale/ixp425/if_npe.c#4 edit
.. //depot/projects/arm/src/sys/arm/xscale/ixp425/if_npereg.h#2 edit

Differences ...

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

@@ -92,6 +92,7 @@
 	bus_space_handle_t sc_miih;	/* MII register window */
 	struct ixpnpe_softc *sc_npe;	/* NPE support */
 	int		sc_portid;
+	int		debug;
 	struct callout	tick_ch;	/* Tick callout */
 	struct npedma	txdma;
 	struct npebuf	*tx_free;	/* list of free tx buffers */
@@ -101,8 +102,11 @@
 	int		rx_freeqid;	/* rx free buffers qid */
 	int		tx_qid;		/* tx qid */
 	int		tx_doneqid;	/* tx completed qid */
-	struct ifmib_iso_8802_3 mibdata;/* stuff for network mgmt */
-	int		debug;
+	struct ifmib_iso_8802_3 mibdata;
+	bus_dma_tag_t	sc_stats_tag;	/* bus dma tag for stats block */
+	struct npestats	*sc_stats;
+	bus_dmamap_t	sc_stats_map;
+	bus_addr_t	sc_stats_phys;	/* phys addr of sc_stats */
 };
 
 /*
@@ -128,10 +132,10 @@
 	  .regsize	= IXP425_MAC_A_SIZE,
 	  .miibase	= IXP425_MAC_A_HWBASE,
 	  .miisize	= IXP425_MAC_A_SIZE,
-	  .rx_qid	= NPE_B_RX_Q,
-	  .rx_freeqid	= NPE_B_RX_FREEQ,
-	  .tx_qid	= NPE_B_TX_Q,
-	  .tx_doneqid	= NPE_B_TX_DONEQ
+	  .rx_qid	= 4,
+	  .rx_freeqid	= 27,
+	  .tx_qid	= 24,
+	  .tx_doneqid	= 31
 	},
 	{ .desc		= "IXP NPE-C",
 	  .portid	= 1,
@@ -140,10 +144,10 @@
 	  .regsize	= IXP425_MAC_B_SIZE,
 	  .miibase	= IXP425_MAC_A_HWBASE,
 	  .miisize	= IXP425_MAC_A_SIZE,
-	  .rx_qid	= NPE_C_RX_Q,
-	  .rx_freeqid	= NPE_C_RX_FREEQ,
-	  .tx_qid	= NPE_C_TX_Q,
-	  .tx_doneqid	= NPE_C_TX_DONEQ
+	  .rx_qid	= 4,
+	  .rx_freeqid	= 28,
+	  .tx_qid	= 25,
+	  .tx_doneqid	= 31
 	},
 };
 
@@ -187,8 +191,18 @@
 static void	npewatchdog(struct ifnet *);
 static int	npeioctl(struct ifnet * ifp, u_long, caddr_t);
 
-static	int tx_doneqid = -1;
-static	int rx_qid = -1;
+static int	npe_setrxqosentry(struct npe_softc *, int classix,
+			int trafclass, int qid);
+static int	npe_updatestats(struct npe_softc *);
+#if 0
+static int	npe_getstats(struct npe_softc *);
+static uint32_t	npe_getimageid(struct npe_softc *);
+static int	npe_setloopback(struct npe_softc *, int ena);
+#endif
+
+/* NB: all tx+rx traffic goes through one queue */
+static int tx_doneqid = -1;
+static int rx_qid = -1;
 
 static int npe_debug = 0;
 SYSCTL_INT(_debug, OID_AUTO, npe, CTLFLAG_RW, &npe_debug,
@@ -267,7 +281,7 @@
 	ifp->if_timer = 0;
 	ifp->if_linkmib = &sc->mibdata;
 	ifp->if_linkmiblen = sizeof(sc->mibdata);
-	sc->mibdata.dot3Compliance = DOT3COMPLIANCE_COLLS;
+	sc->mibdata.dot3Compliance = DOT3COMPLIANCE_STATS;
 
 	ether_ifattach(ifp, eaddr);
 	return 0;
@@ -455,27 +469,12 @@
 	memset(dma, 0, sizeof(dma));
 }
 
-static void
-npe_setrxqosentry(struct npe_softc *sc, int classix, int trafclass, int qid)
-{
-	uint32_t msg[2];
-
-	msg[0] = (NPE_SETRXQOSENTRY << 24) | (sc->sc_portid << 16) | classix;
-	msg[1] = (trafclass << 24) | (1 << 23) | (qid << 16) | (qid << 4);
-	if (ixpnpe_sendmsg(sc->sc_npe, msg) != 0)
-		device_printf(sc->sc_dev, "send setrxqosentry\n");
-	else if (ixpnpe_recvmsg(sc->sc_npe, msg) != 0)
-		device_printf(sc->sc_dev, "recv setrxqosentry\n");
-	else
-		DPRINTF(sc, "%s: 0x%x 0x%x\n", __func__, msg[0], msg[1]);
-}
-
 static int
 npe_activate(device_t dev)
 {
 	struct npe_softc * sc = device_get_softc(dev);
 	int unit = device_get_unit(dev);
-	int error;
+	int error, i;
 
 	/* load NPE firmware and start it running */
 	error = ixpnpe_init(sc->sc_npe, "npe_fw", npeconfig[unit].imageid);
@@ -483,19 +482,6 @@
 		return error;
 
 	sc->sc_portid = npeconfig[unit].portid;
-#if 0
-/* ask for firmware rev (really imageid) to check if npe is running properly */
-{ uint32_t msg[2];
-  msg[0] = NPE_GETSTATUS<<NPE_MAC_MSGID_SHL;
-  msg[1] = 0;
-  if (ixpnpe_sendmsg(sc->sc_npe, msg) != 0)
-      device_printf(dev, "error sending status msg\n");
-  else if (ixpnpe_recvmsg(sc->sc_npe, msg) != 0)
-      device_printf(dev, "error recving status msg\n");
-  else
-      device_printf(dev, "status: 0x%x 0x%x\n", msg[0], msg[1]);
-}
-#endif
 	if (bus_space_map(sc->sc_iot, npeconfig[unit].regbase,
 	    npeconfig[unit].regsize, 0, &sc->sc_ioh)) {
 		device_printf(dev, "Cannot map registers 0x%x:0x%x\n",
@@ -525,6 +511,32 @@
 	if (error != 0)
 		return error;
 
+	/* setup statistics block */
+	error = bus_dma_tag_create(NULL, 4, 0, BUS_SPACE_MAXADDR_32BIT,
+	    BUS_SPACE_MAXADDR, NULL, NULL, sizeof(struct npestats), 1,
+	    sizeof(struct npestats), 0,
+	    busdma_lock_mutex, &sc->sc_mtx, &sc->sc_stats_tag);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "unable to create stats tag, "
+		     "error %u\n", error);
+		return error;
+	}
+	if (bus_dmamem_alloc(sc->sc_stats_tag, (void **)&sc->sc_stats,
+	    BUS_DMA_NOWAIT, &sc->sc_stats_map) != 0) {
+		device_printf(sc->sc_dev,
+		     "unable to allocate memory for stats block, error %u\n",
+		     error);
+		return error;
+	}
+	if (bus_dmamap_load(sc->sc_stats_tag, sc->sc_stats_map,
+	    sc->sc_stats, sizeof(struct npestats), npe_getaddr, sc, 0) != 0) {
+		device_printf(sc->sc_dev,
+		     "unable to load memory for stats block, error %u\n",
+		     error);
+		return error;
+	}
+	sc->sc_stats_phys = sc->buf_phys;
+
 	/* XXX disable half-bridge LEARNING+FILTERING feature */
 
 	/*
@@ -553,14 +565,8 @@
 	ixpqmgr_qconfig(sc->rx_freeqid,	NPE_MAX_RX_BUFFERS, 0,
 		NPE_MAX_RX_BUFFERS/2, 0, NULL, sc);
 	/* tell the NPE to direct all traffic to rx_qid */
-	npe_setrxqosentry(sc, 0, 0, sc->rx_qid);
-	npe_setrxqosentry(sc, 1, 0, sc->rx_qid);
-	npe_setrxqosentry(sc, 2, 0, sc->rx_qid);
-	npe_setrxqosentry(sc, 3, 0, sc->rx_qid);
-	npe_setrxqosentry(sc, 4, 0, sc->rx_qid);
-	npe_setrxqosentry(sc, 5, 0, sc->rx_qid);
-	npe_setrxqosentry(sc, 6, 0, sc->rx_qid);
-	npe_setrxqosentry(sc, 7, 0, sc->rx_qid);
+	for (i = 0; i < 8; i++)
+		npe_setrxqosentry(sc, i, 0, sc->rx_qid);
 
 	sc->tx_qid = npeconfig[unit].tx_qid;
 	sc->tx_doneqid = npeconfig[unit].tx_doneqid;
@@ -583,6 +589,14 @@
 	/* XXX disable q's */
 	if (sc->sc_npe != NULL)
 		ixpnpe_stop(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,
+			sc->sc_stats_map);
+		bus_dmamap_destroy(sc->sc_stats_tag, sc->sc_stats_map);
+	}
+	if (sc->sc_stats_tag != NULL)
+		bus_dma_tag_destroy(sc->sc_stats_tag);
 	npe_dma_destroy(sc, &sc->txdma);
 	npe_dma_destroy(sc, &sc->rxdma);
 	bus_generic_detach(sc->sc_dev);
@@ -634,45 +648,51 @@
 static void
 npe_tick(void *xsc)
 {
+#define	MIBADD(x)	sc->mibdata.x += be32toh(ns->x)
 	struct npe_softc *sc = xsc;
+	struct ifnet *ifp = sc->sc_ifp;
+	struct npestats *ns = sc->sc_stats;
 
 	NPE_ASSERT_LOCKED(sc);
-#if 0
-	/* XXX intel driver uses the message send mechanism, to get stats... */
-	/*
-	 * Update the stats as best we can.  When we're done, clear
-	 * the status counters and start over.  We're supposed to read these
-	 * registers often enough that they won't overflow.  Hopefully
-	 * once a second is often enough.  Some don't map well to
-	 * the dot3Stats mib, so for those we just count them as general
-	 * errors.  Stats for iframes, ibutes, oframes and obytes are
-	 * collected elsewhere.  These registers zero on a read to prevent
-	 * races.
-	 */
-	sc->mibdata.dot3StatsAlignmentErrors += RD4(sc, ETH_ALE);
-	sc->mibdata.dot3StatsFCSErrors += RD4(sc, ETH_SEQE);
-	sc->mibdata.dot3StatsSingleCollisionFrames += RD4(sc, ETH_SCOL);
-	sc->mibdata.dot3StatsMultipleCollisionFrames += RD4(sc, ETH_MCOL);
-	sc->mibdata.dot3StatsSQETestErrors += RD4(sc, ETH_SQEE);
-	sc->mibdata.dot3StatsDeferredTransmissions += RD4(sc, ETH_DTE);
-	sc->mibdata.dot3StatsLateCollisions += RD4(sc, ETH_LCOL);
-	sc->mibdata.dot3StatsExcessiveCollisions += RD4(sc, ETH_ECOL);
-	sc->mibdata.dot3StatsCarrierSenseErrors += RD4(sc, ETH_CSE);
-	sc->mibdata.dot3StatsFrameTooLongs += RD4(sc, ETH_ELR);
-	sc->mibdata.dot3StatsInternalMacReceiveErrors += RD4(sc, ETH_DRFC);
-	/*
-	 * not sure where to lump these, so count them against the errors
-	 * for the interface.
-	 */
-	sc->sc_ifp->if_oerrors += RD4(sc, ETH_CSE) + RD4(sc, ETH_TUE);
-	sc->sc_ifp->if_ierrors += RD4(sc, ETH_CDE) + RD4(sc, ETH_RJB) +
-	    RD4(sc, ETH_USF);
-#endif
+	npe_updatestats(sc);		/* update + clear stats */
+	bus_dmamap_sync(sc->sc_stats_tag, sc->sc_stats_map,
+		BUS_DMASYNC_POSTREAD);
+
+	MIBADD(dot3StatsAlignmentErrors);
+	MIBADD(dot3StatsFCSErrors);
+	MIBADD(dot3StatsSingleCollisionFrames);
+	MIBADD(dot3StatsMultipleCollisionFrames);
+	/* XXX? */
+	sc->mibdata.dot3StatsSQETestErrors +=
+	    be32toh(ns->dot3StatsCarrierSenseErrors);
+	MIBADD(dot3StatsDeferredTransmissions);
+	MIBADD(dot3StatsLateCollisions);
+	MIBADD(dot3StatsExcessiveCollisions);
+	MIBADD(dot3StatsInternalMacTransmitErrors);
+	MIBADD(dot3StatsCarrierSenseErrors);
+	sc->mibdata.dot3StatsFrameTooLongs +=
+	      be32toh(ns->RxLargeFramesDiscards)
+	    + be32toh(ns->TxLargeFrameDiscards);
+	MIBADD(dot3StatsInternalMacReceiveErrors);
+	sc->mibdata.dot3StatsMissedFrames +=
+	      be32toh(ns->RxOverrunDiscards)
+	    + be32toh(ns->RxUnderflowEntryDiscards);
+
+	ifp->if_oerrors += be32toh(ns->dot3StatsCarrierSenseErrors)
+		+ be32toh(ns->dot3StatsInternalMacTransmitErrors)
+		+ be32toh(ns->TxVLANIdFilterDiscards)
+		;
+	ifp->if_ierrors += be32toh(ns->dot3StatsFCSErrors)
+		+ be32toh(ns->dot3StatsInternalMacReceiveErrors)
+		+ be32toh(ns->RxOverrunDiscards)
+		+ be32toh(ns->RxUnderflowEntryDiscards)
+		;
 
 	/*
 	 * Schedule another timeout one second from now.
 	 */
 	callout_reset(&sc->tick_ch, hz, npe_tick, sc);
+#undef MIBADD
 }
 
 static void
@@ -1188,6 +1208,73 @@
 	return error;
 }
 
+/*
+ * Setup a traffic class -> rx queue mapping.
+ */
+static int
+npe_setrxqosentry(struct npe_softc *sc, int classix, int trafclass, int qid)
+{
+	uint32_t msg[2];
+
+	msg[0] = (NPE_SETRXQOSENTRY << 24) | (sc->sc_portid << 16) | classix;
+	msg[1] = (trafclass << 24) | (1 << 23) | (qid << 16) | (qid << 4);
+	return ixpnpe_sendandrecvmsg(sc->sc_npe, msg, msg);
+}
+
+/*
+ * Update and reset the statistics in the NPE.
+ */
+static int
+npe_updatestats(struct npe_softc *sc)
+{
+	uint32_t msg[2];
+
+	msg[0] = NPE_RESETSTATS << NPE_MAC_MSGID_SHL;
+	msg[1] = sc->sc_stats_phys;	/* physical address of stat block */
+	return ixpnpe_sendandrecvmsg(sc->sc_npe, msg, msg);
+}
+
+#if 0
+/*
+ * Get the current statistics block.
+ */
+static int
+npe_getstats(struct npe_softc *sc)
+{
+	uint32_t msg[2];
+
+	msg[0] = NPE_GETSTATS << NPE_MAC_MSGID_SHL;
+	msg[1] = sc->sc_stats_phys;	/* physical address of stat block */
+	return ixpnpe_sendandrecvmsg(sc->sc_npe, msg, msg);
+}
+
+/*
+ * Query the image id of the loaded firmware.
+ */
+static uint32_t
+npe_getimageid(struct npe_softc *sc)
+{
+	uint32_t msg[2];
+
+	msg[0] = NPE_GETSTATUS << NPE_MAC_MSGID_SHL;
+	msg[1] = 0;
+	return ixpnpe_sendandrecvmsg(sc->sc_npe, msg, msg) == 0 ? msg[1] : 0;
+}
+
+/*
+ * Enable/disable loopback.
+ */
+static int
+npe_setloopback(struct npe_softc *sc, int ena)
+{
+	uint32_t msg[2];
+
+	msg[0] = (NPE_SETLOOPBACK << NPE_MAC_MSGID_SHL) | (ena != 0);
+	msg[1] = 0;
+	return ixpnpe_sendandrecvmsg(sc->sc_npe, msg, msg);
+}
+#endif
+
 static void
 npe_child_detached(device_t dev, device_t child)
 {

==== //depot/projects/arm/src/sys/arm/xscale/ixp425/if_npereg.h#2 (text+ko) ====

@@ -79,25 +79,6 @@
 #define	ix_ne_data	ix_ne[2]	/* phys addr of data buffer */
 };
 
-/* NB: these assume a ucode image that supports 4 ports, no QoS */
-#define	NPE_A_RX_Q	11
-#define	NPE_A_TX_Q	23		/* for submitting tx buffers to NPE-A */
-#define	NPE_A_RX_FREEQ	26		/* for supplying rx buffers to NPE-A */
-#define	NPE_A_TX_DONEQ	31		/* NB: shared */
-
-#define	NPE_B_RX_Q	4
-#define	NPE_B_TX_Q	24		/* for submitting tx buffers to NPE-B */
-#define	NPE_B_RX_FREEQ	27		/* for supplying rx buffers to NPE-B */
-#define	NPE_B_TX_DONEQ	31		/* NB: shared */
-
-#define	NPE_C_RX_Q	4
-#define	NPE_C_TX_Q	25		/* for submitting tx buffers to NPE-C */
-#define	NPE_C_RX_FREEQ	28		/* for supplying rx buffers to NPE-C */
-#define	NPE_C_TX_DONEQ	31		/* NB: shared */
-
-#define NPE_MAX_TX_FRAMES_TO_SUBMIT 128
-
-#define NPE_MAX_MULTICAST_ADDRESSES 256
 #define NPE_PORTS_MAX		3
 #define NPE_FRAME_SIZE_DEFAULT	1536
 #define NPE_FRAME_SIZE_MAX	(65536-64)
@@ -128,6 +109,7 @@
 #define	NPE_SETRXTAGMODE	0x07	/* configure VLAN rx operating mode */
 #define	NPE_SETDEFRXVID		0x08	/* set def VLAN tag + traffic class */
 #define	NPE_SETRXQOSENTRY	0x0b	/* map user pri -> QoS class+rx qid */
+#define	NPE_SETLOOPBACK		0x12	/* enable/disable loopback */
 /* ... XXX more */
 
 /*
@@ -219,6 +201,34 @@
 #define NPE_ETH_MAC_BCAST_MCAST_BIT ( 1) 
 
 /*
+ * Stat block returned by NPE with NPE_GETSTATS msg.
+ */
+struct npestats {
+	uint32_t dot3StatsAlignmentErrors;
+	uint32_t dot3StatsFCSErrors;
+	uint32_t dot3StatsInternalMacReceiveErrors;
+	uint32_t RxOverrunDiscards;
+	uint32_t RxLearnedEntryDiscards;
+	uint32_t RxLargeFramesDiscards;
+	uint32_t RxSTPBlockedDiscards;
+	uint32_t RxVLANTypeFilterDiscards;
+	uint32_t RxVLANIdFilterDiscards;
+	uint32_t RxInvalidSourceDiscards;
+	uint32_t RxBlackListDiscards;
+	uint32_t RxWhiteListDiscards;
+	uint32_t RxUnderflowEntryDiscards;
+	uint32_t dot3StatsSingleCollisionFrames;
+	uint32_t dot3StatsMultipleCollisionFrames;
+	uint32_t dot3StatsDeferredTransmissions;
+	uint32_t dot3StatsLateCollisions;
+	uint32_t dot3StatsExcessiveCollisions;
+	uint32_t dot3StatsInternalMacTransmitErrors;
+	uint32_t dot3StatsCarrierSenseErrors;
+	uint32_t TxLargeFrameDiscards;
+	uint32_t TxVLANIdFilterDiscards;
+};
+
+/*
  * Default values
  */
 #define NPE_TX_CNTRL1_DEFAULT \



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