svn commit: r185597 - head/sys/dev/jme

Pyun YongHyeon yongari at FreeBSD.org
Wed Dec 3 18:16:55 PST 2008


Author: yongari
Date: Thu Dec  4 02:16:53 2008
New Revision: 185597
URL: http://svn.freebsd.org/changeset/base/185597

Log:
  Add HW MAC counter support for newer JMC250/JMC260 revisions.

Modified:
  head/sys/dev/jme/if_jme.c
  head/sys/dev/jme/if_jmereg.h
  head/sys/dev/jme/if_jmevar.h

Modified: head/sys/dev/jme/if_jme.c
==============================================================================
--- head/sys/dev/jme/if_jme.c	Thu Dec  4 01:58:40 2008	(r185596)
+++ head/sys/dev/jme/if_jme.c	Thu Dec  4 02:16:53 2008	(r185597)
@@ -150,6 +150,9 @@ static void jme_init_ssb(struct jme_soft
 static int jme_newbuf(struct jme_softc *, struct jme_rxdesc *);
 static void jme_set_vlan(struct jme_softc *);
 static void jme_set_filter(struct jme_softc *);
+static void jme_stats_clear(struct jme_softc *);
+static void jme_stats_save(struct jme_softc *);
+static void jme_stats_update(struct jme_softc *);
 static int sysctl_int_range(SYSCTL_HANDLER_ARGS, int, int);
 static int sysctl_hw_jme_tx_coal_to(SYSCTL_HANDLER_ARGS);
 static int sysctl_hw_jme_tx_coal_pkt(SYSCTL_HANDLER_ARGS);
@@ -656,6 +659,7 @@ jme_attach(device_t dev)
 		    CHIPMODE_REVFM(sc->jme_chip_rev) == 2)
 			sc->jme_flags |= JME_FLAG_DMA32BIT;
 		sc->jme_flags |= JME_FLAG_TXCLK;
+		sc->jme_flags |= JME_FLAG_HWMIB;
 	}
 
 	/* Reset the ethernet controller. */
@@ -887,35 +891,41 @@ jme_detach(device_t dev)
 	return (0);
 }
 
+#define	JME_SYSCTL_STAT_ADD32(c, h, n, p, d)	\
+	    SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d)
+
 static void
 jme_sysctl_node(struct jme_softc *sc)
 {
+	struct sysctl_ctx_list *ctx;
+	struct sysctl_oid_list *child, *parent;
+	struct sysctl_oid *tree;
+	struct jme_hw_stats *stats;
 	int error;
 
-	SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->jme_dev),
-	    SYSCTL_CHILDREN(device_get_sysctl_tree(sc->jme_dev)), OID_AUTO,
-	    "tx_coal_to", CTLTYPE_INT | CTLFLAG_RW, &sc->jme_tx_coal_to,
-	    0, sysctl_hw_jme_tx_coal_to, "I", "jme tx coalescing timeout");
-
-	SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->jme_dev),
-	    SYSCTL_CHILDREN(device_get_sysctl_tree(sc->jme_dev)), OID_AUTO,
-	    "tx_coal_pkt", CTLTYPE_INT | CTLFLAG_RW, &sc->jme_tx_coal_pkt,
-	    0, sysctl_hw_jme_tx_coal_pkt, "I", "jme tx coalescing packet");
-
-	SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->jme_dev),
-	    SYSCTL_CHILDREN(device_get_sysctl_tree(sc->jme_dev)), OID_AUTO,
-	    "rx_coal_to", CTLTYPE_INT | CTLFLAG_RW, &sc->jme_rx_coal_to,
-	    0, sysctl_hw_jme_rx_coal_to, "I", "jme rx coalescing timeout");
-
-	SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->jme_dev),
-	    SYSCTL_CHILDREN(device_get_sysctl_tree(sc->jme_dev)), OID_AUTO,
-	    "rx_coal_pkt", CTLTYPE_INT | CTLFLAG_RW, &sc->jme_rx_coal_pkt,
-	    0, sysctl_hw_jme_rx_coal_pkt, "I", "jme rx coalescing packet");
-
-	SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->jme_dev),
-	    SYSCTL_CHILDREN(device_get_sysctl_tree(sc->jme_dev)), OID_AUTO,
-	    "process_limit", CTLTYPE_INT | CTLFLAG_RW, &sc->jme_process_limit,
-	    0, sysctl_hw_jme_proc_limit, "I",
+	stats = &sc->jme_stats;
+	ctx = device_get_sysctl_ctx(sc->jme_dev);
+	child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->jme_dev));
+
+	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "tx_coal_to",
+	    CTLTYPE_INT | CTLFLAG_RW, &sc->jme_tx_coal_to, 0,
+	    sysctl_hw_jme_tx_coal_to, "I", "jme tx coalescing timeout");
+
+	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "tx_coal_pkt",
+	    CTLTYPE_INT | CTLFLAG_RW, &sc->jme_tx_coal_pkt, 0,
+	    sysctl_hw_jme_tx_coal_pkt, "I", "jme tx coalescing packet");
+
+	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rx_coal_to",
+	    CTLTYPE_INT | CTLFLAG_RW, &sc->jme_rx_coal_to, 0,
+	    sysctl_hw_jme_rx_coal_to, "I", "jme rx coalescing timeout");
+
+	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rx_coal_pkt",
+	    CTLTYPE_INT | CTLFLAG_RW, &sc->jme_rx_coal_pkt, 0,
+	    sysctl_hw_jme_rx_coal_pkt, "I", "jme rx coalescing packet");
+
+	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "process_limit",
+	    CTLTYPE_INT | CTLFLAG_RW, &sc->jme_process_limit, 0,
+	    sysctl_hw_jme_proc_limit, "I",
 	    "max number of Rx events to process");
 
 	/* Pull in device tunables. */
