svn commit: r200910 - head/sys/dev/ste

Pyun YongHyeon yongari at FreeBSD.org
Wed Dec 23 19:18:08 UTC 2009


Author: yongari
Date: Wed Dec 23 19:18:07 2009
New Revision: 200910
URL: http://svn.freebsd.org/changeset/base/200910

Log:
  Implement hardware MAC statistics counter support. The counters
  could be accessed with dev.ste.0.stats sysctl node.

Modified:
  head/sys/dev/ste/if_ste.c
  head/sys/dev/ste/if_stereg.h

Modified: head/sys/dev/ste/if_ste.c
==============================================================================
--- head/sys/dev/ste/if_ste.c	Wed Dec 23 18:53:11 2009	(r200909)
+++ head/sys/dev/ste/if_ste.c	Wed Dec 23 19:18:07 2009	(r200910)
@@ -125,8 +125,10 @@ static int	ste_rxeof(struct ste_softc *,
 static void	ste_rxfilter(struct ste_softc *);
 static void	ste_start(struct ifnet *);
 static void	ste_start_locked(struct ifnet *);
+static void	ste_stats_clear(struct ste_softc *);
 static void	ste_stats_update(struct ste_softc *);
 static void	ste_stop(struct ste_softc *);
+static void	ste_sysctl_node(struct ste_softc *);
 static void	ste_tick(void *);
 static void	ste_txeoc(struct ste_softc *);
 static void	ste_txeof(struct ste_softc *);
@@ -923,16 +925,74 @@ ste_txeof(struct ste_softc *sc)
 }
 
 static void
+ste_stats_clear(struct ste_softc *sc)
+{
+
+	STE_LOCK_ASSERT(sc);
+
+	/* Rx stats. */
+	CSR_READ_2(sc, STE_STAT_RX_OCTETS_LO);
+	CSR_READ_2(sc, STE_STAT_RX_OCTETS_HI);
+	CSR_READ_2(sc, STE_STAT_RX_FRAMES);
+	CSR_READ_1(sc, STE_STAT_RX_BCAST);
+	CSR_READ_1(sc, STE_STAT_RX_MCAST);
+	CSR_READ_1(sc, STE_STAT_RX_LOST);
+	/* Tx stats. */
+	CSR_READ_2(sc, STE_STAT_TX_OCTETS_LO);
+	CSR_READ_2(sc, STE_STAT_TX_OCTETS_HI);
+	CSR_READ_2(sc, STE_STAT_TX_FRAMES);
+	CSR_READ_1(sc, STE_STAT_TX_BCAST);
+	CSR_READ_1(sc, STE_STAT_TX_MCAST);
+	CSR_READ_1(sc, STE_STAT_CARRIER_ERR);
+	CSR_READ_1(sc, STE_STAT_SINGLE_COLLS);
+	CSR_READ_1(sc, STE_STAT_MULTI_COLLS);
+	CSR_READ_1(sc, STE_STAT_LATE_COLLS);
+	CSR_READ_1(sc, STE_STAT_TX_DEFER);
+	CSR_READ_1(sc, STE_STAT_TX_EXDEFER);
+	CSR_READ_1(sc, STE_STAT_TX_ABORT);
+}
+
+static void
 ste_stats_update(struct ste_softc *sc)
 {
 	struct ifnet *ifp;
+	struct ste_hw_stats *stats;
+	uint32_t val;
 
 	STE_LOCK_ASSERT(sc);
 
 	ifp = sc->ste_ifp;
-	ifp->if_collisions += CSR_READ_1(sc, STE_LATE_COLLS)
-	    + CSR_READ_1(sc, STE_MULTI_COLLS)
-	    + CSR_READ_1(sc, STE_SINGLE_COLLS);
+	stats = &sc->ste_stats;
+	/* Rx stats. */
+	val = (uint32_t)CSR_READ_2(sc, STE_STAT_RX_OCTETS_LO) |
+	    ((uint32_t)CSR_READ_2(sc, STE_STAT_RX_OCTETS_HI)) << 16;
+	val &= 0x000FFFFF;
+	stats->rx_bytes += val;
+	stats->rx_frames += CSR_READ_2(sc, STE_STAT_RX_FRAMES);
+	stats->rx_bcast_frames += CSR_READ_1(sc, STE_STAT_RX_BCAST);
+	stats->rx_mcast_frames += CSR_READ_1(sc, STE_STAT_RX_MCAST);
+	stats->rx_lost_frames += CSR_READ_1(sc, STE_STAT_RX_LOST);
+	/* Tx stats. */
+	val = (uint32_t)CSR_READ_2(sc, STE_STAT_TX_OCTETS_LO) |
+	    ((uint32_t)CSR_READ_2(sc, STE_STAT_TX_OCTETS_HI)) << 16;
+	val &= 0x000FFFFF;
+	stats->tx_bytes += val;
+	stats->tx_frames += CSR_READ_2(sc, STE_STAT_TX_FRAMES);
+	stats->tx_bcast_frames += CSR_READ_1(sc, STE_STAT_TX_BCAST);
+	stats->tx_mcast_frames += CSR_READ_1(sc, STE_STAT_TX_MCAST);
+	stats->tx_carrsense_errs += CSR_READ_1(sc, STE_STAT_CARRIER_ERR);
+	val = CSR_READ_1(sc, STE_STAT_SINGLE_COLLS);
+	stats->tx_single_colls += val;
+	ifp->if_collisions += val;
+	val = CSR_READ_1(sc, STE_STAT_MULTI_COLLS);
+	stats->tx_multi_colls += val;
+	ifp->if_collisions += val;
+	val += CSR_READ_1(sc, STE_STAT_LATE_COLLS);
+	stats->tx_late_colls += val;
+	ifp->if_collisions += val;
+	stats->tx_frames_defered += CSR_READ_1(sc, STE_STAT_TX_DEFER);
+	stats->tx_excess_defers += CSR_READ_1(sc, STE_STAT_TX_EXDEFER);
+	stats->tx_abort += CSR_READ_1(sc, STE_STAT_TX_ABORT);
 }
 
 /*
@@ -1032,6 +1092,7 @@ ste_attach(device_t dev)
 		error = ENXIO;;
 		goto fail;
 	}
+	ste_sysctl_node(sc);
 
 	if ((error = ste_dma_alloc(sc)) != 0)
 		goto fail;
@@ -1625,6 +1686,8 @@ ste_init_locked(struct ste_softc *sc)
 
 	/* Enable stats counters. */
 	STE_SETBIT2(sc, STE_MACCTL1, STE_MACCTL1_STATS_ENABLE);
