Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 24 Dec 2008 17:51:44 +0900
From:      Pyun YongHyeon <pyunyh@gmail.com>
To:        Ian FREISLICH <ianf@clue.co.za>
Cc:        "Sam Fourman Jr." <sfourman@gmail.com>, current@freebsd.org
Subject:   Re: msk(4) stops working.
Message-ID:  <20081224085143.GH95088@cdnetworks.co.kr>
In-Reply-To: <E1LFNdS-0001pT-0q@clue.co.za>
References:  <11167f520812232229g5ee1d475kdd92fd6511c50c29@mail.gmail.com> <E1LF7Oc-000Djt-C1@clue.co.za> <20081224021016.GF95088@cdnetworks.co.kr> <E1LFMVU-0001fB-Mz@clue.co.za> <E1LFNdS-0001pT-0q@clue.co.za>

next in thread | previous in thread | raw e-mail | index | archive | help

--3lcZGd9BuhuYXNfi
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Wed, Dec 24, 2008 at 08:54:26AM +0200, Ian FREISLICH wrote:
 > "Sam Fourman Jr." wrote:
 > > >> About 2-3 months ago I committed workaround for Yukon silicon bug.
 > > >> Do you use latest CURRENT?
 > > >
 > > > Yes, this is on yesterday's sources.  It was better for a month or
 > > > so, but over the last month it's been really bad.  Now I can provoke
 > > > this condition in under 1 minute of uptime.
 > > >
 > > I have a few msk cards, and I could stand to install -CURRENT on a system
 > > how do I reproduce your problem?
 > 
 > I induce it by scp-ing a large (several GB) file from one host to
 > another.  I only have one interface msk interface in my laptop, but
 > it's an SMP system.  Maybe that has something to do with it.
 > 

Would you show me the output of "sysctl dev.msk.0.stats" before and
after the watchdog timeouts after appling attached patch?
BTW, did you intentionally disable MSI?

-- 
Regards,
Pyun YongHyeon

--3lcZGd9BuhuYXNfi
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="msk.hwstat.patch"

Index: sys/dev/msk/if_msk.c
===================================================================
--- sys/dev/msk/if_msk.c	(revision 186475)
+++ sys/dev/msk/if_msk.c	(working copy)
@@ -289,6 +289,11 @@
 static void msk_setvlan(struct msk_if_softc *, struct ifnet *);
 static void msk_setpromisc(struct msk_if_softc *);
 
+static void msk_stats_clear(struct msk_if_softc *);
+static void msk_stats_update(struct msk_if_softc *);
+static int msk_sysctl_stat32(SYSCTL_HANDLER_ARGS);
+static int msk_sysctl_stat64(SYSCTL_HANDLER_ARGS);
+static void msk_sysctl_node(struct msk_if_softc *);
 static int sysctl_int_range(SYSCTL_HANDLER_ARGS, int, int);
 static int sysctl_hw_msk_proc_limit(SYSCTL_HANDLER_ARGS);
 
@@ -1442,6 +1447,7 @@
 
 	callout_init_mtx(&sc_if->msk_tick_ch, &sc_if->msk_softc->msk_mtx, 0);
 	TASK_INIT(&sc_if->msk_link_task, 0, msk_link_task, sc_if);
+	msk_sysctl_node(sc_if);
 
 	if ((error = msk_txrx_dma_alloc(sc_if) != 0))
 		goto fail;
@@ -3664,15 +3670,8 @@
 	/* Dummy read the Interrupt Source Register. */
 	CSR_READ_1(sc, MR_ADDR(sc_if->msk_port, GMAC_IRQ_SRC));
 