@@ -984,8 +994,43 @@ jme_sysctl_node(struct jme_softc *sc)
 			sc->jme_rx_coal_pkt = PCCRX_COAL_PKT_DEFAULT;
 		}
 	}
+
+	if ((sc->jme_flags & JME_FLAG_HWMIB) == 0)
+		return;
+
+	tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
+	    NULL, "JME 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);
+	JME_SYSCTL_STAT_ADD32(ctx, child, "good_frames",
+	    &stats->rx_good_frames, "Good frames");
+	JME_SYSCTL_STAT_ADD32(ctx, child, "crc_errs",
+	    &stats->rx_crc_errs, "CRC errors");
+	JME_SYSCTL_STAT_ADD32(ctx, child, "mii_errs",
+	    &stats->rx_mii_errs, "MII errors");
+	JME_SYSCTL_STAT_ADD32(ctx, child, "fifo_oflows",
+	    &stats->rx_fifo_oflows, "FIFO overflows");
+	JME_SYSCTL_STAT_ADD32(ctx, child, "desc_empty",
+	    &stats->rx_desc_empty, "Descriptor empty");
+	JME_SYSCTL_STAT_ADD32(ctx, child, "bad_frames",
+	    &stats->rx_bad_frames, "Bad frames");
+
+	/* Tx statistics. */
+	tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "tx", CTLFLAG_RD,
+	    NULL, "Tx MAC statistics");
+	child = SYSCTL_CHILDREN(tree);
+	JME_SYSCTL_STAT_ADD32(ctx, child, "good_frames",
+	    &stats->tx_good_frames, "Good frames");
+	JME_SYSCTL_STAT_ADD32(ctx, child, "bad_frames",
+	    &stats->tx_bad_frames, "Bad frames");
 }
 
+#undef	JME_SYSCTL_STAT_ADD32
+
 struct jme_dmamap_arg {
 	bus_addr_t	jme_busaddr;
 };
@@ -2164,6 +2209,7 @@ jme_link_task(void *arg, int pending)
 	/* Program MAC with resolved speed/duplex/flow-control. */
 	if ((sc->jme_flags & JME_FLAG_LINK) != 0) {
 		jme_mac_config(sc);
+		jme_stats_clear(sc);
 
 		CSR_WRITE_4(sc, JME_RXCSR, sc->jme_rxcsr);
 		CSR_WRITE_4(sc, JME_TXCSR, sc->jme_txcsr);
@@ -2553,6 +2599,7 @@ jme_tick(void *arg)
 	 * faster and limit the maximum delay to a hz.
 	 */
 	jme_txeof(sc);
+	jme_stats_update(sc);
 	jme_watchdog(sc);
 	callout_reset(&sc->jme_tick_ch, hz, jme_tick, sc);
 }
@@ -2862,6 +2909,8 @@ jme_stop(struct jme_softc *sc)
 			txd->tx_ndesc = 0;
 		}
         }