+	/* Clear stats counters. */
+	ste_stats_clear(sc);
 
 	CSR_WRITE_2(sc, STE_ISR, 0xFFFF);
 #ifdef DEVICE_POLLING
@@ -2013,3 +2076,70 @@ ste_shutdown(device_t dev)
 
 	return (0);
 }
+
+#define	STE_SYSCTL_STAT_ADD32(c, h, n, p, d)	\
+	    SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d)
+#define	STE_SYSCTL_STAT_ADD64(c, h, n, p, d)	\
+	    SYSCTL_ADD_QUAD(c, h, OID_AUTO, n, CTLFLAG_RD, p, d)
+
+static void
+ste_sysctl_node(struct ste_softc *sc)
+{
+	struct sysctl_ctx_list *ctx;
+	struct sysctl_oid_list *child, *parent;
+	struct sysctl_oid *tree;
+	struct ste_hw_stats *stats;
+
+	stats = &sc->ste_stats;
+	ctx = device_get_sysctl_ctx(sc->ste_dev);
+	child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->ste_dev));
+
+	tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
+	    NULL, "STE statistics");
+	parent = SYSCTL_CHILDREN(tree);
+
+	/* Rx statistics. */
+	tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "rx", CTLFLAG_RD,
+	    NULL, "Rx MAC statistics");
+	child = SYSCTL_CHILDREN(tree);
+	STE_SYSCTL_STAT_ADD64(ctx, child, "good_octets",
+	    &stats->rx_bytes, "Good octets");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "good_frames",
+	    &stats->rx_frames, "Good frames");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "good_bcast_frames",
+	    &stats->rx_bcast_frames, "Good broadcast frames");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "good_mcast_frames",
+	    &stats->rx_mcast_frames, "Good multicast frames");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "lost_frames",
+	    &stats->rx_lost_frames, "Lost frames");
+
+	/* Tx statistics. */
+	tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "tx", CTLFLAG_RD,
+	    NULL, "Tx MAC statistics");
+	child = SYSCTL_CHILDREN(tree);
+	STE_SYSCTL_STAT_ADD64(ctx, child, "good_octets",
+	    &stats->tx_bytes, "Good octets");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "good_frames",
+	    &stats->tx_frames, "Good frames");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "good_bcast_frames",
+	    &stats->tx_bcast_frames, "Good broadcast frames");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "good_mcast_frames",
+	    &stats->tx_mcast_frames, "Good multicast frames");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "carrier_errs",
+	    &stats->tx_carrsense_errs, "Carrier sense errors");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "single_colls",
+	    &stats->tx_single_colls, "Single collisions");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "multi_colls",
+	    &stats->tx_multi_colls, "Multiple collisions");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "late_colls",
+	    &stats->tx_late_colls, "Late collisions");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "defers",
+	    &stats->tx_frames_defered, "Frames with deferrals");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "excess_defers",
+	    &stats->tx_excess_defers, "Frames with excessive derferrals");
+	STE_SYSCTL_STAT_ADD32(ctx, child, "abort",
+	    &stats->tx_abort, "Aborted frames due to Excessive collisions");
+}
+
+#undef STE_SYSCTL_STAT_ADD32
+#undef STE_SYSCTL_STAT_ADD64

