xref: /onnv-gate/usr/src/uts/common/io/nge/nge_kstats.c (revision 10837:440639357e43)
15578Smx205022 /*
25578Smx205022  * CDDL HEADER START
35578Smx205022  *
45578Smx205022  * The contents of this file are subject to the terms of the
55578Smx205022  * Common Development and Distribution License (the "License").
65578Smx205022  * You may not use this file except in compliance with the License.
75578Smx205022  *
85578Smx205022  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95578Smx205022  * or http://www.opensolaris.org/os/licensing.
105578Smx205022  * See the License for the specific language governing permissions
115578Smx205022  * and limitations under the License.
125578Smx205022  *
135578Smx205022  * When distributing Covered Code, include this CDDL HEADER in each
145578Smx205022  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155578Smx205022  * If applicable, add the following below this CDDL HEADER, with the
165578Smx205022  * fields enclosed by brackets "[]" replaced with your own identifying
175578Smx205022  * information: Portions Copyright [yyyy] [name of copyright owner]
185578Smx205022  *
195578Smx205022  * CDDL HEADER END
205578Smx205022  */
215578Smx205022 
225574Smx205022 /*
23*10837SLi-Zhen.You@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
245574Smx205022  * Use is subject to license terms.
255574Smx205022  */
265574Smx205022 
275574Smx205022 
285574Smx205022 #include "nge.h"
295574Smx205022 
305574Smx205022 #undef	NGE_DBG
315574Smx205022 #define	NGE_DBG		NGE_DBG_STATS	/* debug flag for this code	*/
325574Smx205022 
335574Smx205022 /*
345574Smx205022  * Table of Hardware-defined Statistics Block Offsets and Names
355574Smx205022  */
365574Smx205022 #define	KS_NAME(s)			{ KS_ ## s, #s }
375574Smx205022 
385574Smx205022 const nge_ksindex_t nge_statistics[] = {
395574Smx205022 
405574Smx205022 	KS_NAME(ifHOutOctets),
415574Smx205022 	KS_NAME(ifHOutZeroRetranCount),
425574Smx205022 	KS_NAME(ifHOutOneRetranCount),
435574Smx205022 	KS_NAME(ifHOutMoreRetranCount),
445574Smx205022 	KS_NAME(ifHOutColCount),
455574Smx205022 	KS_NAME(ifHOutFifoovCount),
465574Smx205022 	KS_NAME(ifHOutLOCCount),
475574Smx205022 	KS_NAME(ifHOutExDecCount),
485574Smx205022 	KS_NAME(ifHOutRetryCount),
495574Smx205022 	KS_NAME(ifHInFrameErrCount),
505574Smx205022 	KS_NAME(ifHInExtraOctErrCount),
515574Smx205022 	KS_NAME(ifHInLColErrCount),
525574Smx205022 	KS_NAME(ifHInOversizeErrCount),
535574Smx205022 	KS_NAME(ifHInFovErrCount),
545574Smx205022 	KS_NAME(ifHInFCSErrCount),
555574Smx205022 	KS_NAME(ifHInAlignErrCount),
565574Smx205022 	KS_NAME(ifHInLenErrCount),
575574Smx205022 	KS_NAME(ifHInUniPktsCount),
585574Smx205022 	KS_NAME(ifHInBroadPksCount),
595574Smx205022 	KS_NAME(ifHInMulPksCount),
605574Smx205022 	{ KS_STATS_SIZE, NULL }
615574Smx205022 };
625574Smx205022 
635574Smx205022 /*
645574Smx205022  * Local datatype for defining tables of (Offset, Name) pairs
655574Smx205022  */
665574Smx205022 static int
nge_statistics_update(kstat_t * ksp,int flag)675574Smx205022 nge_statistics_update(kstat_t *ksp, int flag)
685574Smx205022 {
695574Smx205022 	uint32_t regno;
705574Smx205022 	nge_t *ngep;
715574Smx205022 	nge_statistics_t *istp;
725574Smx205022 	nge_hw_statistics_t *hw_stp;
735574Smx205022 	kstat_named_t *knp;
745574Smx205022 	const nge_ksindex_t *ksip;
755574Smx205022 
765574Smx205022 	if (flag != KSTAT_READ)
775574Smx205022 		return (EACCES);
785574Smx205022 
795574Smx205022 	ngep = ksp->ks_private;
805574Smx205022 	istp = &ngep->statistics;
815574Smx205022 	hw_stp = &istp->hw_statistics;
825574Smx205022 	knp = ksp->ks_data;
835574Smx205022 
845574Smx205022 	/*
855574Smx205022 	 * Transfer the statistics values from the hardware statistics regs
865574Smx205022 	 */
875574Smx205022 	for (ksip = nge_statistics; ksip->name != NULL; ++knp, ++ksip) {
885574Smx205022 		regno = KS_BASE + ksip->index * sizeof (uint32_t);
895898Sjj146644 		hw_stp->a[ksip->index] += nge_reg_get32(ngep, regno);
905898Sjj146644 		knp->value.ui64 = hw_stp->a[ksip->index];
915574Smx205022 	}
925574Smx205022 
935574Smx205022 	return (0);
945574Smx205022 }
955574Smx205022 
965574Smx205022 
975574Smx205022 static const nge_ksindex_t nge_chipinfo[] = {
985574Smx205022 	{ 0,				"businfo"		},
995574Smx205022 	{ 1,				"command"		},
1005574Smx205022 	{ 2,				"vendor_id"		},
1015574Smx205022 	{ 3,				"device_id"		},
1025574Smx205022 	{ 4,				"subsystem_vendor_id"	},
1035574Smx205022 	{ 5,				"subsystem_device_id"	},
1045574Smx205022 	{ 6,				"revision_id"		},
1055574Smx205022 	{ 7,				"cache_line_size"	},
1065574Smx205022 	{ 8,				"latency_timer"		},
1075574Smx205022 	{ 9,				"phy_mode"		},
1085574Smx205022 	{ 10,				"phy_id"		},
1095574Smx205022 	{ 11,				"hw_mac_addr"		},
1105574Smx205022 	{ 12,				"&bus_type"		},
1115574Smx205022 	{ 13,				"&bus_speed"		},
1125574Smx205022 	{ 14,				"&bus_size"		},
1135574Smx205022 	{ -1,				NULL 			}
1145574Smx205022 };
1155574Smx205022 
1165574Smx205022 static const nge_ksindex_t nge_debuginfo[] = {
1175574Smx205022 	{ 0,				"rx_realloc"		},
1185574Smx205022 	{ 1,				"rx_realloc_fails"	},
1195574Smx205022 	{ 2,				"rx_realloc_DMA_fails"	},
1205574Smx205022 	{ 3,				"rx_realloc_MP_fails"	},
1215574Smx205022 	{ 4,				"rx_rcfree"		},
1225574Smx205022 	{ 5,				"context_switch"	},
1235574Smx205022 	{ 6,				"ip_hsum_err"		},
1245574Smx205022 	{ 7,				"tcp_hsum_err"		},
1255574Smx205022 	{ 8,				"tc_next"		},
1265574Smx205022 	{ 9,				"tx_next"		},
1275574Smx205022 	{ 10,				"tx_free"		},
1285574Smx205022 	{ 11,				"tx_flow"		},
1295574Smx205022 	{ 12,				"rx_prod"		},
1305574Smx205022 	{ 13,				"rx_hold"		},
1315574Smx205022 	{ 14,				"rx_nobuf"		},
1325574Smx205022 	{ 15,				"rx_err"		},
1335574Smx205022 	{16,				"tx_err"		},
1345574Smx205022 	{17,				"tx_stall"		},
1355574Smx205022 	{ -1,				NULL 			}
1365574Smx205022 };
1375574Smx205022 
1385574Smx205022 static int
nge_chipinfo_update(kstat_t * ksp,int flag)1395574Smx205022 nge_chipinfo_update(kstat_t *ksp, int flag)
1405574Smx205022 {
1415574Smx205022 	nge_t *ngep;
1425574Smx205022 	kstat_named_t *knp;
1435574Smx205022 	chip_info_t *infop;
1445574Smx205022 
1455574Smx205022 	if (flag != KSTAT_READ)
1465574Smx205022 		return (EACCES);
1475574Smx205022 
1485574Smx205022 	ngep = ksp->ks_private;
1495574Smx205022 	infop = &ngep->chipinfo;
1505574Smx205022 	knp = ksp->ks_data;
1515574Smx205022 
1525574Smx205022 	(knp++)->value.ui64 = infop->businfo;
1535574Smx205022 	(knp++)->value.ui64 = infop->command;
1545574Smx205022 	(knp++)->value.ui64 = infop->vendor;
1555574Smx205022 	(knp++)->value.ui64 = infop->device;
1565574Smx205022 	(knp++)->value.ui64 = infop->subven;
1575574Smx205022 	(knp++)->value.ui64 = infop->subdev;
1585574Smx205022 	(knp++)->value.ui64 = infop->revision;
1595574Smx205022 	(knp++)->value.ui64 = infop->clsize;
1605574Smx205022 	(knp++)->value.ui64 = infop->latency;
1615574Smx205022 	(knp++)->value.ui64 = ngep->phy_mode;
1625574Smx205022 	(knp++)->value.ui64 = ngep->phy_id;
1635574Smx205022 	(knp++)->value.ui64 = infop->hw_mac_addr;
1645574Smx205022 	return (0);
1655574Smx205022 }
1665574Smx205022 
1675574Smx205022 static int
nge_debuginfo_update(kstat_t * ksp,int flag)1685574Smx205022 nge_debuginfo_update(kstat_t *ksp, int flag)
1695574Smx205022 {
1705574Smx205022 	nge_t *ngep;
1715574Smx205022 	kstat_named_t *knp;
1725574Smx205022 	nge_sw_statistics_t *sw_stp;
1735574Smx205022 
1745574Smx205022 	if (flag != KSTAT_READ)
1755574Smx205022 		return (EACCES);
1765574Smx205022 
1775574Smx205022 	ngep = ksp->ks_private;
1785574Smx205022 	sw_stp = &ngep->statistics.sw_statistics;
1795574Smx205022 	knp = ksp->ks_data;
1805574Smx205022 
1815574Smx205022 	(knp++)->value.ui64 = sw_stp->recv_realloc;
1825574Smx205022 	(knp++)->value.ui64 = sw_stp->kmem_alloc_err;
1835574Smx205022 	(knp++)->value.ui64 = sw_stp->dma_alloc_err;
1845574Smx205022 	(knp++)->value.ui64 = sw_stp->mp_alloc_err;
1855574Smx205022 	(knp++)->value.ui64 = sw_stp->recy_free;
1865574Smx205022 	(knp++)->value.ui64 = sw_stp->load_context;
1875574Smx205022 	(knp++)->value.ui64 = sw_stp->ip_hwsum_err;
1885574Smx205022 	(knp++)->value.ui64 = sw_stp->tcp_hwsum_err;
1895574Smx205022 	(knp++)->value.ui64 = ngep->send->tc_next;
1905574Smx205022 	(knp++)->value.ui64 = ngep->send->tx_next;
1915574Smx205022 	(knp++)->value.ui64 = ngep->send->tx_free;
1925574Smx205022 	(knp++)->value.ui64 = ngep->send->tx_flow;
1935574Smx205022 	(knp++)->value.ui64 = ngep->recv->prod_index;
1945574Smx205022 	(knp++)->value.ui64 = ngep->buff->rx_hold;
1955574Smx205022 	(knp++)->value.ui64 = sw_stp->rx_nobuffer;
1965574Smx205022 	(knp++)->value.ui64 = sw_stp->rx_err;
1975574Smx205022 	(knp++)->value.ui64 = sw_stp->tx_stop_err;
1985574Smx205022 	(knp++)->value.ui64 = sw_stp->tx_stall;
1995574Smx205022 	return (0);
2005574Smx205022 }
2015574Smx205022 
2025574Smx205022 static kstat_t *
nge_setup_named_kstat(nge_t * ngep,int instance,char * name,const nge_ksindex_t * ksip,size_t size,int (* update)(kstat_t *,int))2035574Smx205022 nge_setup_named_kstat(nge_t *ngep, int instance, char *name,
2045574Smx205022 	const nge_ksindex_t *ksip, size_t size, int (*update)(kstat_t *, int))
2055574Smx205022 {
2065574Smx205022 	kstat_t *ksp;
2075574Smx205022 	kstat_named_t *knp;
2085574Smx205022 	char *np;
2095574Smx205022 	int type;
2105574Smx205022 
2115574Smx205022 	size /= sizeof (nge_ksindex_t);
2125574Smx205022 	ksp = kstat_create(NGE_DRIVER_NAME, instance, name, "net",
2135574Smx205022 	    KSTAT_TYPE_NAMED, size-1, KSTAT_FLAG_PERSISTENT);
2145574Smx205022 	if (ksp == NULL)
2155574Smx205022 		return (NULL);
2165574Smx205022 
2175574Smx205022 	ksp->ks_private = ngep;
2185574Smx205022 	ksp->ks_update = update;
2195574Smx205022 	for (knp = ksp->ks_data; (np = ksip->name) != NULL; ++knp, ++ksip) {
2205574Smx205022 		switch (*np) {
2215574Smx205022 		default:
2225574Smx205022 			type = KSTAT_DATA_UINT64;
2235574Smx205022 			break;
2245574Smx205022 		case '%':
2255574Smx205022 			np += 1;
2265574Smx205022 			type = KSTAT_DATA_UINT32;
2275574Smx205022 			break;
2285574Smx205022 
2295574Smx205022 		case '$':
2305574Smx205022 			np ++;
2315574Smx205022 			type = KSTAT_DATA_STRING;
2325574Smx205022 			break;
2335574Smx205022 		case '&':
2345574Smx205022 			np ++;
2355574Smx205022 			type = KSTAT_DATA_CHAR;
2365574Smx205022 			break;
2375574Smx205022 		}
2385574Smx205022 		kstat_named_init(knp, np, type);
2395574Smx205022 	}
2405574Smx205022 	kstat_install(ksp);
2415574Smx205022 
2425574Smx205022 	return (ksp);
2435574Smx205022 }
2445574Smx205022 
2455574Smx205022 void
nge_init_kstats(nge_t * ngep,int instance)2465574Smx205022 nge_init_kstats(nge_t *ngep, int instance)
2475574Smx205022 {
2485574Smx205022 	NGE_TRACE(("nge_init_kstats($%p, %d)", (void *)ngep, instance));
2495574Smx205022 
2505574Smx205022 	ngep->nge_kstats[NGE_KSTAT_STATS] = nge_setup_named_kstat(ngep,
2515574Smx205022 	    instance, "statistics", nge_statistics,
2525574Smx205022 	    sizeof (nge_statistics), nge_statistics_update);
2535574Smx205022 
2545574Smx205022 	ngep->nge_kstats[NGE_KSTAT_CHIPID] = nge_setup_named_kstat(ngep,
2555574Smx205022 	    instance, "chipinfo", nge_chipinfo,
2565574Smx205022 	    sizeof (nge_chipinfo), nge_chipinfo_update);
2575574Smx205022 
2585574Smx205022 	ngep->nge_kstats[NGE_KSTAT_DEBUG] = nge_setup_named_kstat(ngep,
2595574Smx205022 	    instance, "driver-debug", nge_debuginfo,
2605574Smx205022 	    sizeof (nge_debuginfo), nge_debuginfo_update);
2615574Smx205022 
2625574Smx205022 }
2635574Smx205022 
2645574Smx205022 void
nge_fini_kstats(nge_t * ngep)2655574Smx205022 nge_fini_kstats(nge_t *ngep)
2665574Smx205022 {
2675574Smx205022 	int i;
2685574Smx205022 
2695574Smx205022 	NGE_TRACE(("nge_fini_kstats($%p)", (void *)ngep));
2705574Smx205022 	for (i = NGE_KSTAT_COUNT;  --i >= 0; )
2715574Smx205022 		if (ngep->nge_kstats[i] != NULL)
2725574Smx205022 			kstat_delete(ngep->nge_kstats[i]);
2735574Smx205022 }
2745574Smx205022 
2755574Smx205022 int
nge_m_stat(void * arg,uint_t stat,uint64_t * val)2765574Smx205022 nge_m_stat(void *arg, uint_t stat, uint64_t *val)
2775574Smx205022 {
2785574Smx205022 	nge_t *ngep = arg;
2795898Sjj146644 	uint32_t regno;
2805574Smx205022 	nge_statistics_t *nstp = &ngep->statistics;
2815574Smx205022 	nge_hw_statistics_t *hw_stp = &nstp->hw_statistics;
2825574Smx205022 	nge_sw_statistics_t *sw_stp = &nstp->sw_statistics;
2835574Smx205022 
2845574Smx205022 	switch (stat) {
2855574Smx205022 	case MAC_STAT_IFSPEED:
2865574Smx205022 		*val = ngep->param_link_speed * 1000000ull;
2875574Smx205022 		break;
2885574Smx205022 
2895574Smx205022 	case MAC_STAT_MULTIRCV:
2905898Sjj146644 		regno = KS_BASE + KS_ifHInMulPksCount * sizeof (uint32_t);
2915898Sjj146644 		hw_stp->s.InMulPksCount += nge_reg_get32(ngep, regno);
2925574Smx205022 		*val = hw_stp->s.InMulPksCount;
2935574Smx205022 		break;
2945574Smx205022 
2955574Smx205022 	case MAC_STAT_BRDCSTRCV:
2965898Sjj146644 		regno = KS_BASE +  KS_ifHInBroadPksCount * sizeof (uint32_t);
2975898Sjj146644 		hw_stp->s.InBroadPksCount += nge_reg_get32(ngep, regno);
2985574Smx205022 		*val = hw_stp->s.InBroadPksCount;
2995574Smx205022 		break;
3005574Smx205022 
3015574Smx205022 	case MAC_STAT_NORCVBUF:
3025574Smx205022 		*val = sw_stp->rx_nobuffer;
3035574Smx205022 		break;
3045574Smx205022 
3055574Smx205022 	case MAC_STAT_IERRORS:
3065898Sjj146644 		regno = KS_BASE + KS_ifHInFrameErrCount * sizeof (uint32_t);
3075898Sjj146644 		hw_stp->s.InFrameErrCount += nge_reg_get32(ngep, regno);
3085898Sjj146644 		regno = KS_BASE + KS_ifHInExtraOctErrCount * sizeof (uint32_t);
3095898Sjj146644 		hw_stp->s.InExtraOctErrCount += nge_reg_get32(ngep, regno);
3105898Sjj146644 		regno = KS_BASE + KS_ifHInLColErrCount * sizeof (uint32_t);
3115898Sjj146644 		hw_stp->s.InLColErrCount += nge_reg_get32(ngep, regno);
3125898Sjj146644 		regno = KS_BASE + KS_ifHInOversizeErrCount * sizeof (uint32_t);
3135898Sjj146644 		hw_stp->s.InOversizeErrCount += nge_reg_get32(ngep, regno);
3145898Sjj146644 		regno = KS_BASE + KS_ifHInFovErrCount * sizeof (uint32_t);
3155898Sjj146644 		hw_stp->s.InFovErrCount += nge_reg_get32(ngep, regno);
3165898Sjj146644 		regno = KS_BASE + KS_ifHInFCSErrCount * sizeof (uint32_t);
3175898Sjj146644 		hw_stp->s.InFCSErrCount += nge_reg_get32(ngep, regno);
3185898Sjj146644 		regno = KS_BASE + KS_ifHInAlignErrCount * sizeof (uint32_t);
3195898Sjj146644 		hw_stp->s.InAlignErrCount += nge_reg_get32(ngep, regno);
3205898Sjj146644 		regno = KS_BASE + KS_ifHInLenErrCount * sizeof (uint32_t);
3215898Sjj146644 		hw_stp->s.InLenErrCount += nge_reg_get32(ngep, regno);
3225574Smx205022 		*val = hw_stp->s.InFrameErrCount +
3235574Smx205022 		    hw_stp->s.InExtraOctErrCount +
3245574Smx205022 		    hw_stp->s.InLColErrCount +
3255574Smx205022 		    hw_stp->s.InOversizeErrCount +
3265574Smx205022 		    hw_stp->s.InFovErrCount +
3275574Smx205022 		    hw_stp->s.InFCSErrCount +
3285574Smx205022 		    hw_stp->s.InAlignErrCount +
3295574Smx205022 		    hw_stp->s.InLenErrCount;
3305574Smx205022 		break;
3315574Smx205022 
3325574Smx205022 	case MAC_STAT_OERRORS:
3335898Sjj146644 		regno = KS_BASE + KS_ifHOutFifoovCount * sizeof (uint32_t);
3345898Sjj146644 		hw_stp->s.OutFifoovCount += nge_reg_get32(ngep, regno);
3355898Sjj146644 		regno = KS_BASE + KS_ifHOutLOCCount * sizeof (uint32_t);
3365898Sjj146644 		hw_stp->s.OutLOCCount += nge_reg_get32(ngep, regno);
3375898Sjj146644 		regno = KS_BASE + KS_ifHOutExDecCount * sizeof (uint32_t);
3385898Sjj146644 		hw_stp->s.OutExDecCount += nge_reg_get32(ngep, regno);
3395898Sjj146644 		regno = KS_BASE + KS_ifHOutRetryCount * sizeof (uint32_t);
3405898Sjj146644 		hw_stp->s.OutRetryCount += nge_reg_get32(ngep, regno);
3415574Smx205022 		*val = hw_stp->s.OutFifoovCount +
3425574Smx205022 		    hw_stp->s.OutLOCCount +
3435574Smx205022 		    hw_stp->s.OutExDecCount +
3445574Smx205022 		    hw_stp->s.OutRetryCount;
3455574Smx205022 		break;
3465574Smx205022 
3475574Smx205022 	case MAC_STAT_COLLISIONS:
3485898Sjj146644 		regno = KS_BASE + KS_ifHOutColCount * sizeof (uint32_t);
3495898Sjj146644 		hw_stp->s.OutColCount += nge_reg_get32(ngep, regno);
3505574Smx205022 		*val = hw_stp->s.OutColCount;
3515574Smx205022 		break;
3525574Smx205022 
3535574Smx205022 	case MAC_STAT_RBYTES:
3545574Smx205022 		*val = sw_stp->rbytes;
3555574Smx205022 		break;
3565574Smx205022 
3575574Smx205022 	case MAC_STAT_IPACKETS:
3585574Smx205022 		*val = sw_stp->recv_count;
3595574Smx205022 		break;
3605574Smx205022 
3615574Smx205022 	case MAC_STAT_OBYTES:
3625574Smx205022 		*val = sw_stp->obytes;
3635574Smx205022 		break;
3645574Smx205022 
3655574Smx205022 	case MAC_STAT_OPACKETS:
3665574Smx205022 		*val = sw_stp->xmit_count;
3675574Smx205022 		break;
3685574Smx205022 
3695574Smx205022 	case ETHER_STAT_ALIGN_ERRORS:
3705898Sjj146644 		regno = KS_BASE + KS_ifHInAlignErrCount * sizeof (uint32_t);
3715898Sjj146644 		hw_stp->s.InAlignErrCount += nge_reg_get32(ngep, regno);
3725574Smx205022 		*val = hw_stp->s.InAlignErrCount;
3735574Smx205022 		break;
3745574Smx205022 
3755574Smx205022 	case ETHER_STAT_FCS_ERRORS:
3765898Sjj146644 		regno = KS_BASE + KS_ifHInFCSErrCount * sizeof (uint32_t);
3775898Sjj146644 		hw_stp->s.InFCSErrCount += nge_reg_get32(ngep, regno);
3785574Smx205022 		*val = hw_stp->s.InFCSErrCount;
3795574Smx205022 		break;
3805574Smx205022 
3815574Smx205022 	case ETHER_STAT_FIRST_COLLISIONS:
382*10837SLi-Zhen.You@Sun.COM 		regno = KS_BASE + KS_ifHOutOneRetranCount * sizeof (uint32_t);
383*10837SLi-Zhen.You@Sun.COM 		hw_stp->s.OutOneRetranCount += nge_reg_get32(ngep, regno);
384*10837SLi-Zhen.You@Sun.COM 		*val = hw_stp->s.OutOneRetranCount;
3855574Smx205022 		break;
3865574Smx205022 
3875574Smx205022 	case ETHER_STAT_MULTI_COLLISIONS:
3885898Sjj146644 		regno = KS_BASE + KS_ifHOutMoreRetranCount * sizeof (uint32_t);
3895898Sjj146644 		hw_stp->s.OutMoreRetranCount += nge_reg_get32(ngep, regno);
390*10837SLi-Zhen.You@Sun.COM 		*val =  hw_stp->s.OutMoreRetranCount;
3915574Smx205022 		break;
3925574Smx205022 
3935574Smx205022 	case ETHER_STAT_DEFER_XMTS:
3945898Sjj146644 		regno = KS_BASE + KS_ifHOutExDecCount * sizeof (uint32_t);
3955898Sjj146644 		hw_stp->s.OutExDecCount += nge_reg_get32(ngep, regno);
3965574Smx205022 		*val = hw_stp->s.OutExDecCount;
3975574Smx205022 		break;
3985574Smx205022 
3995574Smx205022 	case ETHER_STAT_TX_LATE_COLLISIONS:
4005898Sjj146644 		regno = KS_BASE + KS_ifHOutColCount * sizeof (uint32_t);
4015898Sjj146644 		hw_stp->s.OutColCount += nge_reg_get32(ngep, regno);
4025574Smx205022 		*val = hw_stp->s.OutColCount;
4035574Smx205022 		break;
4045574Smx205022 
4055574Smx205022 	case ETHER_STAT_EX_COLLISIONS:
4065898Sjj146644 		regno = KS_BASE + KS_ifHOutOneRetranCount * sizeof (uint32_t);
4075898Sjj146644 		hw_stp->s.OutOneRetranCount += nge_reg_get32(ngep, regno);
4085898Sjj146644 		*val = hw_stp->s.OutOneRetranCount;
4095574Smx205022 		break;
4105574Smx205022 
4115574Smx205022 	case ETHER_STAT_CARRIER_ERRORS:
4125898Sjj146644 		regno = KS_BASE + KS_ifHOutLOCCount * sizeof (uint32_t);
4135898Sjj146644 		hw_stp->s.OutLOCCount += nge_reg_get32(ngep, regno);
4145574Smx205022 		*val = hw_stp->s.OutLOCCount;
4155574Smx205022 		break;
4165574Smx205022 
4175574Smx205022 	case ETHER_STAT_TOOLONG_ERRORS:
4185898Sjj146644 		regno = KS_BASE + KS_ifHInOversizeErrCount * sizeof (uint32_t);
4195898Sjj146644 		hw_stp->s.InOversizeErrCount += nge_reg_get32(ngep, regno);
4205574Smx205022 		*val = hw_stp->s.InOversizeErrCount;
4215574Smx205022 		break;
4225574Smx205022 
4235574Smx205022 	case ETHER_STAT_XCVR_ADDR:
4245574Smx205022 		*val = ngep->phy_xmii_addr;
4255574Smx205022 		break;
4265574Smx205022 
4275574Smx205022 	case ETHER_STAT_XCVR_ID:
4285574Smx205022 		*val = ngep->phy_id;
4295574Smx205022 		break;
4305574Smx205022 
4315574Smx205022 	case ETHER_STAT_XCVR_INUSE:
4325574Smx205022 		*val = XCVR_1000T;
4335574Smx205022 		break;
4345574Smx205022 
4355574Smx205022 	case ETHER_STAT_CAP_1000FDX:
4365574Smx205022 		*val = 1;
4375574Smx205022 		break;
4385574Smx205022 
4395574Smx205022 	case ETHER_STAT_CAP_1000HDX:
4405574Smx205022 		*val = 0;
4415574Smx205022 		break;
4425574Smx205022 
4435574Smx205022 	case ETHER_STAT_CAP_100FDX:
4445574Smx205022 		*val = 1;
4455574Smx205022 		break;
4465574Smx205022 
4475574Smx205022 	case ETHER_STAT_CAP_100HDX:
4485574Smx205022 		*val = 1;
4495574Smx205022 		break;
4505574Smx205022 
4515574Smx205022 	case ETHER_STAT_CAP_10FDX:
4525574Smx205022 		*val = 1;
4535574Smx205022 		break;
4545574Smx205022 
4555574Smx205022 	case ETHER_STAT_CAP_10HDX:
4565574Smx205022 		*val = 1;
4575574Smx205022 		break;
4585574Smx205022 
4595574Smx205022 	case ETHER_STAT_CAP_ASMPAUSE:
4605574Smx205022 		*val = 1;
4615574Smx205022 		break;
4625574Smx205022 
4635574Smx205022 	case ETHER_STAT_CAP_PAUSE:
4645574Smx205022 		*val = 1;
4655574Smx205022 		break;
4665574Smx205022 
4675574Smx205022 	case ETHER_STAT_CAP_AUTONEG:
4685574Smx205022 		*val = 1;
4695574Smx205022 		break;
4705574Smx205022 
4715574Smx205022 	case ETHER_STAT_ADV_CAP_1000FDX:
4725574Smx205022 		*val = ngep->param_adv_1000fdx;
4735574Smx205022 		break;
4745574Smx205022 
4755574Smx205022 	case ETHER_STAT_ADV_CAP_1000HDX:
4765574Smx205022 		*val = ngep->param_adv_1000hdx;
4775574Smx205022 		break;
4785574Smx205022 
4795574Smx205022 	case ETHER_STAT_ADV_CAP_100FDX:
4805574Smx205022 		*val = ngep->param_adv_100fdx;
4815574Smx205022 		break;
4825574Smx205022 
4835574Smx205022 	case ETHER_STAT_ADV_CAP_100HDX:
4845574Smx205022 		*val = ngep->param_adv_100hdx;
4855574Smx205022 		break;
4865574Smx205022 
4875574Smx205022 	case ETHER_STAT_ADV_CAP_10FDX:
4885574Smx205022 		*val = ngep->param_adv_10fdx;
4895574Smx205022 		break;
4905574Smx205022 
4915574Smx205022 	case ETHER_STAT_ADV_CAP_10HDX:
4925574Smx205022 		*val = ngep->param_adv_10hdx;
4935574Smx205022 		break;
4945574Smx205022 
4955574Smx205022 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
4965574Smx205022 		*val = ngep->param_adv_asym_pause;
4975574Smx205022 		break;
4985574Smx205022 
4995574Smx205022 	case ETHER_STAT_ADV_CAP_PAUSE:
5005574Smx205022 		*val = ngep->param_adv_pause;
5015574Smx205022 		break;
5025574Smx205022 
5035574Smx205022 	case ETHER_STAT_ADV_CAP_AUTONEG:
5045574Smx205022 		*val = ngep->param_adv_autoneg;
5055574Smx205022 		break;
5065574Smx205022 
5075574Smx205022 	case ETHER_STAT_LP_CAP_1000FDX:
5085574Smx205022 		*val = ngep->param_lp_1000fdx;
5095574Smx205022 		break;
5105574Smx205022 
5115574Smx205022 	case ETHER_STAT_LP_CAP_1000HDX:
5125574Smx205022 		*val = ngep->param_lp_1000hdx;
5135574Smx205022 		break;
5145574Smx205022 
5155574Smx205022 	case ETHER_STAT_LP_CAP_100FDX:
5165574Smx205022 		*val = ngep->param_lp_100fdx;
5175574Smx205022 		break;
5185574Smx205022 
5195574Smx205022 	case ETHER_STAT_LP_CAP_100HDX:
5205574Smx205022 		*val = ngep->param_lp_100hdx;
5215574Smx205022 		break;
5225574Smx205022 
5235574Smx205022 	case ETHER_STAT_LP_CAP_10FDX:
5245574Smx205022 		*val = ngep->param_lp_10fdx;
5255574Smx205022 		break;
5265574Smx205022 
5275574Smx205022 	case ETHER_STAT_LP_CAP_10HDX:
5285574Smx205022 		*val = ngep->param_lp_10hdx;
5295574Smx205022 		break;
5305574Smx205022 
5315574Smx205022 	case ETHER_STAT_LP_CAP_ASMPAUSE:
5325574Smx205022 		*val = ngep->param_lp_asym_pause;
5335574Smx205022 		break;
5345574Smx205022 
5355574Smx205022 	case ETHER_STAT_LP_CAP_PAUSE:
5365574Smx205022 		*val = ngep->param_lp_pause;
5375574Smx205022 		break;
5385574Smx205022 
5395574Smx205022 	case ETHER_STAT_LP_CAP_AUTONEG:
5405574Smx205022 		*val = ngep->param_lp_autoneg;
5415574Smx205022 		break;
5425574Smx205022 
5435574Smx205022 	case ETHER_STAT_LINK_ASMPAUSE:
5445574Smx205022 		*val = ngep->param_adv_asym_pause &&
5455574Smx205022 		    ngep->param_lp_asym_pause &&
5465574Smx205022 		    ngep->param_adv_pause != ngep->param_lp_pause;
5475574Smx205022 		break;
5485574Smx205022 
5495574Smx205022 	case ETHER_STAT_LINK_PAUSE:
5505574Smx205022 		*val = ngep->param_link_rx_pause;
5515574Smx205022 		break;
5525574Smx205022 
5535574Smx205022 	case ETHER_STAT_LINK_AUTONEG:
5545574Smx205022 		*val = ngep->param_link_autoneg;
5555574Smx205022 		break;
5565574Smx205022 
5575574Smx205022 	case ETHER_STAT_LINK_DUPLEX:
5585574Smx205022 		*val = ngep->param_link_duplex;
5595574Smx205022 		break;
5605574Smx205022 
5616512Ssowmini 	case ETHER_STAT_CAP_100T4:
5626512Ssowmini 	case ETHER_STAT_LP_CAP_100T4:
5636512Ssowmini 		*val = 0;
5646512Ssowmini 		break;
5656512Ssowmini 
5665574Smx205022 	default:
5675574Smx205022 		return (ENOTSUP);
5685574Smx205022 	}
5695574Smx205022 
5705574Smx205022 	return (0);
5715574Smx205022 }
572