PERFORCE change 109395 for review
Sam Leffler
sam at FreeBSD.org
Mon Nov 6 22:39:53 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=109395
Change 109395 by sam at 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 \
More information about the p4-projects
mailing list