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>