-	/* Set MIB Clear Counter Mode. */
-	gmac = GMAC_READ_2(sc, sc_if->msk_port, GM_PHY_ADDR);
-	GMAC_WRITE_2(sc, sc_if->msk_port, GM_PHY_ADDR, gmac | GM_PAR_MIB_CLR);
-	/* Read all MIB Counters with Clear Mode set. */
-	for (i = 0; i < GM_MIB_CNT_SIZE; i++)
-		GMAC_READ_2(sc, sc_if->msk_port, GM_MIB_CNT_BASE + 8 * i);
-	/* Clear MIB Clear Counter Mode. */
-	gmac &= ~GM_PAR_MIB_CLR;
-	GMAC_WRITE_2(sc, sc_if->msk_port, GM_PHY_ADDR, gmac);
+	/* Clear MIB stats. */
+	msk_stats_clear(sc_if);
 
 	/* Disable FCS. */
 	GMAC_WRITE_2(sc, sc_if->msk_port, GM_RX_CTRL, GM_RXCR_CRC_DIS);
@@ -3958,6 +3957,8 @@
 	GMAC_WRITE_2(sc, sc_if->msk_port, GM_GP_CTRL, val);
 	/* Read again to ensure writing. */
 	GMAC_READ_2(sc, sc_if->msk_port, GM_GP_CTRL);
+	/* Update stats and clear counters. */
+	msk_stats_update(sc_if);
 
 	/* Stop Tx BMU. */
 	CSR_WRITE_4(sc, Q_ADDR(sc_if->msk_txq, Q_CSR), BMU_STOP);
@@ -4073,7 +4074,296 @@
 	sc_if->msk_link = 0;
 }
 
