xref: /onnv-gate/usr/src/uts/common/io/bge/bge_kstats.c (revision 4711:92bc2003b9d8)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51369Sdduvall  * Common Development and Distribution License (the "License").
61369Sdduvall  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
211369Sdduvall 
220Sstevel@tonic-gate /*
233907Szh199473  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
292675Szh199473 #include "bge_impl.h"
300Sstevel@tonic-gate 
310Sstevel@tonic-gate #define	BGE_DBG		BGE_DBG_STATS	/* debug flag for this code	*/
320Sstevel@tonic-gate 
330Sstevel@tonic-gate /*
340Sstevel@tonic-gate  * Local datatype for defining tables of (Offset, Name) pairs
350Sstevel@tonic-gate  */
360Sstevel@tonic-gate typedef struct {
370Sstevel@tonic-gate 	offset_t	index;
380Sstevel@tonic-gate 	char		*name;
390Sstevel@tonic-gate } bge_ksindex_t;
400Sstevel@tonic-gate 
410Sstevel@tonic-gate 
420Sstevel@tonic-gate /*
430Sstevel@tonic-gate  * Table of Hardware-defined Statistics Block Offsets and Names
440Sstevel@tonic-gate  */
450Sstevel@tonic-gate #define	KS_NAME(s)			{ KS_ ## s, #s }
460Sstevel@tonic-gate 
470Sstevel@tonic-gate static const bge_ksindex_t bge_statistics[] = {
480Sstevel@tonic-gate 	KS_NAME(ifHCInOctets),
490Sstevel@tonic-gate 	KS_NAME(etherStatsFragments),
500Sstevel@tonic-gate 	KS_NAME(ifHCInUcastPkts),
510Sstevel@tonic-gate 	KS_NAME(ifHCInMulticastPkts),
520Sstevel@tonic-gate 	KS_NAME(ifHCInBroadcastPkts),
530Sstevel@tonic-gate 	KS_NAME(dot3StatsFCSErrors),
540Sstevel@tonic-gate 	KS_NAME(dot3StatsAlignmentErrors),
550Sstevel@tonic-gate 	KS_NAME(xonPauseFramesReceived),
560Sstevel@tonic-gate 	KS_NAME(xoffPauseFramesReceived),
570Sstevel@tonic-gate 	KS_NAME(macControlFramesReceived),
580Sstevel@tonic-gate 	KS_NAME(xoffStateEntered),
590Sstevel@tonic-gate 	KS_NAME(dot3StatsFrameTooLongs),
600Sstevel@tonic-gate 	KS_NAME(etherStatsJabbers),
610Sstevel@tonic-gate 	KS_NAME(etherStatsUndersizePkts),
620Sstevel@tonic-gate 	KS_NAME(inRangeLengthError),
630Sstevel@tonic-gate 	KS_NAME(outRangeLengthError),
640Sstevel@tonic-gate 	KS_NAME(etherStatsPkts64Octets),
650Sstevel@tonic-gate 	KS_NAME(etherStatsPkts65to127Octets),
660Sstevel@tonic-gate 	KS_NAME(etherStatsPkts128to255Octets),
670Sstevel@tonic-gate 	KS_NAME(etherStatsPkts256to511Octets),
680Sstevel@tonic-gate 	KS_NAME(etherStatsPkts512to1023Octets),
690Sstevel@tonic-gate 	KS_NAME(etherStatsPkts1024to1518Octets),
700Sstevel@tonic-gate 	KS_NAME(etherStatsPkts1519to2047Octets),
710Sstevel@tonic-gate 	KS_NAME(etherStatsPkts2048to4095Octets),
720Sstevel@tonic-gate 	KS_NAME(etherStatsPkts4096to8191Octets),
730Sstevel@tonic-gate 	KS_NAME(etherStatsPkts8192to9022Octets),
740Sstevel@tonic-gate 
750Sstevel@tonic-gate 	KS_NAME(ifHCOutOctets),
760Sstevel@tonic-gate 	KS_NAME(etherStatsCollisions),
770Sstevel@tonic-gate 	KS_NAME(outXonSent),
780Sstevel@tonic-gate 	KS_NAME(outXoffSent),
790Sstevel@tonic-gate 	KS_NAME(flowControlDone),
800Sstevel@tonic-gate 	KS_NAME(dot3StatsInternalMacTransmitErrors),
810Sstevel@tonic-gate 	KS_NAME(dot3StatsSingleCollisionFrames),
820Sstevel@tonic-gate 	KS_NAME(dot3StatsMultipleCollisionFrames),
830Sstevel@tonic-gate 	KS_NAME(dot3StatsDeferredTransmissions),
840Sstevel@tonic-gate 	KS_NAME(dot3StatsExcessiveCollisions),
850Sstevel@tonic-gate 	KS_NAME(dot3StatsLateCollisions),
860Sstevel@tonic-gate 	KS_NAME(dot3Collided2Times),
870Sstevel@tonic-gate 	KS_NAME(dot3Collided3Times),
880Sstevel@tonic-gate 	KS_NAME(dot3Collided4Times),
890Sstevel@tonic-gate 	KS_NAME(dot3Collided5Times),
900Sstevel@tonic-gate 	KS_NAME(dot3Collided6Times),
910Sstevel@tonic-gate 	KS_NAME(dot3Collided7Times),
920Sstevel@tonic-gate 	KS_NAME(dot3Collided8Times),
930Sstevel@tonic-gate 	KS_NAME(dot3Collided9Times),
940Sstevel@tonic-gate 	KS_NAME(dot3Collided10Times),
950Sstevel@tonic-gate 	KS_NAME(dot3Collided11Times),
960Sstevel@tonic-gate 	KS_NAME(dot3Collided12Times),
970Sstevel@tonic-gate 	KS_NAME(dot3Collided13Times),
980Sstevel@tonic-gate 	KS_NAME(dot3Collided14Times),
990Sstevel@tonic-gate 	KS_NAME(dot3Collided15Times),
1000Sstevel@tonic-gate 	KS_NAME(ifHCOutUcastPkts),
1010Sstevel@tonic-gate 	KS_NAME(ifHCOutMulticastPkts),
1020Sstevel@tonic-gate 	KS_NAME(ifHCOutBroadcastPkts),
1030Sstevel@tonic-gate 	KS_NAME(dot3StatsCarrierSenseErrors),
1040Sstevel@tonic-gate 	KS_NAME(ifOutDiscards),
1050Sstevel@tonic-gate 	KS_NAME(ifOutErrors),
1060Sstevel@tonic-gate 
1070Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_1),
1080Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_2),
1090Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_3),
1100Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_4),
1110Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_5),
1120Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_6),
1130Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_7),
1140Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_8),
1150Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_9),
1160Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_10),
1170Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_11),
1180Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_12),
1190Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_13),
1200Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_14),
1210Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_15),
1220Sstevel@tonic-gate 	KS_NAME(COSIfHCInPkts_16),
1230Sstevel@tonic-gate 	KS_NAME(COSFramesDroppedDueToFilters),
1240Sstevel@tonic-gate 	KS_NAME(nicDmaWriteQueueFull),
1250Sstevel@tonic-gate 	KS_NAME(nicDmaWriteHighPriQueueFull),
1260Sstevel@tonic-gate 	KS_NAME(nicNoMoreRxBDs),
1270Sstevel@tonic-gate 	KS_NAME(ifInDiscards),
1280Sstevel@tonic-gate 	KS_NAME(ifInErrors),
1290Sstevel@tonic-gate 	KS_NAME(nicRecvThresholdHit),
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_1),
1320Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_2),
1330Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_3),
1340Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_4),
1350Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_5),
1360Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_6),
1370Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_7),
1380Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_8),
1390Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_9),
1400Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_10),
1410Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_11),
1420Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_12),
1430Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_13),
1440Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_14),
1450Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_15),
1460Sstevel@tonic-gate 	KS_NAME(COSIfHCOutPkts_16),
1470Sstevel@tonic-gate 	KS_NAME(nicDmaReadQueueFull),
1480Sstevel@tonic-gate 	KS_NAME(nicDmaReadHighPriQueueFull),
1490Sstevel@tonic-gate 	KS_NAME(nicSendDataCompQueueFull),
1500Sstevel@tonic-gate 	KS_NAME(nicRingSetSendProdIndex),
1510Sstevel@tonic-gate 	KS_NAME(nicRingStatusUpdate),
1520Sstevel@tonic-gate 	KS_NAME(nicInterrupts),
1530Sstevel@tonic-gate 	KS_NAME(nicAvoidedInterrupts),
1540Sstevel@tonic-gate 	KS_NAME(nicSendThresholdHit),
1550Sstevel@tonic-gate 
1560Sstevel@tonic-gate 	{ KS_STATS_SIZE, NULL }
1570Sstevel@tonic-gate };
1580Sstevel@tonic-gate 
1591102Sly149593 static const bge_ksindex_t bge_stat_val[] = {
1601102Sly149593 	KS_NAME(ifHCOutOctets),
1611102Sly149593 	KS_NAME(etherStatsCollisions),
1621102Sly149593 	KS_NAME(outXonSent),
1631102Sly149593 	KS_NAME(outXoffSent),
1641102Sly149593 	KS_NAME(dot3StatsInternalMacTransmitErrors),
1651102Sly149593 	KS_NAME(dot3StatsSingleCollisionFrames),
1661102Sly149593 	KS_NAME(dot3StatsMultipleCollisionFrames),
1671102Sly149593 	KS_NAME(dot3StatsDeferredTransmissions),
1681102Sly149593 	KS_NAME(dot3StatsExcessiveCollisions),
1691102Sly149593 	KS_NAME(dot3StatsLateCollisions),
1701102Sly149593 	KS_NAME(ifHCOutUcastPkts),
1711102Sly149593 	KS_NAME(ifHCOutMulticastPkts),
1721102Sly149593 	KS_NAME(ifHCOutBroadcastPkts),
1731102Sly149593 	KS_NAME(ifHCInOctets),
1741102Sly149593 	KS_NAME(etherStatsFragments),
1751102Sly149593 	KS_NAME(ifHCInUcastPkts),
1761102Sly149593 	KS_NAME(ifHCInMulticastPkts),
1771102Sly149593 	KS_NAME(ifHCInBroadcastPkts),
1781102Sly149593 	KS_NAME(dot3StatsFCSErrors),
1791102Sly149593 	KS_NAME(dot3StatsAlignmentErrors),
1801102Sly149593 	KS_NAME(xonPauseFramesReceived),
1811102Sly149593 	KS_NAME(xoffPauseFramesReceived),
1821102Sly149593 	KS_NAME(macControlFramesReceived),
1831102Sly149593 	KS_NAME(xoffStateEntered),
1841102Sly149593 	KS_NAME(dot3StatsFrameTooLongs),
1851102Sly149593 	KS_NAME(etherStatsJabbers),
1861102Sly149593 	KS_NAME(etherStatsUndersizePkts),
1871102Sly149593 
1881102Sly149593 	{ KS_STAT_REG_SIZE, NULL }
1891102Sly149593 };
1901102Sly149593 
1910Sstevel@tonic-gate static int
1920Sstevel@tonic-gate bge_statistics_update(kstat_t *ksp, int flag)
1930Sstevel@tonic-gate {
1940Sstevel@tonic-gate 	bge_t *bgep;
1950Sstevel@tonic-gate 	bge_statistics_t *bstp;
1963334Sgs150176 	bge_statistics_reg_t *pstats;
1970Sstevel@tonic-gate 	kstat_named_t *knp;
1980Sstevel@tonic-gate 	const bge_ksindex_t *ksip;
1990Sstevel@tonic-gate 
2000Sstevel@tonic-gate 	if (flag != KSTAT_READ)
2010Sstevel@tonic-gate 		return (EACCES);
2020Sstevel@tonic-gate 
2030Sstevel@tonic-gate 	bgep = ksp->ks_private;
2041102Sly149593 	if (bgep->chipid.statistic_type == BGE_STAT_BLK)
2051102Sly149593 		bstp = DMA_VPTR(bgep->statistics);
2061102Sly149593 
2070Sstevel@tonic-gate 	knp = ksp->ks_data;
2080Sstevel@tonic-gate 
2090Sstevel@tonic-gate 	/*
2100Sstevel@tonic-gate 	 * Transfer the statistics values from the copy that the
2110Sstevel@tonic-gate 	 * chip updates via DMA to the named-kstat structure.
2120Sstevel@tonic-gate 	 *
2130Sstevel@tonic-gate 	 * As above, we don't bother to sync or stop updates to the
2140Sstevel@tonic-gate 	 * statistics, 'cos it doesn't really matter if they're a few
2152135Szh199473 	 * microseconds out of date or less than 100% consistent ...
2160Sstevel@tonic-gate 	 */
2171102Sly149593 	if (bgep->chipid.statistic_type == BGE_STAT_BLK)
2181102Sly149593 		for (ksip = bge_statistics; ksip->name != NULL; ++knp, ++ksip)
2191102Sly149593 			knp->value.ui64 = bstp->a[ksip->index];
2201102Sly149593 	else {
2213334Sgs150176 		pstats = bgep->pstats;
2223334Sgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->ifHCOutOctets);
2233334Sgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->etherStatsCollisions);
2243334Sgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->outXonSent);
2253334Sgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->outXoffSent);
2261102Sly149593 		(knp++)->value.ui64 =
2273334Sgs150176 		    (uint64_t)(pstats->dot3StatsInternalMacTransmitErrors);
2281102Sly149593 		(knp++)->value.ui64 =
2293334Sgs150176 		    (uint64_t)(pstats->dot3StatsSingleCollisionFrames);
2301102Sly149593 		(knp++)->value.ui64 =
2313334Sgs150176 		    (uint64_t)(pstats->dot3StatsMultipleCollisionFrames);
2321102Sly149593 		(knp++)->value.ui64 =
2333334Sgs150176 		    (uint64_t)(pstats->dot3StatsDeferredTransmissions);
2341102Sly149593 		(knp++)->value.ui64 =
2353334Sgs150176 		    (uint64_t)(pstats->dot3StatsExcessiveCollisions);
2361102Sly149593 		(knp++)->value.ui64 =
2373334Sgs150176 		    (uint64_t)(pstats->dot3StatsLateCollisions);
2383334Sgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->ifHCOutUcastPkts);
2393334Sgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->ifHCOutMulticastPkts);
2403334Sgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->ifHCOutBroadcastPkts);
2413334Sgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->ifHCInOctets);
2423334Sgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->etherStatsFragments);
2433334Sgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->ifHCInUcastPkts);
2443334Sgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->ifHCInMulticastPkts);
2453334Sgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->ifHCInBroadcastPkts);
2463334Sgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->dot3StatsFCSErrors);
2471102Sly149593 		(knp++)->value.ui64 =
2483334Sgs150176 		    (uint64_t)(pstats->dot3StatsAlignmentErrors);
2491102Sly149593 		(knp++)->value.ui64 =
2503334Sgs150176 		    (uint64_t)(pstats->xonPauseFramesReceived);
2511102Sly149593 		(knp++)->value.ui64 =
2523334Sgs150176 		    (uint64_t)(pstats->xoffPauseFramesReceived);
2531102Sly149593 		(knp++)->value.ui64 =
2543334Sgs150176 		    (uint64_t)(pstats->macControlFramesReceived);
2553334Sgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->xoffStateEntered);
2561102Sly149593 		(knp++)->value.ui64 =
2573334Sgs150176 		    (uint64_t)(pstats->dot3StatsFrameTooLongs);
2583334Sgs150176 		(knp++)->value.ui64 = (uint64_t)(pstats->etherStatsJabbers);
2591102Sly149593 		(knp++)->value.ui64 =
2603334Sgs150176 		    (uint64_t)(pstats->etherStatsUndersizePkts);
2611102Sly149593 	}
2620Sstevel@tonic-gate 
2630Sstevel@tonic-gate 	return (0);
2640Sstevel@tonic-gate }
2650Sstevel@tonic-gate 
2660Sstevel@tonic-gate static const bge_ksindex_t bge_chipid[] = {
2670Sstevel@tonic-gate 	{ 0,				"asic_rev"		},
2680Sstevel@tonic-gate 	{ 1,				"businfo"		},
2690Sstevel@tonic-gate 	{ 2,				"command"		},
2700Sstevel@tonic-gate 
2710Sstevel@tonic-gate 	{ 3,				"vendor_id"		},
2720Sstevel@tonic-gate 	{ 4,				"device_id"		},
2730Sstevel@tonic-gate 	{ 5,				"subsystem_vendor_id"	},
2740Sstevel@tonic-gate 	{ 6,				"subsystem_device_id"	},
2750Sstevel@tonic-gate 	{ 7,				"revision_id"		},
2760Sstevel@tonic-gate 	{ 8,				"cache_line_size"	},
2770Sstevel@tonic-gate 	{ 9,				"latency_timer"		},
2780Sstevel@tonic-gate 
2790Sstevel@tonic-gate 	{ 10,				"flags"			},
2800Sstevel@tonic-gate 	{ 11,				"chip_type"		},
2810Sstevel@tonic-gate 	{ 12,				"mbuf_base"		},
2820Sstevel@tonic-gate 	{ 13,				"mbuf_count"		},
2830Sstevel@tonic-gate 	{ 14,				"hw_mac_addr"		},
2840Sstevel@tonic-gate 
2850Sstevel@tonic-gate 	{ 15,				"&bus_type"		},
2860Sstevel@tonic-gate 	{ 16,				"&bus_speed"		},
2870Sstevel@tonic-gate 	{ 17,				"&bus_size"		},
2880Sstevel@tonic-gate 	{ 18,				"&supported"		},
2890Sstevel@tonic-gate 	{ 19,				"&interface"		},
2900Sstevel@tonic-gate 
2910Sstevel@tonic-gate 	{ -1,				NULL 			}
2920Sstevel@tonic-gate };
2930Sstevel@tonic-gate 
2940Sstevel@tonic-gate static void
2950Sstevel@tonic-gate bge_set_char_kstat(kstat_named_t *knp, const char *s)
2960Sstevel@tonic-gate {
2970Sstevel@tonic-gate 	(void) strncpy(knp->value.c, s, sizeof (knp->value.c));
2980Sstevel@tonic-gate }
2990Sstevel@tonic-gate 
3000Sstevel@tonic-gate static int
3010Sstevel@tonic-gate bge_chipid_update(kstat_t *ksp, int flag)
3020Sstevel@tonic-gate {
3030Sstevel@tonic-gate 	bge_t *bgep;
3040Sstevel@tonic-gate 	kstat_named_t *knp;
3050Sstevel@tonic-gate 	uint64_t tmp;
3060Sstevel@tonic-gate 
3070Sstevel@tonic-gate 	if (flag != KSTAT_READ)
3080Sstevel@tonic-gate 		return (EACCES);
3090Sstevel@tonic-gate 
3100Sstevel@tonic-gate 	bgep = ksp->ks_private;
3110Sstevel@tonic-gate 	knp = ksp->ks_data;
3120Sstevel@tonic-gate 
3130Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.asic_rev;
3140Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.businfo;
3150Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.command;
3160Sstevel@tonic-gate 
3170Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.vendor;
3180Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.device;
3190Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.subven;
3200Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.subdev;
3210Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.revision;
3220Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.clsize;
3230Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.latency;
3240Sstevel@tonic-gate 
3250Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.flags;
3260Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.chip_label;
3270Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.mbuf_base;
3280Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.mbuf_length;
3290Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chipid.hw_mac_addr;
3300Sstevel@tonic-gate 
3310Sstevel@tonic-gate 	/*
3320Sstevel@tonic-gate 	 * Now we interpret some of the above into readable strings
3330Sstevel@tonic-gate 	 */
3340Sstevel@tonic-gate 	tmp = bgep->chipid.businfo;
3350Sstevel@tonic-gate 	bge_set_char_kstat(knp++,
336*4711Sml149210 	    tmp & PCISTATE_BUS_IS_PCI ? "PCI" : "PCI-X");
3370Sstevel@tonic-gate 	bge_set_char_kstat(knp++,
338*4711Sml149210 	    tmp & PCISTATE_BUS_IS_FAST ? "fast" : "normal");
3390Sstevel@tonic-gate 	bge_set_char_kstat(knp++,
340*4711Sml149210 	    tmp & PCISTATE_BUS_IS_32_BIT ? "32 bit" : "64 bit");
3410Sstevel@tonic-gate 
3420Sstevel@tonic-gate 	tmp = bgep->chipid.flags;
3430Sstevel@tonic-gate 	bge_set_char_kstat(knp++,
344*4711Sml149210 	    tmp & CHIP_FLAG_SUPPORTED ? "yes" : "no");
3450Sstevel@tonic-gate 	bge_set_char_kstat(knp++,
346*4711Sml149210 	    tmp & CHIP_FLAG_SERDES ? "serdes" : "copper");
3470Sstevel@tonic-gate 
3480Sstevel@tonic-gate 	return (0);
3490Sstevel@tonic-gate }
3500Sstevel@tonic-gate 
3510Sstevel@tonic-gate static const bge_ksindex_t bge_driverinfo[] = {
3520Sstevel@tonic-gate 	{ 0,				"rx_buff_addr"		},
3530Sstevel@tonic-gate 	{ 1,				"tx_buff_addr"		},
3540Sstevel@tonic-gate 	{ 2,				"rx_desc_addr"		},
3550Sstevel@tonic-gate 	{ 3,				"tx_desc_addr"		},
3560Sstevel@tonic-gate 
3570Sstevel@tonic-gate 	{ 4,				"tx_desc_free"		},
3583334Sgs150176 	{ 5,				"tx_array"		},
3593334Sgs150176 	{ 6,				"tc_next"		},
3603334Sgs150176 	{ 7,				"tx_next"		},
3613334Sgs150176 	{ 8,				"txfill_next"		},
3623334Sgs150176 	{ 9,				"txpkt_next"		},
3633334Sgs150176 	{ 10,				"tx_bufs"		},
3643334Sgs150176 	{ 11,				"tx_flow"		},
3653334Sgs150176 	{ 12,				"tx_resched_needed"	},
3663334Sgs150176 	{ 13,				"tx_resched"		},
3673334Sgs150176 	{ 14,				"tx_nobuf"		},
3683334Sgs150176 	{ 15,				"tx_nobd"		},
3693334Sgs150176 	{ 16,				"tx_block"		},
3703334Sgs150176 	{ 17,				"tx_alloc_fail"		},
3710Sstevel@tonic-gate 
3723334Sgs150176 	{ 18,				"watchdog"		},
3733334Sgs150176 	{ 19,				"chip_resets"		},
3743334Sgs150176 	{ 20,				"dma_misses"		},
3753907Szh199473 	{ 21,				"update_misses"		},
3760Sstevel@tonic-gate 
3773907Szh199473 	{ 22,				"misc_host_config"	},
3783907Szh199473 	{ 23,				"dma_rw_control"	},
3793907Szh199473 	{ 24,				"pci_bus_info"		},
3803334Sgs150176 
3813907Szh199473 	{ 25,				"buff_mgr_status"	},
3823907Szh199473 	{ 26,				"rcv_init_status"	},
3830Sstevel@tonic-gate 
3840Sstevel@tonic-gate 	{ -1,				NULL 			}
3850Sstevel@tonic-gate };
3860Sstevel@tonic-gate 
3870Sstevel@tonic-gate static int
3880Sstevel@tonic-gate bge_driverinfo_update(kstat_t *ksp, int flag)
3890Sstevel@tonic-gate {
3900Sstevel@tonic-gate 	bge_t *bgep;
3910Sstevel@tonic-gate 	kstat_named_t *knp;
3920Sstevel@tonic-gate 	ddi_acc_handle_t handle;
3930Sstevel@tonic-gate 
3940Sstevel@tonic-gate 	if (flag != KSTAT_READ)
3950Sstevel@tonic-gate 		return (EACCES);
3960Sstevel@tonic-gate 
3970Sstevel@tonic-gate 	bgep = ksp->ks_private;
3981865Sdilpreet 	if (bgep->bge_chip_state == BGE_CHIP_FAULT)
3991865Sdilpreet 		return (EIO);
4001865Sdilpreet 
4010Sstevel@tonic-gate 	knp = ksp->ks_data;
4020Sstevel@tonic-gate 
4030Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->rx_buff[0].cookie.dmac_laddress;
4040Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->tx_buff[0].cookie.dmac_laddress;
4050Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->rx_desc[0].cookie.dmac_laddress;
4060Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->tx_desc.cookie.dmac_laddress;
4070Sstevel@tonic-gate 
4080Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->send[0].tx_free;
4093334Sgs150176 	(knp++)->value.ui64 = bgep->send[0].tx_array;
4103334Sgs150176 	(knp++)->value.ui64 = bgep->send[0].tc_next;
4113334Sgs150176 	(knp++)->value.ui64 = bgep->send[0].tx_next;
4123334Sgs150176 	(knp++)->value.ui64 = bgep->send[0].txfill_next;
4133334Sgs150176 	(knp++)->value.ui64 = bgep->send[0].txpkt_next;
4143334Sgs150176 	(knp++)->value.ui64 = bgep->send[0].txbuf_pop_queue->count +
4153334Sgs150176 	    bgep->send[0].txbuf_push_queue->count;
4163334Sgs150176 	(knp++)->value.ui64 = bgep->send[0].tx_flow;
4173334Sgs150176 	(knp++)->value.ui64 = bgep->tx_resched_needed;
4183334Sgs150176 	(knp++)->value.ui64 = bgep->tx_resched;
4193334Sgs150176 	(knp++)->value.ui64 = bgep->send[0].tx_nobuf;
4203334Sgs150176 	(knp++)->value.ui64 = bgep->send[0].tx_nobd;
4213334Sgs150176 	(knp++)->value.ui64 = bgep->send[0].tx_block;
4223334Sgs150176 	(knp++)->value.ui64 = bgep->send[0].tx_alloc_fail;
4233334Sgs150176 
4240Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->watchdog;
4250Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->chip_resets;
4260Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->missed_dmas;
4273907Szh199473 	(knp++)->value.ui64 = bgep->missed_updates;
4280Sstevel@tonic-gate 
4290Sstevel@tonic-gate 	/*
4300Sstevel@tonic-gate 	 * Hold the mutex while accessing the chip registers
4310Sstevel@tonic-gate 	 * just in case the factotum is trying to reset it!
4320Sstevel@tonic-gate 	 */
4330Sstevel@tonic-gate 	handle = bgep->cfg_handle;
4340Sstevel@tonic-gate 	mutex_enter(bgep->genlock);
4350Sstevel@tonic-gate 	(knp++)->value.ui64 = pci_config_get32(handle, PCI_CONF_BGE_MHCR);
4360Sstevel@tonic-gate 	(knp++)->value.ui64 = pci_config_get32(handle, PCI_CONF_BGE_PDRWCR);
4370Sstevel@tonic-gate 	(knp++)->value.ui64 = pci_config_get32(handle, PCI_CONF_BGE_PCISTATE);
4381865Sdilpreet 	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
4391865Sdilpreet 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
4401865Sdilpreet 		mutex_exit(bgep->genlock);
4411865Sdilpreet 		return (EIO);
4421865Sdilpreet 	}
4430Sstevel@tonic-gate 
4440Sstevel@tonic-gate 	(knp++)->value.ui64 = bge_reg_get32(bgep, BUFFER_MANAGER_STATUS_REG);
4450Sstevel@tonic-gate 	(knp++)->value.ui64 = bge_reg_get32(bgep, RCV_INITIATOR_STATUS_REG);
4461865Sdilpreet 	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
4471865Sdilpreet 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
4481865Sdilpreet 		mutex_exit(bgep->genlock);
4491865Sdilpreet 		return (EIO);
4501865Sdilpreet 	}
4510Sstevel@tonic-gate 	mutex_exit(bgep->genlock);
4520Sstevel@tonic-gate 
4530Sstevel@tonic-gate 	return (0);
4540Sstevel@tonic-gate }
4550Sstevel@tonic-gate 
4560Sstevel@tonic-gate static const bge_ksindex_t bge_serdes[] = {
4570Sstevel@tonic-gate 	{ 0,				"serdes_status"		},
4580Sstevel@tonic-gate 	{ 1,				"serdes_advert"		},
4590Sstevel@tonic-gate 	{ 2,				"serdes_lpadv"		},
4600Sstevel@tonic-gate 
4610Sstevel@tonic-gate 	{ -1,				NULL }
4620Sstevel@tonic-gate };
4630Sstevel@tonic-gate 
4640Sstevel@tonic-gate static int
4650Sstevel@tonic-gate bge_serdes_update(kstat_t *ksp, int flag)
4660Sstevel@tonic-gate {
4670Sstevel@tonic-gate 	bge_t *bgep;
4680Sstevel@tonic-gate 	kstat_named_t *knp;
4690Sstevel@tonic-gate 
4700Sstevel@tonic-gate 	if (flag != KSTAT_READ)
4710Sstevel@tonic-gate 		return (EACCES);
4720Sstevel@tonic-gate 
4730Sstevel@tonic-gate 	bgep = ksp->ks_private;
4740Sstevel@tonic-gate 	knp = ksp->ks_data;
4750Sstevel@tonic-gate 
4760Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->serdes_status;
4770Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->serdes_advert;
4780Sstevel@tonic-gate 	(knp++)->value.ui64 = bgep->serdes_lpadv;
4790Sstevel@tonic-gate 
4800Sstevel@tonic-gate 	return (0);
4810Sstevel@tonic-gate }
4820Sstevel@tonic-gate 
4830Sstevel@tonic-gate static const bge_ksindex_t bge_phydata[] = {
4840Sstevel@tonic-gate 	{ MII_CONTROL,			"mii_control"		},
4850Sstevel@tonic-gate 	{ MII_STATUS,			"mii_status"		},
4860Sstevel@tonic-gate 	{ MII_PHYIDH,			"phy_identifier"	},
4870Sstevel@tonic-gate 	{ MII_AN_ADVERT,		"an_advert"		},
4880Sstevel@tonic-gate 	{ MII_AN_LPABLE,		"an_lp_ability"		},
4890Sstevel@tonic-gate 	{ MII_AN_EXPANSION,		"an_expansion"		},
4900Sstevel@tonic-gate 	{ MII_AN_LPNXTPG,		"an_lp_nextpage"	},
4910Sstevel@tonic-gate 	{ MII_1000BASE_T_CONTROL,	"gbit_control"		},
4920Sstevel@tonic-gate 	{ MII_1000BASE_T_STATUS,	"gbit_status"		},
4930Sstevel@tonic-gate 	{ MII_IEEE_EXT_STATUS,		"ieee_ext_status"	},
4940Sstevel@tonic-gate 	{ MII_EXT_CONTROL,		"phy_ext_control"	},
4950Sstevel@tonic-gate 	{ MII_EXT_STATUS,		"phy_ext_status"	},
4960Sstevel@tonic-gate 	{ MII_RCV_ERR_COUNT,		"receive_error_count"	},
4970Sstevel@tonic-gate 	{ MII_FALSE_CARR_COUNT,		"false_carrier_count"	},
4980Sstevel@tonic-gate 	{ MII_RCV_NOT_OK_COUNT,		"receiver_not_ok_count"	},
4990Sstevel@tonic-gate 	{ MII_AUX_CONTROL,		"aux_control"		},
5000Sstevel@tonic-gate 	{ MII_AUX_STATUS,		"aux_status"		},
5010Sstevel@tonic-gate 	{ MII_INTR_STATUS,		"intr_status"		},
5020Sstevel@tonic-gate 	{ MII_INTR_MASK,		"intr_mask"		},
5030Sstevel@tonic-gate 	{ MII_HCD_STATUS,		"hcd_status"		},
5040Sstevel@tonic-gate 
5050Sstevel@tonic-gate 	{ -1,				NULL }
5060Sstevel@tonic-gate };
5070Sstevel@tonic-gate 
5080Sstevel@tonic-gate static int
5090Sstevel@tonic-gate bge_phydata_update(kstat_t *ksp, int flag)
5100Sstevel@tonic-gate {
5110Sstevel@tonic-gate 	bge_t *bgep;
5120Sstevel@tonic-gate 	kstat_named_t *knp;
5130Sstevel@tonic-gate 	const bge_ksindex_t *ksip;
5140Sstevel@tonic-gate 
5150Sstevel@tonic-gate 	if (flag != KSTAT_READ)
5160Sstevel@tonic-gate 		return (EACCES);
5170Sstevel@tonic-gate 
5180Sstevel@tonic-gate 	bgep = ksp->ks_private;
5191865Sdilpreet 	if (bgep->bge_chip_state == BGE_CHIP_FAULT)
5201865Sdilpreet 		return (EIO);
5211865Sdilpreet 
5220Sstevel@tonic-gate 	knp = ksp->ks_data;
5230Sstevel@tonic-gate 
5240Sstevel@tonic-gate 	/*
5250Sstevel@tonic-gate 	 * Read the PHY registers & update the kstats ...
5260Sstevel@tonic-gate 	 *
5270Sstevel@tonic-gate 	 * We need to hold the mutex while performing MII reads, but
5280Sstevel@tonic-gate 	 * we don't want to hold it across the entire sequence of reads.
5290Sstevel@tonic-gate 	 * So we grab and release it on each iteration, 'cos it doesn't
5300Sstevel@tonic-gate 	 * really matter if the kstats are less than 100% consistent ...
5310Sstevel@tonic-gate 	 */
5320Sstevel@tonic-gate 	for (ksip = bge_phydata; ksip->name != NULL; ++knp, ++ksip) {
5330Sstevel@tonic-gate 		mutex_enter(bgep->genlock);
5340Sstevel@tonic-gate 		switch (ksip->index) {
5350Sstevel@tonic-gate 		case MII_STATUS:
5360Sstevel@tonic-gate 			knp->value.ui64 = bgep->phy_gen_status;
5370Sstevel@tonic-gate 			break;
5380Sstevel@tonic-gate 
5390Sstevel@tonic-gate 		case MII_PHYIDH:
5400Sstevel@tonic-gate 			knp->value.ui64 = bge_mii_get16(bgep, MII_PHYIDH);
5410Sstevel@tonic-gate 			knp->value.ui64 <<= 16;
5420Sstevel@tonic-gate 			knp->value.ui64 |= bge_mii_get16(bgep, MII_PHYIDL);
5430Sstevel@tonic-gate 			break;
5440Sstevel@tonic-gate 
5450Sstevel@tonic-gate 		default:
5460Sstevel@tonic-gate 			knp->value.ui64 = bge_mii_get16(bgep, ksip->index);
5470Sstevel@tonic-gate 			break;
5480Sstevel@tonic-gate 		}
5491865Sdilpreet 		if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
5501865Sdilpreet 			ddi_fm_service_impact(bgep->devinfo,
5511865Sdilpreet 			    DDI_SERVICE_DEGRADED);
5521865Sdilpreet 			mutex_exit(bgep->genlock);
5531865Sdilpreet 			return (EIO);
5541865Sdilpreet 		}
5550Sstevel@tonic-gate 		mutex_exit(bgep->genlock);
5560Sstevel@tonic-gate 	}
5570Sstevel@tonic-gate 
5580Sstevel@tonic-gate 	return (0);
5590Sstevel@tonic-gate }
5600Sstevel@tonic-gate 
5610Sstevel@tonic-gate static kstat_t *
5620Sstevel@tonic-gate bge_setup_named_kstat(bge_t *bgep, int instance, char *name,
5630Sstevel@tonic-gate 	const bge_ksindex_t *ksip, size_t size, int (*update)(kstat_t *, int))
5640Sstevel@tonic-gate {
5650Sstevel@tonic-gate 	kstat_t *ksp;
5660Sstevel@tonic-gate 	kstat_named_t *knp;
5670Sstevel@tonic-gate 	char *np;
5680Sstevel@tonic-gate 	int type;
5690Sstevel@tonic-gate 
5700Sstevel@tonic-gate 	size /= sizeof (bge_ksindex_t);
5710Sstevel@tonic-gate 	ksp = kstat_create(BGE_DRIVER_NAME, instance, name, "net",
572*4711Sml149210 	    KSTAT_TYPE_NAMED, size-1, KSTAT_FLAG_PERSISTENT);
5730Sstevel@tonic-gate 	if (ksp == NULL)
5740Sstevel@tonic-gate 		return (NULL);
5750Sstevel@tonic-gate 
5760Sstevel@tonic-gate 	ksp->ks_private = bgep;
5770Sstevel@tonic-gate 	ksp->ks_update = update;
5780Sstevel@tonic-gate 	for (knp = ksp->ks_data; (np = ksip->name) != NULL; ++knp, ++ksip) {
5790Sstevel@tonic-gate 		switch (*np) {
5800Sstevel@tonic-gate 		default:
5810Sstevel@tonic-gate 			type = KSTAT_DATA_UINT64;
5820Sstevel@tonic-gate 			break;
5830Sstevel@tonic-gate 		case '%':
5840Sstevel@tonic-gate 			np += 1;
5850Sstevel@tonic-gate 			type = KSTAT_DATA_UINT32;
5860Sstevel@tonic-gate 			break;
5870Sstevel@tonic-gate 		case '$':
5880Sstevel@tonic-gate 			np += 1;
5890Sstevel@tonic-gate 			type = KSTAT_DATA_STRING;
5900Sstevel@tonic-gate 			break;
5910Sstevel@tonic-gate 		case '&':
5920Sstevel@tonic-gate 			np += 1;
5930Sstevel@tonic-gate 			type = KSTAT_DATA_CHAR;
5940Sstevel@tonic-gate 			break;
5950Sstevel@tonic-gate 		}
5960Sstevel@tonic-gate 		kstat_named_init(knp, np, type);
5970Sstevel@tonic-gate 	}
5980Sstevel@tonic-gate 	kstat_install(ksp);
5990Sstevel@tonic-gate 
6000Sstevel@tonic-gate 	return (ksp);
6010Sstevel@tonic-gate }
6020Sstevel@tonic-gate 
6030Sstevel@tonic-gate /*
6040Sstevel@tonic-gate  * Create kstats corresponding to NDD parameters
6050Sstevel@tonic-gate  */
6060Sstevel@tonic-gate static kstat_t *
6070Sstevel@tonic-gate bge_setup_params_kstat(bge_t *bgep, int instance, char *name,
6080Sstevel@tonic-gate 	int (*update)(kstat_t *, int))
6090Sstevel@tonic-gate {
6100Sstevel@tonic-gate 	kstat_t *ksp;
6110Sstevel@tonic-gate 	kstat_named_t *knp;
6120Sstevel@tonic-gate 	int i;
6130Sstevel@tonic-gate 
6140Sstevel@tonic-gate 	ksp = kstat_create(BGE_DRIVER_NAME, instance, name, "net",
615*4711Sml149210 	    KSTAT_TYPE_NAMED, PARAM_COUNT, KSTAT_FLAG_PERSISTENT);
6160Sstevel@tonic-gate 	if (ksp != NULL) {
6170Sstevel@tonic-gate 		ksp->ks_private = bgep;
6180Sstevel@tonic-gate 		ksp->ks_update = update;
6190Sstevel@tonic-gate 		for (knp = ksp->ks_data, i = 0; i < PARAM_COUNT; ++knp, ++i)
6200Sstevel@tonic-gate 			kstat_named_init(knp, bgep->nd_params[i].ndp_name+1,
621*4711Sml149210 			    KSTAT_DATA_UINT64);
6220Sstevel@tonic-gate 		kstat_install(ksp);
6230Sstevel@tonic-gate 	}
6240Sstevel@tonic-gate 
6250Sstevel@tonic-gate 	return (ksp);
6260Sstevel@tonic-gate }
6270Sstevel@tonic-gate 
6280Sstevel@tonic-gate void
6290Sstevel@tonic-gate bge_init_kstats(bge_t *bgep, int instance)
6300Sstevel@tonic-gate {
6310Sstevel@tonic-gate 	kstat_t *ksp;
6320Sstevel@tonic-gate 
6330Sstevel@tonic-gate 	BGE_TRACE(("bge_init_kstats($%p, %d)", (void *)bgep, instance));
6340Sstevel@tonic-gate 
6351102Sly149593 	if (bgep->chipid.statistic_type == BGE_STAT_BLK) {
6361102Sly149593 		DMA_ZERO(bgep->statistics);
6371102Sly149593 		bgep->bge_kstats[BGE_KSTAT_RAW] = ksp =
638*4711Sml149210 		    kstat_create(BGE_DRIVER_NAME, instance,
639*4711Sml149210 		    "raw_statistics", "net", KSTAT_TYPE_RAW,
640*4711Sml149210 		    sizeof (bge_statistics_t), KSTAT_FLAG_VIRTUAL);
6411102Sly149593 		if (ksp != NULL) {
6421102Sly149593 			ksp->ks_data = DMA_VPTR(bgep->statistics);
6431102Sly149593 			kstat_install(ksp);
6441102Sly149593 		}
6451102Sly149593 
6461102Sly149593 		bgep->bge_kstats[BGE_KSTAT_STATS] = bge_setup_named_kstat(bgep,
647*4711Sml149210 		    instance, "statistics", bge_statistics,
648*4711Sml149210 		    sizeof (bge_statistics), bge_statistics_update);
6491102Sly149593 	} else {
6501102Sly149593 		bgep->bge_kstats[BGE_KSTAT_STATS] = bge_setup_named_kstat(bgep,
651*4711Sml149210 		    instance, "statistics", bge_stat_val,
652*4711Sml149210 		    sizeof (bge_stat_val), bge_statistics_update);
6530Sstevel@tonic-gate 	}
6540Sstevel@tonic-gate 
6550Sstevel@tonic-gate 	bgep->bge_kstats[BGE_KSTAT_CHIPID] = bge_setup_named_kstat(bgep,
656*4711Sml149210 	    instance, "chipid", bge_chipid,
657*4711Sml149210 	    sizeof (bge_chipid), bge_chipid_update);
6580Sstevel@tonic-gate 
6590Sstevel@tonic-gate 	bgep->bge_kstats[BGE_KSTAT_DRIVER] = bge_setup_named_kstat(bgep,
660*4711Sml149210 	    instance, "driverinfo", bge_driverinfo,
661*4711Sml149210 	    sizeof (bge_driverinfo), bge_driverinfo_update);
6620Sstevel@tonic-gate 
6630Sstevel@tonic-gate 	if (bgep->chipid.flags & CHIP_FLAG_SERDES)
6640Sstevel@tonic-gate 		bgep->bge_kstats[BGE_KSTAT_PHYS] = bge_setup_named_kstat(bgep,
665*4711Sml149210 		    instance, "serdes", bge_serdes,
666*4711Sml149210 		    sizeof (bge_serdes), bge_serdes_update);
6670Sstevel@tonic-gate 	else
6680Sstevel@tonic-gate 		bgep->bge_kstats[BGE_KSTAT_PHYS] = bge_setup_named_kstat(bgep,
669*4711Sml149210 		    instance, "phydata", bge_phydata,
670*4711Sml149210 		    sizeof (bge_phydata), bge_phydata_update);
6710Sstevel@tonic-gate 
6720Sstevel@tonic-gate }
6730Sstevel@tonic-gate 
6740Sstevel@tonic-gate void
6750Sstevel@tonic-gate bge_fini_kstats(bge_t *bgep)
6760Sstevel@tonic-gate {
6770Sstevel@tonic-gate 	int i;
6780Sstevel@tonic-gate 
6790Sstevel@tonic-gate 	BGE_TRACE(("bge_fini_kstats($%p)", (void *)bgep));
6800Sstevel@tonic-gate 
6810Sstevel@tonic-gate 	for (i = BGE_KSTAT_COUNT; --i >= 0; )
6820Sstevel@tonic-gate 		if (bgep->bge_kstats[i] != NULL)
6830Sstevel@tonic-gate 			kstat_delete(bgep->bge_kstats[i]);
6840Sstevel@tonic-gate }
6850Sstevel@tonic-gate 
6862311Sseb int
6872311Sseb bge_m_stat(void *arg, uint_t stat, uint64_t *val)
6880Sstevel@tonic-gate {
6890Sstevel@tonic-gate 	bge_t *bgep = arg;
6901102Sly149593 	bge_statistics_t *bstp;
6913334Sgs150176 	bge_statistics_reg_t *pstats;
6920Sstevel@tonic-gate 
6931865Sdilpreet 	if (bgep->bge_chip_state == BGE_CHIP_FAULT) {
6942311Sseb 		return (EINVAL);
6952311Sseb 	}
6962311Sseb 
6972311Sseb 	/*
6982311Sseb 	 * The MII/GMII physical layer 802.3 stats are not supported by the
6992311Sseb 	 * bge optical interface.
7002311Sseb 	 */
7012311Sseb 	if ((bgep->chipid.flags & CHIP_FLAG_SERDES) && ETHER_STAT_ISMII(stat)) {
7022311Sseb 		return (ENOTSUP);
7031865Sdilpreet 	}
7041865Sdilpreet 
7051102Sly149593 	if (bgep->chipid.statistic_type == BGE_STAT_BLK)
7061102Sly149593 		bstp = DMA_VPTR(bgep->statistics);
7071102Sly149593 	else {
7083334Sgs150176 		pstats = bgep->pstats;
7093334Sgs150176 		pstats->ifHCOutOctets +=
7103334Sgs150176 		    bge_reg_get32(bgep, STAT_IFHCOUT_OCTETS_REG);
7113334Sgs150176 		pstats->etherStatsCollisions +=
7123334Sgs150176 		    bge_reg_get32(bgep, STAT_ETHER_COLLIS_REG);
7133334Sgs150176 		pstats->outXonSent +=
7143334Sgs150176 		    bge_reg_get32(bgep, STAT_OUTXON_SENT_REG);
7153334Sgs150176 		pstats->outXoffSent +=
7163334Sgs150176 		    bge_reg_get32(bgep, STAT_OUTXOFF_SENT_REG);
7173334Sgs150176 		pstats->dot3StatsInternalMacTransmitErrors +=
7183334Sgs150176 		    bge_reg_get32(bgep, STAT_DOT3_INTMACTX_ERR_REG);
7193334Sgs150176 		pstats->dot3StatsSingleCollisionFrames +=
7203334Sgs150176 		    bge_reg_get32(bgep, STAT_DOT3_SCOLLI_FRAME_REG);
7213334Sgs150176 		pstats->dot3StatsMultipleCollisionFrames +=
7223334Sgs150176 		    bge_reg_get32(bgep, STAT_DOT3_MCOLLI_FRAME_REG);
7233334Sgs150176 		pstats->dot3StatsDeferredTransmissions +=
7243334Sgs150176 		    bge_reg_get32(bgep, STAT_DOT3_DEFERED_TX_REG);
7253334Sgs150176 		pstats->dot3StatsExcessiveCollisions +=
7263334Sgs150176 		    bge_reg_get32(bgep, STAT_DOT3_EXCE_COLLI_REG);
7273334Sgs150176 		pstats->dot3StatsLateCollisions +=
7283334Sgs150176 		    bge_reg_get32(bgep, STAT_DOT3_LATE_COLLI_REG);
7293334Sgs150176 		pstats->ifHCOutUcastPkts +=
7303334Sgs150176 		    bge_reg_get32(bgep, STAT_IFHCOUT_UPKGS_REG);
7313334Sgs150176 		pstats->ifHCOutMulticastPkts +=
7323334Sgs150176 		    bge_reg_get32(bgep, STAT_IFHCOUT_MPKGS_REG);
7333334Sgs150176 		pstats->ifHCOutBroadcastPkts +=
7343334Sgs150176 		    bge_reg_get32(bgep, STAT_IFHCOUT_BPKGS_REG);
7353334Sgs150176 		pstats->ifHCInOctets +=
7363334Sgs150176 		    bge_reg_get32(bgep, STAT_IFHCIN_OCTETS_REG);
7373334Sgs150176 		pstats->etherStatsFragments +=
7383334Sgs150176 		    bge_reg_get32(bgep, STAT_ETHER_FRAGMENT_REG);
7393334Sgs150176 		pstats->ifHCInUcastPkts +=
7403334Sgs150176 		    bge_reg_get32(bgep, STAT_IFHCIN_UPKGS_REG);
7413334Sgs150176 		pstats->ifHCInMulticastPkts +=
7423334Sgs150176 		    bge_reg_get32(bgep, STAT_IFHCIN_MPKGS_REG);
7433334Sgs150176 		pstats->ifHCInBroadcastPkts +=
7443334Sgs150176 		    bge_reg_get32(bgep, STAT_IFHCIN_BPKGS_REG);
7453334Sgs150176 		pstats->dot3StatsFCSErrors +=
7463334Sgs150176 		    bge_reg_get32(bgep, STAT_DOT3_FCS_ERR_REG);
7473334Sgs150176 		pstats->dot3StatsAlignmentErrors +=
7483334Sgs150176 		    bge_reg_get32(bgep, STAT_DOT3_ALIGN_ERR_REG);
7493334Sgs150176 		pstats->xonPauseFramesReceived +=
7503334Sgs150176 		    bge_reg_get32(bgep, STAT_XON_PAUSE_RX_REG);
7513334Sgs150176 		pstats->xoffPauseFramesReceived +=
7523334Sgs150176 		    bge_reg_get32(bgep, STAT_XOFF_PAUSE_RX_REG);
7533334Sgs150176 		pstats->macControlFramesReceived +=
7543334Sgs150176 		    bge_reg_get32(bgep, STAT_MAC_CTRL_RX_REG);
7553334Sgs150176 		pstats->xoffStateEntered +=
7563334Sgs150176 		    bge_reg_get32(bgep, STAT_XOFF_STATE_ENTER_REG);
7573334Sgs150176 		pstats->dot3StatsFrameTooLongs +=
7583334Sgs150176 		    bge_reg_get32(bgep, STAT_DOT3_FRAME_TOOLONG_REG);
7593334Sgs150176 		pstats->etherStatsJabbers +=
7603334Sgs150176 		    bge_reg_get32(bgep, STAT_ETHER_JABBERS_REG);
7613334Sgs150176 		pstats->etherStatsUndersizePkts +=
7623334Sgs150176 		    bge_reg_get32(bgep, STAT_ETHER_UNDERSIZE_REG);
7632675Szh199473 		mutex_enter(bgep->genlock);
7641865Sdilpreet 		if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
7651865Sdilpreet 			ddi_fm_service_impact(bgep->devinfo,
7661865Sdilpreet 			    DDI_SERVICE_UNAFFECTED);
7671102Sly149593 		}
7682675Szh199473 		mutex_exit(bgep->genlock);
7691865Sdilpreet 	}
7701102Sly149593 
7710Sstevel@tonic-gate 	switch (stat) {
7720Sstevel@tonic-gate 	case MAC_STAT_IFSPEED:
7732311Sseb 		*val = bgep->param_link_speed * 1000000ull;
7740Sstevel@tonic-gate 		break;
7750Sstevel@tonic-gate 
7760Sstevel@tonic-gate 	case MAC_STAT_MULTIRCV:
7771102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
7782311Sseb 			*val = bstp->s.ifHCInMulticastPkts;
7791102Sly149593 		else
7803334Sgs150176 			*val = pstats->ifHCInMulticastPkts;
7810Sstevel@tonic-gate 		break;
7820Sstevel@tonic-gate 
7830Sstevel@tonic-gate 	case MAC_STAT_BRDCSTRCV:
7841102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
7852311Sseb 			*val = bstp->s.ifHCInBroadcastPkts;
7861102Sly149593 		else
7873334Sgs150176 			*val = pstats->ifHCInBroadcastPkts;
7880Sstevel@tonic-gate 		break;
7890Sstevel@tonic-gate 
7900Sstevel@tonic-gate 	case MAC_STAT_MULTIXMT:
7911102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
7922311Sseb 			*val = bstp->s.ifHCOutMulticastPkts;
7931102Sly149593 		else
7943334Sgs150176 			*val = pstats->ifHCOutMulticastPkts;
7950Sstevel@tonic-gate 		break;
7960Sstevel@tonic-gate 
7970Sstevel@tonic-gate 	case MAC_STAT_BRDCSTXMT:
7981102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
7992311Sseb 			*val = bstp->s.ifHCOutBroadcastPkts;
8001102Sly149593 		else
8013334Sgs150176 			*val = pstats->ifHCOutBroadcastPkts;
8020Sstevel@tonic-gate 		break;
8030Sstevel@tonic-gate 
8040Sstevel@tonic-gate 	case MAC_STAT_NORCVBUF:
8051102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
8062311Sseb 			*val = bstp->s.ifInDiscards;
8071102Sly149593 		else
8082311Sseb 			*val = 0;
8090Sstevel@tonic-gate 		break;
8100Sstevel@tonic-gate 
8110Sstevel@tonic-gate 	case MAC_STAT_IERRORS:
8122311Sseb 		if (bgep->chipid.statistic_type == BGE_STAT_BLK) {
8132311Sseb 			*val = bstp->s.dot3StatsFCSErrors +
8143334Sgs150176 			    bstp->s.dot3StatsAlignmentErrors +
8153334Sgs150176 			    bstp->s.dot3StatsFrameTooLongs +
8163334Sgs150176 			    bstp->s.etherStatsUndersizePkts +
8173334Sgs150176 			    bstp->s.etherStatsJabbers;
8182311Sseb 		} else {
8193334Sgs150176 			*val = pstats->dot3StatsFCSErrors +
8203334Sgs150176 			    pstats->dot3StatsAlignmentErrors +
8213334Sgs150176 			    pstats->dot3StatsFrameTooLongs +
8223334Sgs150176 			    pstats->etherStatsUndersizePkts +
8233334Sgs150176 			    pstats->etherStatsJabbers;
8242311Sseb 		}
8250Sstevel@tonic-gate 		break;
8260Sstevel@tonic-gate 
8270Sstevel@tonic-gate 	case MAC_STAT_NOXMTBUF:
8281102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
8292311Sseb 			*val = bstp->s.ifOutDiscards;
8301102Sly149593 		else
8312311Sseb 			*val = 0;
8320Sstevel@tonic-gate 		break;
8330Sstevel@tonic-gate 
8340Sstevel@tonic-gate 	case MAC_STAT_OERRORS:
8351102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
8362311Sseb 			*val = bstp->s.ifOutDiscards;
8371102Sly149593 		else
8382311Sseb 			*val = 0;
8390Sstevel@tonic-gate 		break;
8400Sstevel@tonic-gate 
8410Sstevel@tonic-gate 	case MAC_STAT_COLLISIONS:
8421102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
8432311Sseb 			*val = bstp->s.etherStatsCollisions;
8441102Sly149593 		else
8453334Sgs150176 			*val = pstats->etherStatsCollisions;
8460Sstevel@tonic-gate 		break;
8470Sstevel@tonic-gate 
8480Sstevel@tonic-gate 	case MAC_STAT_RBYTES:
8491102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
8502311Sseb 			*val = bstp->s.ifHCInOctets;
8511102Sly149593 		else
8523334Sgs150176 			*val = pstats->ifHCInOctets;
8530Sstevel@tonic-gate 		break;
8540Sstevel@tonic-gate 
8550Sstevel@tonic-gate 	case MAC_STAT_IPACKETS:
8561102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
8572311Sseb 			*val = bstp->s.ifHCInUcastPkts +
8582311Sseb 			    bstp->s.ifHCInMulticastPkts +
8592311Sseb 			    bstp->s.ifHCInBroadcastPkts;
8601102Sly149593 		else
8613334Sgs150176 			*val = pstats->ifHCInUcastPkts +
8623334Sgs150176 			    pstats->ifHCInMulticastPkts +
8633334Sgs150176 			    pstats->ifHCInBroadcastPkts;
8640Sstevel@tonic-gate 		break;
8650Sstevel@tonic-gate 
8660Sstevel@tonic-gate 	case MAC_STAT_OBYTES:
8671102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
8682311Sseb 			*val = bstp->s.ifHCOutOctets;
8691102Sly149593 		else
8703334Sgs150176 			*val = pstats->ifHCOutOctets;
8710Sstevel@tonic-gate 		break;
8720Sstevel@tonic-gate 
8730Sstevel@tonic-gate 	case MAC_STAT_OPACKETS:
8741102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
8752311Sseb 			*val = bstp->s.ifHCOutUcastPkts +
8762311Sseb 			    bstp->s.ifHCOutMulticastPkts +
8772311Sseb 			    bstp->s.ifHCOutBroadcastPkts;
8781102Sly149593 		else
8793334Sgs150176 			*val = pstats->ifHCOutUcastPkts +
8803334Sgs150176 			    pstats->ifHCOutMulticastPkts +
8813334Sgs150176 			    pstats->ifHCOutBroadcastPkts;
8820Sstevel@tonic-gate 		break;
8830Sstevel@tonic-gate 
8842311Sseb 	case ETHER_STAT_ALIGN_ERRORS:
8851102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
8862311Sseb 			*val = bstp->s.dot3StatsAlignmentErrors;
8871102Sly149593 		else
8883334Sgs150176 			*val = pstats->dot3StatsAlignmentErrors;
8890Sstevel@tonic-gate 		break;
8900Sstevel@tonic-gate 
8912311Sseb 	case ETHER_STAT_FCS_ERRORS:
8921102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
8932311Sseb 			*val = bstp->s.dot3StatsFCSErrors;
8941102Sly149593 		else
8953334Sgs150176 			*val = pstats->dot3StatsFCSErrors;
8960Sstevel@tonic-gate 		break;
8970Sstevel@tonic-gate 
8982311Sseb 	case ETHER_STAT_FIRST_COLLISIONS:
8991102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
9002311Sseb 			*val = bstp->s.dot3StatsSingleCollisionFrames;
9011102Sly149593 		else
9023334Sgs150176 			*val = pstats->dot3StatsSingleCollisionFrames;
9030Sstevel@tonic-gate 		break;
9040Sstevel@tonic-gate 
9052311Sseb 	case ETHER_STAT_MULTI_COLLISIONS:
9061102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
9072311Sseb 			*val = bstp->s.dot3StatsMultipleCollisionFrames;
9081102Sly149593 		else
9093334Sgs150176 			*val = pstats->dot3StatsMultipleCollisionFrames;
9100Sstevel@tonic-gate 		break;
9110Sstevel@tonic-gate 
9122311Sseb 	case ETHER_STAT_DEFER_XMTS:
9131102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
9142311Sseb 			*val = bstp->s.dot3StatsDeferredTransmissions;
9151102Sly149593 		else
9163334Sgs150176 			*val = pstats->dot3StatsDeferredTransmissions;
9170Sstevel@tonic-gate 		break;
9180Sstevel@tonic-gate 
9192311Sseb 	case ETHER_STAT_TX_LATE_COLLISIONS:
9201102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
9212311Sseb 			*val = bstp->s.dot3StatsLateCollisions;
9221102Sly149593 		else
9233334Sgs150176 			*val = pstats->dot3StatsLateCollisions;
9240Sstevel@tonic-gate 		break;
9250Sstevel@tonic-gate 
9262311Sseb 	case ETHER_STAT_EX_COLLISIONS:
9271102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
9282311Sseb 			*val = bstp->s.dot3StatsExcessiveCollisions;
9291102Sly149593 		else
9303334Sgs150176 			*val = pstats->dot3StatsExcessiveCollisions;
9310Sstevel@tonic-gate 		break;
9320Sstevel@tonic-gate 
9332311Sseb 	case ETHER_STAT_MACXMT_ERRORS:
9341102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
9352311Sseb 			*val = bstp->s.dot3StatsInternalMacTransmitErrors;
9361102Sly149593 		else
9373334Sgs150176 			*val = bgep->pstats->dot3StatsInternalMacTransmitErrors;
9380Sstevel@tonic-gate 		break;
9390Sstevel@tonic-gate 
9402311Sseb 	case ETHER_STAT_CARRIER_ERRORS:
9411102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
9422311Sseb 			*val = bstp->s.dot3StatsCarrierSenseErrors;
9431102Sly149593 		else
9442311Sseb 			*val = 0;
9450Sstevel@tonic-gate 		break;
9460Sstevel@tonic-gate 
9472311Sseb 	case ETHER_STAT_TOOLONG_ERRORS:
9481102Sly149593 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
9492311Sseb 			*val = bstp->s.dot3StatsFrameTooLongs;
9501102Sly149593 		else
9513334Sgs150176 			*val = pstats->dot3StatsFrameTooLongs;
9520Sstevel@tonic-gate 		break;
9530Sstevel@tonic-gate 
9544089Sgd78059 	case ETHER_STAT_TOOSHORT_ERRORS:
9554089Sgd78059 		if (bgep->chipid.statistic_type == BGE_STAT_BLK)
9564089Sgd78059 			*val = bstp->s.etherStatsUndersizePkts;
9574089Sgd78059 		else
9584089Sgd78059 			*val = pstats->etherStatsUndersizePkts;
9594089Sgd78059 		break;
9604089Sgd78059 
9612311Sseb 	case ETHER_STAT_XCVR_ADDR:
9622311Sseb 		*val = bgep->phy_mii_addr;
9630Sstevel@tonic-gate 		break;
9640Sstevel@tonic-gate 
9652311Sseb 	case ETHER_STAT_XCVR_ID:
9662675Szh199473 		mutex_enter(bgep->genlock);
9672311Sseb 		*val = bge_mii_get16(bgep, MII_PHYIDH);
9682311Sseb 		*val <<= 16;
9692311Sseb 		*val |= bge_mii_get16(bgep, MII_PHYIDL);
9701865Sdilpreet 		if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
9711865Sdilpreet 			ddi_fm_service_impact(bgep->devinfo,
9721865Sdilpreet 			    DDI_SERVICE_UNAFFECTED);
9731865Sdilpreet 		}
9742675Szh199473 		mutex_exit(bgep->genlock);
9750Sstevel@tonic-gate 		break;
9760Sstevel@tonic-gate 
9772311Sseb 	case ETHER_STAT_XCVR_INUSE:
9782311Sseb 		*val = XCVR_1000T;
9790Sstevel@tonic-gate 		break;
9800Sstevel@tonic-gate 
9812311Sseb 	case ETHER_STAT_CAP_1000FDX:
9822311Sseb 		*val = 1;
9830Sstevel@tonic-gate 		break;
9840Sstevel@tonic-gate 
9852311Sseb 	case ETHER_STAT_CAP_1000HDX:
9862311Sseb 		*val = 1;
9870Sstevel@tonic-gate 		break;
9880Sstevel@tonic-gate 
9892311Sseb 	case ETHER_STAT_CAP_100FDX:
9902311Sseb 		*val = 1;
9910Sstevel@tonic-gate 		break;
9920Sstevel@tonic-gate 
9932311Sseb 	case ETHER_STAT_CAP_100HDX:
9942311Sseb 		*val = 1;
9950Sstevel@tonic-gate 		break;
9960Sstevel@tonic-gate 
9972311Sseb 	case ETHER_STAT_CAP_10FDX:
9982311Sseb 		*val = 1;
9990Sstevel@tonic-gate 		break;
10000Sstevel@tonic-gate 
10012311Sseb 	case ETHER_STAT_CAP_10HDX:
10022311Sseb 		*val = 1;
10030Sstevel@tonic-gate 		break;
10040Sstevel@tonic-gate 
10052311Sseb 	case ETHER_STAT_CAP_ASMPAUSE:
10062311Sseb 		*val = 1;
10070Sstevel@tonic-gate 		break;
10080Sstevel@tonic-gate 
10092311Sseb 	case ETHER_STAT_CAP_PAUSE:
10102311Sseb 		*val = 1;
10110Sstevel@tonic-gate 		break;
10120Sstevel@tonic-gate 
10132311Sseb 	case ETHER_STAT_CAP_AUTONEG:
10142311Sseb 		*val = 1;
10150Sstevel@tonic-gate 		break;
10160Sstevel@tonic-gate 
10174089Sgd78059 	case ETHER_STAT_CAP_REMFAULT:
10184089Sgd78059 		*val = 1;
10194089Sgd78059 		break;
10204089Sgd78059 
10212311Sseb 	case ETHER_STAT_ADV_CAP_1000FDX:
10222311Sseb 		*val = bgep->param_adv_1000fdx;
10230Sstevel@tonic-gate 		break;
10240Sstevel@tonic-gate 
10252311Sseb 	case ETHER_STAT_ADV_CAP_1000HDX:
10262311Sseb 		*val = bgep->param_adv_1000hdx;
10270Sstevel@tonic-gate 		break;
10280Sstevel@tonic-gate 
10292311Sseb 	case ETHER_STAT_ADV_CAP_100FDX:
10302311Sseb 		*val = bgep->param_adv_100fdx;
10310Sstevel@tonic-gate 		break;
10320Sstevel@tonic-gate 
10332311Sseb 	case ETHER_STAT_ADV_CAP_100HDX:
10342311Sseb 		*val = bgep->param_adv_100hdx;
10350Sstevel@tonic-gate 		break;
10360Sstevel@tonic-gate 
10372311Sseb 	case ETHER_STAT_ADV_CAP_10FDX:
10382311Sseb 		*val = bgep->param_adv_10fdx;
10390Sstevel@tonic-gate 		break;
10400Sstevel@tonic-gate 
10412311Sseb 	case ETHER_STAT_ADV_CAP_10HDX:
10422311Sseb 		*val = bgep->param_adv_10hdx;
10430Sstevel@tonic-gate 		break;
10440Sstevel@tonic-gate 
10452311Sseb 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
10462311Sseb 		*val = bgep->param_adv_asym_pause;
10470Sstevel@tonic-gate 		break;
10480Sstevel@tonic-gate 
10492311Sseb 	case ETHER_STAT_ADV_CAP_PAUSE:
10502311Sseb 		*val = bgep->param_adv_pause;
10510Sstevel@tonic-gate 		break;
10520Sstevel@tonic-gate 
10532311Sseb 	case ETHER_STAT_ADV_CAP_AUTONEG:
10542311Sseb 		*val = bgep->param_adv_autoneg;
10550Sstevel@tonic-gate 		break;
10560Sstevel@tonic-gate 
10574089Sgd78059 	case ETHER_STAT_ADV_REMFAULT:
10584089Sgd78059 		mutex_enter(bgep->genlock);
10594089Sgd78059 		*val = bge_mii_get16(bgep, MII_AN_ADVERT) &
10604089Sgd78059 		    MII_AN_ADVERT_REMFAULT ? 1 : 0;
10614089Sgd78059 		if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
10624089Sgd78059 			ddi_fm_service_impact(bgep->devinfo,
10634089Sgd78059 			    DDI_SERVICE_UNAFFECTED);
10644089Sgd78059 		}
10654089Sgd78059 		mutex_exit(bgep->genlock);
10664089Sgd78059 		break;
10674089Sgd78059 
10682311Sseb 	case ETHER_STAT_LP_CAP_1000FDX:
10692311Sseb 		*val = bgep->param_lp_1000fdx;
10700Sstevel@tonic-gate 		break;
10710Sstevel@tonic-gate 
10722311Sseb 	case ETHER_STAT_LP_CAP_1000HDX:
10732311Sseb 		*val = bgep->param_lp_1000hdx;
10740Sstevel@tonic-gate 		break;
10750Sstevel@tonic-gate 
10762311Sseb 	case ETHER_STAT_LP_CAP_100FDX:
10772311Sseb 		*val = bgep->param_lp_100fdx;
10780Sstevel@tonic-gate 		break;
10790Sstevel@tonic-gate 
10802311Sseb 	case ETHER_STAT_LP_CAP_100HDX:
10812311Sseb 		*val = bgep->param_lp_100hdx;
10820Sstevel@tonic-gate 		break;
10830Sstevel@tonic-gate 
10842311Sseb 	case ETHER_STAT_LP_CAP_10FDX:
10852311Sseb 		*val = bgep->param_lp_10fdx;
10860Sstevel@tonic-gate 		break;
10870Sstevel@tonic-gate 
10882311Sseb 	case ETHER_STAT_LP_CAP_10HDX:
10892311Sseb 		*val = bgep->param_lp_10hdx;
10900Sstevel@tonic-gate 		break;
10910Sstevel@tonic-gate 
10922311Sseb 	case ETHER_STAT_LP_CAP_ASMPAUSE:
10932311Sseb 		*val = bgep->param_lp_asym_pause;
10940Sstevel@tonic-gate 		break;
10950Sstevel@tonic-gate 
10962311Sseb 	case ETHER_STAT_LP_CAP_PAUSE:
10972311Sseb 		*val = bgep->param_lp_pause;
10982311Sseb 		break;
10992311Sseb 
11002311Sseb 	case ETHER_STAT_LP_CAP_AUTONEG:
11012311Sseb 		*val = bgep->param_lp_autoneg;
11020Sstevel@tonic-gate 		break;
11030Sstevel@tonic-gate 
11044089Sgd78059 	case ETHER_STAT_LP_REMFAULT:
11054089Sgd78059 		mutex_enter(bgep->genlock);
11064089Sgd78059 		*val = bge_mii_get16(bgep, MII_AN_LPABLE) &
11074089Sgd78059 		    MII_AN_ADVERT_REMFAULT ? 1 : 0;
11084089Sgd78059 		if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
11094089Sgd78059 			ddi_fm_service_impact(bgep->devinfo,
11104089Sgd78059 			    DDI_SERVICE_UNAFFECTED);
11114089Sgd78059 		}
11124089Sgd78059 		mutex_exit(bgep->genlock);
11134089Sgd78059 		break;
11144089Sgd78059 
11152311Sseb 	case ETHER_STAT_LINK_ASMPAUSE:
11162311Sseb 		*val = bgep->param_adv_asym_pause &&
11172311Sseb 		    bgep->param_lp_asym_pause &&
11182311Sseb 		    bgep->param_adv_pause != bgep->param_lp_pause;
11192675Szh199473 		break;
11200Sstevel@tonic-gate 
11212311Sseb 	case ETHER_STAT_LINK_PAUSE:
11222311Sseb 		*val = bgep->param_link_rx_pause;
11230Sstevel@tonic-gate 		break;
11240Sstevel@tonic-gate 
11252311Sseb 	case ETHER_STAT_LINK_AUTONEG:
11262311Sseb 		*val = bgep->param_link_autoneg;
11272311Sseb 		break;
11282311Sseb 
11292311Sseb 	case ETHER_STAT_LINK_DUPLEX:
11302311Sseb 		*val = bgep->param_link_duplex;
11312311Sseb 		break;
11322311Sseb 
11330Sstevel@tonic-gate 	default:
11342311Sseb 		return (ENOTSUP);
11350Sstevel@tonic-gate 	}
11360Sstevel@tonic-gate 
11372311Sseb 	return (0);
11380Sstevel@tonic-gate }
1139