xref: /illumos-gate/usr/src/uts/common/io/nge/nge_kstats.c (revision 2b55f462)
16f3e57acSmx /*
247693af9Smx  * CDDL HEADER START
347693af9Smx  *
447693af9Smx  * The contents of this file are subject to the terms of the
547693af9Smx  * Common Development and Distribution License (the "License").
647693af9Smx  * You may not use this file except in compliance with the License.
747693af9Smx  *
847693af9Smx  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
947693af9Smx  * or http://www.opensolaris.org/os/licensing.
1047693af9Smx  * See the License for the specific language governing permissions
1147693af9Smx  * and limitations under the License.
1247693af9Smx  *
1347693af9Smx  * When distributing Covered Code, include this CDDL HEADER in each
1447693af9Smx  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1547693af9Smx  * If applicable, add the following below this CDDL HEADER, with the
1647693af9Smx  * fields enclosed by brackets "[]" replaced with your own identifying
1747693af9Smx  * information: Portions Copyright [yyyy] [name of copyright owner]
1847693af9Smx  *
1947693af9Smx  * CDDL HEADER END
206f3e57acSmx  */
216f3e57acSmx 
226f3e57acSmx /*
23*2b55f462SLi-Zhen You  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
2447693af9Smx  * Use is subject to license terms.
256f3e57acSmx  */
266f3e57acSmx 
276f3e57acSmx 
286f3e57acSmx #include "nge.h"
296f3e57acSmx 
306f3e57acSmx #undef	NGE_DBG
316f3e57acSmx #define	NGE_DBG		NGE_DBG_STATS	/* debug flag for this code	*/
326f3e57acSmx 
336f3e57acSmx /*
346f3e57acSmx  * Table of Hardware-defined Statistics Block Offsets and Names
356f3e57acSmx  */
366f3e57acSmx #define	KS_NAME(s)			{ KS_ ## s, #s }
376f3e57acSmx 
386f3e57acSmx const nge_ksindex_t nge_statistics[] = {
396f3e57acSmx 
406f3e57acSmx 	KS_NAME(ifHOutOctets),
416f3e57acSmx 	KS_NAME(ifHOutZeroRetranCount),
426f3e57acSmx 	KS_NAME(ifHOutOneRetranCount),
436f3e57acSmx 	KS_NAME(ifHOutMoreRetranCount),
446f3e57acSmx 	KS_NAME(ifHOutColCount),
456f3e57acSmx 	KS_NAME(ifHOutFifoovCount),
466f3e57acSmx 	KS_NAME(ifHOutLOCCount),
476f3e57acSmx 	KS_NAME(ifHOutExDecCount),
486f3e57acSmx 	KS_NAME(ifHOutRetryCount),
496f3e57acSmx 	KS_NAME(ifHInFrameErrCount),
506f3e57acSmx 	KS_NAME(ifHInExtraOctErrCount),
516f3e57acSmx 	KS_NAME(ifHInLColErrCount),
526f3e57acSmx 	KS_NAME(ifHInOversizeErrCount),
536f3e57acSmx 	KS_NAME(ifHInFovErrCount),
546f3e57acSmx 	KS_NAME(ifHInFCSErrCount),
556f3e57acSmx 	KS_NAME(ifHInAlignErrCount),
566f3e57acSmx 	KS_NAME(ifHInLenErrCount),
576f3e57acSmx 	KS_NAME(ifHInUniPktsCount),
586f3e57acSmx 	KS_NAME(ifHInBroadPksCount),
596f3e57acSmx 	KS_NAME(ifHInMulPksCount),
606f3e57acSmx 	{ KS_STATS_SIZE, NULL }
616f3e57acSmx };
626f3e57acSmx 
636f3e57acSmx /*
646f3e57acSmx  * Local datatype for defining tables of (Offset, Name) pairs
656f3e57acSmx  */
666f3e57acSmx static int
nge_statistics_update(kstat_t * ksp,int flag)676f3e57acSmx nge_statistics_update(kstat_t *ksp, int flag)
686f3e57acSmx {
696f3e57acSmx 	uint32_t regno;
706f3e57acSmx 	nge_t *ngep;
716f3e57acSmx 	nge_statistics_t *istp;
726f3e57acSmx 	nge_hw_statistics_t *hw_stp;
736f3e57acSmx 	kstat_named_t *knp;
746f3e57acSmx 	const nge_ksindex_t *ksip;
756f3e57acSmx 
766f3e57acSmx 	if (flag != KSTAT_READ)
776f3e57acSmx 		return (EACCES);
786f3e57acSmx 
796f3e57acSmx 	ngep = ksp->ks_private;
806f3e57acSmx 	istp = &ngep->statistics;
816f3e57acSmx 	hw_stp = &istp->hw_statistics;
826f3e57acSmx 	knp = ksp->ks_data;
836f3e57acSmx 
846f3e57acSmx 	/*
856f3e57acSmx 	 * Transfer the statistics values from the hardware statistics regs
866f3e57acSmx 	 */
876f3e57acSmx 	for (ksip = nge_statistics; ksip->name != NULL; ++knp, ++ksip) {
886f3e57acSmx 		regno = KS_BASE + ksip->index * sizeof (uint32_t);
89da9d0014Sjj 		hw_stp->a[ksip->index] += nge_reg_get32(ngep, regno);
90da9d0014Sjj 		knp->value.ui64 = hw_stp->a[ksip->index];
916f3e57acSmx 	}
926f3e57acSmx 
936f3e57acSmx 	return (0);
946f3e57acSmx }
956f3e57acSmx 
966f3e57acSmx 
976f3e57acSmx static const nge_ksindex_t nge_chipinfo[] = {
986f3e57acSmx 	{ 0,				"businfo"		},
996f3e57acSmx 	{ 1,				"command"		},
1006f3e57acSmx 	{ 2,				"vendor_id"		},
1016f3e57acSmx 	{ 3,				"device_id"		},
1026f3e57acSmx 	{ 4,				"subsystem_vendor_id"	},
1036f3e57acSmx 	{ 5,				"subsystem_device_id"	},
1046f3e57acSmx 	{ 6,				"revision_id"		},
1056f3e57acSmx 	{ 7,				"cache_line_size"	},
1066f3e57acSmx 	{ 8,				"latency_timer"		},
1076f3e57acSmx 	{ 9,				"phy_mode"		},
1086f3e57acSmx 	{ 10,				"phy_id"		},
1096f3e57acSmx 	{ 11,				"hw_mac_addr"		},
1106f3e57acSmx 	{ 12,				"&bus_type"		},
1116f3e57acSmx 	{ 13,				"&bus_speed"		},
1126f3e57acSmx 	{ 14,				"&bus_size"		},
1136f3e57acSmx 	{ -1,				NULL 			}
1146f3e57acSmx };
1156f3e57acSmx 
1166f3e57acSmx static const nge_ksindex_t nge_debuginfo[] = {
1176f3e57acSmx 	{ 0,				"rx_realloc"		},
1186f3e57acSmx 	{ 1,				"rx_realloc_fails"	},
1196f3e57acSmx 	{ 2,				"rx_realloc_DMA_fails"	},
1206f3e57acSmx 	{ 3,				"rx_realloc_MP_fails"	},
1216f3e57acSmx 	{ 4,				"rx_rcfree"		},
1226f3e57acSmx 	{ 5,				"context_switch"	},
1236f3e57acSmx 	{ 6,				"ip_hsum_err"		},
1246f3e57acSmx 	{ 7,				"tcp_hsum_err"		},
1256f3e57acSmx 	{ 8,				"tc_next"		},
1266f3e57acSmx 	{ 9,				"tx_next"		},
1276f3e57acSmx 	{ 10,				"tx_free"		},
1286f3e57acSmx 	{ 11,				"tx_flow"		},
1296f3e57acSmx 	{ 12,				"rx_prod"		},
1306f3e57acSmx 	{ 13,				"rx_hold"		},
1316f3e57acSmx 	{ 14,				"rx_nobuf"		},
1326f3e57acSmx 	{ 15,				"rx_err"		},
1336f3e57acSmx 	{16,				"tx_err"		},
1346f3e57acSmx 	{17,				"tx_stall"		},
1356f3e57acSmx 	{ -1,				NULL 			}
1366f3e57acSmx };
1376f3e57acSmx 
1386f3e57acSmx static int
nge_chipinfo_update(kstat_t * ksp,int flag)1396f3e57acSmx nge_chipinfo_update(kstat_t *ksp, int flag)
1406f3e57acSmx {
1416f3e57acSmx 	nge_t *ngep;
1426f3e57acSmx 	kstat_named_t *knp;
1436f3e57acSmx 	chip_info_t *infop;
1446f3e57acSmx 
1456f3e57acSmx 	if (flag != KSTAT_READ)
1466f3e57acSmx 		return (EACCES);
1476f3e57acSmx 
1486f3e57acSmx 	ngep = ksp->ks_private;
1496f3e57acSmx 	infop = &ngep->chipinfo;
1506f3e57acSmx 	knp = ksp->ks_data;
1516f3e57acSmx 
1526f3e57acSmx 	(knp++)->value.ui64 = infop->businfo;
1536f3e57acSmx 	(knp++)->value.ui64 = infop->command;
1546f3e57acSmx 	(knp++)->value.ui64 = infop->vendor;
1556f3e57acSmx 	(knp++)->value.ui64 = infop->device;
1566f3e57acSmx 	(knp++)->value.ui64 = infop->subven;
1576f3e57acSmx 	(knp++)->value.ui64 = infop->subdev;
1586f3e57acSmx 	(knp++)->value.ui64 = infop->revision;
1596f3e57acSmx 	(knp++)->value.ui64 = infop->clsize;
1606f3e57acSmx 	(knp++)->value.ui64 = infop->latency;
1616f3e57acSmx 	(knp++)->value.ui64 = ngep->phy_mode;
1626f3e57acSmx 	(knp++)->value.ui64 = ngep->phy_id;
1636f3e57acSmx 	(knp++)->value.ui64 = infop->hw_mac_addr;
1646f3e57acSmx 	return (0);
1656f3e57acSmx }
1666f3e57acSmx 
1676f3e57acSmx static int
nge_debuginfo_update(kstat_t * ksp,int flag)1686f3e57acSmx nge_debuginfo_update(kstat_t *ksp, int flag)
1696f3e57acSmx {
1706f3e57acSmx 	nge_t *ngep;
1716f3e57acSmx 	kstat_named_t *knp;
1726f3e57acSmx 	nge_sw_statistics_t *sw_stp;
1736f3e57acSmx 
1746f3e57acSmx 	if (flag != KSTAT_READ)
1756f3e57acSmx 		return (EACCES);
1766f3e57acSmx 
1776f3e57acSmx 	ngep = ksp->ks_private;
1786f3e57acSmx 	sw_stp = &ngep->statistics.sw_statistics;
1796f3e57acSmx 	knp = ksp->ks_data;
1806f3e57acSmx 
1816f3e57acSmx 	(knp++)->value.ui64 = sw_stp->recv_realloc;
1826f3e57acSmx 	(knp++)->value.ui64 = sw_stp->kmem_alloc_err;
1836f3e57acSmx 	(knp++)->value.ui64 = sw_stp->dma_alloc_err;
1846f3e57acSmx 	(knp++)->value.ui64 = sw_stp->mp_alloc_err;
1856f3e57acSmx 	(knp++)->value.ui64 = sw_stp->recy_free;
1866f3e57acSmx 	(knp++)->value.ui64 = sw_stp->load_context;
1876f3e57acSmx 	(knp++)->value.ui64 = sw_stp->ip_hwsum_err;
1886f3e57acSmx 	(knp++)->value.ui64 = sw_stp->tcp_hwsum_err;
1896f3e57acSmx 	(knp++)->value.ui64 = ngep->send->tc_next;
1906f3e57acSmx 	(knp++)->value.ui64 = ngep->send->tx_next;
1916f3e57acSmx 	(knp++)->value.ui64 = ngep->send->tx_free;
1926f3e57acSmx 	(knp++)->value.ui64 = ngep->send->tx_flow;
1936f3e57acSmx 	(knp++)->value.ui64 = ngep->recv->prod_index;
1946f3e57acSmx 	(knp++)->value.ui64 = ngep->buff->rx_hold;
1956f3e57acSmx 	(knp++)->value.ui64 = sw_stp->rx_nobuffer;
1966f3e57acSmx 	(knp++)->value.ui64 = sw_stp->rx_err;
1976f3e57acSmx 	(knp++)->value.ui64 = sw_stp->tx_stop_err;
1986f3e57acSmx 	(knp++)->value.ui64 = sw_stp->tx_stall;
1996f3e57acSmx 	return (0);
2006f3e57acSmx }
2016f3e57acSmx 
2026f3e57acSmx 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))2036f3e57acSmx nge_setup_named_kstat(nge_t *ngep, int instance, char *name,
2046f3e57acSmx 	const nge_ksindex_t *ksip, size_t size, int (*update)(kstat_t *, int))
2056f3e57acSmx {
2066f3e57acSmx 	kstat_t *ksp;
2076f3e57acSmx 	kstat_named_t *knp;
2086f3e57acSmx 	char *np;
2096f3e57acSmx 	int type;
2106f3e57acSmx 
2116f3e57acSmx 	size /= sizeof (nge_ksindex_t);
2126f3e57acSmx 	ksp = kstat_create(NGE_DRIVER_NAME, instance, name, "net",
2136f3e57acSmx 	    KSTAT_TYPE_NAMED, size-1, KSTAT_FLAG_PERSISTENT);
2146f3e57acSmx 	if (ksp == NULL)
2156f3e57acSmx 		return (NULL);
2166f3e57acSmx 
2176f3e57acSmx 	ksp->ks_private = ngep;
2186f3e57acSmx 	ksp->ks_update = update;
2196f3e57acSmx 	for (knp = ksp->ks_data; (np = ksip->name) != NULL; ++knp, ++ksip) {
2206f3e57acSmx 		switch (*np) {
2216f3e57acSmx 		default:
2226f3e57acSmx 			type = KSTAT_DATA_UINT64;
2236f3e57acSmx 			break;
2246f3e57acSmx 		case '%':
2256f3e57acSmx 			np += 1;
2266f3e57acSmx 			type = KSTAT_DATA_UINT32;
2276f3e57acSmx 			break;
2286f3e57acSmx 
2296f3e57acSmx 		case '$':
2306f3e57acSmx 			np ++;
2316f3e57acSmx 			type = KSTAT_DATA_STRING;
2326f3e57acSmx 			break;
2336f3e57acSmx 		case '&':
2346f3e57acSmx 			np ++;
2356f3e57acSmx 			type = KSTAT_DATA_CHAR;
2366f3e57acSmx 			break;
2376f3e57acSmx 		}
2386f3e57acSmx 		kstat_named_init(knp, np, type);
2396f3e57acSmx 	}
2406f3e57acSmx 	kstat_install(ksp);
2416f3e57acSmx 
2426f3e57acSmx 	return (ksp);
2436f3e57acSmx }
2446f3e57acSmx 
2456f3e57acSmx void
nge_init_kstats(nge_t * ngep,int instance)2466f3e57acSmx nge_init_kstats(nge_t *ngep, int instance)
2476f3e57acSmx {
2486f3e57acSmx 	NGE_TRACE(("nge_init_kstats($%p, %d)", (void *)ngep, instance));
2496f3e57acSmx 
2506f3e57acSmx 	ngep->nge_kstats[NGE_KSTAT_STATS] = nge_setup_named_kstat(ngep,
2516f3e57acSmx 	    instance, "statistics", nge_statistics,
2526f3e57acSmx 	    sizeof (nge_statistics), nge_statistics_update);
2536f3e57acSmx 
2546f3e57acSmx 	ngep->nge_kstats[NGE_KSTAT_CHIPID] = nge_setup_named_kstat(ngep,
2556f3e57acSmx 	    instance, "chipinfo", nge_chipinfo,
2566f3e57acSmx 	    sizeof (nge_chipinfo), nge_chipinfo_update);
2576f3e57acSmx 
2586f3e57acSmx 	ngep->nge_kstats[NGE_KSTAT_DEBUG] = nge_setup_named_kstat(ngep,
2596f3e57acSmx 	    instance, "driver-debug", nge_debuginfo,
2606f3e57acSmx 	    sizeof (nge_debuginfo), nge_debuginfo_update);
2616f3e57acSmx 
2626f3e57acSmx }
2636f3e57acSmx 
2646f3e57acSmx void
nge_fini_kstats(nge_t * ngep)2656f3e57acSmx nge_fini_kstats(nge_t *ngep)
2666f3e57acSmx {
2676f3e57acSmx 	int i;
2686f3e57acSmx 
2696f3e57acSmx 	NGE_TRACE(("nge_fini_kstats($%p)", (void *)ngep));
2706f3e57acSmx 	for (i = NGE_KSTAT_COUNT;  --i >= 0; )
2716f3e57acSmx 		if (ngep->nge_kstats[i] != NULL)
2726f3e57acSmx 			kstat_delete(ngep->nge_kstats[i]);
2736f3e57acSmx }
2746f3e57acSmx 
2756f3e57acSmx int
nge_m_stat(void * arg,uint_t stat,uint64_t * val)2766f3e57acSmx nge_m_stat(void *arg, uint_t stat, uint64_t *val)
2776f3e57acSmx {
2786f3e57acSmx 	nge_t *ngep = arg;
279da9d0014Sjj 	uint32_t regno;
2806f3e57acSmx 	nge_statistics_t *nstp = &ngep->statistics;
2816f3e57acSmx 	nge_hw_statistics_t *hw_stp = &nstp->hw_statistics;
2826f3e57acSmx 	nge_sw_statistics_t *sw_stp = &nstp->sw_statistics;
2836f3e57acSmx 
2846f3e57acSmx 	switch (stat) {
2856f3e57acSmx 	case MAC_STAT_IFSPEED:
2866f3e57acSmx 		*val = ngep->param_link_speed * 1000000ull;
2876f3e57acSmx 		break;
2886f3e57acSmx 
2896f3e57acSmx 	case MAC_STAT_MULTIRCV:
290da9d0014Sjj 		regno = KS_BASE + KS_ifHInMulPksCount * sizeof (uint32_t);
291da9d0014Sjj 		hw_stp->s.InMulPksCount += nge_reg_get32(ngep, regno);
2926f3e57acSmx 		*val = hw_stp->s.InMulPksCount;
2936f3e57acSmx 		break;
2946f3e57acSmx 
2956f3e57acSmx 	case MAC_STAT_BRDCSTRCV:
296da9d0014Sjj 		regno = KS_BASE +  KS_ifHInBroadPksCount * sizeof (uint32_t);
297da9d0014Sjj 		hw_stp->s.InBroadPksCount += nge_reg_get32(ngep, regno);
2986f3e57acSmx 		*val = hw_stp->s.InBroadPksCount;
2996f3e57acSmx 		break;
3006f3e57acSmx 
3016f3e57acSmx 	case MAC_STAT_NORCVBUF:
3026f3e57acSmx 		*val = sw_stp->rx_nobuffer;
3036f3e57acSmx 		break;
3046f3e57acSmx 
3056f3e57acSmx 	case MAC_STAT_IERRORS:
306da9d0014Sjj 		regno = KS_BASE + KS_ifHInFrameErrCount * sizeof (uint32_t);
307da9d0014Sjj 		hw_stp->s.InFrameErrCount += nge_reg_get32(ngep, regno);
308da9d0014Sjj 		regno = KS_BASE + KS_ifHInExtraOctErrCount * sizeof (uint32_t);
309da9d0014Sjj 		hw_stp->s.InExtraOctErrCount += nge_reg_get32(ngep, regno);
310da9d0014Sjj 		regno = KS_BASE + KS_ifHInLColErrCount * sizeof (uint32_t);
311da9d0014Sjj 		hw_stp->s.InLColErrCount += nge_reg_get32(ngep, regno);
312da9d0014Sjj 		regno = KS_BASE + KS_ifHInOversizeErrCount * sizeof (uint32_t);
313da9d0014Sjj 		hw_stp->s.InOversizeErrCount += nge_reg_get32(ngep, regno);
314da9d0014Sjj 		regno = KS_BASE + KS_ifHInFovErrCount * sizeof (uint32_t);
315da9d0014Sjj 		hw_stp->s.InFovErrCount += nge_reg_get32(ngep, regno);
316da9d0014Sjj 		regno = KS_BASE + KS_ifHInFCSErrCount * sizeof (uint32_t);
317da9d0014Sjj 		hw_stp->s.InFCSErrCount += nge_reg_get32(ngep, regno);
318da9d0014Sjj 		regno = KS_BASE + KS_ifHInAlignErrCount * sizeof (uint32_t);
319da9d0014Sjj 		hw_stp->s.InAlignErrCount += nge_reg_get32(ngep, regno);
320da9d0014Sjj 		regno = KS_BASE + KS_ifHInLenErrCount * sizeof (uint32_t);
321da9d0014Sjj 		hw_stp->s.InLenErrCount += nge_reg_get32(ngep, regno);
3226f3e57acSmx 		*val = hw_stp->s.InFrameErrCount +
3236f3e57acSmx 		    hw_stp->s.InExtraOctErrCount +
3246f3e57acSmx 		    hw_stp->s.InLColErrCount +
3256f3e57acSmx 		    hw_stp->s.InOversizeErrCount +
3266f3e57acSmx 		    hw_stp->s.InFovErrCount +
3276f3e57acSmx 		    hw_stp->s.InFCSErrCount +
3286f3e57acSmx 		    hw_stp->s.InAlignErrCount +
3296f3e57acSmx 		    hw_stp->s.InLenErrCount;
3306f3e57acSmx 		break;
3316f3e57acSmx 
3326f3e57acSmx 	case MAC_STAT_OERRORS:
333da9d0014Sjj 		regno = KS_BASE + KS_ifHOutFifoovCount * sizeof (uint32_t);
334da9d0014Sjj 		hw_stp->s.OutFifoovCount += nge_reg_get32(ngep, regno);
335da9d0014Sjj 		regno = KS_BASE + KS_ifHOutLOCCount * sizeof (uint32_t);
336da9d0014Sjj 		hw_stp->s.OutLOCCount += nge_reg_get32(ngep, regno);
337da9d0014Sjj 		regno = KS_BASE + KS_ifHOutExDecCount * sizeof (uint32_t);
338da9d0014Sjj 		hw_stp->s.OutExDecCount += nge_reg_get32(ngep, regno);
339da9d0014Sjj 		regno = KS_BASE + KS_ifHOutRetryCount * sizeof (uint32_t);
340da9d0014Sjj 		hw_stp->s.OutRetryCount += nge_reg_get32(ngep, regno);
3416f3e57acSmx 		*val = hw_stp->s.OutFifoovCount +
3426f3e57acSmx 		    hw_stp->s.OutLOCCount +
3436f3e57acSmx 		    hw_stp->s.OutExDecCount +
3446f3e57acSmx 		    hw_stp->s.OutRetryCount;
3456f3e57acSmx 		break;
3466f3e57acSmx 
3476f3e57acSmx 	case MAC_STAT_COLLISIONS:
348da9d0014Sjj 		regno = KS_BASE + KS_ifHOutColCount * sizeof (uint32_t);
349da9d0014Sjj 		hw_stp->s.OutColCount += nge_reg_get32(ngep, regno);
3506f3e57acSmx 		*val = hw_stp->s.OutColCount;
3516f3e57acSmx 		break;
3526f3e57acSmx 
3536f3e57acSmx 	case MAC_STAT_RBYTES:
3546f3e57acSmx 		*val = sw_stp->rbytes;
3556f3e57acSmx 		break;
3566f3e57acSmx 
3576f3e57acSmx 	case MAC_STAT_IPACKETS:
3586f3e57acSmx 		*val = sw_stp->recv_count;
3596f3e57acSmx 		break;
3606f3e57acSmx 
3616f3e57acSmx 	case MAC_STAT_OBYTES:
3626f3e57acSmx 		*val = sw_stp->obytes;
3636f3e57acSmx 		break;
3646f3e57acSmx 
3656f3e57acSmx 	case MAC_STAT_OPACKETS:
3666f3e57acSmx 		*val = sw_stp->xmit_count;
3676f3e57acSmx 		break;
3686f3e57acSmx 
3696f3e57acSmx 	case ETHER_STAT_ALIGN_ERRORS:
370da9d0014Sjj 		regno = KS_BASE + KS_ifHInAlignErrCount * sizeof (uint32_t);
371da9d0014Sjj 		hw_stp->s.InAlignErrCount += nge_reg_get32(ngep, regno);
3726f3e57acSmx 		*val = hw_stp->s.InAlignErrCount;
3736f3e57acSmx 		break;
3746f3e57acSmx 
3756f3e57acSmx 	case ETHER_STAT_FCS_ERRORS:
376da9d0014Sjj 		regno = KS_BASE + KS_ifHInFCSErrCount * sizeof (uint32_t);
377da9d0014Sjj 		hw_stp->s.InFCSErrCount += nge_reg_get32(ngep, regno);
3786f3e57acSmx 		*val = hw_stp->s.InFCSErrCount;
3796f3e57acSmx 		break;
3806f3e57acSmx 
3816f3e57acSmx 	case ETHER_STAT_FIRST_COLLISIONS:
382*2b55f462SLi-Zhen You 		regno = KS_BASE + KS_ifHOutOneRetranCount * sizeof (uint32_t);
383*2b55f462SLi-Zhen You 		hw_stp->s.OutOneRetranCount += nge_reg_get32(ngep, regno);
384*2b55f462SLi-Zhen You 		*val = hw_stp->s.OutOneRetranCount;
3856f3e57acSmx 		break;
3866f3e57acSmx 
3876f3e57acSmx 	case ETHER_STAT_MULTI_COLLISIONS:
388da9d0014Sjj 		regno = KS_BASE + KS_ifHOutMoreRetranCount * sizeof (uint32_t);
389da9d0014Sjj 		hw_stp->s.OutMoreRetranCount += nge_reg_get32(ngep, regno);
390*2b55f462SLi-Zhen You 		*val =  hw_stp->s.OutMoreRetranCount;
3916f3e57acSmx 		break;
3926f3e57acSmx 
3936f3e57acSmx 	case ETHER_STAT_DEFER_XMTS:
394da9d0014Sjj 		regno = KS_BASE + KS_ifHOutExDecCount * sizeof (uint32_t);
395da9d0014Sjj 		hw_stp->s.OutExDecCount += nge_reg_get32(ngep, regno);
3966f3e57acSmx 		*val = hw_stp->s.OutExDecCount;
3976f3e57acSmx 		break;
3986f3e57acSmx 
3996f3e57acSmx 	case ETHER_STAT_TX_LATE_COLLISIONS:
400da9d0014Sjj 		regno = KS_BASE + KS_ifHOutColCount * sizeof (uint32_t);
401da9d0014Sjj 		hw_stp->s.OutColCount += nge_reg_get32(ngep, regno);
4026f3e57acSmx 		*val = hw_stp->s.OutColCount;
4036f3e57acSmx 		break;
4046f3e57acSmx 
4056f3e57acSmx 	case ETHER_STAT_EX_COLLISIONS:
406da9d0014Sjj 		regno = KS_BASE + KS_ifHOutOneRetranCount * sizeof (uint32_t);
407da9d0014Sjj 		hw_stp->s.OutOneRetranCount += nge_reg_get32(ngep, regno);
408da9d0014Sjj 		*val = hw_stp->s.OutOneRetranCount;
4096f3e57acSmx 		break;
4106f3e57acSmx 
4116f3e57acSmx 	case ETHER_STAT_CARRIER_ERRORS:
412da9d0014Sjj 		regno = KS_BASE + KS_ifHOutLOCCount * sizeof (uint32_t);
413da9d0014Sjj 		hw_stp->s.OutLOCCount += nge_reg_get32(ngep, regno);
4146f3e57acSmx 		*val = hw_stp->s.OutLOCCount;
4156f3e57acSmx 		break;
4166f3e57acSmx 
4176f3e57acSmx 	case ETHER_STAT_TOOLONG_ERRORS:
418da9d0014Sjj 		regno = KS_BASE + KS_ifHInOversizeErrCount * sizeof (uint32_t);
419da9d0014Sjj 		hw_stp->s.InOversizeErrCount += nge_reg_get32(ngep, regno);
4206f3e57acSmx 		*val = hw_stp->s.InOversizeErrCount;
4216f3e57acSmx 		break;
4226f3e57acSmx 
4236f3e57acSmx 	case ETHER_STAT_XCVR_ADDR:
4246f3e57acSmx 		*val = ngep->phy_xmii_addr;
4256f3e57acSmx 		break;
4266f3e57acSmx 
4276f3e57acSmx 	case ETHER_STAT_XCVR_ID:
4286f3e57acSmx 		*val = ngep->phy_id;
4296f3e57acSmx 		break;
4306f3e57acSmx 
4316f3e57acSmx 	case ETHER_STAT_XCVR_INUSE:
4326f3e57acSmx 		*val = XCVR_1000T;
4336f3e57acSmx 		break;
4346f3e57acSmx 
4356f3e57acSmx 	case ETHER_STAT_CAP_1000FDX:
4366f3e57acSmx 		*val = 1;
4376f3e57acSmx 		break;
4386f3e57acSmx 
4396f3e57acSmx 	case ETHER_STAT_CAP_1000HDX:
4406f3e57acSmx 		*val = 0;
4416f3e57acSmx 		break;
4426f3e57acSmx 
4436f3e57acSmx 	case ETHER_STAT_CAP_100FDX:
4446f3e57acSmx 		*val = 1;
4456f3e57acSmx 		break;
4466f3e57acSmx 
4476f3e57acSmx 	case ETHER_STAT_CAP_100HDX:
4486f3e57acSmx 		*val = 1;
4496f3e57acSmx 		break;
4506f3e57acSmx 
4516f3e57acSmx 	case ETHER_STAT_CAP_10FDX:
4526f3e57acSmx 		*val = 1;
4536f3e57acSmx 		break;
4546f3e57acSmx 
4556f3e57acSmx 	case ETHER_STAT_CAP_10HDX:
4566f3e57acSmx 		*val = 1;
4576f3e57acSmx 		break;
4586f3e57acSmx 
4596f3e57acSmx 	case ETHER_STAT_CAP_ASMPAUSE:
4606f3e57acSmx 		*val = 1;
4616f3e57acSmx 		break;
4626f3e57acSmx 
4636f3e57acSmx 	case ETHER_STAT_CAP_PAUSE:
4646f3e57acSmx 		*val = 1;
4656f3e57acSmx 		break;
4666f3e57acSmx 
4676f3e57acSmx 	case ETHER_STAT_CAP_AUTONEG:
4686f3e57acSmx 		*val = 1;
4696f3e57acSmx 		break;
4706f3e57acSmx 
4716f3e57acSmx 	case ETHER_STAT_ADV_CAP_1000FDX:
4726f3e57acSmx 		*val = ngep->param_adv_1000fdx;
4736f3e57acSmx 		break;
4746f3e57acSmx 
4756f3e57acSmx 	case ETHER_STAT_ADV_CAP_1000HDX:
4766f3e57acSmx 		*val = ngep->param_adv_1000hdx;
4776f3e57acSmx 		break;
4786f3e57acSmx 
4796f3e57acSmx 	case ETHER_STAT_ADV_CAP_100FDX:
4806f3e57acSmx 		*val = ngep->param_adv_100fdx;
4816f3e57acSmx 		break;
4826f3e57acSmx 
4836f3e57acSmx 	case ETHER_STAT_ADV_CAP_100HDX:
4846f3e57acSmx 		*val = ngep->param_adv_100hdx;
4856f3e57acSmx 		break;
4866f3e57acSmx 
4876f3e57acSmx 	case ETHER_STAT_ADV_CAP_10FDX:
4886f3e57acSmx 		*val = ngep->param_adv_10fdx;
4896f3e57acSmx 		break;
4906f3e57acSmx 
4916f3e57acSmx 	case ETHER_STAT_ADV_CAP_10HDX:
4926f3e57acSmx 		*val = ngep->param_adv_10hdx;
4936f3e57acSmx 		break;
4946f3e57acSmx 
4956f3e57acSmx 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
4966f3e57acSmx 		*val = ngep->param_adv_asym_pause;
4976f3e57acSmx 		break;
4986f3e57acSmx 
4996f3e57acSmx 	case ETHER_STAT_ADV_CAP_PAUSE:
5006f3e57acSmx 		*val = ngep->param_adv_pause;
5016f3e57acSmx 		break;
5026f3e57acSmx 
5036f3e57acSmx 	case ETHER_STAT_ADV_CAP_AUTONEG:
5046f3e57acSmx 		*val = ngep->param_adv_autoneg;
5056f3e57acSmx 		break;
5066f3e57acSmx 
5076f3e57acSmx 	case ETHER_STAT_LP_CAP_1000FDX:
5086f3e57acSmx 		*val = ngep->param_lp_1000fdx;
5096f3e57acSmx 		break;
5106f3e57acSmx 
5116f3e57acSmx 	case ETHER_STAT_LP_CAP_1000HDX:
5126f3e57acSmx 		*val = ngep->param_lp_1000hdx;
5136f3e57acSmx 		break;
5146f3e57acSmx 
5156f3e57acSmx 	case ETHER_STAT_LP_CAP_100FDX:
5166f3e57acSmx 		*val = ngep->param_lp_100fdx;
5176f3e57acSmx 		break;
5186f3e57acSmx 
5196f3e57acSmx 	case ETHER_STAT_LP_CAP_100HDX:
5206f3e57acSmx 		*val = ngep->param_lp_100hdx;
5216f3e57acSmx 		break;
5226f3e57acSmx 
5236f3e57acSmx 	case ETHER_STAT_LP_CAP_10FDX:
5246f3e57acSmx 		*val = ngep->param_lp_10fdx;
5256f3e57acSmx 		break;
5266f3e57acSmx 
5276f3e57acSmx 	case ETHER_STAT_LP_CAP_10HDX:
5286f3e57acSmx 		*val = ngep->param_lp_10hdx;
5296f3e57acSmx 		break;
5306f3e57acSmx 
5316f3e57acSmx 	case ETHER_STAT_LP_CAP_ASMPAUSE:
5326f3e57acSmx 		*val = ngep->param_lp_asym_pause;
5336f3e57acSmx 		break;
5346f3e57acSmx 
5356f3e57acSmx 	case ETHER_STAT_LP_CAP_PAUSE:
5366f3e57acSmx 		*val = ngep->param_lp_pause;
5376f3e57acSmx 		break;
5386f3e57acSmx 
5396f3e57acSmx 	case ETHER_STAT_LP_CAP_AUTONEG:
5406f3e57acSmx 		*val = ngep->param_lp_autoneg;
5416f3e57acSmx 		break;
5426f3e57acSmx 
5436f3e57acSmx 	case ETHER_STAT_LINK_ASMPAUSE:
5446f3e57acSmx 		*val = ngep->param_adv_asym_pause &&
5456f3e57acSmx 		    ngep->param_lp_asym_pause &&
5466f3e57acSmx 		    ngep->param_adv_pause != ngep->param_lp_pause;
5476f3e57acSmx 		break;
5486f3e57acSmx 
5496f3e57acSmx 	case ETHER_STAT_LINK_PAUSE:
5506f3e57acSmx 		*val = ngep->param_link_rx_pause;
5516f3e57acSmx 		break;
5526f3e57acSmx 
5536f3e57acSmx 	case ETHER_STAT_LINK_AUTONEG:
5546f3e57acSmx 		*val = ngep->param_link_autoneg;
5556f3e57acSmx 		break;
5566f3e57acSmx 
5576f3e57acSmx 	case ETHER_STAT_LINK_DUPLEX:
5586f3e57acSmx 		*val = ngep->param_link_duplex;
5596f3e57acSmx 		break;
5606f3e57acSmx 
5614045d941Ssowmini 	case ETHER_STAT_CAP_100T4:
5624045d941Ssowmini 	case ETHER_STAT_LP_CAP_100T4:
5634045d941Ssowmini 		*val = 0;
5644045d941Ssowmini 		break;
5654045d941Ssowmini 
5666f3e57acSmx 	default:
5676f3e57acSmx 		return (ENOTSUP);
5686f3e57acSmx 	}
5696f3e57acSmx 
5706f3e57acSmx 	return (0);
5716f3e57acSmx }
572