+/*
+ * When GM_PAR_MIB_CLR bit of GM_PHY_ADDR is set, reading lower
+ * counter clears high 16bits of the counter such that accessing
+ * lower 16bits should be the last operation.
+ */
+#define	MSK_READ_MIB32(x, y)					\
+	(((uint32_t)GMAC_READ_2(sc, x, (y) + 4)) << 16) +	\
+	(uint32_t)GMAC_READ_2(sc, x, y)
+#define	MSK_READ_MIB64(x, y)					\
+	(((uint64_t)MSK_READ_MIB32(x, (y) + 8)) << 32) +	\
+	(uint64_t)MSK_READ_MIB32(x, y)
+
+static void
+msk_stats_clear(struct msk_if_softc *sc_if)
+{
+	struct msk_softc *sc;
+	uint32_t reg;
+	uint16_t gmac;
+	int i;
+
+	MSK_IF_LOCK_ASSERT(sc_if);
+
+	sc = sc_if->msk_softc;
+	/* Set MIB Clear Counter Mode. */
+	gmac = GMAC_READ_2(sc, sc_if->msk_port, GM_PHY_ADDR);
+	GMAC_WRITE_2(sc, sc_if->msk_port, GM_PHY_ADDR, gmac | GM_PAR_MIB_CLR);
+	/* Read all MIB Counters with Clear Mode set. */
+	for (i = GM_RXF_UC_OK; i <= GM_TXE_FIFO_UR; i++)
+		reg = MSK_READ_MIB32(sc_if->msk_port, i);
+	/* Clear MIB Clear Counter Mode. */
+	gmac &= ~GM_PAR_MIB_CLR;
+	GMAC_WRITE_2(sc, sc_if->msk_port, GM_PHY_ADDR, gmac);
+}
+
+static void
+msk_stats_update(struct msk_if_softc *sc_if)
+{
+	struct msk_softc *sc;
+	struct ifnet *ifp;
+	struct msk_hw_stats *stats;
+	uint16_t gmac;
+	uint32_t reg;
+
+	MSK_IF_LOCK_ASSERT(sc_if);
+
+	ifp = sc_if->msk_ifp;
+	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+		return;
+	sc = sc_if->msk_softc;
+	stats = &sc_if->msk_stats;
+	/* Set MIB Clear Counter Mode. */
+	gmac = GMAC_READ_2(sc, sc_if->msk_port, GM_PHY_ADDR);
+	GMAC_WRITE_2(sc, sc_if->msk_port, GM_PHY_ADDR, gmac | GM_PAR_MIB_CLR);
+
+	/* Rx stats. */
+	stats->rx_ucast_frames +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_RXF_UC_OK);
+	stats->rx_bcast_frames +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_RXF_BC_OK);
+	stats->rx_pause_frames +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_RXF_MPAUSE);
+	stats->rx_mcast_frames +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_RXF_MC_OK);
+	stats->rx_crc_errs +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_RXF_FCS_ERR);
+	reg = MSK_READ_MIB32(sc_if->msk_port, GM_RXF_SPARE1);
+	stats->rx_good_octets +=
+	    MSK_READ_MIB64(sc_if->msk_port, GM_RXO_OK_LO);
+	stats->rx_bad_octets +=
+	    MSK_READ_MIB64(sc_if->msk_port, GM_RXO_ERR_LO);
+	stats->rx_runts +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_RXF_SHT);
+	stats->rx_runt_errs +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_RXE_FRAG);
+	stats->rx_pkts_64 +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_RXF_64B);
+	stats->rx_pkts_65_127 +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_RXF_127B);
+	stats->rx_pkts_128_255 +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_RXF_255B);
+	stats->rx_pkts_256_511 +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_RXF_511B);
+	stats->rx_pkts_512_1023 +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_RXF_1023B);
+	stats->rx_pkts_1024_1518 +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_RXF_1518B);
+	stats->rx_pkts_1519_max +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_RXF_MAX_SZ);
+	stats->rx_pkts_too_long +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_RXF_LNG_ERR);
+	stats->rx_pkts_jabbers +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_RXF_JAB_PKT);
+	reg = MSK_READ_MIB32(sc_if->msk_port, GM_RXF_SPARE2);
+	stats->rx_fifo_oflows +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_RXE_FIFO_OV);
+	reg = MSK_READ_MIB32(sc_if->msk_port, GM_RXF_SPARE3);
+
+	/* Tx stats. */
+	stats->tx_ucast_frames +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_TXF_UC_OK);
+	stats->tx_bcast_frames +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_TXF_BC_OK);
+	stats->tx_pause_frames +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_TXF_MPAUSE);
+	stats->tx_mcast_frames +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_TXF_MC_OK);
+	stats->tx_octets +=
+	    MSK_READ_MIB64(sc_if->msk_port, GM_TXO_OK_LO);
+	stats->tx_pkts_64 +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_TXF_64B);
+	stats->tx_pkts_65_127 +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_TXF_127B);
+	stats->tx_pkts_128_255 +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_TXF_255B);
+	stats->tx_pkts_256_511 +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_TXF_511B);
+	stats->tx_pkts_512_1023 +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_TXF_1023B);
+	stats->tx_pkts_1024_1518 +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_TXF_1518B);
+	stats->tx_pkts_1519_max +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_TXF_MAX_SZ);
+	reg = MSK_READ_MIB32(sc_if->msk_port, GM_TXF_SPARE1);
+	stats->tx_colls +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_TXF_COL);
+	stats->tx_late_colls +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_TXF_LAT_COL);
+	stats->tx_excess_colls +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_TXF_ABO_COL);
+	stats->tx_multi_colls +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_TXF_MUL_COL);
+	stats->tx_single_colls +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_TXF_SNG_COL);
+	stats->tx_underflows +=
+	    MSK_READ_MIB32(sc_if->msk_port, GM_TXE_FIFO_UR);
+	/* Clear MIB Clear Counter Mode. */
+	gmac &= ~GM_PAR_MIB_CLR;
+	GMAC_WRITE_2(sc, sc_if->msk_port, GM_PHY_ADDR, gmac);
+}
+
 static int
