From owner-svn-src-all@FreeBSD.ORG Wed Dec 7 21:46:09 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7E764106564A; Wed, 7 Dec 2011 21:46:09 +0000 (UTC) (envelope-from yongari@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 6C44E8FC12; Wed, 7 Dec 2011 21:46:09 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id pB7Lk9bD057130; Wed, 7 Dec 2011 21:46:09 GMT (envelope-from yongari@svn.freebsd.org) Received: (from yongari@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id pB7Lk9L8057126; Wed, 7 Dec 2011 21:46:09 GMT (envelope-from yongari@svn.freebsd.org) Message-Id: <201112072146.pB7Lk9L8057126@svn.freebsd.org> From: Pyun YongHyeon Date: Wed, 7 Dec 2011 21:46:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r228332 - head/sys/dev/et X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 07 Dec 2011 21:46:09 -0000 Author: yongari Date: Wed Dec 7 21:46:09 2011 New Revision: 228332 URL: http://svn.freebsd.org/changeset/base/228332 Log: Implement hardware MAC statistics counter. Counters could be queried with dev.et.%d.stats sysctl node where %d is an instance of device. Modified: head/sys/dev/et/if_et.c head/sys/dev/et/if_etreg.h head/sys/dev/et/if_etvar.h Modified: head/sys/dev/et/if_et.c ============================================================================== --- head/sys/dev/et/if_et.c Wed Dec 7 21:29:51 2011 (r228331) +++ head/sys/dev/et/if_et.c Wed Dec 7 21:46:09 2011 (r228332) @@ -146,6 +146,7 @@ static int et_bus_config(struct et_softc static void et_get_eaddr(device_t, uint8_t[]); static void et_setmulti(struct et_softc *); static void et_tick(void *); +static void et_stats_update(struct et_softc *); static const struct et_dev { uint16_t vid; @@ -635,6 +636,7 @@ et_stop(struct et_softc *sc) et_stop_rxdma(sc); et_stop_txdma(sc); + et_stats_update(sc); et_free_tx_ring(sc); et_free_rx_ring(sc); @@ -2049,7 +2051,6 @@ et_rxeof(struct et_softc *sc) m = rbd->rbd_buf[buf_idx].rb_mbuf; if ((rxst_info1 & ET_RXST_INFO1_OK) == 0){ /* Discard errored frame. */ - ifp->if_ierrors++; rbd->rbd_discard(rbd, buf_idx); } else if (rbd->rbd_newbuf(rbd, buf_idx) != 0) { /* No available mbufs, discard it. */ @@ -2063,7 +2064,6 @@ et_rxeof(struct et_softc *sc) } else { m->m_pkthdr.len = m->m_len = buflen; m->m_pkthdr.rcvif = ifp; - ifp->if_ipackets++; ET_UNLOCK(sc); ifp->if_input(ifp, m); ET_LOCK(sc); @@ -2229,7 +2229,6 @@ et_txeof(struct et_softc *sc) bus_dmamap_unload(sc->sc_tx_tag, tb->tb_dmap); m_freem(tb->tb_mbuf); tb->tb_mbuf = NULL; - ifp->if_opackets++; } if (++tbd->tbd_start_index == ET_TX_NDESC) { @@ -2259,6 +2258,7 @@ et_tick(void *xsc) mii = device_get_softc(sc->sc_miibus); mii_tick(mii); + et_stats_update(sc); if (et_watchdog(sc) == EJUSTRETURN) return; callout_reset(&sc->sc_tick, hz, et_tick, sc); @@ -2371,6 +2371,11 @@ et_newbuf_hdr(struct et_rxbuf_data *rbd, return (0); } +#define ET_SYSCTL_STAT_ADD32(c, h, n, p, d) \ + SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d) +#define ET_SYSCTL_STAT_ADD64(c, h, n, p, d) \ + SYSCTL_ADD_UQUAD(c, h, OID_AUTO, n, CTLFLAG_RD, p, d) + /* * Create sysctl tree */ @@ -2378,7 +2383,9 @@ static void et_add_sysctls(struct et_softc * sc) { struct sysctl_ctx_list *ctx; - struct sysctl_oid_list *children; + struct sysctl_oid_list *children, *parent; + struct sysctl_oid *tree; + struct et_hw_stats *stats; ctx = device_get_sysctl_ctx(sc->dev); children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)); @@ -2394,8 +2401,116 @@ et_add_sysctls(struct et_softc * sc) "TX IM, # segments per TX interrupt"); SYSCTL_ADD_UINT(ctx, children, OID_AUTO, "timer", CTLFLAG_RW, &sc->sc_timer, 0, "TX timer"); + + tree = SYSCTL_ADD_NODE(ctx, children, OID_AUTO, "stats", CTLFLAG_RD, + NULL, "ET statistics"); + parent = SYSCTL_CHILDREN(tree); + + /* TX/RX statistics. */ + stats = &sc->sc_stats; + ET_SYSCTL_STAT_ADD64(ctx, parent, "frames_64", &stats->pkts_64, + "0 to 64 bytes frames"); + ET_SYSCTL_STAT_ADD64(ctx, parent, "frames_65_127", &stats->pkts_65, + "65 to 127 bytes frames"); + ET_SYSCTL_STAT_ADD64(ctx, parent, "frames_128_255", &stats->pkts_128, + "128 to 255 bytes frames"); + ET_SYSCTL_STAT_ADD64(ctx, parent, "frames_256_511", &stats->pkts_256, + "256 to 511 bytes frames"); + ET_SYSCTL_STAT_ADD64(ctx, parent, "frames_512_1023", &stats->pkts_512, + "512 to 1023 bytes frames"); + ET_SYSCTL_STAT_ADD64(ctx, parent, "frames_1024_1518", &stats->pkts_1024, + "1024 to 1518 bytes frames"); + ET_SYSCTL_STAT_ADD64(ctx, parent, "frames_1519_1522", &stats->pkts_1519, + "1519 to 1522 bytes frames"); + + /* RX statistics. */ + tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "rx", CTLFLAG_RD, + NULL, "RX MAC statistics"); + children = SYSCTL_CHILDREN(tree); + ET_SYSCTL_STAT_ADD64(ctx, children, "bytes", + &stats->rx_bytes, "Good bytes"); + ET_SYSCTL_STAT_ADD64(ctx, children, "frames", + &stats->rx_frames, "Good frames"); + ET_SYSCTL_STAT_ADD32(ctx, children, "crc_errs", + &stats->rx_crcerrs, "CRC errors"); + ET_SYSCTL_STAT_ADD64(ctx, children, "mcast_frames", + &stats->rx_mcast, "Multicast frames"); + ET_SYSCTL_STAT_ADD64(ctx, children, "bcast_frames", + &stats->rx_bcast, "Broadcast frames"); + ET_SYSCTL_STAT_ADD32(ctx, children, "control", + &stats->rx_control, "Control frames"); + ET_SYSCTL_STAT_ADD32(ctx, children, "pause", + &stats->rx_pause, "Pause frames"); + ET_SYSCTL_STAT_ADD32(ctx, children, "unknown_control", + &stats->rx_unknown_control, "Unknown control frames"); + ET_SYSCTL_STAT_ADD32(ctx, children, "align_errs", + &stats->rx_alignerrs, "Alignment errors"); + ET_SYSCTL_STAT_ADD32(ctx, children, "len_errs", + &stats->rx_lenerrs, "Frames with length mismatched"); + ET_SYSCTL_STAT_ADD32(ctx, children, "code_errs", + &stats->rx_codeerrs, "Frames with code error"); + ET_SYSCTL_STAT_ADD32(ctx, children, "cs_errs", + &stats->rx_cserrs, "Frames with carrier sense error"); + ET_SYSCTL_STAT_ADD32(ctx, children, "runts", + &stats->rx_runts, "Too short frames"); + ET_SYSCTL_STAT_ADD64(ctx, children, "oversize", + &stats->rx_oversize, "Oversized frames"); + ET_SYSCTL_STAT_ADD32(ctx, children, "fragments", + &stats->rx_fragments, "Fragmented frames"); + ET_SYSCTL_STAT_ADD32(ctx, children, "jabbers", + &stats->rx_jabbers, "Frames with jabber error"); + ET_SYSCTL_STAT_ADD32(ctx, children, "drop", + &stats->rx_drop, "Dropped frames"); + + /* TX statistics. */ + tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "tx", CTLFLAG_RD, + NULL, "TX MAC statistics"); + children = SYSCTL_CHILDREN(tree); + ET_SYSCTL_STAT_ADD64(ctx, children, "bytes", + &stats->tx_bytes, "Good bytes"); + ET_SYSCTL_STAT_ADD64(ctx, children, "frames", + &stats->tx_frames, "Good frames"); + ET_SYSCTL_STAT_ADD64(ctx, children, "mcast_frames", + &stats->tx_mcast, "Multicast frames"); + ET_SYSCTL_STAT_ADD64(ctx, children, "bcast_frames", + &stats->tx_bcast, "Broadcast frames"); + ET_SYSCTL_STAT_ADD32(ctx, children, "pause", + &stats->tx_pause, "Pause frames"); + ET_SYSCTL_STAT_ADD32(ctx, children, "deferred", + &stats->tx_deferred, "Deferred frames"); + ET_SYSCTL_STAT_ADD32(ctx, children, "excess_deferred", + &stats->tx_excess_deferred, "Excessively deferred frames"); + ET_SYSCTL_STAT_ADD32(ctx, children, "single_colls", + &stats->tx_single_colls, "Single collisions"); + ET_SYSCTL_STAT_ADD32(ctx, children, "multi_colls", + &stats->tx_multi_colls, "Multiple collisions"); + ET_SYSCTL_STAT_ADD32(ctx, children, "late_colls", + &stats->tx_late_colls, "Late collisions"); + ET_SYSCTL_STAT_ADD32(ctx, children, "excess_colls", + &stats->tx_excess_colls, "Excess collisions"); + ET_SYSCTL_STAT_ADD32(ctx, children, "total_colls", + &stats->tx_total_colls, "Total collisions"); + ET_SYSCTL_STAT_ADD32(ctx, children, "pause_honored", + &stats->tx_pause_honored, "Honored pause frames"); + ET_SYSCTL_STAT_ADD32(ctx, children, "drop", + &stats->tx_drop, "Dropped frames"); + ET_SYSCTL_STAT_ADD32(ctx, children, "jabbers", + &stats->tx_jabbers, "Frames with jabber errors"); + ET_SYSCTL_STAT_ADD32(ctx, children, "crc_errs", + &stats->tx_crcerrs, "Frames with CRC errors"); + ET_SYSCTL_STAT_ADD32(ctx, children, "control", + &stats->tx_control, "Control frames"); + ET_SYSCTL_STAT_ADD64(ctx, children, "oversize", + &stats->tx_oversize, "Oversized frames"); + ET_SYSCTL_STAT_ADD32(ctx, children, "undersize", + &stats->tx_undersize, "Undersized frames"); + ET_SYSCTL_STAT_ADD32(ctx, children, "fragments", + &stats->tx_fragments, "Fragmented frames"); } +#undef ET_SYSCTL_STAT_ADD32 +#undef ET_SYSCTL_STAT_ADD64 + static int et_sysctl_rx_intr_npkts(SYSCTL_HANDLER_ARGS) { @@ -2446,6 +2561,73 @@ back: return (error); } +static void +et_stats_update(struct et_softc *sc) +{ + struct ifnet *ifp; + struct et_hw_stats *stats; + + stats = &sc->sc_stats; + stats->pkts_64 += CSR_READ_4(sc, ET_STAT_PKTS_64); + stats->pkts_65 += CSR_READ_4(sc, ET_STAT_PKTS_65_127); + stats->pkts_128 += CSR_READ_4(sc, ET_STAT_PKTS_128_255); + stats->pkts_256 += CSR_READ_4(sc, ET_STAT_PKTS_256_511); + stats->pkts_512 += CSR_READ_4(sc, ET_STAT_PKTS_512_1023); + stats->pkts_1024 += CSR_READ_4(sc, ET_STAT_PKTS_1024_1518); + stats->pkts_1519 += CSR_READ_4(sc, ET_STAT_PKTS_1519_1522); + + stats->rx_bytes += CSR_READ_4(sc, ET_STAT_RX_BYTES); + stats->rx_frames += CSR_READ_4(sc, ET_STAT_RX_FRAMES); + stats->rx_crcerrs += CSR_READ_4(sc, ET_STAT_RX_CRC_ERR); + stats->rx_mcast += CSR_READ_4(sc, ET_STAT_RX_MCAST); + stats->rx_bcast += CSR_READ_4(sc, ET_STAT_RX_BCAST); + stats->rx_control += CSR_READ_4(sc, ET_STAT_RX_CTL); + stats->rx_pause += CSR_READ_4(sc, ET_STAT_RX_PAUSE); + stats->rx_unknown_control += CSR_READ_4(sc, ET_STAT_RX_UNKNOWN_CTL); + stats->rx_alignerrs += CSR_READ_4(sc, ET_STAT_RX_ALIGN_ERR); + stats->rx_lenerrs += CSR_READ_4(sc, ET_STAT_RX_LEN_ERR); + stats->rx_codeerrs += CSR_READ_4(sc, ET_STAT_RX_CODE_ERR); + stats->rx_cserrs += CSR_READ_4(sc, ET_STAT_RX_CS_ERR); + stats->rx_runts += CSR_READ_4(sc, ET_STAT_RX_RUNT); + stats->rx_oversize += CSR_READ_4(sc, ET_STAT_RX_OVERSIZE); + stats->rx_fragments += CSR_READ_4(sc, ET_STAT_RX_FRAG); + stats->rx_jabbers += CSR_READ_4(sc, ET_STAT_RX_JABBER); + stats->rx_drop += CSR_READ_4(sc, ET_STAT_RX_DROP); + + stats->tx_bytes += CSR_READ_4(sc, ET_STAT_TX_BYTES); + stats->tx_frames += CSR_READ_4(sc, ET_STAT_TX_FRAMES); + stats->tx_mcast += CSR_READ_4(sc, ET_STAT_TX_MCAST); + stats->tx_bcast += CSR_READ_4(sc, ET_STAT_TX_BCAST); + stats->tx_pause += CSR_READ_4(sc, ET_STAT_TX_PAUSE); + stats->tx_deferred += CSR_READ_4(sc, ET_STAT_TX_DEFER); + stats->tx_excess_deferred += CSR_READ_4(sc, ET_STAT_TX_EXCESS_DEFER); + stats->tx_single_colls += CSR_READ_4(sc, ET_STAT_TX_SINGLE_COL); + stats->tx_multi_colls += CSR_READ_4(sc, ET_STAT_TX_MULTI_COL); + stats->tx_late_colls += CSR_READ_4(sc, ET_STAT_TX_LATE_COL); + stats->tx_excess_colls += CSR_READ_4(sc, ET_STAT_TX_EXCESS_COL); + stats->tx_total_colls += CSR_READ_4(sc, ET_STAT_TX_TOTAL_COL); + stats->tx_pause_honored += CSR_READ_4(sc, ET_STAT_TX_PAUSE_HONOR); + stats->tx_drop += CSR_READ_4(sc, ET_STAT_TX_DROP); + stats->tx_jabbers += CSR_READ_4(sc, ET_STAT_TX_JABBER); + stats->tx_crcerrs += CSR_READ_4(sc, ET_STAT_TX_CRC_ERR); + stats->tx_control += CSR_READ_4(sc, ET_STAT_TX_CTL); + stats->tx_oversize += CSR_READ_4(sc, ET_STAT_TX_OVERSIZE); + stats->tx_undersize += CSR_READ_4(sc, ET_STAT_TX_UNDERSIZE); + stats->tx_fragments += CSR_READ_4(sc, ET_STAT_TX_FRAG); + + /* Update ifnet counters. */ + ifp = sc->ifp; + ifp->if_opackets = (u_long)stats->tx_frames; + ifp->if_collisions = stats->tx_total_colls; + ifp->if_oerrors = stats->tx_drop + stats->tx_jabbers + + stats->tx_crcerrs + stats->tx_excess_deferred + + stats->tx_late_colls; + ifp->if_ipackets = (u_long)stats->rx_frames; + ifp->if_ierrors = stats->rx_crcerrs + stats->rx_alignerrs + + stats->rx_lenerrs + stats->rx_codeerrs + stats->rx_cserrs + + stats->rx_runts + stats->rx_jabbers + stats->rx_drop; +} + static int et_suspend(device_t dev) { Modified: head/sys/dev/et/if_etreg.h ============================================================================== --- head/sys/dev/et/if_etreg.h Wed Dec 7 21:29:51 2011 (r228331) +++ head/sys/dev/et/if_etreg.h Wed Dec 7 21:46:09 2011 (r228332) @@ -318,6 +318,52 @@ #define ET_MAC_ADDR1 0x5040 #define ET_MAC_ADDR2 0x5044 +/* MAC statistics counters. */ +#define ET_STAT_PKTS_64 0x6080 +#define ET_STAT_PKTS_65_127 0x6084 +#define ET_STAT_PKTS_128_255 0x6088 +#define ET_STAT_PKTS_256_511 0x608C +#define ET_STAT_PKTS_512_1023 0x6090 +#define ET_STAT_PKTS_1024_1518 0x6094 +#define ET_STAT_PKTS_1519_1522 0x6098 +#define ET_STAT_RX_BYTES 0x609C +#define ET_STAT_RX_FRAMES 0x60A0 +#define ET_STAT_RX_CRC_ERR 0x60A4 +#define ET_STAT_RX_MCAST 0x60A8 +#define ET_STAT_RX_BCAST 0x60AC +#define ET_STAT_RX_CTL 0x60B0 +#define ET_STAT_RX_PAUSE 0x60B4 +#define ET_STAT_RX_UNKNOWN_CTL 0x60B8 +#define ET_STAT_RX_ALIGN_ERR 0x60BC +#define ET_STAT_RX_LEN_ERR 0x60C0 +#define ET_STAT_RX_CODE_ERR 0x60C4 +#define ET_STAT_RX_CS_ERR 0x60C8 +#define ET_STAT_RX_RUNT 0x60CC +#define ET_STAT_RX_OVERSIZE 0x60D0 +#define ET_STAT_RX_FRAG 0x60D4 +#define ET_STAT_RX_JABBER 0x60D8 +#define ET_STAT_RX_DROP 0x60DC +#define ET_STAT_TX_BYTES 0x60E0 +#define ET_STAT_TX_FRAMES 0x60E4 +#define ET_STAT_TX_MCAST 0x60E8 +#define ET_STAT_TX_BCAST 0x60EC +#define ET_STAT_TX_PAUSE 0x60F0 +#define ET_STAT_TX_DEFER 0x60F4 +#define ET_STAT_TX_EXCESS_DEFER 0x60F8 +#define ET_STAT_TX_SINGLE_COL 0x60FC +#define ET_STAT_TX_MULTI_COL 0x6100 +#define ET_STAT_TX_LATE_COL 0x6104 +#define ET_STAT_TX_EXCESS_COL 0x6108 +#define ET_STAT_TX_TOTAL_COL 0x610C +#define ET_STAT_TX_PAUSE_HONOR 0x6110 +#define ET_STAT_TX_DROP 0x6114 +#define ET_STAT_TX_JABBER 0x6118 +#define ET_STAT_TX_CRC_ERR 0x611C +#define ET_STAT_TX_CTL 0x6120 +#define ET_STAT_TX_OVERSIZE 0x6124 +#define ET_STAT_TX_UNDERSIZE 0x6128 +#define ET_STAT_TX_FRAG 0x612C + #define ET_MMC_CTRL 0x7000 #define ET_MMC_CTRL_ENABLE 0x00000001 #define ET_MMC_CTRL_ARB_DISABLE 0x00000002 Modified: head/sys/dev/et/if_etvar.h ============================================================================== --- head/sys/dev/et/if_etvar.h Wed Dec 7 21:29:51 2011 (r228331) +++ head/sys/dev/et/if_etvar.h Wed Dec 7 21:46:09 2011 (r228332) @@ -231,6 +231,56 @@ struct et_rxbuf_data { void (*rbd_discard)(struct et_rxbuf_data *, int); }; +struct et_hw_stats { + /* RX/TX stats. */ + uint64_t pkts_64; + uint64_t pkts_65; + uint64_t pkts_128; + uint64_t pkts_256; + uint64_t pkts_512; + uint64_t pkts_1024; + uint64_t pkts_1519; + /* RX stats. */ + uint64_t rx_bytes; + uint64_t rx_frames; + uint32_t rx_crcerrs; + uint64_t rx_mcast; + uint64_t rx_bcast; + uint32_t rx_control; + uint32_t rx_pause; + uint32_t rx_unknown_control; + uint32_t rx_alignerrs; + uint32_t rx_lenerrs; + uint32_t rx_codeerrs; + uint32_t rx_cserrs; + uint32_t rx_runts; + uint64_t rx_oversize; + uint32_t rx_fragments; + uint32_t rx_jabbers; + uint32_t rx_drop; + /* TX stats. */ + uint64_t tx_bytes; + uint64_t tx_frames; + uint64_t tx_mcast; + uint64_t tx_bcast; + uint32_t tx_pause; + uint32_t tx_deferred; + uint32_t tx_excess_deferred; + uint32_t tx_single_colls; + uint32_t tx_multi_colls; + uint32_t tx_late_colls; + uint32_t tx_excess_colls; + uint32_t tx_total_colls; + uint32_t tx_pause_honored; + uint32_t tx_drop; + uint32_t tx_jabbers; + uint32_t tx_crcerrs; + uint32_t tx_control; + uint64_t tx_oversize; + uint32_t tx_undersize; + uint32_t tx_fragments; +}; + struct et_softc { struct ifnet *ifp; device_t dev; @@ -271,6 +321,7 @@ struct et_softc { struct et_rxbuf_data sc_rx_data[ET_RX_NRING]; struct et_txbuf_data sc_tx_data; + struct et_hw_stats sc_stats; uint32_t sc_tx; uint32_t sc_tx_intr;