xref: /illumos-gate/usr/src/uts/common/io/bge/bge_kstats.c (revision bdb9230ac765cb7af3fc1f4119caf2c5720dceb3)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
562387023Sdduvall  * Common Development and Distribution License (the "License").
662387023Sdduvall  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
2162387023Sdduvall 
227c478bd9Sstevel@tonic-gate /*
23*bdb9230aSGarrett D'Amore  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
27f724721bSzh199473 #include "bge_impl.h"
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #define	BGE_DBG		BGE_DBG_STATS	/* debug flag for this code	*/
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate /*
327c478bd9Sstevel@tonic-gate  * Local datatype for defining tables of (Offset, Name) pairs
337c478bd9Sstevel@tonic-gate  */
347c478bd9Sstevel@tonic-gate typedef struct {
357c478bd9Sstevel@tonic-gate 	offset_t	index;
367c478bd9Sstevel@tonic-gate 	char		*name;
377c478bd9Sstevel@tonic-gate } bge_ksindex_t;
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate /*
417c478bd9Sstevel@tonic-gate  * Table of Hardware-defined Statistics Block Offsets and Names
427c478bd9Sstevel@tonic-gate  */
437c478bd9Sstevel@tonic-gate #define	KS_NAME(s)			{ KS_ ## s, #s }
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate static const bge_ksindex_t bge_statistics[] = {
467c478bd9Sstevel@tonic-gate 	KS_NAME(ifHCInOctets),
477c478bd9Sstevel@tonic-gate 	KS_NAME(etherStatsFragments),
487c478bd9Sstevel@tonic-gate 	KS_NAME(ifHCInUcastPkts),
497c478bd9Sstevel@tonic-gate 	KS_NAME(ifHCInMulticastPkts),
507c478bd9Sstevel@tonic-gate 	KS_NAME(ifHCInBroadcastPkts),
517c478bd9Sstevel@tonic-gate 	KS_NAME(dot3StatsFCSErrors),
527c478bd9Sstevel@tonic-gate 	KS_NAME(dot3StatsAlignmentErrors),
537c478bd9Sstevel@tonic-gate 	KS_NAME(xonPauseFramesReceived),
547c478bd9Sstevel@tonic-gate 	KS_NAME(xoffPauseFramesReceived),
557c478bd9Sstevel@tonic-gate 	KS_NAME(macControlFramesReceived),
567c478bd9Sstevel@tonic-gate 	KS_NAME(xoffStateEntered),
577c478bd9Sstevel@tonic-gate 	KS_NAME(dot3StatsFrameTooLongs),
587c478bd9Sstevel@tonic-gate 	KS_NAME(etherStatsJabbers),
597c478bd9Sstevel@tonic-gate 	KS_NAME(etherStatsUndersizePkts),
607c478bd9Sstevel@tonic-gate 	KS_NAME(inRangeLengthError),
617c478bd9Sstevel@tonic-gate 	KS_NAME(outRangeLengthError),
627c478bd9Sstevel@tonic-gate 	KS_NAME(etherStatsPkts64Octets),
637c478bd9Sstevel@tonic-gate 	KS_NAME(etherStatsPkts65to127Octets),
647c478bd9Sstevel@tonic-gate 	KS_NAME(etherStatsPkts128to255Octets),
657c478bd9Sstevel@tonic-gate 	KS_NAME(etherStatsPkts256to511Octets),
667c478bd9Sstevel@tonic-gate 	KS_NAME(etherStatsPkts512to1023Octets),
677c478bd9Sstevel@tonic-gate 	KS_NAME(etherStatsPkts1024to1518Octets),
687c478bd9Sstevel@tonic-gate 	KS_NAME(etherStatsPkts1519to2047Octets),
697c478bd9Sstevel@tonic-gate 	KS_NAME(etherStatsPkts2048to4095Octets),
707c478bd9Sstevel@tonic-gate 	KS_NAME(etherStatsPkts4096to8191Octets),
717c478bd9Sstevel@tonic-gate 	KS_NAME(etherStatsPkts8192to9022Octets),
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate 	KS_NAME(ifHCOutOctets),
747c478bd9Sstevel@tonic-gate 	KS_NAME(etherStatsCollisions),
757c478bd9Sstevel@tonic-gate 	KS_NAME(outXonSent),
767c478bd9Sstevel@tonic-gate 	KS_NAME(outXoffSent),
777c478bd9Sstevel@tonic-gate 	KS_NAME(flowControlDone),
787c478bd9Sstevel@tonic-gate 	KS_NAME(dot3StatsInternalMacTransmitErrors),
797c478bd9Sstevel@tonic-gate 	KS_NAME(dot3StatsSingleCollisionFrames),
807c478bd9Sstevel@tonic-gate 	KS_NAME(dot3StatsMultipleCollisionFrames),
817c478bd9Sstevel@tonic-gate 	KS_NAME(dot3StatsDeferredTransmissions),
827c478bd9Sstevel@tonic-gate 	KS_NAME(dot3StatsExcessiveCollisions),
837c478bd9Sstevel@tonic-gate 	KS_NAME(dot3StatsLateCollisions),
847c478bd9Sstevel@tonic-gate 	KS_NAME(dot3Collided2Times),
857c478bd9Sstevel@tonic-gate 	KS_NAME(dot3Collided3Times),
867c478bd9Sstevel@tonic-gate 	KS_NAME(dot3Collided4Times),
877c478bd9Sstevel@tonic-gate 	KS_NAME(dot3Collided5Times),
887c478bd9Sstevel@tonic-gate 	KS_NAME(dot3Collided6Times),
897c478bd9Sstevel@tonic-gate 	KS_NAME(dot3Collided7Times),
907c478bd9Sstevel@tonic-gate 	KS_NAME(dot3Collided8Times),
917c478bd9Sstevel@tonic-gate 	KS_NAME(dot3Collided9Times),
927c478bd9Sstevel@tonic-gate 	KS_NAME(dot3Collided10Times),
937c478bd9Sstevel@tonic-gate 	KS_NAME(dot3Collided11Times),
947c478bd9Sstevel@tonic-gate 	KS_NAME(dot3Collided12Times),
957c478bd9Sstevel@tonic-gate 	KS_NAME(dot3Collided13Times),
967c478bd9Sstevel@tonic-gate 	KS_NAME(dot3Collided14Times),
977c478bd9Sstevel@tonic-gate 	KS_NAME(dot3Collided15Times),
987c478bd9Sstevel@tonic-gate 	KS_NAME(ifHCOutUcastPkts),
997c478bd9Sstevel@tonic-gate 	KS_NAME(ifHCOutMulticastPkts),
1007c478bd9Sstevel@tonic-gate 	KS_NAME(ifHCOutBroadcastPkts),
1017c478bd9Sstevel@tonic-gate 	KS_NAME(dot3StatsCarrierSenseErrors),
1027c478bd9Sstevel@tonic-gate 	KS_NAME(ifOutDiscards),
1037c478bd9Sstevel@tonic-gate 	KS_NAME(ifOutErrors),
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_1),
1067c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_2),
1077c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_3),
1087c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_4),
1097c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_5),
1107c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_6),
1117c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_7),
1127c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_8),
1137c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_9),
1147c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_10),
1157c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_11),
1167c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_12),
1177c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_13),
1187c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_14),
1197c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_15),
1207c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_16),
1217c478bd9Sstevel@tonic-gate 	KS_NAME(COSFramesDroppedDueToFilters),
1227c478bd9Sstevel@tonic-gate 	KS_NAME(nicDmaWriteQueueFull),
1237c478bd9Sstevel@tonic-gate 	KS_NAME(nicDmaWriteHighPriQueueFull),
1247c478bd9Sstevel@tonic-gate 	KS_NAME(nicNoMoreRxBDs),
1257c478bd9Sstevel@tonic-gate 	KS_NAME(ifInDiscards),
1267c478bd9Sstevel@tonic-gate 	KS_NAME(ifInErrors),
1277c478bd9Sstevel@tonic-gate 	KS_NAME(nicRecvThresholdHit),
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_1),
1307c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_2),
1317c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_3),
1327c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_4),
1337c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_5),
1347c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_6),
1357c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_7),
1367c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_8),
1377c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_9),
1387c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_10),
1397c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_11),
1407c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_12),
1417c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_13),
1427c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_14),
1437c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_15),
1447c478bd9Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_16),
1457c478bd9Sstevel@tonic-gate 	KS_NAME(nicDmaReadQueueFull),
1467c478bd9Sstevel@tonic-gate 	KS_NAME(nicDmaReadHighPriQueueFull),
1477c478bd9Sstevel@tonic-gate 	KS_NAME(nicSendDataCompQueueFull),
1487c478bd9Sstevel@tonic-gate 	KS_NAME(nicRingSetSendProdIndex),
1497c478bd9Sstevel@tonic-gate 	KS_NAME(nicRingStatusUpdate),
1507c478bd9Sstevel@tonic-gate 	KS_NAME(nicInterrupts),
1517c478bd9Sstevel@tonic-gate 	KS_NAME(nicAvoidedInterrupts),
1527c478bd9Sstevel@tonic-gate 	KS_NAME(nicSendThresholdHit),
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate 	{ KS_STATS_SIZE, NULL }
1557c478bd9Sstevel@tonic-gate };
1567c478bd9Sstevel@tonic-gate 
1578eb6c4f9Sly149593 static const bge_ksindex_t bge_stat_val[] = {
1588eb6c4f9Sly149593 	KS_NAME(ifHCOutOctets),
1598eb6c4f9Sly149593 	KS_NAME(etherStatsCollisions),
1608eb6c4f9Sly149593 	KS_NAME(outXonSent),
1618eb6c4f9Sly149593 	KS_NAME(outXoffSent),
1628eb6c4f9Sly149593 	KS_NAME(dot3StatsInternalMacTransmitErrors),
1638eb6c4f9Sly149593 	KS_NAME(dot3StatsSingleCollisionFrames),
1648eb6c4f9Sly149593 	KS_NAME(dot3StatsMultipleCollisionFrames),
1658eb6c4f9Sly149593 	KS_NAME(dot3StatsDeferredTransmissions),
1668eb6c4f9Sly149593 	KS_NAME(dot3StatsExcessiveCollisions),
1678eb6c4f9Sly149593 	KS_NAME(dot3StatsLateCollisions),
1688eb6c4f9Sly149593 	KS_NAME(ifHCOutUcastPkts),
1698eb6c4f9Sly149593 	KS_NAME(ifHCOutMulticastPkts),
1708eb6c4f9Sly149593 	KS_NAME(ifHCOutBroadcastPkts),
1718eb6c4f9Sly149593 	KS_NAME(ifHCInOctets),
1728eb6c4f9Sly149593 	KS_NAME(etherStatsFragments),
1738eb6c4f9Sly149593 	KS_NAME(ifHCInUcastPkts),
1748eb6c4f9Sly149593 	KS_NAME(ifHCInMulticastPkts),
1758eb6c4f9Sly149593 	KS_NAME(ifHCInBroadcastPkts),
1768eb6c4f9Sly149593 	KS_NAME(dot3StatsFCSErrors),
1778eb6c4f9Sly149593 	KS_NAME(dot3StatsAlignmentErrors),
1788eb6c4f9Sly149593 	KS_NAME(xonPauseFramesReceived),
1798eb6c4f9Sly149593 	KS_NAME(xoffPauseFramesReceived),
1808eb6c4f9Sly149593 	KS_NAME(macControlFramesReceived),
1818eb6c4f9Sly149593 	KS_NAME(xoffStateEntered),
1828eb6c4f9Sly149593 	KS_NAME(dot3StatsFrameTooLongs),
1838eb6c4f9Sly149593 	KS_NAME(etherStatsJabbers),
1848eb6c4f9Sly149593 	KS_NAME(etherStatsUndersizePkts),
1858eb6c4f9Sly149593 
1868eb6c4f9Sly149593 	{ KS_STAT_REG_SIZE, NULL }
1878eb6c4f9Sly149593 };
1888eb6c4f9Sly149593 
1897c478bd9Sstevel@tonic-gate static int
1907c478bd9Sstevel@tonic-gate bge_statistics_update(kstat_t *ksp, int flag)
1917c478bd9Sstevel@tonic-gate {
1927c478bd9Sstevel@tonic-gate 	bge_t *bgep;
1937c478bd9Sstevel@tonic-gate 	bge_statistics_t *bstp;
194931dca7dSgs150176 	bge_statistics_reg_t *pstats;
1957c478bd9Sstevel@tonic-gate 	kstat_named_t *knp;
1967c478bd9Sstevel@tonic-gate 	const bge_ksindex_t *ksip;
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate 	if (flag != KSTAT_READ)
1997c478bd9Sstevel@tonic-gate 		return (EACCES);
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate 	bgep = ksp->ks_private;
2028eb6c4f9Sly149593 	if (bgep->chipid.statistic_type == BGE_STAT_BLK)
2037c478bd9Sstevel@tonic-gate 		bstp = DMA_VPTR(bgep->statistics);
2048eb6c4f9Sly149593 
2057c478bd9Sstevel@tonic-gate 	knp = ksp->ks_data;
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	/*
2087c478bd9Sstevel@tonic-gate 	 * Transfer the statistics values from the copy that the
2097c478bd9Sstevel@tonic-gate 	 * chip updates via DMA to the named-kstat structure.
2107c478bd9Sstevel@tonic-gate 	 *
2117c478bd9Sstevel@tonic-gate 	 * As above, we don't bother to sync or stop updates to the
2127c478bd9Sstevel@tonic-gate 	 * statistics, 'cos it doesn't really matter if they're a few
213256e438eSzh199473 	 * microseconds out of date or less than 100% consistent ...
2147c478bd9Sstevel@tonic-gate 	 */
2158eb6c4f9Sly149593 	if (bgep->chipid.statistic_type == BGE_STAT_BLK)
2167c478bd9Sstevel@tonic-gate 		for (ksip = bge_statistics; ksip->name != NULL; ++knp, ++ksip)
2177c478bd9Sstevel@tonic-gate 			knp->value.ui64 = bstp->a[ksip->index];
2188eb6c4f9Sly149593 	else {
219931dca7dSgs150176 		pstats = bgep->pstats;
220931dca7dSgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->ifHCOutOctets);
221931dca7dSgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->etherStatsCollisions);
222931dca7dSgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->outXonSent);
223931dca7dSgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->outXoffSent);
2248eb6c4f9Sly149593 		(knp++)->value.ui64 =
225931dca7dSgs150176 		    (uint64_t)(pstats->dot3StatsInternalMacTransmitErrors);
2268eb6c4f9Sly149593 		(knp++)->value.ui64 =
227931dca7dSgs150176 		    (uint64_t)(pstats->dot3StatsSingleCollisionFrames);
2288eb6c4f9Sly149593 		(knp++)->value.ui64 =
229931dca7dSgs150176 		    (uint64_t)(pstats->dot3StatsMultipleCollisionFrames);
2308eb6c4f9Sly149593 		(knp++)->value.ui64 =
231931dca7dSgs150176 		    (uint64_t)(pstats->dot3StatsDeferredTransmissions);
2328eb6c4f9Sly149593 		(knp++)->value.ui64 =
233931dca7dSgs150176 		    (uint64_t)(pstats->dot3StatsExcessiveCollisions);
2348eb6c4f9Sly149593 		(knp++)->value.ui64 =
235931dca7dSgs150176 		    (uint64_t)(pstats->dot3StatsLateCollisions);
236931dca7dSgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->ifHCOutUcastPkts);
237931dca7dSgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->ifHCOutMulticastPkts);
238931dca7dSgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->ifHCOutBroadcastPkts);
239931dca7dSgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->ifHCInOctets);
240931dca7dSgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->etherStatsFragments);
241931dca7dSgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->ifHCInUcastPkts);
242931dca7dSgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->ifHCInMulticastPkts);
243931dca7dSgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->ifHCInBroadcastPkts);
244931dca7dSgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->dot3StatsFCSErrors);
2458eb6c4f9Sly149593 		(knp++)->value.ui64 =
246931dca7dSgs150176 		    (uint64_t)(pstats->dot3StatsAlignmentErrors);
2478eb6c4f9Sly149593 		(knp++)->value.ui64 =
248931dca7dSgs150176 		    (uint64_t)(pstats->xonPauseFramesReceived);
2498eb6c4f9Sly149593 		(knp++)->value.ui64 =
250931dca7dSgs150176 		    (uint64_t)(pstats->xoffPauseFramesReceived);
2518eb6c4f9Sly149593 		(knp++)->value.ui64 =
252931dca7dSgs150176 		    (uint64_t)(pstats->macControlFramesReceived);
253931dca7dSgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->xoffStateEntered);
2548eb6c4f9Sly149593 		(knp++)->value.ui64 =
255931dca7dSgs150176 		    (uint64_t)(pstats->dot3StatsFrameTooLongs);
256931dca7dSgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->etherStatsJabbers);
2578eb6c4f9Sly149593 		(knp++)->value.ui64 =
258931dca7dSgs150176 		    (uint64_t)(pstats->etherStatsUndersizePkts);
2598eb6c4f9Sly149593 	}
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate 	return (0);
2627c478bd9Sstevel@tonic-gate }
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate static const bge_ksindex_t bge_chipid[] = {
2657c478bd9Sstevel@tonic-gate 	{ 0,				"asic_rev"		},
2667c478bd9Sstevel@tonic-gate 	{ 1,				"businfo"		},
2677c478bd9Sstevel@tonic-gate 	{ 2,				"command"		},
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate 	{ 3,				"vendor_id"		},
2707c478bd9Sstevel@tonic-gate 	{ 4,				"device_id"		},
2717c478bd9Sstevel@tonic-gate 	{ 5,				"subsystem_vendor_id"	},
2727c478bd9Sstevel@tonic-gate 	{ 6,				"subsystem_device_id"	},
2737c478bd9Sstevel@tonic-gate 	{ 7,				"revision_id"		},
2747c478bd9Sstevel@tonic-gate 	{ 8,				"cache_line_size"	},
2757c478bd9Sstevel@tonic-gate 	{ 9,				"latency_timer"		},
2767c478bd9Sstevel@tonic-gate 
2777c478bd9Sstevel@tonic-gate 	{ 10,				"flags"			},
2787c478bd9Sstevel@tonic-gate 	{ 11,				"chip_type"		},
2797c478bd9Sstevel@tonic-gate 	{ 12,				"mbuf_base"		},
2807c478bd9Sstevel@tonic-gate 	{ 13,				"mbuf_count"		},
2817c478bd9Sstevel@tonic-gate 	{ 14,				"hw_mac_addr"		},
2827c478bd9Sstevel@tonic-gate 
2837c478bd9Sstevel@tonic-gate 	{ 15,				"&bus_type"		},
2847c478bd9Sstevel@tonic-gate 	{ 16,				"&bus_speed"		},
2857c478bd9Sstevel@tonic-gate 	{ 17,				"&bus_size"		},
2867c478bd9Sstevel@tonic-gate 	{ 18,				"&supported"		},
2877c478bd9Sstevel@tonic-gate 	{ 19,				"&interface"		},
2887c478bd9Sstevel@tonic-gate 
2897c478bd9Sstevel@tonic-gate 	{ -1,				NULL 			}
2907c478bd9Sstevel@tonic-gate };
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate static void
2937c478bd9Sstevel@tonic-gate bge_set_char_kstat(kstat_named_t *knp, const char *s)
2947c478bd9Sstevel@tonic-gate {
2957c478bd9Sstevel@tonic-gate 	(void) strncpy(knp->value.c, s, sizeof (knp->value.c));
2967c478bd9Sstevel@tonic-gate }
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate static int
2997c478bd9Sstevel@tonic-gate bge_chipid_update(kstat_t *ksp, int flag)
3007c478bd9Sstevel@tonic-gate {
3017c478bd9Sstevel@tonic-gate 	bge_t *bgep;
3027c478bd9Sstevel@tonic-gate 	kstat_named_t *knp;
3037c478bd9Sstevel@tonic-gate 	uint64_t tmp;
3047c478bd9Sstevel@tonic-gate 
3057c478bd9Sstevel@tonic-gate 	if (flag != KSTAT_READ)
3067c478bd9Sstevel@tonic-gate 		return (EACCES);
3077c478bd9Sstevel@tonic-gate 
3087c478bd9Sstevel@tonic-gate 	bgep = ksp->ks_private;
3097c478bd9Sstevel@tonic-gate 	knp = ksp->ks_data;
3107c478bd9Sstevel@tonic-gate 
3117c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.asic_rev;
3127c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.businfo;
3137c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.command;
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.vendor;
3167c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.device;
3177c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.subven;
3187c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.subdev;
3197c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.revision;
3207c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.clsize;
3217c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.latency;
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.flags;
3247c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.chip_label;
3257c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.mbuf_base;
3267c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.mbuf_length;
3277c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.hw_mac_addr;
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate 	/*
3307c478bd9Sstevel@tonic-gate 	 * Now we interpret some of the above into readable strings
3317c478bd9Sstevel@tonic-gate 	 */
3327c478bd9Sstevel@tonic-gate 	tmp = bgep->chipid.businfo;
3337c478bd9Sstevel@tonic-gate 	bge_set_char_kstat(knp++,
3347c478bd9Sstevel@tonic-gate 	    tmp & PCISTATE_BUS_IS_PCI ? "PCI" : "PCI-X");
3357c478bd9Sstevel@tonic-gate 	bge_set_char_kstat(knp++,
3367c478bd9Sstevel@tonic-gate 	    tmp & PCISTATE_BUS_IS_FAST ? "fast" : "normal");
3377c478bd9Sstevel@tonic-gate 	bge_set_char_kstat(knp++,
3387c478bd9Sstevel@tonic-gate 	    tmp & PCISTATE_BUS_IS_32_BIT ? "32 bit" : "64 bit");
3397c478bd9Sstevel@tonic-gate 
3407c478bd9Sstevel@tonic-gate 	tmp = bgep->chipid.flags;
3417c478bd9Sstevel@tonic-gate 	bge_set_char_kstat(knp++,
3427c478bd9Sstevel@tonic-gate 	    tmp & CHIP_FLAG_SUPPORTED ? "yes" : "no");
3437c478bd9Sstevel@tonic-gate 	bge_set_char_kstat(knp++,
3447c478bd9Sstevel@tonic-gate 	    tmp & CHIP_FLAG_SERDES ? "serdes" : "copper");
3457c478bd9Sstevel@tonic-gate 
3467c478bd9Sstevel@tonic-gate 	return (0);
3477c478bd9Sstevel@tonic-gate }
3487c478bd9Sstevel@tonic-gate 
3497c478bd9Sstevel@tonic-gate static const bge_ksindex_t bge_driverinfo[] = {
3507c478bd9Sstevel@tonic-gate 	{ 0,				"rx_buff_addr"		},
3517c478bd9Sstevel@tonic-gate 	{ 1,				"tx_buff_addr"		},
3527c478bd9Sstevel@tonic-gate 	{ 2,				"rx_desc_addr"		},
3537c478bd9Sstevel@tonic-gate 	{ 3,				"tx_desc_addr"		},
3547c478bd9Sstevel@tonic-gate 
3557c478bd9Sstevel@tonic-gate 	{ 4,				"tx_desc_free"		},
356931dca7dSgs150176 	{ 5,				"tx_array"		},
357931dca7dSgs150176 	{ 6,				"tc_next"		},
358931dca7dSgs150176 	{ 7,				"tx_next"		},
359931dca7dSgs150176 	{ 8,				"txfill_next"		},
360931dca7dSgs150176 	{ 9,				"txpkt_next"		},
361931dca7dSgs150176 	{ 10,				"tx_bufs"		},
362931dca7dSgs150176 	{ 11,				"tx_flow"		},
363931dca7dSgs150176 	{ 12,				"tx_resched_needed"	},
364931dca7dSgs150176 	{ 13,				"tx_resched"		},
365931dca7dSgs150176 	{ 14,				"tx_nobuf"		},
366931dca7dSgs150176 	{ 15,				"tx_nobd"		},
367931dca7dSgs150176 	{ 16,				"tx_block"		},
368931dca7dSgs150176 	{ 17,				"tx_alloc_fail"		},
3697c478bd9Sstevel@tonic-gate 
370931dca7dSgs150176 	{ 18,				"watchdog"		},
371931dca7dSgs150176 	{ 19,				"chip_resets"		},
372931dca7dSgs150176 	{ 20,				"dma_misses"		},
3735952d588Szh199473 	{ 21,				"update_misses"		},
3747c478bd9Sstevel@tonic-gate 
3755952d588Szh199473 	{ 22,				"misc_host_config"	},
3765952d588Szh199473 	{ 23,				"dma_rw_control"	},
3775952d588Szh199473 	{ 24,				"pci_bus_info"		},
378931dca7dSgs150176 
3795952d588Szh199473 	{ 25,				"buff_mgr_status"	},
3805952d588Szh199473 	{ 26,				"rcv_init_status"	},
3817c478bd9Sstevel@tonic-gate 
3827c478bd9Sstevel@tonic-gate 	{ -1,				NULL 			}
3837c478bd9Sstevel@tonic-gate };
3847c478bd9Sstevel@tonic-gate 
3857c478bd9Sstevel@tonic-gate static int
3867c478bd9Sstevel@tonic-gate bge_driverinfo_update(kstat_t *ksp, int flag)
3877c478bd9Sstevel@tonic-gate {
3887c478bd9Sstevel@tonic-gate 	bge_t *bgep;
3897c478bd9Sstevel@tonic-gate 	kstat_named_t *knp;
3907c478bd9Sstevel@tonic-gate 	ddi_acc_handle_t handle;
3917c478bd9Sstevel@tonic-gate 
3927c478bd9Sstevel@tonic-gate 	if (flag != KSTAT_READ)
3937c478bd9Sstevel@tonic-gate 		return (EACCES);
3947c478bd9Sstevel@tonic-gate 
3957c478bd9Sstevel@tonic-gate 	bgep = ksp->ks_private;
39600d0963fSdilpreet 	if (bgep->bge_chip_state == BGE_CHIP_FAULT)
39700d0963fSdilpreet 		return (EIO);
39800d0963fSdilpreet 
3997c478bd9Sstevel@tonic-gate 	knp = ksp->ks_data;
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->rx_buff[0].cookie.dmac_laddress;
4027c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->tx_buff[0].cookie.dmac_laddress;
4037c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->rx_desc[0].cookie.dmac_laddress;
4047c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->tx_desc.cookie.dmac_laddress;
4057c478bd9Sstevel@tonic-gate 
4067c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->send[0].tx_free;
407931dca7dSgs150176 	(knp++)->value.ui64 = bgep->send[0].tx_array;
408931dca7dSgs150176 	(knp++)->value.ui64 = bgep->send[0].tc_next;
409931dca7dSgs150176 	(knp++)->value.ui64 = bgep->send[0].tx_next;
410931dca7dSgs150176 	(knp++)->value.ui64 = bgep->send[0].txfill_next;
411931dca7dSgs150176 	(knp++)->value.ui64 = bgep->send[0].txpkt_next;
412931dca7dSgs150176 	(knp++)->value.ui64 = bgep->send[0].txbuf_pop_queue->count +
413931dca7dSgs150176 	    bgep->send[0].txbuf_push_queue->count;
414931dca7dSgs150176 	(knp++)->value.ui64 = bgep->send[0].tx_flow;
415931dca7dSgs150176 	(knp++)->value.ui64 = bgep->tx_resched_needed;
416931dca7dSgs150176 	(knp++)->value.ui64 = bgep->tx_resched;
417931dca7dSgs150176 	(knp++)->value.ui64 = bgep->send[0].tx_nobuf;
418931dca7dSgs150176 	(knp++)->value.ui64 = bgep->send[0].tx_nobd;
419931dca7dSgs150176 	(knp++)->value.ui64 = bgep->send[0].tx_block;
420931dca7dSgs150176 	(knp++)->value.ui64 = bgep->send[0].tx_alloc_fail;
421931dca7dSgs150176 
4227c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->watchdog;
4237c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chip_resets;
4247c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->missed_dmas;
4255952d588Szh199473 	(knp++)->value.ui64 = bgep->missed_updates;
4267c478bd9Sstevel@tonic-gate 
4277c478bd9Sstevel@tonic-gate 	/*
4287c478bd9Sstevel@tonic-gate 	 * Hold the mutex while accessing the chip registers
4297c478bd9Sstevel@tonic-gate 	 * just in case the factotum is trying to reset it!
4307c478bd9Sstevel@tonic-gate 	 */
4317c478bd9Sstevel@tonic-gate 	handle = bgep->cfg_handle;
4327c478bd9Sstevel@tonic-gate 	mutex_enter(bgep->genlock);
4337c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = pci_config_get32(handle, PCI_CONF_BGE_MHCR);
4347c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = pci_config_get32(handle, PCI_CONF_BGE_PDRWCR);
4357c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = pci_config_get32(handle, PCI_CONF_BGE_PCISTATE);
43600d0963fSdilpreet 	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
43700d0963fSdilpreet 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
43800d0963fSdilpreet 		mutex_exit(bgep->genlock);
43900d0963fSdilpreet 		return (EIO);
44000d0963fSdilpreet 	}
4417c478bd9Sstevel@tonic-gate 
4427c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bge_reg_get32(bgep, BUFFER_MANAGER_STATUS_REG);
4437c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bge_reg_get32(bgep, RCV_INITIATOR_STATUS_REG);
44400d0963fSdilpreet 	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
44500d0963fSdilpreet 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
44600d0963fSdilpreet 		mutex_exit(bgep->genlock);
44700d0963fSdilpreet 		return (EIO);
44800d0963fSdilpreet 	}
4497c478bd9Sstevel@tonic-gate 	mutex_exit(bgep->genlock);
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate 	return (0);
4527c478bd9Sstevel@tonic-gate }
4537c478bd9Sstevel@tonic-gate 
4547c478bd9Sstevel@tonic-gate static const bge_ksindex_t bge_serdes[] = {
4557c478bd9Sstevel@tonic-gate 	{ 0,				"serdes_status"		},
4567c478bd9Sstevel@tonic-gate 	{ 1,				"serdes_advert"		},
4577c478bd9Sstevel@tonic-gate 	{ 2,				"serdes_lpadv"		},
4587c478bd9Sstevel@tonic-gate 
4597c478bd9Sstevel@tonic-gate 	{ -1,				NULL }
4607c478bd9Sstevel@tonic-gate };
4617c478bd9Sstevel@tonic-gate 
4627c478bd9Sstevel@tonic-gate static int
4637c478bd9Sstevel@tonic-gate bge_serdes_update(kstat_t *ksp, int flag)
4647c478bd9Sstevel@tonic-gate {
4657c478bd9Sstevel@tonic-gate 	bge_t *bgep;
4667c478bd9Sstevel@tonic-gate 	kstat_named_t *knp;
4677c478bd9Sstevel@tonic-gate 
4687c478bd9Sstevel@tonic-gate 	if (flag != KSTAT_READ)
4697c478bd9Sstevel@tonic-gate 		return (EACCES);
4707c478bd9Sstevel@tonic-gate 
4717c478bd9Sstevel@tonic-gate 	bgep = ksp->ks_private;
4727c478bd9Sstevel@tonic-gate 	knp = ksp->ks_data;
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->serdes_status;
4757c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->serdes_advert;
4767c478bd9Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->serdes_lpadv;
4777c478bd9Sstevel@tonic-gate 
4787c478bd9Sstevel@tonic-gate 	return (0);
4797c478bd9Sstevel@tonic-gate }
4807c478bd9Sstevel@tonic-gate 
4817c478bd9Sstevel@tonic-gate static const bge_ksindex_t bge_phydata[] = {
4827c478bd9Sstevel@tonic-gate 	{ MII_CONTROL,			"mii_control"		},
4837c478bd9Sstevel@tonic-gate 	{ MII_STATUS,			"mii_status"		},
4847c478bd9Sstevel@tonic-gate 	{ MII_PHYIDH,			"phy_identifier"	},
4857c478bd9Sstevel@tonic-gate 	{ MII_AN_ADVERT,		"an_advert"		},
4867c478bd9Sstevel@tonic-gate 	{ MII_AN_LPABLE,		"an_lp_ability"		},
4877c478bd9Sstevel@tonic-gate 	{ MII_AN_EXPANSION,		"an_expansion"		},
488*bdb9230aSGarrett D'Amore 	{ MII_AN_NXTPGLP,		"an_lp_nextpage"	},
489*bdb9230aSGarrett D'Amore 	{ MII_MSCONTROL,		"gbit_control"		},
490*bdb9230aSGarrett D'Amore 	{ MII_MSSTATUS,			"gbit_status"		},
491*bdb9230aSGarrett D'Amore 	{ MII_EXTSTATUS,		"ieee_ext_status"	},
4927c478bd9Sstevel@tonic-gate 	{ MII_EXT_CONTROL,		"phy_ext_control"	},
4937c478bd9Sstevel@tonic-gate 	{ MII_EXT_STATUS,		"phy_ext_status"	},
4947c478bd9Sstevel@tonic-gate 	{ MII_RCV_ERR_COUNT,		"receive_error_count"	},
4957c478bd9Sstevel@tonic-gate 	{ MII_FALSE_CARR_COUNT,		"false_carrier_count"	},
4967c478bd9Sstevel@tonic-gate 	{ MII_RCV_NOT_OK_COUNT,		"receiver_not_ok_count"	},
4977c478bd9Sstevel@tonic-gate 	{ MII_AUX_CONTROL,		"aux_control"		},
4987c478bd9Sstevel@tonic-gate 	{ MII_AUX_STATUS,		"aux_status"		},
4997c478bd9Sstevel@tonic-gate 	{ MII_INTR_STATUS,		"intr_status"		},
5007c478bd9Sstevel@tonic-gate 	{ MII_INTR_MASK,		"intr_mask"		},
5017c478bd9Sstevel@tonic-gate 	{ MII_HCD_STATUS,		"hcd_status"		},
5027c478bd9Sstevel@tonic-gate 
5037c478bd9Sstevel@tonic-gate 	{ -1,				NULL }
5047c478bd9Sstevel@tonic-gate };
5057c478bd9Sstevel@tonic-gate 
5067c478bd9Sstevel@tonic-gate static int
5077c478bd9Sstevel@tonic-gate bge_phydata_update(kstat_t *ksp, int flag)
5087c478bd9Sstevel@tonic-gate {
5097c478bd9Sstevel@tonic-gate 	bge_t *bgep;
5107c478bd9Sstevel@tonic-gate 	kstat_named_t *knp;
5117c478bd9Sstevel@tonic-gate 	const bge_ksindex_t *ksip;
5127c478bd9Sstevel@tonic-gate 
5137c478bd9Sstevel@tonic-gate 	if (flag != KSTAT_READ)
5147c478bd9Sstevel@tonic-gate 		return (EACCES);
5157c478bd9Sstevel@tonic-gate 
5167c478bd9Sstevel@tonic-gate 	bgep = ksp->ks_private;
51700d0963fSdilpreet 	if (bgep->bge_chip_state == BGE_CHIP_FAULT)
51800d0963fSdilpreet 		return (EIO);
51900d0963fSdilpreet 
5207c478bd9Sstevel@tonic-gate 	knp = ksp->ks_data;
5217c478bd9Sstevel@tonic-gate 
5227c478bd9Sstevel@tonic-gate 	/*
5237c478bd9Sstevel@tonic-gate 	 * Read the PHY registers & update the kstats ...
5247c478bd9Sstevel@tonic-gate 	 *
5257c478bd9Sstevel@tonic-gate 	 * We need to hold the mutex while performing MII reads, but
5267c478bd9Sstevel@tonic-gate 	 * we don't want to hold it across the entire sequence of reads.
5277c478bd9Sstevel@tonic-gate 	 * So we grab and release it on each iteration, 'cos it doesn't
5287c478bd9Sstevel@tonic-gate 	 * really matter if the kstats are less than 100% consistent ...
5297c478bd9Sstevel@tonic-gate 	 */
5307c478bd9Sstevel@tonic-gate 	for (ksip = bge_phydata; ksip->name != NULL; ++knp, ++ksip) {
5317c478bd9Sstevel@tonic-gate 		mutex_enter(bgep->genlock);
5327c478bd9Sstevel@tonic-gate 		switch (ksip->index) {
5337c478bd9Sstevel@tonic-gate 		case MII_STATUS:
5347c478bd9Sstevel@tonic-gate 			knp->value.ui64 = bgep->phy_gen_status;
5357c478bd9Sstevel@tonic-gate 			break;
5367c478bd9Sstevel@tonic-gate 
5377c478bd9Sstevel@tonic-gate 		case MII_PHYIDH:
5387c478bd9Sstevel@tonic-gate 			knp->value.ui64 = bge_mii_get16(bgep, MII_PHYIDH);
5397c478bd9Sstevel@tonic-gate 			knp->value.ui64 <<= 16;
5407c478bd9Sstevel@tonic-gate 			knp->value.ui64 |= bge_mii_get16(bgep, MII_PHYIDL);
5417c478bd9Sstevel@tonic-gate 			break;
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate 		default:
5447c478bd9Sstevel@tonic-gate 			knp->value.ui64 = bge_mii_get16(bgep, ksip->index);
5457c478bd9Sstevel@tonic-gate 			break;
5467c478bd9Sstevel@tonic-gate 		}
54700d0963fSdilpreet 		if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
54800d0963fSdilpreet 			ddi_fm_service_impact(bgep->devinfo,
54900d0963fSdilpreet 			    DDI_SERVICE_DEGRADED);
55000d0963fSdilpreet 			mutex_exit(bgep->genlock);
55100d0963fSdilpreet 			return (EIO);
55200d0963fSdilpreet 		}
5537c478bd9Sstevel@tonic-gate 		mutex_exit(bgep->genlock);
5547c478bd9Sstevel@tonic-gate 	}
5557c478bd9Sstevel@tonic-gate 
5567c478bd9Sstevel@tonic-gate 	return (0);
5577c478bd9Sstevel@tonic-gate }
5587c478bd9Sstevel@tonic-gate 
5597c478bd9Sstevel@tonic-gate static kstat_t *
5607c478bd9Sstevel@tonic-gate bge_setup_named_kstat(bge_t *bgep, int instance, char *name,
5617c478bd9Sstevel@tonic-gate 	const bge_ksindex_t *ksip, size_t size, int (*update)(kstat_t *, int))
5627c478bd9Sstevel@tonic-gate {
5637c478bd9Sstevel@tonic-gate 	kstat_t *ksp;
5647c478bd9Sstevel@tonic-gate 	kstat_named_t *knp;
5657c478bd9Sstevel@tonic-gate 	char *np;
5667c478bd9Sstevel@tonic-gate 	int type;
5677c478bd9Sstevel@tonic-gate 
5687c478bd9Sstevel@tonic-gate 	size /= sizeof (bge_ksindex_t);
5697c478bd9Sstevel@tonic-gate 	ksp = kstat_create(BGE_DRIVER_NAME, instance, name, "net",
5707c478bd9Sstevel@tonic-gate 	    KSTAT_TYPE_NAMED, size-1, KSTAT_FLAG_PERSISTENT);
5717c478bd9Sstevel@tonic-gate 	if (ksp == NULL)
5727c478bd9Sstevel@tonic-gate 		return (NULL);
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate 	ksp->ks_private = bgep;
5757c478bd9Sstevel@tonic-gate 	ksp->ks_update = update;
5767c478bd9Sstevel@tonic-gate 	for (knp = ksp->ks_data; (np = ksip->name) != NULL; ++knp, ++ksip) {
5777c478bd9Sstevel@tonic-gate 		switch (*np) {
5787c478bd9Sstevel@tonic-gate 		default:
5797c478bd9Sstevel@tonic-gate 			type = KSTAT_DATA_UINT64;
5807c478bd9Sstevel@tonic-gate 			break;
5817c478bd9Sstevel@tonic-gate 		case '%':
5827c478bd9Sstevel@tonic-gate 			np += 1;
5837c478bd9Sstevel@tonic-gate 			type = KSTAT_DATA_UINT32;
5847c478bd9Sstevel@tonic-gate 			break;
5857c478bd9Sstevel@tonic-gate 		case '$':
5867c478bd9Sstevel@tonic-gate 			np += 1;
5877c478bd9Sstevel@tonic-gate 			type = KSTAT_DATA_STRING;
5887c478bd9Sstevel@tonic-gate 			break;
5897c478bd9Sstevel@tonic-gate 		case '&':
5907c478bd9Sstevel@tonic-gate 			np += 1;
5917c478bd9Sstevel@tonic-gate 			type = KSTAT_DATA_CHAR;
5927c478bd9Sstevel@tonic-gate 			break;
5937c478bd9Sstevel@tonic-gate 		}
5947c478bd9Sstevel@tonic-gate 		kstat_named_init(knp, np, type);
5957c478bd9Sstevel@tonic-gate 	}
5967c478bd9Sstevel@tonic-gate 	kstat_install(ksp);
5977c478bd9Sstevel@tonic-gate 
5987c478bd9Sstevel@tonic-gate 	return (ksp);
5997c478bd9Sstevel@tonic-gate }
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate void
6027c478bd9Sstevel@tonic-gate bge_init_kstats(bge_t *bgep, int instance)
6037c478bd9Sstevel@tonic-gate {
6047c478bd9Sstevel@tonic-gate 	kstat_t *ksp;
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate 	BGE_TRACE(("bge_init_kstats($%p, %d)", (void *)bgep, instance));
6077c478bd9Sstevel@tonic-gate 
6088eb6c4f9Sly149593 	if (bgep->chipid.statistic_type == BGE_STAT_BLK) {
6097c478bd9Sstevel@tonic-gate 		DMA_ZERO(bgep->statistics);
6108eb6c4f9Sly149593 		bgep->bge_kstats[BGE_KSTAT_RAW] = ksp =
6118eb6c4f9Sly149593 		    kstat_create(BGE_DRIVER_NAME, instance,
6128eb6c4f9Sly149593 		    "raw_statistics", "net", KSTAT_TYPE_RAW,
6137c478bd9Sstevel@tonic-gate 		    sizeof (bge_statistics_t), KSTAT_FLAG_VIRTUAL);
6147c478bd9Sstevel@tonic-gate 		if (ksp != NULL) {
6157c478bd9Sstevel@tonic-gate 			ksp->ks_data = DMA_VPTR(bgep->statistics);
6167c478bd9Sstevel@tonic-gate 			kstat_install(ksp);
6177c478bd9Sstevel@tonic-gate 		}
6187c478bd9Sstevel@tonic-gate 
6197c478bd9Sstevel@tonic-gate 		bgep->bge_kstats[BGE_KSTAT_STATS] = bge_setup_named_kstat(bgep,
6207c478bd9Sstevel@tonic-gate 		    instance, "statistics", bge_statistics,
6217c478bd9Sstevel@tonic-gate 		    sizeof (bge_statistics), bge_statistics_update);
6228eb6c4f9Sly149593 	} else {
6238eb6c4f9Sly149593 		bgep->bge_kstats[BGE_KSTAT_STATS] = bge_setup_named_kstat(bgep,
6248eb6c4f9Sly149593 		    instance, "statistics", bge_stat_val,
6258eb6c4f9Sly149593 		    sizeof (bge_stat_val), bge_statistics_update);
6268eb6c4f9Sly149593 	}
6277c478bd9Sstevel@tonic-gate 
6287c478bd9Sstevel@tonic-gate 	bgep->bge_kstats[BGE_KSTAT_CHIPID] = bge_setup_named_kstat(bgep,
6297c478bd9Sstevel@tonic-gate 	    instance, "chipid", bge_chipid,
6307c478bd9Sstevel@tonic-gate 	    sizeof (bge_chipid), bge_chipid_update);
6317c478bd9Sstevel@tonic-gate 
6327c478bd9Sstevel@tonic-gate 	bgep->bge_kstats[BGE_KSTAT_DRIVER] = bge_setup_named_kstat(bgep,
6337c478bd9Sstevel@tonic-gate 	    instance, "driverinfo", bge_driverinfo,
6347c478bd9Sstevel@tonic-gate 	    sizeof (bge_driverinfo), bge_driverinfo_update);
6357c478bd9Sstevel@tonic-gate 
6367c478bd9Sstevel@tonic-gate 	if (bgep->chipid.flags & CHIP_FLAG_SERDES)
6377c478bd9Sstevel@tonic-gate 		bgep->bge_kstats[BGE_KSTAT_PHYS] = bge_setup_named_kstat(bgep,
6387c478bd9Sstevel@tonic-gate 		    instance, "serdes", bge_serdes,
6397c478bd9Sstevel@tonic-gate 		    sizeof (bge_serdes), bge_serdes_update);
6407c478bd9Sstevel@tonic-gate 	else
6417c478bd9Sstevel@tonic-gate 		bgep->bge_kstats[BGE_KSTAT_PHYS] = bge_setup_named_kstat(bgep,
6427c478bd9Sstevel@tonic-gate 		    instance, "phydata", bge_phydata,
6437c478bd9Sstevel@tonic-gate 		    sizeof (bge_phydata), bge_phydata_update);
6447c478bd9Sstevel@tonic-gate 
6457c478bd9Sstevel@tonic-gate }
6467c478bd9Sstevel@tonic-gate 
6477c478bd9Sstevel@tonic-gate void
6487c478bd9Sstevel@tonic-gate bge_fini_kstats(bge_t *bgep)
6497c478bd9Sstevel@tonic-gate {
6507c478bd9Sstevel@tonic-gate 	int i;
6517c478bd9Sstevel@tonic-gate 
6527c478bd9Sstevel@tonic-gate 	BGE_TRACE(("bge_fini_kstats($%p)", (void *)bgep));
6537c478bd9Sstevel@tonic-gate 
6547c478bd9Sstevel@tonic-gate 	for (i = BGE_KSTAT_COUNT; --i >= 0; )
6557c478bd9Sstevel@tonic-gate 		if (bgep->bge_kstats[i] != NULL)
6567c478bd9Sstevel@tonic-gate 			kstat_delete(bgep->bge_kstats[i]);
6577c478bd9Sstevel@tonic-gate }
6587c478bd9Sstevel@tonic-gate 
659ba2e4443Sseb int
660ba2e4443Sseb bge_m_stat(void *arg, uint_t stat, uint64_t *val)
6617c478bd9Sstevel@tonic-gate {
6627c478bd9Sstevel@tonic-gate 	bge_t *bgep = arg;
6638eb6c4f9Sly149593 	bge_statistics_t *bstp;
664931dca7dSgs150176 	bge_statistics_reg_t *pstats;
6657c478bd9Sstevel@tonic-gate 
66600d0963fSdilpreet 	if (bgep->bge_chip_state == BGE_CHIP_FAULT) {
667ba2e4443Sseb 		return (EINVAL);
668ba2e4443Sseb 	}
669ba2e4443Sseb 
6708eb6c4f9Sly149593 	if (bgep->chipid.statistic_type == BGE_STAT_BLK)
6718eb6c4f9Sly149593 		bstp = DMA_VPTR(bgep->statistics);
6728eb6c4f9Sly149593 	else {
673931dca7dSgs150176 		pstats = bgep->pstats;
674931dca7dSgs150176 		pstats->ifHCOutOctets +=
6758eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_IFHCOUT_OCTETS_REG);
676931dca7dSgs150176 		pstats->etherStatsCollisions +=
6778eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_ETHER_COLLIS_REG);
678931dca7dSgs150176 		pstats->outXonSent +=
6798eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_OUTXON_SENT_REG);
680931dca7dSgs150176 		pstats->outXoffSent +=
6818eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_OUTXOFF_SENT_REG);
682931dca7dSgs150176 		pstats->dot3StatsInternalMacTransmitErrors +=
6838eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_DOT3_INTMACTX_ERR_REG);
684931dca7dSgs150176 		pstats->dot3StatsSingleCollisionFrames +=
6858eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_DOT3_SCOLLI_FRAME_REG);
686931dca7dSgs150176 		pstats->dot3StatsMultipleCollisionFrames +=
6878eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_DOT3_MCOLLI_FRAME_REG);
688931dca7dSgs150176 		pstats->dot3StatsDeferredTransmissions +=
6898eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_DOT3_DEFERED_TX_REG);
690931dca7dSgs150176 		pstats->dot3StatsExcessiveCollisions +=
6918eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_DOT3_EXCE_COLLI_REG);
692931dca7dSgs150176 		pstats->dot3StatsLateCollisions +=
6938eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_DOT3_LATE_COLLI_REG);
694931dca7dSgs150176 		pstats->ifHCOutUcastPkts +=
6958eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_IFHCOUT_UPKGS_REG);
696931dca7dSgs150176 		pstats->ifHCOutMulticastPkts +=
6978eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_IFHCOUT_MPKGS_REG);
698931dca7dSgs150176 		pstats->ifHCOutBroadcastPkts +=
6998eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_IFHCOUT_BPKGS_REG);
700931dca7dSgs150176 		pstats->ifHCInOctets +=
7018eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_IFHCIN_OCTETS_REG);
702931dca7dSgs150176 		pstats->etherStatsFragments +=
7038eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_ETHER_FRAGMENT_REG);
704931dca7dSgs150176 		pstats->ifHCInUcastPkts +=
7058eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_IFHCIN_UPKGS_REG);
706931dca7dSgs150176 		pstats->ifHCInMulticastPkts +=
7078eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_IFHCIN_MPKGS_REG);
708931dca7dSgs150176 		pstats->ifHCInBroadcastPkts +=
7098eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_IFHCIN_BPKGS_REG);
710931dca7dSgs150176 		pstats->dot3StatsFCSErrors +=
7118eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_DOT3_FCS_ERR_REG);
712931dca7dSgs150176 		pstats->dot3StatsAlignmentErrors +=
7138eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_DOT3_ALIGN_ERR_REG);
714931dca7dSgs150176 		pstats->xonPauseFramesReceived +=
7158eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_XON_PAUSE_RX_REG);
716931dca7dSgs150176 		pstats->xoffPauseFramesReceived +=
7178eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_XOFF_PAUSE_RX_REG);
718931dca7dSgs150176 		pstats->macControlFramesReceived +=
7198eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_MAC_CTRL_RX_REG);
720931dca7dSgs150176 		pstats->xoffStateEntered +=
7218eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_XOFF_STATE_ENTER_REG);
722931dca7dSgs150176 		pstats->dot3StatsFrameTooLongs +=
7238eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_DOT3_FRAME_TOOLONG_REG);
724931dca7dSgs150176 		pstats->etherStatsJabbers +=
7258eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_ETHER_JABBERS_REG);
726931dca7dSgs150176 		pstats->etherStatsUndersizePkts +=
7278eb6c4f9Sly149593 		    bge_reg_get32(bgep, STAT_ETHER_UNDERSIZE_REG);
728f724721bSzh199473 		mutex_enter(bgep->genlock);
72900d0963fSdilpreet 		if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
73000d0963fSdilpreet 			ddi_fm_service_impact(bgep->devinfo,
73100d0963fSdilpreet 			    DDI_SERVICE_UNAFFECTED);
73200d0963fSdilpreet 		}
733f724721bSzh199473 		mutex_exit(bgep->genlock);
7348eb6c4f9Sly149593 	}
7358eb6c4f9Sly149593 
7367c478bd9Sstevel@tonic-gate 	switch (stat) {
7377c478bd9Sstevel@tonic-gate 	case MAC_STAT_IFSPEED:
738ba2e4443Sseb 		*val = bgep->param_link_speed * 1000000ull;
7397c478bd9Sstevel@tonic-gate 		break;
7407c478bd9Sstevel@tonic-gate 
7417c478bd9Sstevel@tonic-gate 	case MAC_STAT_MULTIRCV:
7428eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
743ba2e4443Sseb 			*val = bstp->s.ifHCInMulticastPkts;
7448eb6c4f9Sly149593 		else
745931dca7dSgs150176 			*val = pstats->ifHCInMulticastPkts;
7467c478bd9Sstevel@tonic-gate 		break;
7477c478bd9Sstevel@tonic-gate 
7487c478bd9Sstevel@tonic-gate 	case MAC_STAT_BRDCSTRCV:
7498eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
750ba2e4443Sseb 			*val = bstp->s.ifHCInBroadcastPkts;
7518eb6c4f9Sly149593 		else
752931dca7dSgs150176 			*val = pstats->ifHCInBroadcastPkts;
7537c478bd9Sstevel@tonic-gate 		break;
7547c478bd9Sstevel@tonic-gate 
7557c478bd9Sstevel@tonic-gate 	case MAC_STAT_MULTIXMT:
7568eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
757ba2e4443Sseb 			*val = bstp->s.ifHCOutMulticastPkts;
7588eb6c4f9Sly149593 		else
759931dca7dSgs150176 			*val = pstats->ifHCOutMulticastPkts;
7607c478bd9Sstevel@tonic-gate 		break;
7617c478bd9Sstevel@tonic-gate 
7627c478bd9Sstevel@tonic-gate 	case MAC_STAT_BRDCSTXMT:
7638eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
764ba2e4443Sseb 			*val = bstp->s.ifHCOutBroadcastPkts;
7658eb6c4f9Sly149593 		else
766931dca7dSgs150176 			*val = pstats->ifHCOutBroadcastPkts;
7677c478bd9Sstevel@tonic-gate 		break;
7687c478bd9Sstevel@tonic-gate 
7697c478bd9Sstevel@tonic-gate 	case MAC_STAT_NORCVBUF:
7708eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
771ba2e4443Sseb 			*val = bstp->s.ifInDiscards;
7728eb6c4f9Sly149593 		else
773ba2e4443Sseb 			*val = 0;
7747c478bd9Sstevel@tonic-gate 		break;
7757c478bd9Sstevel@tonic-gate 
7767c478bd9Sstevel@tonic-gate 	case MAC_STAT_IERRORS:
777ba2e4443Sseb 		if (bgep->chipid.statistic_type == BGE_STAT_BLK) {
778ba2e4443Sseb 			*val = bstp->s.dot3StatsFCSErrors +
7793c46fd93Szh199473 			    bstp->s.dot3StatsAlignmentErrors +
7803c46fd93Szh199473 			    bstp->s.dot3StatsFrameTooLongs +
7813c46fd93Szh199473 			    bstp->s.etherStatsUndersizePkts +
7823c46fd93Szh199473 			    bstp->s.etherStatsJabbers;
783ba2e4443Sseb 		} else {
784931dca7dSgs150176 			*val = pstats->dot3StatsFCSErrors +
785931dca7dSgs150176 			    pstats->dot3StatsAlignmentErrors +
786931dca7dSgs150176 			    pstats->dot3StatsFrameTooLongs +
787931dca7dSgs150176 			    pstats->etherStatsUndersizePkts +
788931dca7dSgs150176 			    pstats->etherStatsJabbers;
789ba2e4443Sseb 		}
7907c478bd9Sstevel@tonic-gate 		break;
7917c478bd9Sstevel@tonic-gate 
7927c478bd9Sstevel@tonic-gate 	case MAC_STAT_NOXMTBUF:
7938eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
794ba2e4443Sseb 			*val = bstp->s.ifOutDiscards;
7958eb6c4f9Sly149593 		else
796ba2e4443Sseb 			*val = 0;
7977c478bd9Sstevel@tonic-gate 		break;
7987c478bd9Sstevel@tonic-gate 
7997c478bd9Sstevel@tonic-gate 	case MAC_STAT_OERRORS:
8008eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
801ba2e4443Sseb 			*val = bstp->s.ifOutDiscards;
8028eb6c4f9Sly149593 		else
803ba2e4443Sseb 			*val = 0;
8047c478bd9Sstevel@tonic-gate 		break;
8057c478bd9Sstevel@tonic-gate 
8067c478bd9Sstevel@tonic-gate 	case MAC_STAT_COLLISIONS:
8078eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
808ba2e4443Sseb 			*val = bstp->s.etherStatsCollisions;
8098eb6c4f9Sly149593 		else
810931dca7dSgs150176 			*val = pstats->etherStatsCollisions;
8117c478bd9Sstevel@tonic-gate 		break;
8127c478bd9Sstevel@tonic-gate 
8137c478bd9Sstevel@tonic-gate 	case MAC_STAT_RBYTES:
8148eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
815ba2e4443Sseb 			*val = bstp->s.ifHCInOctets;
8168eb6c4f9Sly149593 		else
817931dca7dSgs150176 			*val = pstats->ifHCInOctets;
8187c478bd9Sstevel@tonic-gate 		break;
8197c478bd9Sstevel@tonic-gate 
8207c478bd9Sstevel@tonic-gate 	case MAC_STAT_IPACKETS:
8218eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
822ba2e4443Sseb 			*val = bstp->s.ifHCInUcastPkts +
8237c478bd9Sstevel@tonic-gate 			    bstp->s.ifHCInMulticastPkts +
8247c478bd9Sstevel@tonic-gate 			    bstp->s.ifHCInBroadcastPkts;
8258eb6c4f9Sly149593 		else
826931dca7dSgs150176 			*val = pstats->ifHCInUcastPkts +
827931dca7dSgs150176 			    pstats->ifHCInMulticastPkts +
828931dca7dSgs150176 			    pstats->ifHCInBroadcastPkts;
8297c478bd9Sstevel@tonic-gate 		break;
8307c478bd9Sstevel@tonic-gate 
8317c478bd9Sstevel@tonic-gate 	case MAC_STAT_OBYTES:
8328eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
833ba2e4443Sseb 			*val = bstp->s.ifHCOutOctets;
8348eb6c4f9Sly149593 		else
835931dca7dSgs150176 			*val = pstats->ifHCOutOctets;
8367c478bd9Sstevel@tonic-gate 		break;
8377c478bd9Sstevel@tonic-gate 
8387c478bd9Sstevel@tonic-gate 	case MAC_STAT_OPACKETS:
8398eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
840ba2e4443Sseb 			*val = bstp->s.ifHCOutUcastPkts +
8417c478bd9Sstevel@tonic-gate 			    bstp->s.ifHCOutMulticastPkts +
8427c478bd9Sstevel@tonic-gate 			    bstp->s.ifHCOutBroadcastPkts;
8438eb6c4f9Sly149593 		else
844931dca7dSgs150176 			*val = pstats->ifHCOutUcastPkts +
845931dca7dSgs150176 			    pstats->ifHCOutMulticastPkts +
846931dca7dSgs150176 			    pstats->ifHCOutBroadcastPkts;
8477c478bd9Sstevel@tonic-gate 		break;
8487c478bd9Sstevel@tonic-gate 
849ba2e4443Sseb 	case ETHER_STAT_ALIGN_ERRORS:
8508eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
851ba2e4443Sseb 			*val = bstp->s.dot3StatsAlignmentErrors;
8528eb6c4f9Sly149593 		else
853931dca7dSgs150176 			*val = pstats->dot3StatsAlignmentErrors;
8547c478bd9Sstevel@tonic-gate 		break;
8557c478bd9Sstevel@tonic-gate 
856ba2e4443Sseb 	case ETHER_STAT_FCS_ERRORS:
8578eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
858ba2e4443Sseb 			*val = bstp->s.dot3StatsFCSErrors;
8598eb6c4f9Sly149593 		else
860931dca7dSgs150176 			*val = pstats->dot3StatsFCSErrors;
8617c478bd9Sstevel@tonic-gate 		break;
8627c478bd9Sstevel@tonic-gate 
863ba2e4443Sseb 	case ETHER_STAT_FIRST_COLLISIONS:
8648eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
865ba2e4443Sseb 			*val = bstp->s.dot3StatsSingleCollisionFrames;
8668eb6c4f9Sly149593 		else
867931dca7dSgs150176 			*val = pstats->dot3StatsSingleCollisionFrames;
8687c478bd9Sstevel@tonic-gate 		break;
8697c478bd9Sstevel@tonic-gate 
870ba2e4443Sseb 	case ETHER_STAT_MULTI_COLLISIONS:
8718eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
872ba2e4443Sseb 			*val = bstp->s.dot3StatsMultipleCollisionFrames;
8738eb6c4f9Sly149593 		else
874931dca7dSgs150176 			*val = pstats->dot3StatsMultipleCollisionFrames;
8757c478bd9Sstevel@tonic-gate 		break;
8767c478bd9Sstevel@tonic-gate 
877ba2e4443Sseb 	case ETHER_STAT_DEFER_XMTS:
8788eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
879ba2e4443Sseb 			*val = bstp->s.dot3StatsDeferredTransmissions;
8808eb6c4f9Sly149593 		else
881931dca7dSgs150176 			*val = pstats->dot3StatsDeferredTransmissions;
8827c478bd9Sstevel@tonic-gate 		break;
8837c478bd9Sstevel@tonic-gate 
884ba2e4443Sseb 	case ETHER_STAT_TX_LATE_COLLISIONS:
8858eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
886ba2e4443Sseb 			*val = bstp->s.dot3StatsLateCollisions;
8878eb6c4f9Sly149593 		else
888931dca7dSgs150176 			*val = pstats->dot3StatsLateCollisions;
8897c478bd9Sstevel@tonic-gate 		break;
8907c478bd9Sstevel@tonic-gate 
891ba2e4443Sseb 	case ETHER_STAT_EX_COLLISIONS:
8928eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
893ba2e4443Sseb 			*val = bstp->s.dot3StatsExcessiveCollisions;
8948eb6c4f9Sly149593 		else
895931dca7dSgs150176 			*val = pstats->dot3StatsExcessiveCollisions;
8967c478bd9Sstevel@tonic-gate 		break;
8977c478bd9Sstevel@tonic-gate 
898ba2e4443Sseb 	case ETHER_STAT_MACXMT_ERRORS:
8998eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
900ba2e4443Sseb 			*val = bstp->s.dot3StatsInternalMacTransmitErrors;
9018eb6c4f9Sly149593 		else
902931dca7dSgs150176 			*val = bgep->pstats->dot3StatsInternalMacTransmitErrors;
9037c478bd9Sstevel@tonic-gate 		break;
9047c478bd9Sstevel@tonic-gate 
905ba2e4443Sseb 	case ETHER_STAT_CARRIER_ERRORS:
9068eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
907ba2e4443Sseb 			*val = bstp->s.dot3StatsCarrierSenseErrors;
9088eb6c4f9Sly149593 		else
909ba2e4443Sseb 			*val = 0;
9107c478bd9Sstevel@tonic-gate 		break;
9117c478bd9Sstevel@tonic-gate 
912ba2e4443Sseb 	case ETHER_STAT_TOOLONG_ERRORS:
9138eb6c4f9Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
914ba2e4443Sseb 			*val = bstp->s.dot3StatsFrameTooLongs;
9158eb6c4f9Sly149593 		else
916931dca7dSgs150176 			*val = pstats->dot3StatsFrameTooLongs;
9177c478bd9Sstevel@tonic-gate 		break;
9187c478bd9Sstevel@tonic-gate 
9199b14cf1dSgd78059 	case ETHER_STAT_TOOSHORT_ERRORS:
9209b14cf1dSgd78059 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
9219b14cf1dSgd78059 			*val = bstp->s.etherStatsUndersizePkts;
9229b14cf1dSgd78059 		else
9239b14cf1dSgd78059 			*val = pstats->etherStatsUndersizePkts;
9249b14cf1dSgd78059 		break;
9259b14cf1dSgd78059 
926ba2e4443Sseb 	case ETHER_STAT_XCVR_ADDR:
927ba2e4443Sseb 		*val = bgep->phy_mii_addr;
9287c478bd9Sstevel@tonic-gate 		break;
9297c478bd9Sstevel@tonic-gate 
930ba2e4443Sseb 	case ETHER_STAT_XCVR_ID:
931f724721bSzh199473 		mutex_enter(bgep->genlock);
932ba2e4443Sseb 		*val = bge_mii_get16(bgep, MII_PHYIDH);
933ba2e4443Sseb 		*val <<= 16;
934ba2e4443Sseb 		*val |= bge_mii_get16(bgep, MII_PHYIDL);
93500d0963fSdilpreet 		if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
93600d0963fSdilpreet 			ddi_fm_service_impact(bgep->devinfo,
93700d0963fSdilpreet 			    DDI_SERVICE_UNAFFECTED);
93800d0963fSdilpreet 		}
939f724721bSzh199473 		mutex_exit(bgep->genlock);
9407c478bd9Sstevel@tonic-gate 		break;
9417c478bd9Sstevel@tonic-gate 
942ba2e4443Sseb 	case ETHER_STAT_XCVR_INUSE:
943dca582a1Sgh162552 		if (bgep->chipid.flags & CHIP_FLAG_SERDES)
944dca582a1Sgh162552 			*val = XCVR_1000X;
945dca582a1Sgh162552 		else
946ba2e4443Sseb 			*val = XCVR_1000T;
9477c478bd9Sstevel@tonic-gate 		break;
9487c478bd9Sstevel@tonic-gate 
949ba2e4443Sseb 	case ETHER_STAT_CAP_1000FDX:
950ba2e4443Sseb 		*val = 1;
9517c478bd9Sstevel@tonic-gate 		break;
9527c478bd9Sstevel@tonic-gate 
953ba2e4443Sseb 	case ETHER_STAT_CAP_1000HDX:
954ba2e4443Sseb 		*val = 1;
9557c478bd9Sstevel@tonic-gate 		break;
9567c478bd9Sstevel@tonic-gate 
957ba2e4443Sseb 	case ETHER_STAT_CAP_100FDX:
958dca582a1Sgh162552 		if (bgep->chipid.flags & CHIP_FLAG_SERDES)
959dca582a1Sgh162552 			*val = 0;
960dca582a1Sgh162552 		else
961ba2e4443Sseb 			*val = 1;
9627c478bd9Sstevel@tonic-gate 		break;
9637c478bd9Sstevel@tonic-gate 
964ba2e4443Sseb 	case ETHER_STAT_CAP_100HDX:
965dca582a1Sgh162552 		if (bgep->chipid.flags & CHIP_FLAG_SERDES)
966dca582a1Sgh162552 			*val = 0;
967dca582a1Sgh162552 		else
968ba2e4443Sseb 			*val = 1;
9697c478bd9Sstevel@tonic-gate 		break;
9707c478bd9Sstevel@tonic-gate 
971ba2e4443Sseb 	case ETHER_STAT_CAP_10FDX:
972dca582a1Sgh162552 		if (bgep->chipid.flags & CHIP_FLAG_SERDES)
973dca582a1Sgh162552 			*val = 0;
974dca582a1Sgh162552 		else
975ba2e4443Sseb 			*val = 1;
9767c478bd9Sstevel@tonic-gate 		break;
9777c478bd9Sstevel@tonic-gate 
978ba2e4443Sseb 	case ETHER_STAT_CAP_10HDX:
979dca582a1Sgh162552 		if (bgep->chipid.flags & CHIP_FLAG_SERDES)
980dca582a1Sgh162552 			*val = 0;
981dca582a1Sgh162552 		else
982ba2e4443Sseb 			*val = 1;
9837c478bd9Sstevel@tonic-gate 		break;
9847c478bd9Sstevel@tonic-gate 
985ba2e4443Sseb 	case ETHER_STAT_CAP_ASMPAUSE:
986ba2e4443Sseb 		*val = 1;
9877c478bd9Sstevel@tonic-gate 		break;
9887c478bd9Sstevel@tonic-gate 
989ba2e4443Sseb 	case ETHER_STAT_CAP_PAUSE:
990ba2e4443Sseb 		*val = 1;
9917c478bd9Sstevel@tonic-gate 		break;
9927c478bd9Sstevel@tonic-gate 
993ba2e4443Sseb 	case ETHER_STAT_CAP_AUTONEG:
994ba2e4443Sseb 		*val = 1;
9957c478bd9Sstevel@tonic-gate 		break;
9967c478bd9Sstevel@tonic-gate 
9979b14cf1dSgd78059 	case ETHER_STAT_CAP_REMFAULT:
9989b14cf1dSgd78059 		*val = 1;
9999b14cf1dSgd78059 		break;
10009b14cf1dSgd78059 
1001ba2e4443Sseb 	case ETHER_STAT_ADV_CAP_1000FDX:
1002ba2e4443Sseb 		*val = bgep->param_adv_1000fdx;
10037c478bd9Sstevel@tonic-gate 		break;
10047c478bd9Sstevel@tonic-gate 
1005ba2e4443Sseb 	case ETHER_STAT_ADV_CAP_1000HDX:
1006ba2e4443Sseb 		*val = bgep->param_adv_1000hdx;
10077c478bd9Sstevel@tonic-gate 		break;
10087c478bd9Sstevel@tonic-gate 
1009ba2e4443Sseb 	case ETHER_STAT_ADV_CAP_100FDX:
1010ba2e4443Sseb 		*val = bgep->param_adv_100fdx;
10117c478bd9Sstevel@tonic-gate 		break;
10127c478bd9Sstevel@tonic-gate 
1013ba2e4443Sseb 	case ETHER_STAT_ADV_CAP_100HDX:
1014ba2e4443Sseb 		*val = bgep->param_adv_100hdx;
10157c478bd9Sstevel@tonic-gate 		break;
10167c478bd9Sstevel@tonic-gate 
1017ba2e4443Sseb 	case ETHER_STAT_ADV_CAP_10FDX:
1018ba2e4443Sseb 		*val = bgep->param_adv_10fdx;
10197c478bd9Sstevel@tonic-gate 		break;
10207c478bd9Sstevel@tonic-gate 
1021ba2e4443Sseb 	case ETHER_STAT_ADV_CAP_10HDX:
1022ba2e4443Sseb 		*val = bgep->param_adv_10hdx;
10237c478bd9Sstevel@tonic-gate 		break;
10247c478bd9Sstevel@tonic-gate 
1025ba2e4443Sseb 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
1026ba2e4443Sseb 		*val = bgep->param_adv_asym_pause;
10277c478bd9Sstevel@tonic-gate 		break;
10287c478bd9Sstevel@tonic-gate 
1029ba2e4443Sseb 	case ETHER_STAT_ADV_CAP_PAUSE:
1030ba2e4443Sseb 		*val = bgep->param_adv_pause;
10317c478bd9Sstevel@tonic-gate 		break;
10327c478bd9Sstevel@tonic-gate 
1033ba2e4443Sseb 	case ETHER_STAT_ADV_CAP_AUTONEG:
1034ba2e4443Sseb 		*val = bgep->param_adv_autoneg;
10357c478bd9Sstevel@tonic-gate 		break;
10367c478bd9Sstevel@tonic-gate 
10379b14cf1dSgd78059 	case ETHER_STAT_ADV_REMFAULT:
1038dca582a1Sgh162552 		if (bgep->chipid.flags & CHIP_FLAG_SERDES)
1039dca582a1Sgh162552 			*val = 0;
1040dca582a1Sgh162552 		else {
10419b14cf1dSgd78059 			mutex_enter(bgep->genlock);
10429b14cf1dSgd78059 			*val = bge_mii_get16(bgep, MII_AN_ADVERT) &
10439b14cf1dSgd78059 			    MII_AN_ADVERT_REMFAULT ? 1 : 0;
1044dca582a1Sgh162552 			if (bge_check_acc_handle(bgep, bgep->io_handle) !=
1045dca582a1Sgh162552 			    DDI_FM_OK) {
10469b14cf1dSgd78059 				ddi_fm_service_impact(bgep->devinfo,
10479b14cf1dSgd78059 				    DDI_SERVICE_UNAFFECTED);
10489b14cf1dSgd78059 			}
10499b14cf1dSgd78059 			mutex_exit(bgep->genlock);
1050dca582a1Sgh162552 		}
10519b14cf1dSgd78059 		break;
10529b14cf1dSgd78059 
1053ba2e4443Sseb 	case ETHER_STAT_LP_CAP_1000FDX:
1054ba2e4443Sseb 		*val = bgep->param_lp_1000fdx;
10557c478bd9Sstevel@tonic-gate 		break;
10567c478bd9Sstevel@tonic-gate 
1057ba2e4443Sseb 	case ETHER_STAT_LP_CAP_1000HDX:
1058ba2e4443Sseb 		*val = bgep->param_lp_1000hdx;
10597c478bd9Sstevel@tonic-gate 		break;
10607c478bd9Sstevel@tonic-gate 
1061ba2e4443Sseb 	case ETHER_STAT_LP_CAP_100FDX:
1062ba2e4443Sseb 		*val = bgep->param_lp_100fdx;
10637c478bd9Sstevel@tonic-gate 		break;
10647c478bd9Sstevel@tonic-gate 
1065ba2e4443Sseb 	case ETHER_STAT_LP_CAP_100HDX:
1066ba2e4443Sseb 		*val = bgep->param_lp_100hdx;
10677c478bd9Sstevel@tonic-gate 		break;
10687c478bd9Sstevel@tonic-gate 
1069ba2e4443Sseb 	case ETHER_STAT_LP_CAP_10FDX:
1070ba2e4443Sseb 		*val = bgep->param_lp_10fdx;
10717c478bd9Sstevel@tonic-gate 		break;
10727c478bd9Sstevel@tonic-gate 
1073ba2e4443Sseb 	case ETHER_STAT_LP_CAP_10HDX:
1074ba2e4443Sseb 		*val = bgep->param_lp_10hdx;
10757c478bd9Sstevel@tonic-gate 		break;
10767c478bd9Sstevel@tonic-gate 
1077ba2e4443Sseb 	case ETHER_STAT_LP_CAP_ASMPAUSE:
1078ba2e4443Sseb 		*val = bgep->param_lp_asym_pause;
10797c478bd9Sstevel@tonic-gate 		break;
10807c478bd9Sstevel@tonic-gate 
1081ba2e4443Sseb 	case ETHER_STAT_LP_CAP_PAUSE:
1082ba2e4443Sseb 		*val = bgep->param_lp_pause;
10837c478bd9Sstevel@tonic-gate 		break;
10847c478bd9Sstevel@tonic-gate 
1085ba2e4443Sseb 	case ETHER_STAT_LP_CAP_AUTONEG:
1086ba2e4443Sseb 		*val = bgep->param_lp_autoneg;
10877c478bd9Sstevel@tonic-gate 		break;
10887c478bd9Sstevel@tonic-gate 
10899b14cf1dSgd78059 	case ETHER_STAT_LP_REMFAULT:
1090dca582a1Sgh162552 		if (bgep->chipid.flags & CHIP_FLAG_SERDES)
1091dca582a1Sgh162552 			*val = 0;
1092dca582a1Sgh162552 		else {
10939b14cf1dSgd78059 			mutex_enter(bgep->genlock);
10949b14cf1dSgd78059 			*val = bge_mii_get16(bgep, MII_AN_LPABLE) &
10959b14cf1dSgd78059 			    MII_AN_ADVERT_REMFAULT ? 1 : 0;
1096dca582a1Sgh162552 			if (bge_check_acc_handle(bgep, bgep->io_handle) !=
1097dca582a1Sgh162552 			    DDI_FM_OK) {
10989b14cf1dSgd78059 				ddi_fm_service_impact(bgep->devinfo,
10999b14cf1dSgd78059 				    DDI_SERVICE_UNAFFECTED);
11009b14cf1dSgd78059 			}
11019b14cf1dSgd78059 			mutex_exit(bgep->genlock);
1102dca582a1Sgh162552 		}
11039b14cf1dSgd78059 		break;
11049b14cf1dSgd78059 
1105ba2e4443Sseb 	case ETHER_STAT_LINK_ASMPAUSE:
1106ba2e4443Sseb 		*val = bgep->param_adv_asym_pause &&
11077c478bd9Sstevel@tonic-gate 		    bgep->param_lp_asym_pause &&
11087c478bd9Sstevel@tonic-gate 		    bgep->param_adv_pause != bgep->param_lp_pause;
11097c478bd9Sstevel@tonic-gate 		break;
11107c478bd9Sstevel@tonic-gate 
1111ba2e4443Sseb 	case ETHER_STAT_LINK_PAUSE:
1112ba2e4443Sseb 		*val = bgep->param_link_rx_pause;
11137c478bd9Sstevel@tonic-gate 		break;
11147c478bd9Sstevel@tonic-gate 
1115ba2e4443Sseb 	case ETHER_STAT_LINK_AUTONEG:
1116ba2e4443Sseb 		*val = bgep->param_link_autoneg;
11177c478bd9Sstevel@tonic-gate 		break;
11187c478bd9Sstevel@tonic-gate 
1119ba2e4443Sseb 	case ETHER_STAT_LINK_DUPLEX:
1120ba2e4443Sseb 		*val = bgep->param_link_duplex;
11217c478bd9Sstevel@tonic-gate 		break;
11227c478bd9Sstevel@tonic-gate 
11237c478bd9Sstevel@tonic-gate 	default:
1124ba2e4443Sseb 		return (ENOTSUP);
11257c478bd9Sstevel@tonic-gate 	}
11267c478bd9Sstevel@tonic-gate 
1127ba2e4443Sseb 	return (0);
11287c478bd9Sstevel@tonic-gate }
1129