+msk_sysctl_stat32(SYSCTL_HANDLER_ARGS)
+{
+	struct msk_softc *sc;
+	struct msk_if_softc *sc_if;
+	uint32_t result, *stat;
+	int off;
+
+	sc_if = (struct msk_if_softc *)arg1;
+	sc = sc_if->msk_softc;
+	off = arg2;
+	stat = (uint32_t *)((uint8_t *)&sc_if->msk_stats + off);
+
+	MSK_IF_LOCK(sc_if);
+	result = MSK_READ_MIB32(sc_if->msk_port, GM_MIB_CNT_BASE + off * 2);
+	result += *stat;
+	MSK_IF_UNLOCK(sc_if);
+
+	return (sysctl_handle_int(oidp, &result, 0, req));
+}
+
+static int
+msk_sysctl_stat64(SYSCTL_HANDLER_ARGS)
+{
+	struct msk_softc *sc;
+	struct msk_if_softc *sc_if;
+	uint64_t result, *stat;
+	int off;
+
+	sc_if = (struct msk_if_softc *)arg1;
+	sc = sc_if->msk_softc;
+	off = arg2;
+	stat = (uint64_t *)((uint8_t *)&sc_if->msk_stats + off);
+
+	MSK_IF_LOCK(sc_if);
+	result = MSK_READ_MIB64(sc_if->msk_port, GM_MIB_CNT_BASE + off * 2);
+	result += *stat;
+	MSK_IF_UNLOCK(sc_if);
+
+	return (sysctl_handle_quad(oidp, &result, 0, req));
+}
+
+#undef MSK_READ_MIB32
+#undef MSK_READ_MIB64
+
+#define MSK_SYSCTL_STAT32(sc, c, o, p, n, d) 				\
+	SYSCTL_ADD_PROC(c, p, OID_AUTO, o, CTLTYPE_UINT | CTLFLAG_RD, 	\
+	    sc, offsetof(struct msk_hw_stats, n), msk_sysctl_stat32,	\
+	    "IU", d)
+#define MSK_SYSCTL_STAT64(sc, c, o, p, n, d) 				\
+	SYSCTL_ADD_PROC(c, p, OID_AUTO, o, CTLTYPE_UINT | CTLFLAG_RD, 	\
+	    sc, offsetof(struct msk_hw_stats, n), msk_sysctl_stat64,	\
+	    "Q", d)
+
+static void
+msk_sysctl_node(struct msk_if_softc *sc_if)
+{
+	struct sysctl_ctx_list *ctx;
+	struct sysctl_oid_list *child, *schild;
+	struct sysctl_oid *tree;
+
+	ctx = device_get_sysctl_ctx(sc_if->msk_if_dev);
+	child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc_if->msk_if_dev));
+
+	tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD,
+	    NULL, "MSK Statistics");
+	schild = child = SYSCTL_CHILDREN(tree);
+	tree = SYSCTL_ADD_NODE(ctx, schild, OID_AUTO, "rx", CTLFLAG_RD,
+	    NULL, "MSK RX Statistics");
+	child = SYSCTL_CHILDREN(tree);
+	MSK_SYSCTL_STAT32(sc_if, ctx, "ucast_frames",
+	    child, rx_ucast_frames, "Good unicast frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "bcast_frames",
+	    child, rx_bcast_frames, "Good broadcast frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "pause_frames",
+	    child, rx_pause_frames, "Pause frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "mcast_frames",
+	    child, rx_mcast_frames, "Multicast frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "crc_errs",
+	    child, rx_crc_errs, "CRC errors");
+	MSK_SYSCTL_STAT64(sc_if, ctx, "good_octets",
+	    child, rx_good_octets, "Good octets");
+	MSK_SYSCTL_STAT64(sc_if, ctx, "bad_octets",
+	    child, rx_bad_octets, "Bad octets");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "frames_64",
+	    child, rx_pkts_64, "64 bytes frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "frames_65_127",
+	    child, rx_pkts_65_127, "65 to 127 bytes frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "frames_128_255",
+	    child, rx_pkts_128_255, "128 to 255 bytes frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "frames_256_511",
+	    child, rx_pkts_256_511, "256 to 511 bytes frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "frames_512_1023",
+	    child, rx_pkts_512_1023, "512 to 1023 bytes frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "frames_1024_1518",
+	    child, rx_pkts_1024_1518, "1024 to 1518 bytes frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "frames_1519_max",
+	    child, rx_pkts_1519_max, "1519 to max frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "frames_too_long",
+	    child, rx_pkts_too_long, "frames too long");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "jabbers",
+	    child, rx_pkts_jabbers, "Jabber errors");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "jabbers",
+	    child, rx_fifo_oflows, "FIFO overflows");
+
+	tree = SYSCTL_ADD_NODE(ctx, schild, OID_AUTO, "tx", CTLFLAG_RD,
+	    NULL, "MSK TX Statistics");
+	child = SYSCTL_CHILDREN(tree);
+	MSK_SYSCTL_STAT32(sc_if, ctx, "ucast_frames",
+	    child, tx_ucast_frames, "Unicast frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "bcast_frames",
+	    child, tx_bcast_frames, "Broadcast frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "pause_frames",
+	    child, tx_pause_frames, "Pause frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "mcast_frames",
+	    child, tx_mcast_frames, "Multicast frames");
+	MSK_SYSCTL_STAT64(sc_if, ctx, "octets",
+	    child, tx_octets, "Octets");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "frames_64",
+	    child, tx_pkts_64, "64 bytes frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "frames_65_127",
+	    child, tx_pkts_65_127, "65 to 127 bytes frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "frames_128_255",
+	    child, tx_pkts_128_255, "128 to 255 bytes frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "frames_256_511",
+	    child, tx_pkts_256_511, "256 to 511 bytes frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "frames_512_1023",
+	    child, tx_pkts_512_1023, "512 to 1023 bytes frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "frames_1024_1518",
+	    child, tx_pkts_1024_1518, "1024 to 1518 bytes frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "frames_1519_max",
+	    child, tx_pkts_1519_max, "1519 to max frames");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "colls",
+	    child, tx_colls, "Collisions");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "late_colls",
+	    child, tx_late_colls, "Late collisions");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "excess_colls",
+	    child, tx_excess_colls, "Excessive collisions");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "multi_colls",
+	    child, tx_multi_colls, "Multiple collisions");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "single_colls",
+	    child, tx_single_colls, "Single collisions");
+	MSK_SYSCTL_STAT32(sc_if, ctx, "underflows",
+	    child, tx_underflows, "FIFO underflows");
+}
+
+#undef MSK_SYSCTL_STAT32
+#undef MSK_SYSCTL_STAT64
+
+static int
 sysctl_int_range(SYSCTL_HANDLER_ARGS, int low, int high)
 {
 	int error, value;
Index: sys/dev/msk/if_mskreg.h
===================================================================
--- sys/dev/msk/if_mskreg.h	(revision 186475)
+++ sys/dev/msk/if_mskreg.h	(working copy)
@@ -1614,6 +1614,8 @@
 			(GM_MIB_CNT_BASE + 24)	/* Multicast Frames Received OK */
 #define GM_RXF_FCS_ERR \
 			(GM_MIB_CNT_BASE + 32)	/* Rx Frame Check Seq. Error */
+#define GM_RXF_SPARE1 \
+			(GM_MIB_CNT_BASE + 40)	/* Rx spare 1 */
 #define GM_RXO_OK_LO \
 			(GM_MIB_CNT_BASE + 48)	/* Octets Received OK Low */
 #define GM_RXO_OK_HI \
@@ -1644,8 +1646,12 @@
 			(GM_MIB_CNT_BASE + 152)	/* Rx Frame too Long Error */
 #define GM_RXF_JAB_PKT \
 			(GM_MIB_CNT_BASE + 160)	/* Rx Jabber Packet Frame */
+#define GM_RXF_SPARE2 \
+			(GM_MIB_CNT_BASE + 168)	/* Rx spare 2 */
 #define GM_RXE_FIFO_OV \
 			(GM_MIB_CNT_BASE + 176)	/* Rx FIFO overflow Event */
+#define GM_RXF_SPARE3 \
+			(GM_MIB_CNT_BASE + 184)	/* Rx spare 3 */
 #define GM_TXF_UC_OK \
 			(GM_MIB_CNT_BASE + 192)	/* Unicast Frames Xmitted OK */
 #define GM_TXF_BC_OK \
@@ -1672,6 +1678,8 @@
 			(GM_MIB_CNT_BASE + 280)	/* 1024-1518 Byte Tx Frame */
 #define GM_TXF_MAX_SZ \
 			(GM_MIB_CNT_BASE + 288)	/* 1519-MaxSize Byte Tx Frame */
+#define GM_TXF_SPARE1 \
+			(GM_MIB_CNT_BASE + 296)	/* Tx spare 1 */
 #define GM_TXF_COL \
 			(GM_MIB_CNT_BASE + 304)	/* Tx Collision */
 #define GM_TXF_LAT_COL \
@@ -2291,6 +2299,52 @@
 /* Forward decl. */
 struct msk_if_softc;
 
+struct msk_hw_stats {
+	/* Rx stats. */
+	uint32_t rx_ucast_frames;
+	uint32_t rx_bcast_frames;
+	uint32_t rx_pause_frames;
+	uint32_t rx_mcast_frames;
+	uint32_t rx_crc_errs;
+	uint32_t rx_spare1;
+	uint64_t rx_good_octets;
+	uint64_t rx_bad_octets;
+	uint32_t rx_runts;
+	uint32_t rx_runt_errs;
+	uint32_t rx_pkts_64;
+	uint32_t rx_pkts_65_127;
+	uint32_t rx_pkts_128_255;
+	uint32_t rx_pkts_256_511;
+	uint32_t rx_pkts_512_1023;
+	uint32_t rx_pkts_1024_1518;
+	uint32_t rx_pkts_1519_max;
+	uint32_t rx_pkts_too_long;
+	uint32_t rx_pkts_jabbers;
+	uint32_t rx_spare2;
+	uint32_t rx_fifo_oflows;
+	uint32_t rx_spare3;
+	/* Tx stats. */
+	uint32_t tx_ucast_frames;
+	uint32_t tx_bcast_frames;
+	uint32_t tx_pause_frames;
+	uint32_t tx_mcast_frames;
+	uint64_t tx_octets;
+	uint32_t tx_pkts_64;
+	uint32_t tx_pkts_65_127;
+	uint32_t tx_pkts_128_255;
+	uint32_t tx_pkts_256_511;
+	uint32_t tx_pkts_512_1023;
+	uint32_t tx_pkts_1024_1518;
+	uint32_t tx_pkts_1519_max;
+	uint32_t tx_spare1;
+	uint32_t tx_colls;
+	uint32_t tx_late_colls;
+	uint32_t tx_excess_colls;
+	uint32_t tx_multi_colls;
+	uint32_t tx_single_colls;
+	uint32_t tx_underflows;
+};
+
 /* Softc for the Marvell Yukon II controller. */
 struct msk_softc {
 	struct resource		*msk_res[1];	/* I/O resource */
@@ -2360,6 +2414,7 @@
 	struct msk_chain_data	msk_cdata;
 	struct msk_ring_data	msk_rdata;
 	struct msk_softc	*msk_softc;	/* parent controller */
+	struct msk_hw_stats	msk_stats;
 	struct task		msk_link_task;
 	struct task		msk_tx_task;
 	int			msk_if_flags;

--3lcZGd9BuhuYXNfi--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20081224085143.GH95088>