Modified: head/sys/dev/ste/if_stereg.h
==============================================================================
--- head/sys/dev/ste/if_stereg.h	Wed Dec 23 18:53:11 2009	(r200909)
+++ head/sys/dev/ste/if_stereg.h	Wed Dec 23 19:18:07 2009	(r200910)
@@ -92,11 +92,25 @@
 #define STE_MAR1		0x62
 #define STE_MAR2		0x64
 #define STE_MAR3		0x66
-#define STE_STATS		0x68
 
-#define STE_LATE_COLLS  0x75
-#define STE_MULTI_COLLS	0x76
-#define STE_SINGLE_COLLS 0x77
+#define	STE_STAT_RX_OCTETS_LO	0x68
+#define	STE_STAT_RX_OCTETS_HI	0x6A
+#define	STE_STAT_TX_OCTETS_LO	0x6C
+#define	STE_STAT_TX_OCTETS_HI	0x6E
+#define	STE_STAT_TX_FRAMES	0x70
+#define	STE_STAT_RX_FRAMES	0x72
+#define	STE_STAT_CARRIER_ERR	0x74
+#define	STE_STAT_LATE_COLLS	0x75
+#define	STE_STAT_MULTI_COLLS	0x76
+#define	STE_STAT_SINGLE_COLLS	0x77
+#define	STE_STAT_TX_DEFER	0x78
+#define	STE_STAT_RX_LOST	0x79
+#define	STE_STAT_TX_EXDEFER	0x7A
+#define	STE_STAT_TX_ABORT	0x7B
+#define	STE_STAT_TX_BCAST	0x7C
+#define	STE_STAT_RX_BCAST	0x7D
+#define	STE_STAT_TX_MCAST	0x7E
+#define	STE_STAT_RX_MCAST	0x7F
 
 #define STE_DMACTL_RXDMA_STOPPED	0x00000001
 #define STE_DMACTL_TXDMA_CMPREQ		0x00000002
@@ -388,24 +402,23 @@
 #define STE_PME_EN			0x0010
 #define STE_PME_STATUS			0x8000
 
-
-struct ste_stats {
-	uint32_t		ste_rx_bytes;
-	uint32_t		ste_tx_bytes;
-	uint16_t		ste_tx_frames;
-	uint16_t		ste_rx_frames;
-	uint8_t			ste_carrsense_errs;
-	uint8_t			ste_late_colls;
-	uint8_t			ste_multi_colls;
-	uint8_t			ste_single_colls;
-	uint8_t			ste_tx_frames_defered;
-	uint8_t			ste_rx_lost_frames;
-	uint8_t			ste_tx_excess_defers;
-	uint8_t			ste_tx_abort_excess_colls;
-	uint8_t			ste_tx_bcast_frames;
-	uint8_t			ste_rx_bcast_frames;
-	uint8_t			ste_tx_mcast_frames;
-	uint8_t			ste_rx_mcast_frames;
+struct ste_hw_stats {
+	uint64_t		rx_bytes;
+	uint32_t		rx_frames;
+	uint32_t		rx_bcast_frames;
+	uint32_t		rx_mcast_frames;
+	uint32_t		rx_lost_frames;
+	uint64_t		tx_bytes;
+	uint32_t		tx_frames;
+	uint32_t		tx_bcast_frames;
+	uint32_t		tx_mcast_frames;
+	uint32_t		tx_carrsense_errs;
+	uint32_t		tx_single_colls;
+	uint32_t		tx_multi_colls;
+	uint32_t		tx_late_colls;
+	uint32_t		tx_frames_defered;
+	uint32_t		tx_excess_defers;
+	uint32_t		tx_abort;
 };
 
 struct ste_frag {
@@ -566,6 +579,7 @@ struct ste_softc {
 	struct ste_list_data	ste_ldata;
 	struct ste_chain_data	ste_cdata;
 	struct callout		ste_callout;
+	struct ste_hw_stats	ste_stats;
 	struct mtx		ste_mtx;
 };
 


More information about the svn-src-head mailing list