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