+	jme_stats_update(sc);
+	jme_stats_save(sc);
 }
 
 static void
@@ -3093,6 +3142,76 @@ jme_set_filter(struct jme_softc *sc)
 	CSR_WRITE_4(sc, JME_RXMAC, rxcfg);
 }
 
+static void
+jme_stats_clear(struct jme_softc *sc)
+{
+
+	JME_LOCK_ASSERT(sc);
+
+	if ((sc->jme_flags & JME_FLAG_HWMIB) == 0)
+		return;
+
+	/* Disable and clear counters. */
+	CSR_WRITE_4(sc, JME_STATCSR, 0xFFFFFFFF);
+	/* Activate hw counters. */
+	CSR_WRITE_4(sc, JME_STATCSR, 0);
+	CSR_READ_4(sc, JME_STATCSR);
+	bzero(&sc->jme_stats, sizeof(struct jme_hw_stats));
+}
+
+static void
+jme_stats_save(struct jme_softc *sc)
+{
+
+	JME_LOCK_ASSERT(sc);
+
+	if ((sc->jme_flags & JME_FLAG_HWMIB) == 0)
+		return;
+	/* Save current counters. */
+	bcopy(&sc->jme_stats, &sc->jme_ostats, sizeof(struct jme_hw_stats));
+	/* Disable and clear counters. */
+	CSR_WRITE_4(sc, JME_STATCSR, 0xFFFFFFFF);
+}
+
+static void
+jme_stats_update(struct jme_softc *sc)
+{
+	struct jme_hw_stats *stat, *ostat;
+	uint32_t reg;
+
+	JME_LOCK_ASSERT(sc);
+
+	if ((sc->jme_flags & JME_FLAG_HWMIB) == 0)
+		return;
+	stat = &sc->jme_stats;
+	ostat = &sc->jme_ostats;
+	stat->tx_good_frames = CSR_READ_4(sc, JME_STAT_TXGOOD);
+	stat->rx_good_frames = CSR_READ_4(sc, JME_STAT_RXGOOD);
+	reg = CSR_READ_4(sc, JME_STAT_CRCMII);
+	stat->rx_crc_errs = (reg & STAT_RX_CRC_ERR_MASK) >>
+	    STAT_RX_CRC_ERR_SHIFT;
+	stat->rx_mii_errs = (reg & STAT_RX_MII_ERR_MASK) >>
+	    STAT_RX_MII_ERR_SHIFT;
+	reg = CSR_READ_4(sc, JME_STAT_RXERR);
+	stat->rx_fifo_oflows = (reg & STAT_RXERR_OFLOW_MASK) >>
+	    STAT_RXERR_OFLOW_SHIFT;
+	stat->rx_desc_empty = (reg & STAT_RXERR_MPTY_MASK) >>
+	    STAT_RXERR_MPTY_SHIFT;
+	reg = CSR_READ_4(sc, JME_STAT_FAIL);
+	stat->rx_bad_frames = (reg & STAT_FAIL_RX_MASK) >> STAT_FAIL_RX_SHIFT;
+	stat->tx_bad_frames = (reg & STAT_FAIL_TX_MASK) >> STAT_FAIL_TX_SHIFT;
+
+	/* Account for previous counters. */
+	stat->rx_good_frames += ostat->rx_good_frames;
+	stat->rx_crc_errs += ostat->rx_crc_errs;
+	stat->rx_mii_errs += ostat->rx_mii_errs;
+	stat->rx_fifo_oflows += ostat->rx_fifo_oflows;
+	stat->rx_desc_empty += ostat->rx_desc_empty;
+	stat->rx_bad_frames += ostat->rx_bad_frames;
+	stat->tx_good_frames += ostat->tx_good_frames;
+	stat->tx_bad_frames += ostat->tx_bad_frames;
+}
+
 static int
 sysctl_int_range(SYSCTL_HANDLER_ARGS, int low, int high)
 {

Modified: head/sys/dev/jme/if_jmereg.h
==============================================================================
--- head/sys/dev/jme/if_jmereg.h	Thu Dec  4 01:58:40 2008	(r185596)
+++ head/sys/dev/jme/if_jmereg.h	Thu Dec  4 02:16:53 2008	(r185597)
@@ -199,6 +199,7 @@
 #define	TXMAC_IFG2_DEFAULT	0x40000000
 #define	TXMAC_IFG1_MASK		0x30000000
 #define	TXMAC_IFG1_DEFAULT	0x20000000
+#define	TXMAC_PAUSE_CNT_MASK	0x00FF0000
 #define	TXMAC_THRESH_1_PKT	0x00000300
 #define	TXMAC_THRESH_1_2_PKT	0x00000200
 #define	TXMAC_THRESH_1_4_PKT	0x00000100
@@ -403,6 +404,44 @@
 #define	PMCS_MAGIC_FRAME_ENB	0x00000001
 #define	PMCS_WOL_ENB_MASK	0x0000FFFF
 
+/*
+ * Statistic registers control and status.
+ * These statistics registers are valid only for JMC250/JMC260 REVFM >= 2.
+ */
+#define	JME_STATCSR		0x0064
+#define	STATCSR_RXMPT_DIS	0x00000080
+#define	STATCSR_OFLOW_DIS	0x00000040
+#define	STATCSR_MIIRXER_DIS	0x00000020
+#define	STATCSR_CRCERR_DIS	0x00000010
+#define	STATCSR_RXBAD_DIS	0x00000008
+#define	STATCSR_RXGOOD_DIS	0x00000004
+#define	STATCSR_TXBAD_DIS	0x00000002
+#define	STATCSR_TXGOOD_DIS	0x00000001
+
+#define	JME_STAT_TXGOOD		0x0068
+
+#define	JME_STAT_RXGOOD		0x006C
+
+#define	JME_STAT_CRCMII		0x0070
+#define	STAT_RX_CRC_ERR_MASK	0xFFFF0000
+#define	STAT_RX_MII_ERR_MASK	0x0000FFFF
+#define	STAT_RX_CRC_ERR_SHIFT	16
+#define	STAT_RX_MII_ERR_SHIFT	0
+
+#define	JME_STAT_RXERR		0x0074
+#define	STAT_RXERR_OFLOW_MASK	0xFFFF0000
+#define	STAT_RXERR_MPTY_MASK	0x0000FFFF
+#define	STAT_RXERR_OFLOW_SHIFT	16
+#define	STAT_RXERR_MPTY_SHIFT	0
+
+#define	JME_STAT_RESERVED1	0x0078
+
+#define	JME_STAT_FAIL		0x007C
+#define	STAT_FAIL_RX_MASK	0xFFFF0000
+#define	STAT_FAIL_TX_MASK	0x0000FFFF
+#define	STAT_FAIL_RX_SHIFT	16
+#define	STAT_FAIL_TX_SHIFT	0
+
 /* Giga PHY & EEPROM registers. */
 #define	JME_PHY_EEPROM_BASE_ADDR	0x0400
 

Modified: head/sys/dev/jme/if_jmevar.h
==============================================================================
--- head/sys/dev/jme/if_jmevar.h	Thu Dec  4 01:58:40 2008	(r185596)
+++ head/sys/dev/jme/if_jmevar.h	Thu Dec  4 02:16:53 2008	(r185597)
@@ -154,6 +154,18 @@ struct jme_ring_data {
     (sizeof(struct jme_desc) * JME_RX_RING_CNT)
 #define	JME_SSB_SIZE		sizeof(struct jme_ssb)
 
+/* Statistics counters. */
+struct jme_hw_stats {
+	uint32_t		rx_good_frames;
+	uint32_t		rx_crc_errs;
+	uint32_t		rx_mii_errs;
+	uint32_t		rx_fifo_oflows;
+	uint32_t		rx_desc_empty;
+	uint32_t		rx_bad_frames;
+	uint32_t		tx_good_frames;
+	uint32_t		tx_bad_frames;
+};
+
 /*
  * Software state per device.
  */
@@ -183,9 +195,12 @@ struct jme_softc {
 #define	JME_FLAG_NOJUMBO	0x0080
 #define	JME_FLAG_TXCLK		0x0100
 #define	JME_FLAG_DMA32BIT	0x0200
+#define	JME_FLAG_HWMIB		0x0400
 #define	JME_FLAG_DETACH		0x4000
 #define	JME_FLAG_LINK		0x8000
 
+	struct jme_hw_stats	jme_ostats;
+	struct jme_hw_stats	jme_stats;
 	struct callout		jme_tick_ch;
 	struct jme_chain_data	jme_cdata;
 	struct jme_ring_data	jme_rdata;


More information about the svn-src-all mailing list