xref: /onnv-gate/usr/src/uts/common/io/ixgbe/ixgbe_stat.c (revision 11878:ac93462db6d7)
16621Sbt150084 /*
26621Sbt150084  * CDDL HEADER START
36621Sbt150084  *
49353SSamuel.Tu@Sun.COM  * Copyright(c) 2007-2009 Intel Corporation. All rights reserved.
56621Sbt150084  * The contents of this file are subject to the terms of the
66621Sbt150084  * Common Development and Distribution License (the "License").
76621Sbt150084  * You may not use this file except in compliance with the License.
86621Sbt150084  *
98275SEric Cheng  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
108275SEric Cheng  * or http://www.opensolaris.org/os/licensing.
116621Sbt150084  * See the License for the specific language governing permissions
126621Sbt150084  * and limitations under the License.
136621Sbt150084  *
148275SEric Cheng  * When distributing Covered Code, include this CDDL HEADER in each
158275SEric Cheng  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
166621Sbt150084  * If applicable, add the following below this CDDL HEADER, with the
176621Sbt150084  * fields enclosed by brackets "[]" replaced with your own identifying
186621Sbt150084  * information: Portions Copyright [yyyy] [name of copyright owner]
196621Sbt150084  *
206621Sbt150084  * CDDL HEADER END
216621Sbt150084  */
226621Sbt150084 
236621Sbt150084 /*
2411486SZhen.W@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
258275SEric Cheng  * Use is subject to license terms.
268275SEric Cheng  */
276621Sbt150084 
286621Sbt150084 #include "ixgbe_sw.h"
296621Sbt150084 
306621Sbt150084 /*
316621Sbt150084  * Update driver private statistics.
326621Sbt150084  */
336621Sbt150084 static int
346621Sbt150084 ixgbe_update_stats(kstat_t *ks, int rw)
356621Sbt150084 {
366621Sbt150084 	ixgbe_t *ixgbe;
376621Sbt150084 	struct ixgbe_hw *hw;
386621Sbt150084 	ixgbe_stat_t *ixgbe_ks;
396621Sbt150084 	int i;
406621Sbt150084 
416621Sbt150084 	if (rw == KSTAT_WRITE)
426621Sbt150084 		return (EACCES);
436621Sbt150084 
446621Sbt150084 	ixgbe = (ixgbe_t *)ks->ks_private;
456621Sbt150084 	ixgbe_ks = (ixgbe_stat_t *)ks->ks_data;
466621Sbt150084 	hw = &ixgbe->hw;
476621Sbt150084 
486621Sbt150084 	mutex_enter(&ixgbe->gen_lock);
496621Sbt150084 
506621Sbt150084 	/*
516621Sbt150084 	 * Basic information
526621Sbt150084 	 */
536621Sbt150084 	ixgbe_ks->link_speed.value.ui64 = ixgbe->link_speed;
5410998SChenlu.Chen@Sun.COM 	ixgbe_ks->reset_count.value.ui64 = ixgbe->reset_count;
5511486SZhen.W@Sun.COM 	ixgbe_ks->lroc.value.ui64 = ixgbe->lro_pkt_count;
566621Sbt150084 
576621Sbt150084 #ifdef IXGBE_DEBUG
586621Sbt150084 	ixgbe_ks->rx_frame_error.value.ui64 = 0;
596621Sbt150084 	ixgbe_ks->rx_cksum_error.value.ui64 = 0;
606621Sbt150084 	ixgbe_ks->rx_exceed_pkt.value.ui64 = 0;
616621Sbt150084 	for (i = 0; i < ixgbe->num_rx_rings; i++) {
626621Sbt150084 		ixgbe_ks->rx_frame_error.value.ui64 +=
636621Sbt150084 		    ixgbe->rx_rings[i].stat_frame_error;
646621Sbt150084 		ixgbe_ks->rx_cksum_error.value.ui64 +=
656621Sbt150084 		    ixgbe->rx_rings[i].stat_cksum_error;
666621Sbt150084 		ixgbe_ks->rx_exceed_pkt.value.ui64 +=
676621Sbt150084 		    ixgbe->rx_rings[i].stat_exceed_pkt;
686621Sbt150084 	}
696621Sbt150084 
706621Sbt150084 	ixgbe_ks->tx_overload.value.ui64 = 0;
716621Sbt150084 	ixgbe_ks->tx_fail_no_tbd.value.ui64 = 0;
726621Sbt150084 	ixgbe_ks->tx_fail_no_tcb.value.ui64 = 0;
736621Sbt150084 	ixgbe_ks->tx_fail_dma_bind.value.ui64 = 0;
746621Sbt150084 	ixgbe_ks->tx_reschedule.value.ui64 = 0;
756621Sbt150084 	for (i = 0; i < ixgbe->num_tx_rings; i++) {
766621Sbt150084 		ixgbe_ks->tx_overload.value.ui64 +=
776621Sbt150084 		    ixgbe->tx_rings[i].stat_overload;
786621Sbt150084 		ixgbe_ks->tx_fail_no_tbd.value.ui64 +=
796621Sbt150084 		    ixgbe->tx_rings[i].stat_fail_no_tbd;
806621Sbt150084 		ixgbe_ks->tx_fail_no_tcb.value.ui64 +=
816621Sbt150084 		    ixgbe->tx_rings[i].stat_fail_no_tcb;
826621Sbt150084 		ixgbe_ks->tx_fail_dma_bind.value.ui64 +=
836621Sbt150084 		    ixgbe->tx_rings[i].stat_fail_dma_bind;
846621Sbt150084 		ixgbe_ks->tx_reschedule.value.ui64 +=
856621Sbt150084 		    ixgbe->tx_rings[i].stat_reschedule;
866621Sbt150084 	}
878275SEric Cheng #endif
886621Sbt150084 
896621Sbt150084 	/*
906621Sbt150084 	 * Hardware calculated statistics.
916621Sbt150084 	 */
928275SEric Cheng 	ixgbe_ks->gprc.value.ui64 = 0;
938275SEric Cheng 	ixgbe_ks->gptc.value.ui64 = 0;
948275SEric Cheng 	ixgbe_ks->tor.value.ui64 = 0;
958275SEric Cheng 	ixgbe_ks->tot.value.ui64 = 0;
966621Sbt150084 	for (i = 0; i < 16; i++) {
978275SEric Cheng 		ixgbe_ks->qprc[i].value.ui64 +=
988275SEric Cheng 		    IXGBE_READ_REG(hw, IXGBE_QPRC(i));
998275SEric Cheng 		ixgbe_ks->gprc.value.ui64 += ixgbe_ks->qprc[i].value.ui64;
1008275SEric Cheng 		ixgbe_ks->qptc[i].value.ui64 +=
1018275SEric Cheng 		    IXGBE_READ_REG(hw, IXGBE_QPTC(i));
1028275SEric Cheng 		ixgbe_ks->gptc.value.ui64 += ixgbe_ks->qptc[i].value.ui64;
1038275SEric Cheng 		ixgbe_ks->qbrc[i].value.ui64 +=
1048275SEric Cheng 		    IXGBE_READ_REG(hw, IXGBE_QBRC(i));
1058275SEric Cheng 		ixgbe_ks->tor.value.ui64 += ixgbe_ks->qbrc[i].value.ui64;
1069353SSamuel.Tu@Sun.COM 		if (hw->mac.type >= ixgbe_mac_82599EB) {
1079353SSamuel.Tu@Sun.COM 			ixgbe_ks->qbtc[i].value.ui64 +=
1089353SSamuel.Tu@Sun.COM 			    IXGBE_READ_REG(hw, IXGBE_QBTC_L(i));
1099353SSamuel.Tu@Sun.COM 			ixgbe_ks->qbtc[i].value.ui64 += ((uint64_t)
1109353SSamuel.Tu@Sun.COM 			    (IXGBE_READ_REG(hw, IXGBE_QBTC_H(i))) << 32);
1119353SSamuel.Tu@Sun.COM 		} else {
1129353SSamuel.Tu@Sun.COM 			ixgbe_ks->qbtc[i].value.ui64 +=
1139353SSamuel.Tu@Sun.COM 			    IXGBE_READ_REG(hw, IXGBE_QBTC(i));
1149353SSamuel.Tu@Sun.COM 		}
1158275SEric Cheng 		ixgbe_ks->tot.value.ui64 += ixgbe_ks->qbtc[i].value.ui64;
1166621Sbt150084 	}
1177245Sgg161487 	/*
1187245Sgg161487 	 * This is a Workaround:
1197245Sgg161487 	 * Currently h/w GORCH, GOTCH, TORH registers are not
1207245Sgg161487 	 * correctly implemented. We found that the values in
1217245Sgg161487 	 * these registers are same as those in corresponding
1227245Sgg161487 	 * *L registers (i.e. GORCL, GOTCL, and TORL). Here the
1237245Sgg161487 	 * gor and got stat data will not be retrieved through
1247245Sgg161487 	 * GORC{H/L} and GOTC{H/L} registers but be obtained by
1257245Sgg161487 	 * simply assigning tor/tot stat data, so the gor/got
1267245Sgg161487 	 * stat data will not be accurate.
1277245Sgg161487 	 */
1286621Sbt150084 	ixgbe_ks->gor.value.ui64 = ixgbe_ks->tor.value.ui64;
1297245Sgg161487 	ixgbe_ks->got.value.ui64 = ixgbe_ks->tot.value.ui64;
1306621Sbt150084 
1316621Sbt150084 	ixgbe_ks->prc64.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC64);
1326621Sbt150084 	ixgbe_ks->prc127.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC127);
1336621Sbt150084 	ixgbe_ks->prc255.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC255);
1346621Sbt150084 	ixgbe_ks->prc511.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC511);
1356621Sbt150084 	ixgbe_ks->prc1023.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC1023);
1366621Sbt150084 	ixgbe_ks->prc1522.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC1522);
1376621Sbt150084 	ixgbe_ks->ptc64.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC64);
1386621Sbt150084 	ixgbe_ks->ptc127.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC127);
1396621Sbt150084 	ixgbe_ks->ptc255.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC255);
1406621Sbt150084 	ixgbe_ks->ptc511.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC511);
1416621Sbt150084 	ixgbe_ks->ptc1023.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC1023);
1426621Sbt150084 	ixgbe_ks->ptc1522.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC1522);
1436621Sbt150084 
1446621Sbt150084 	ixgbe_ks->mspdc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_MSPDC);
1456621Sbt150084 	for (i = 0; i < 8; i++)
1466621Sbt150084 		ixgbe_ks->mpc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_MPC(i));
1476621Sbt150084 	ixgbe_ks->mlfc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_MLFC);
1486621Sbt150084 	ixgbe_ks->mrfc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_MRFC);
1496621Sbt150084 	ixgbe_ks->rlec.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RLEC);
1506621Sbt150084 	ixgbe_ks->lxontxc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_LXONTXC);
1519353SSamuel.Tu@Sun.COM 	if (hw->mac.type == ixgbe_mac_82598EB) {
1529353SSamuel.Tu@Sun.COM 		ixgbe_ks->lxonrxc.value.ui64 += IXGBE_READ_REG(hw,
1539353SSamuel.Tu@Sun.COM 		    IXGBE_LXONRXC);
1549353SSamuel.Tu@Sun.COM 	} else {
1559353SSamuel.Tu@Sun.COM 		ixgbe_ks->lxonrxc.value.ui64 += IXGBE_READ_REG(hw,
1569353SSamuel.Tu@Sun.COM 		    IXGBE_LXONRXCNT);
1579353SSamuel.Tu@Sun.COM 	}
1586621Sbt150084 	ixgbe_ks->lxofftxc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
1599353SSamuel.Tu@Sun.COM 	if (hw->mac.type == ixgbe_mac_82598EB) {
1609353SSamuel.Tu@Sun.COM 		ixgbe_ks->lxoffrxc.value.ui64 += IXGBE_READ_REG(hw,
1619353SSamuel.Tu@Sun.COM 		    IXGBE_LXOFFRXC);
1629353SSamuel.Tu@Sun.COM 	} else {
1639353SSamuel.Tu@Sun.COM 		ixgbe_ks->lxoffrxc.value.ui64 += IXGBE_READ_REG(hw,
1649353SSamuel.Tu@Sun.COM 		    IXGBE_LXOFFRXCNT);
1659353SSamuel.Tu@Sun.COM 	}
1666621Sbt150084 	ixgbe_ks->ruc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RUC);
1676621Sbt150084 	ixgbe_ks->rfc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RFC);
1686621Sbt150084 	ixgbe_ks->roc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_ROC);
1696621Sbt150084 	ixgbe_ks->rjc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RJC);
1706621Sbt150084 
1716621Sbt150084 	mutex_exit(&ixgbe->gen_lock);
1726621Sbt150084 
1736621Sbt150084 	if (ixgbe_check_acc_handle(ixgbe->osdep.reg_handle) != DDI_FM_OK)
1746621Sbt150084 		ddi_fm_service_impact(ixgbe->dip, DDI_SERVICE_UNAFFECTED);
1756621Sbt150084 
1766621Sbt150084 	return (0);
1776621Sbt150084 }
1786621Sbt150084 
1796621Sbt150084 /*
1806621Sbt150084  * Create and initialize the driver private statistics.
1816621Sbt150084  */
1826621Sbt150084 int
1836621Sbt150084 ixgbe_init_stats(ixgbe_t *ixgbe)
1846621Sbt150084 {
1856621Sbt150084 	kstat_t *ks;
1866621Sbt150084 	ixgbe_stat_t *ixgbe_ks;
1876621Sbt150084 
1886621Sbt150084 	/*
1896621Sbt150084 	 * Create and init kstat
1906621Sbt150084 	 */
1916621Sbt150084 	ks = kstat_create(MODULE_NAME, ddi_get_instance(ixgbe->dip),
1926621Sbt150084 	    "statistics", "net", KSTAT_TYPE_NAMED,
1936621Sbt150084 	    sizeof (ixgbe_stat_t) / sizeof (kstat_named_t), 0);
1946621Sbt150084 
1956621Sbt150084 	if (ks == NULL) {
1966621Sbt150084 		ixgbe_error(ixgbe,
1976621Sbt150084 		    "Could not create kernel statistics");
1986621Sbt150084 		return (IXGBE_FAILURE);
1996621Sbt150084 	}
2006621Sbt150084 
2016621Sbt150084 	ixgbe->ixgbe_ks = ks;
2026621Sbt150084 
2036621Sbt150084 	ixgbe_ks = (ixgbe_stat_t *)ks->ks_data;
2046621Sbt150084 
2056621Sbt150084 	/*
2066621Sbt150084 	 * Initialize all the statistics.
2076621Sbt150084 	 */
2086621Sbt150084 	kstat_named_init(&ixgbe_ks->link_speed, "link_speed",
2096621Sbt150084 	    KSTAT_DATA_UINT64);
21010998SChenlu.Chen@Sun.COM 	kstat_named_init(&ixgbe_ks->reset_count, "reset_count",
21110998SChenlu.Chen@Sun.COM 	    KSTAT_DATA_UINT64);
2126621Sbt150084 
2136621Sbt150084 #ifdef IXGBE_DEBUG
2146621Sbt150084 	kstat_named_init(&ixgbe_ks->rx_frame_error, "rx_frame_error",
2156621Sbt150084 	    KSTAT_DATA_UINT64);
2166621Sbt150084 	kstat_named_init(&ixgbe_ks->rx_cksum_error, "rx_cksum_error",
2176621Sbt150084 	    KSTAT_DATA_UINT64);
2186621Sbt150084 	kstat_named_init(&ixgbe_ks->rx_exceed_pkt, "rx_exceed_pkt",
2196621Sbt150084 	    KSTAT_DATA_UINT64);
2206621Sbt150084 	kstat_named_init(&ixgbe_ks->tx_overload, "tx_overload",
2216621Sbt150084 	    KSTAT_DATA_UINT64);
2226621Sbt150084 	kstat_named_init(&ixgbe_ks->tx_fail_no_tbd, "tx_fail_no_tbd",
2236621Sbt150084 	    KSTAT_DATA_UINT64);
2246621Sbt150084 	kstat_named_init(&ixgbe_ks->tx_fail_no_tcb, "tx_fail_no_tcb",
2256621Sbt150084 	    KSTAT_DATA_UINT64);
2266621Sbt150084 	kstat_named_init(&ixgbe_ks->tx_fail_dma_bind, "tx_fail_dma_bind",
2276621Sbt150084 	    KSTAT_DATA_UINT64);
2286621Sbt150084 	kstat_named_init(&ixgbe_ks->tx_reschedule, "tx_reschedule",
2296621Sbt150084 	    KSTAT_DATA_UINT64);
2308275SEric Cheng #endif
2316621Sbt150084 
2326621Sbt150084 	kstat_named_init(&ixgbe_ks->gprc, "good_pkts_recvd",
2336621Sbt150084 	    KSTAT_DATA_UINT64);
2346621Sbt150084 	kstat_named_init(&ixgbe_ks->gptc, "good_pkts_xmitd",
2356621Sbt150084 	    KSTAT_DATA_UINT64);
2366621Sbt150084 	kstat_named_init(&ixgbe_ks->gor, "good_octets_recvd",
2376621Sbt150084 	    KSTAT_DATA_UINT64);
2386621Sbt150084 	kstat_named_init(&ixgbe_ks->got, "good_octets_xmitd",
2396621Sbt150084 	    KSTAT_DATA_UINT64);
2406621Sbt150084 	kstat_named_init(&ixgbe_ks->prc64, "pkts_recvd_(  64b)",
2416621Sbt150084 	    KSTAT_DATA_UINT64);
2426621Sbt150084 	kstat_named_init(&ixgbe_ks->prc127, "pkts_recvd_(  65- 127b)",
2436621Sbt150084 	    KSTAT_DATA_UINT64);
2446621Sbt150084 	kstat_named_init(&ixgbe_ks->prc255, "pkts_recvd_( 127- 255b)",
2456621Sbt150084 	    KSTAT_DATA_UINT64);
2466621Sbt150084 	kstat_named_init(&ixgbe_ks->prc511, "pkts_recvd_( 256- 511b)",
2476621Sbt150084 	    KSTAT_DATA_UINT64);
2486621Sbt150084 	kstat_named_init(&ixgbe_ks->prc1023, "pkts_recvd_( 511-1023b)",
2496621Sbt150084 	    KSTAT_DATA_UINT64);
2506621Sbt150084 	kstat_named_init(&ixgbe_ks->prc1522, "pkts_recvd_(1024-1522b)",
2516621Sbt150084 	    KSTAT_DATA_UINT64);
2526621Sbt150084 	kstat_named_init(&ixgbe_ks->ptc64, "pkts_xmitd_(  64b)",
2536621Sbt150084 	    KSTAT_DATA_UINT64);
2546621Sbt150084 	kstat_named_init(&ixgbe_ks->ptc127, "pkts_xmitd_(  65- 127b)",
2556621Sbt150084 	    KSTAT_DATA_UINT64);
2566621Sbt150084 	kstat_named_init(&ixgbe_ks->ptc255, "pkts_xmitd_( 128- 255b)",
2576621Sbt150084 	    KSTAT_DATA_UINT64);
2586621Sbt150084 	kstat_named_init(&ixgbe_ks->ptc511, "pkts_xmitd_( 255- 511b)",
2596621Sbt150084 	    KSTAT_DATA_UINT64);
2606621Sbt150084 	kstat_named_init(&ixgbe_ks->ptc1023, "pkts_xmitd_( 512-1023b)",
2616621Sbt150084 	    KSTAT_DATA_UINT64);
2626621Sbt150084 	kstat_named_init(&ixgbe_ks->ptc1522, "pkts_xmitd_(1024-1522b)",
2636621Sbt150084 	    KSTAT_DATA_UINT64);
2648275SEric Cheng 
2658275SEric Cheng 	kstat_named_init(&ixgbe_ks->qprc[0], "queue_pkts_recvd [ 0]",
2668275SEric Cheng 	    KSTAT_DATA_UINT64);
2678275SEric Cheng 	kstat_named_init(&ixgbe_ks->qprc[1], "queue_pkts_recvd [ 1]",
2688275SEric Cheng 	    KSTAT_DATA_UINT64);
2698275SEric Cheng 	kstat_named_init(&ixgbe_ks->qprc[2], "queue_pkts_recvd [ 2]",
2708275SEric Cheng 	    KSTAT_DATA_UINT64);
2718275SEric Cheng 	kstat_named_init(&ixgbe_ks->qprc[3], "queue_pkts_recvd [ 3]",
2728275SEric Cheng 	    KSTAT_DATA_UINT64);
2738275SEric Cheng 	kstat_named_init(&ixgbe_ks->qprc[4], "queue_pkts_recvd [ 4]",
2748275SEric Cheng 	    KSTAT_DATA_UINT64);
2758275SEric Cheng 	kstat_named_init(&ixgbe_ks->qprc[5], "queue_pkts_recvd [ 5]",
2768275SEric Cheng 	    KSTAT_DATA_UINT64);
2778275SEric Cheng 	kstat_named_init(&ixgbe_ks->qprc[6], "queue_pkts_recvd [ 6]",
2788275SEric Cheng 	    KSTAT_DATA_UINT64);
2798275SEric Cheng 	kstat_named_init(&ixgbe_ks->qprc[7], "queue_pkts_recvd [ 7]",
2808275SEric Cheng 	    KSTAT_DATA_UINT64);
2818275SEric Cheng 	kstat_named_init(&ixgbe_ks->qprc[8], "queue_pkts_recvd [ 8]",
2828275SEric Cheng 	    KSTAT_DATA_UINT64);
2838275SEric Cheng 	kstat_named_init(&ixgbe_ks->qprc[9], "queue_pkts_recvd [ 9]",
2848275SEric Cheng 	    KSTAT_DATA_UINT64);
2858275SEric Cheng 	kstat_named_init(&ixgbe_ks->qprc[10], "queue_pkts_recvd [10]",
2868275SEric Cheng 	    KSTAT_DATA_UINT64);
2878275SEric Cheng 	kstat_named_init(&ixgbe_ks->qprc[11], "queue_pkts_recvd [11]",
2888275SEric Cheng 	    KSTAT_DATA_UINT64);
2898275SEric Cheng 	kstat_named_init(&ixgbe_ks->qprc[12], "queue_pkts_recvd [12]",
2908275SEric Cheng 	    KSTAT_DATA_UINT64);
2918275SEric Cheng 	kstat_named_init(&ixgbe_ks->qprc[13], "queue_pkts_recvd [13]",
2928275SEric Cheng 	    KSTAT_DATA_UINT64);
2938275SEric Cheng 	kstat_named_init(&ixgbe_ks->qprc[14], "queue_pkts_recvd [14]",
2948275SEric Cheng 	    KSTAT_DATA_UINT64);
2958275SEric Cheng 	kstat_named_init(&ixgbe_ks->qprc[15], "queue_pkts_recvd [15]",
2968275SEric Cheng 	    KSTAT_DATA_UINT64);
2978275SEric Cheng 
2988275SEric Cheng 	kstat_named_init(&ixgbe_ks->qptc[0], "queue_pkts_xmitd [ 0]",
2998275SEric Cheng 	    KSTAT_DATA_UINT64);
3008275SEric Cheng 	kstat_named_init(&ixgbe_ks->qptc[1], "queue_pkts_xmitd [ 1]",
3018275SEric Cheng 	    KSTAT_DATA_UINT64);
3028275SEric Cheng 	kstat_named_init(&ixgbe_ks->qptc[2], "queue_pkts_xmitd [ 2]",
3038275SEric Cheng 	    KSTAT_DATA_UINT64);
3048275SEric Cheng 	kstat_named_init(&ixgbe_ks->qptc[3], "queue_pkts_xmitd [ 3]",
3058275SEric Cheng 	    KSTAT_DATA_UINT64);
3068275SEric Cheng 	kstat_named_init(&ixgbe_ks->qptc[4], "queue_pkts_xmitd [ 4]",
3078275SEric Cheng 	    KSTAT_DATA_UINT64);
3088275SEric Cheng 	kstat_named_init(&ixgbe_ks->qptc[5], "queue_pkts_xmitd [ 5]",
3098275SEric Cheng 	    KSTAT_DATA_UINT64);
3108275SEric Cheng 	kstat_named_init(&ixgbe_ks->qptc[6], "queue_pkts_xmitd [ 6]",
3118275SEric Cheng 	    KSTAT_DATA_UINT64);
3128275SEric Cheng 	kstat_named_init(&ixgbe_ks->qptc[7], "queue_pkts_xmitd [ 7]",
3138275SEric Cheng 	    KSTAT_DATA_UINT64);
3148275SEric Cheng 	kstat_named_init(&ixgbe_ks->qptc[8], "queue_pkts_xmitd [ 8]",
3158275SEric Cheng 	    KSTAT_DATA_UINT64);
3168275SEric Cheng 	kstat_named_init(&ixgbe_ks->qptc[9], "queue_pkts_xmitd [ 9]",
3178275SEric Cheng 	    KSTAT_DATA_UINT64);
3188275SEric Cheng 	kstat_named_init(&ixgbe_ks->qptc[10], "queue_pkts_xmitd [10]",
3198275SEric Cheng 	    KSTAT_DATA_UINT64);
3208275SEric Cheng 	kstat_named_init(&ixgbe_ks->qptc[11], "queue_pkts_xmitd [11]",
3218275SEric Cheng 	    KSTAT_DATA_UINT64);
3228275SEric Cheng 	kstat_named_init(&ixgbe_ks->qptc[12], "queue_pkts_xmitd [12]",
3238275SEric Cheng 	    KSTAT_DATA_UINT64);
3248275SEric Cheng 	kstat_named_init(&ixgbe_ks->qptc[13], "queue_pkts_xmitd [13]",
3258275SEric Cheng 	    KSTAT_DATA_UINT64);
3268275SEric Cheng 	kstat_named_init(&ixgbe_ks->qptc[14], "queue_pkts_xmitd [14]",
3278275SEric Cheng 	    KSTAT_DATA_UINT64);
3288275SEric Cheng 	kstat_named_init(&ixgbe_ks->qptc[15], "queue_pkts_xmitd [15]",
3298275SEric Cheng 	    KSTAT_DATA_UINT64);
3308275SEric Cheng 
3318275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbrc[0], "queue_bytes_recvd [ 0]",
3328275SEric Cheng 	    KSTAT_DATA_UINT64);
3338275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbrc[1], "queue_bytes_recvd [ 1]",
3348275SEric Cheng 	    KSTAT_DATA_UINT64);
3358275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbrc[2], "queue_bytes_recvd [ 2]",
3368275SEric Cheng 	    KSTAT_DATA_UINT64);
3378275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbrc[3], "queue_bytes_recvd [ 3]",
3388275SEric Cheng 	    KSTAT_DATA_UINT64);
3398275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbrc[4], "queue_bytes_recvd [ 4]",
3408275SEric Cheng 	    KSTAT_DATA_UINT64);
3418275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbrc[5], "queue_bytes_recvd [ 5]",
3428275SEric Cheng 	    KSTAT_DATA_UINT64);
3438275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbrc[6], "queue_bytes_recvd [ 6]",
3448275SEric Cheng 	    KSTAT_DATA_UINT64);
3458275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbrc[7], "queue_bytes_recvd [ 7]",
3468275SEric Cheng 	    KSTAT_DATA_UINT64);
3478275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbrc[8], "queue_bytes_recvd [ 8]",
3488275SEric Cheng 	    KSTAT_DATA_UINT64);
3498275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbrc[9], "queue_bytes_recvd [ 9]",
3508275SEric Cheng 	    KSTAT_DATA_UINT64);
3518275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbrc[10], "queue_bytes_recvd [10]",
3528275SEric Cheng 	    KSTAT_DATA_UINT64);
3538275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbrc[11], "queue_bytes_recvd [11]",
3548275SEric Cheng 	    KSTAT_DATA_UINT64);
3558275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbrc[12], "queue_bytes_recvd [12]",
3568275SEric Cheng 	    KSTAT_DATA_UINT64);
3578275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbrc[13], "queue_bytes_recvd [13]",
3588275SEric Cheng 	    KSTAT_DATA_UINT64);
3598275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbrc[14], "queue_bytes_recvd [14]",
3608275SEric Cheng 	    KSTAT_DATA_UINT64);
3618275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbrc[15], "queue_bytes_recvd [15]",
3628275SEric Cheng 	    KSTAT_DATA_UINT64);
3638275SEric Cheng 
3648275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbtc[0], "queue_bytes_xmitd [ 0]",
3658275SEric Cheng 	    KSTAT_DATA_UINT64);
3668275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbtc[1], "queue_bytes_xmitd [ 1]",
3678275SEric Cheng 	    KSTAT_DATA_UINT64);
3688275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbtc[2], "queue_bytes_xmitd [ 2]",
3698275SEric Cheng 	    KSTAT_DATA_UINT64);
3708275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbtc[3], "queue_bytes_xmitd [ 3]",
3718275SEric Cheng 	    KSTAT_DATA_UINT64);
3728275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbtc[4], "queue_bytes_xmitd [ 4]",
3738275SEric Cheng 	    KSTAT_DATA_UINT64);
3748275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbtc[5], "queue_bytes_xmitd [ 5]",
3758275SEric Cheng 	    KSTAT_DATA_UINT64);
3768275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbtc[6], "queue_bytes_xmitd [ 6]",
3778275SEric Cheng 	    KSTAT_DATA_UINT64);
3788275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbtc[7], "queue_bytes_xmitd [ 7]",
3798275SEric Cheng 	    KSTAT_DATA_UINT64);
3808275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbtc[8], "queue_bytes_xmitd [ 8]",
3818275SEric Cheng 	    KSTAT_DATA_UINT64);
3828275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbtc[9], "queue_bytes_xmitd [ 9]",
3838275SEric Cheng 	    KSTAT_DATA_UINT64);
3848275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbtc[10], "queue_bytes_xmitd [10]",
3858275SEric Cheng 	    KSTAT_DATA_UINT64);
3868275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbtc[11], "queue_bytes_xmitd [11]",
3878275SEric Cheng 	    KSTAT_DATA_UINT64);
3888275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbtc[12], "queue_bytes_xmitd [12]",
3898275SEric Cheng 	    KSTAT_DATA_UINT64);
3908275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbtc[13], "queue_bytes_xmitd [13]",
3918275SEric Cheng 	    KSTAT_DATA_UINT64);
3928275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbtc[14], "queue_bytes_xmitd [14]",
3938275SEric Cheng 	    KSTAT_DATA_UINT64);
3948275SEric Cheng 	kstat_named_init(&ixgbe_ks->qbtc[15], "queue_bytes_xmitd [15]",
3958275SEric Cheng 	    KSTAT_DATA_UINT64);
3966621Sbt150084 
3976621Sbt150084 	kstat_named_init(&ixgbe_ks->mspdc, "mac_short_packet_discard",
3986621Sbt150084 	    KSTAT_DATA_UINT64);
3996621Sbt150084 	kstat_named_init(&ixgbe_ks->mpc, "missed_packets",
4006621Sbt150084 	    KSTAT_DATA_UINT64);
4016621Sbt150084 	kstat_named_init(&ixgbe_ks->mlfc, "mac_local_fault",
4026621Sbt150084 	    KSTAT_DATA_UINT64);
4036621Sbt150084 	kstat_named_init(&ixgbe_ks->mrfc, "mac_remote_fault",
4046621Sbt150084 	    KSTAT_DATA_UINT64);
4056621Sbt150084 	kstat_named_init(&ixgbe_ks->rlec, "recv_length_err",
4066621Sbt150084 	    KSTAT_DATA_UINT64);
4076621Sbt150084 	kstat_named_init(&ixgbe_ks->lxontxc, "link_xon_xmitd",
4086621Sbt150084 	    KSTAT_DATA_UINT64);
4096621Sbt150084 	kstat_named_init(&ixgbe_ks->lxonrxc, "link_xon_recvd",
4106621Sbt150084 	    KSTAT_DATA_UINT64);
4116621Sbt150084 	kstat_named_init(&ixgbe_ks->lxofftxc, "link_xoff_xmitd",
4126621Sbt150084 	    KSTAT_DATA_UINT64);
4136621Sbt150084 	kstat_named_init(&ixgbe_ks->lxoffrxc, "link_xoff_recvd",
4146621Sbt150084 	    KSTAT_DATA_UINT64);
4156621Sbt150084 	kstat_named_init(&ixgbe_ks->ruc, "recv_undersize",
4166621Sbt150084 	    KSTAT_DATA_UINT64);
4176621Sbt150084 	kstat_named_init(&ixgbe_ks->rfc, "recv_fragment",
4186621Sbt150084 	    KSTAT_DATA_UINT64);
4196621Sbt150084 	kstat_named_init(&ixgbe_ks->roc, "recv_oversize",
4206621Sbt150084 	    KSTAT_DATA_UINT64);
4216621Sbt150084 	kstat_named_init(&ixgbe_ks->rjc, "recv_jabber",
4226621Sbt150084 	    KSTAT_DATA_UINT64);
4238490SPaul.Guo@Sun.COM 	kstat_named_init(&ixgbe_ks->rnbc, "recv_no_buffer",
4248490SPaul.Guo@Sun.COM 	    KSTAT_DATA_UINT64);
42511486SZhen.W@Sun.COM 	kstat_named_init(&ixgbe_ks->lroc, "lro_pkt_count",
42611486SZhen.W@Sun.COM 	    KSTAT_DATA_UINT64);
4276621Sbt150084 	/*
4286621Sbt150084 	 * Function to provide kernel stat update on demand
4296621Sbt150084 	 */
4306621Sbt150084 	ks->ks_update = ixgbe_update_stats;
4316621Sbt150084 
4326621Sbt150084 	ks->ks_private = (void *)ixgbe;
4336621Sbt150084 
4346621Sbt150084 	/*
4356621Sbt150084 	 * Add kstat to systems kstat chain
4366621Sbt150084 	 */
4376621Sbt150084 	kstat_install(ks);
4386621Sbt150084 
4396621Sbt150084 	return (IXGBE_SUCCESS);
4406621Sbt150084 }
441*11878SVenu.Iyer@Sun.COM 
442*11878SVenu.Iyer@Sun.COM /*
443*11878SVenu.Iyer@Sun.COM  * Retrieve a value for one of the statistics.
444*11878SVenu.Iyer@Sun.COM  */
445*11878SVenu.Iyer@Sun.COM int
446*11878SVenu.Iyer@Sun.COM ixgbe_m_stat(void *arg, uint_t stat, uint64_t *val)
447*11878SVenu.Iyer@Sun.COM {
448*11878SVenu.Iyer@Sun.COM 	ixgbe_t *ixgbe = (ixgbe_t *)arg;
449*11878SVenu.Iyer@Sun.COM 	struct ixgbe_hw *hw = &ixgbe->hw;
450*11878SVenu.Iyer@Sun.COM 	ixgbe_stat_t *ixgbe_ks;
451*11878SVenu.Iyer@Sun.COM 	int i;
452*11878SVenu.Iyer@Sun.COM 
453*11878SVenu.Iyer@Sun.COM 	ixgbe_ks = (ixgbe_stat_t *)ixgbe->ixgbe_ks->ks_data;
454*11878SVenu.Iyer@Sun.COM 
455*11878SVenu.Iyer@Sun.COM 	mutex_enter(&ixgbe->gen_lock);
456*11878SVenu.Iyer@Sun.COM 
457*11878SVenu.Iyer@Sun.COM 	if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
458*11878SVenu.Iyer@Sun.COM 		mutex_exit(&ixgbe->gen_lock);
459*11878SVenu.Iyer@Sun.COM 		return (ECANCELED);
460*11878SVenu.Iyer@Sun.COM 	}
461*11878SVenu.Iyer@Sun.COM 
462*11878SVenu.Iyer@Sun.COM 	switch (stat) {
463*11878SVenu.Iyer@Sun.COM 	case MAC_STAT_IFSPEED:
464*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->link_speed * 1000000ull;
465*11878SVenu.Iyer@Sun.COM 		break;
466*11878SVenu.Iyer@Sun.COM 
467*11878SVenu.Iyer@Sun.COM 	case MAC_STAT_MULTIRCV:
468*11878SVenu.Iyer@Sun.COM 		ixgbe_ks->mprc.value.ui64 +=
469*11878SVenu.Iyer@Sun.COM 		    IXGBE_READ_REG(hw, IXGBE_MPRC);
470*11878SVenu.Iyer@Sun.COM 		*val = ixgbe_ks->mprc.value.ui64;
471*11878SVenu.Iyer@Sun.COM 		break;
472*11878SVenu.Iyer@Sun.COM 
473*11878SVenu.Iyer@Sun.COM 	case MAC_STAT_BRDCSTRCV:
474*11878SVenu.Iyer@Sun.COM 		ixgbe_ks->bprc.value.ui64 +=
475*11878SVenu.Iyer@Sun.COM 		    IXGBE_READ_REG(hw, IXGBE_BPRC);
476*11878SVenu.Iyer@Sun.COM 		*val = ixgbe_ks->bprc.value.ui64;
477*11878SVenu.Iyer@Sun.COM 		break;
478*11878SVenu.Iyer@Sun.COM 
479*11878SVenu.Iyer@Sun.COM 	case MAC_STAT_MULTIXMT:
480*11878SVenu.Iyer@Sun.COM 		ixgbe_ks->mptc.value.ui64 +=
481*11878SVenu.Iyer@Sun.COM 		    IXGBE_READ_REG(hw, IXGBE_MPTC);
482*11878SVenu.Iyer@Sun.COM 		*val = ixgbe_ks->mptc.value.ui64;
483*11878SVenu.Iyer@Sun.COM 		break;
484*11878SVenu.Iyer@Sun.COM 
485*11878SVenu.Iyer@Sun.COM 	case MAC_STAT_BRDCSTXMT:
486*11878SVenu.Iyer@Sun.COM 		ixgbe_ks->bptc.value.ui64 +=
487*11878SVenu.Iyer@Sun.COM 		    IXGBE_READ_REG(hw, IXGBE_BPTC);
488*11878SVenu.Iyer@Sun.COM 		*val = ixgbe_ks->bptc.value.ui64;
489*11878SVenu.Iyer@Sun.COM 		break;
490*11878SVenu.Iyer@Sun.COM 
491*11878SVenu.Iyer@Sun.COM 	case MAC_STAT_NORCVBUF:
492*11878SVenu.Iyer@Sun.COM 		for (i = 0; i < 8; i++) {
493*11878SVenu.Iyer@Sun.COM 			ixgbe_ks->rnbc.value.ui64 +=
494*11878SVenu.Iyer@Sun.COM 			    IXGBE_READ_REG(hw, IXGBE_RNBC(i));
495*11878SVenu.Iyer@Sun.COM 		}
496*11878SVenu.Iyer@Sun.COM 		*val = ixgbe_ks->rnbc.value.ui64;
497*11878SVenu.Iyer@Sun.COM 		break;
498*11878SVenu.Iyer@Sun.COM 
499*11878SVenu.Iyer@Sun.COM 	case MAC_STAT_IERRORS:
500*11878SVenu.Iyer@Sun.COM 		ixgbe_ks->crcerrs.value.ui64 +=
501*11878SVenu.Iyer@Sun.COM 		    IXGBE_READ_REG(hw, IXGBE_CRCERRS);
502*11878SVenu.Iyer@Sun.COM 		ixgbe_ks->illerrc.value.ui64 +=
503*11878SVenu.Iyer@Sun.COM 		    IXGBE_READ_REG(hw, IXGBE_ILLERRC);
504*11878SVenu.Iyer@Sun.COM 		ixgbe_ks->errbc.value.ui64 +=
505*11878SVenu.Iyer@Sun.COM 		    IXGBE_READ_REG(hw, IXGBE_ERRBC);
506*11878SVenu.Iyer@Sun.COM 		ixgbe_ks->rlec.value.ui64 +=
507*11878SVenu.Iyer@Sun.COM 		    IXGBE_READ_REG(hw, IXGBE_RLEC);
508*11878SVenu.Iyer@Sun.COM 		*val = ixgbe_ks->crcerrs.value.ui64 +
509*11878SVenu.Iyer@Sun.COM 		    ixgbe_ks->illerrc.value.ui64 +
510*11878SVenu.Iyer@Sun.COM 		    ixgbe_ks->errbc.value.ui64 +
511*11878SVenu.Iyer@Sun.COM 		    ixgbe_ks->rlec.value.ui64;
512*11878SVenu.Iyer@Sun.COM 		break;
513*11878SVenu.Iyer@Sun.COM 
514*11878SVenu.Iyer@Sun.COM 	case MAC_STAT_RBYTES:
515*11878SVenu.Iyer@Sun.COM 		ixgbe_ks->tor.value.ui64 = 0;
516*11878SVenu.Iyer@Sun.COM 		for (i = 0; i < 16; i++) {
517*11878SVenu.Iyer@Sun.COM 			ixgbe_ks->qbrc[i].value.ui64 +=
518*11878SVenu.Iyer@Sun.COM 			    IXGBE_READ_REG(hw, IXGBE_QBRC(i));
519*11878SVenu.Iyer@Sun.COM 			ixgbe_ks->tor.value.ui64 +=
520*11878SVenu.Iyer@Sun.COM 			    ixgbe_ks->qbrc[i].value.ui64;
521*11878SVenu.Iyer@Sun.COM 		}
522*11878SVenu.Iyer@Sun.COM 		*val = ixgbe_ks->tor.value.ui64;
523*11878SVenu.Iyer@Sun.COM 		break;
524*11878SVenu.Iyer@Sun.COM 
525*11878SVenu.Iyer@Sun.COM 	case MAC_STAT_OBYTES:
526*11878SVenu.Iyer@Sun.COM 		ixgbe_ks->tot.value.ui64 = 0;
527*11878SVenu.Iyer@Sun.COM 		for (i = 0; i < 16; i++) {
528*11878SVenu.Iyer@Sun.COM 			if (hw->mac.type >= ixgbe_mac_82599EB) {
529*11878SVenu.Iyer@Sun.COM 				ixgbe_ks->qbtc[i].value.ui64 +=
530*11878SVenu.Iyer@Sun.COM 				    IXGBE_READ_REG(hw, IXGBE_QBTC_L(i));
531*11878SVenu.Iyer@Sun.COM 				ixgbe_ks->qbtc[i].value.ui64 += ((uint64_t)
532*11878SVenu.Iyer@Sun.COM 				    IXGBE_READ_REG(hw, IXGBE_QBTC_H(i))) << 32;
533*11878SVenu.Iyer@Sun.COM 			} else {
534*11878SVenu.Iyer@Sun.COM 				ixgbe_ks->qbtc[i].value.ui64 +=
535*11878SVenu.Iyer@Sun.COM 				    IXGBE_READ_REG(hw, IXGBE_QBTC(i));
536*11878SVenu.Iyer@Sun.COM 			}
537*11878SVenu.Iyer@Sun.COM 			ixgbe_ks->tot.value.ui64 +=
538*11878SVenu.Iyer@Sun.COM 			    ixgbe_ks->qbtc[i].value.ui64;
539*11878SVenu.Iyer@Sun.COM 		}
540*11878SVenu.Iyer@Sun.COM 		*val = ixgbe_ks->tot.value.ui64;
541*11878SVenu.Iyer@Sun.COM 		break;
542*11878SVenu.Iyer@Sun.COM 
543*11878SVenu.Iyer@Sun.COM 	case MAC_STAT_IPACKETS:
544*11878SVenu.Iyer@Sun.COM 		ixgbe_ks->tpr.value.ui64 +=
545*11878SVenu.Iyer@Sun.COM 		    IXGBE_READ_REG(hw, IXGBE_TPR);
546*11878SVenu.Iyer@Sun.COM 		*val = ixgbe_ks->tpr.value.ui64;
547*11878SVenu.Iyer@Sun.COM 		break;
548*11878SVenu.Iyer@Sun.COM 
549*11878SVenu.Iyer@Sun.COM 	case MAC_STAT_OPACKETS:
550*11878SVenu.Iyer@Sun.COM 		ixgbe_ks->tpt.value.ui64 +=
551*11878SVenu.Iyer@Sun.COM 		    IXGBE_READ_REG(hw, IXGBE_TPT);
552*11878SVenu.Iyer@Sun.COM 		*val = ixgbe_ks->tpt.value.ui64;
553*11878SVenu.Iyer@Sun.COM 		break;
554*11878SVenu.Iyer@Sun.COM 
555*11878SVenu.Iyer@Sun.COM 	/* RFC 1643 stats */
556*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_FCS_ERRORS:
557*11878SVenu.Iyer@Sun.COM 		ixgbe_ks->crcerrs.value.ui64 +=
558*11878SVenu.Iyer@Sun.COM 		    IXGBE_READ_REG(hw, IXGBE_CRCERRS);
559*11878SVenu.Iyer@Sun.COM 		*val = ixgbe_ks->crcerrs.value.ui64;
560*11878SVenu.Iyer@Sun.COM 		break;
561*11878SVenu.Iyer@Sun.COM 
562*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_TOOLONG_ERRORS:
563*11878SVenu.Iyer@Sun.COM 		ixgbe_ks->roc.value.ui64 +=
564*11878SVenu.Iyer@Sun.COM 		    IXGBE_READ_REG(hw, IXGBE_ROC);
565*11878SVenu.Iyer@Sun.COM 		*val = ixgbe_ks->roc.value.ui64;
566*11878SVenu.Iyer@Sun.COM 		break;
567*11878SVenu.Iyer@Sun.COM 
568*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_MACRCV_ERRORS:
569*11878SVenu.Iyer@Sun.COM 		ixgbe_ks->crcerrs.value.ui64 +=
570*11878SVenu.Iyer@Sun.COM 		    IXGBE_READ_REG(hw, IXGBE_CRCERRS);
571*11878SVenu.Iyer@Sun.COM 		ixgbe_ks->illerrc.value.ui64 +=
572*11878SVenu.Iyer@Sun.COM 		    IXGBE_READ_REG(hw, IXGBE_ILLERRC);
573*11878SVenu.Iyer@Sun.COM 		ixgbe_ks->errbc.value.ui64 +=
574*11878SVenu.Iyer@Sun.COM 		    IXGBE_READ_REG(hw, IXGBE_ERRBC);
575*11878SVenu.Iyer@Sun.COM 		ixgbe_ks->rlec.value.ui64 +=
576*11878SVenu.Iyer@Sun.COM 		    IXGBE_READ_REG(hw, IXGBE_RLEC);
577*11878SVenu.Iyer@Sun.COM 		*val = ixgbe_ks->crcerrs.value.ui64 +
578*11878SVenu.Iyer@Sun.COM 		    ixgbe_ks->illerrc.value.ui64 +
579*11878SVenu.Iyer@Sun.COM 		    ixgbe_ks->errbc.value.ui64 +
580*11878SVenu.Iyer@Sun.COM 		    ixgbe_ks->rlec.value.ui64;
581*11878SVenu.Iyer@Sun.COM 		break;
582*11878SVenu.Iyer@Sun.COM 
583*11878SVenu.Iyer@Sun.COM 	/* MII/GMII stats */
584*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_XCVR_ADDR:
585*11878SVenu.Iyer@Sun.COM 		/* The Internal PHY's MDI address for each MAC is 1 */
586*11878SVenu.Iyer@Sun.COM 		*val = 1;
587*11878SVenu.Iyer@Sun.COM 		break;
588*11878SVenu.Iyer@Sun.COM 
589*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_XCVR_ID:
590*11878SVenu.Iyer@Sun.COM 		*val = hw->phy.id;
591*11878SVenu.Iyer@Sun.COM 		break;
592*11878SVenu.Iyer@Sun.COM 
593*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_XCVR_INUSE:
594*11878SVenu.Iyer@Sun.COM 		switch (ixgbe->link_speed) {
595*11878SVenu.Iyer@Sun.COM 		case IXGBE_LINK_SPEED_1GB_FULL:
596*11878SVenu.Iyer@Sun.COM 			*val =
597*11878SVenu.Iyer@Sun.COM 			    (hw->phy.media_type == ixgbe_media_type_copper) ?
598*11878SVenu.Iyer@Sun.COM 			    XCVR_1000T : XCVR_1000X;
599*11878SVenu.Iyer@Sun.COM 			break;
600*11878SVenu.Iyer@Sun.COM 		case IXGBE_LINK_SPEED_100_FULL:
601*11878SVenu.Iyer@Sun.COM 			*val = (hw->phy.media_type == ixgbe_media_type_copper) ?
602*11878SVenu.Iyer@Sun.COM 			    XCVR_100T2 : XCVR_100X;
603*11878SVenu.Iyer@Sun.COM 			break;
604*11878SVenu.Iyer@Sun.COM 		default:
605*11878SVenu.Iyer@Sun.COM 			*val = XCVR_NONE;
606*11878SVenu.Iyer@Sun.COM 			break;
607*11878SVenu.Iyer@Sun.COM 		}
608*11878SVenu.Iyer@Sun.COM 		break;
609*11878SVenu.Iyer@Sun.COM 
610*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_CAP_10GFDX:
611*11878SVenu.Iyer@Sun.COM 		*val = 1;
612*11878SVenu.Iyer@Sun.COM 		break;
613*11878SVenu.Iyer@Sun.COM 
614*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_CAP_1000FDX:
615*11878SVenu.Iyer@Sun.COM 		*val = 1;
616*11878SVenu.Iyer@Sun.COM 		break;
617*11878SVenu.Iyer@Sun.COM 
618*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_CAP_100FDX:
619*11878SVenu.Iyer@Sun.COM 		*val = 1;
620*11878SVenu.Iyer@Sun.COM 		break;
621*11878SVenu.Iyer@Sun.COM 
622*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_CAP_ASMPAUSE:
623*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->param_asym_pause_cap;
624*11878SVenu.Iyer@Sun.COM 		break;
625*11878SVenu.Iyer@Sun.COM 
626*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_CAP_PAUSE:
627*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->param_pause_cap;
628*11878SVenu.Iyer@Sun.COM 		break;
629*11878SVenu.Iyer@Sun.COM 
630*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_CAP_AUTONEG:
631*11878SVenu.Iyer@Sun.COM 		*val = 1;
632*11878SVenu.Iyer@Sun.COM 		break;
633*11878SVenu.Iyer@Sun.COM 
634*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_ADV_CAP_10GFDX:
635*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->param_adv_10000fdx_cap;
636*11878SVenu.Iyer@Sun.COM 		break;
637*11878SVenu.Iyer@Sun.COM 
638*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_ADV_CAP_1000FDX:
639*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->param_adv_1000fdx_cap;
640*11878SVenu.Iyer@Sun.COM 		break;
641*11878SVenu.Iyer@Sun.COM 
642*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_ADV_CAP_100FDX:
643*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->param_adv_100fdx_cap;
644*11878SVenu.Iyer@Sun.COM 		break;
645*11878SVenu.Iyer@Sun.COM 
646*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
647*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->param_adv_asym_pause_cap;
648*11878SVenu.Iyer@Sun.COM 		break;
649*11878SVenu.Iyer@Sun.COM 
650*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_ADV_CAP_PAUSE:
651*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->param_adv_pause_cap;
652*11878SVenu.Iyer@Sun.COM 		break;
653*11878SVenu.Iyer@Sun.COM 
654*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_ADV_CAP_AUTONEG:
655*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->param_adv_autoneg_cap;
656*11878SVenu.Iyer@Sun.COM 		break;
657*11878SVenu.Iyer@Sun.COM 
658*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_LP_CAP_10GFDX:
659*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->param_lp_10000fdx_cap;
660*11878SVenu.Iyer@Sun.COM 		break;
661*11878SVenu.Iyer@Sun.COM 
662*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_LP_CAP_1000FDX:
663*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->param_lp_1000fdx_cap;
664*11878SVenu.Iyer@Sun.COM 		break;
665*11878SVenu.Iyer@Sun.COM 
666*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_LP_CAP_100FDX:
667*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->param_lp_100fdx_cap;
668*11878SVenu.Iyer@Sun.COM 		break;
669*11878SVenu.Iyer@Sun.COM 
670*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_LP_CAP_ASMPAUSE:
671*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->param_lp_asym_pause_cap;
672*11878SVenu.Iyer@Sun.COM 		break;
673*11878SVenu.Iyer@Sun.COM 
674*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_LP_CAP_PAUSE:
675*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->param_lp_pause_cap;
676*11878SVenu.Iyer@Sun.COM 		break;
677*11878SVenu.Iyer@Sun.COM 
678*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_LP_CAP_AUTONEG:
679*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->param_lp_autoneg_cap;
680*11878SVenu.Iyer@Sun.COM 		break;
681*11878SVenu.Iyer@Sun.COM 
682*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_LINK_ASMPAUSE:
683*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->param_asym_pause_cap;
684*11878SVenu.Iyer@Sun.COM 		break;
685*11878SVenu.Iyer@Sun.COM 
686*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_LINK_PAUSE:
687*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->param_pause_cap;
688*11878SVenu.Iyer@Sun.COM 		break;
689*11878SVenu.Iyer@Sun.COM 
690*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_LINK_AUTONEG:
691*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->param_adv_autoneg_cap;
692*11878SVenu.Iyer@Sun.COM 		break;
693*11878SVenu.Iyer@Sun.COM 
694*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_LINK_DUPLEX:
695*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->link_duplex;
696*11878SVenu.Iyer@Sun.COM 		break;
697*11878SVenu.Iyer@Sun.COM 
698*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_TOOSHORT_ERRORS:
699*11878SVenu.Iyer@Sun.COM 		ixgbe_ks->ruc.value.ui64 +=
700*11878SVenu.Iyer@Sun.COM 		    IXGBE_READ_REG(hw, IXGBE_RUC);
701*11878SVenu.Iyer@Sun.COM 		*val = ixgbe_ks->ruc.value.ui64;
702*11878SVenu.Iyer@Sun.COM 		break;
703*11878SVenu.Iyer@Sun.COM 
704*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_CAP_REMFAULT:
705*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->param_rem_fault;
706*11878SVenu.Iyer@Sun.COM 		break;
707*11878SVenu.Iyer@Sun.COM 
708*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_ADV_REMFAULT:
709*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->param_adv_rem_fault;
710*11878SVenu.Iyer@Sun.COM 		break;
711*11878SVenu.Iyer@Sun.COM 
712*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_LP_REMFAULT:
713*11878SVenu.Iyer@Sun.COM 		*val = ixgbe->param_lp_rem_fault;
714*11878SVenu.Iyer@Sun.COM 		break;
715*11878SVenu.Iyer@Sun.COM 
716*11878SVenu.Iyer@Sun.COM 	case ETHER_STAT_JABBER_ERRORS:
717*11878SVenu.Iyer@Sun.COM 		ixgbe_ks->rjc.value.ui64 +=
718*11878SVenu.Iyer@Sun.COM 		    IXGBE_READ_REG(hw, IXGBE_RJC);
719*11878SVenu.Iyer@Sun.COM 		*val = ixgbe_ks->rjc.value.ui64;
720*11878SVenu.Iyer@Sun.COM 		break;
721*11878SVenu.Iyer@Sun.COM 
722*11878SVenu.Iyer@Sun.COM 	default:
723*11878SVenu.Iyer@Sun.COM 		mutex_exit(&ixgbe->gen_lock);
724*11878SVenu.Iyer@Sun.COM 		return (ENOTSUP);
725*11878SVenu.Iyer@Sun.COM 	}
726*11878SVenu.Iyer@Sun.COM 
727*11878SVenu.Iyer@Sun.COM 	mutex_exit(&ixgbe->gen_lock);
728*11878SVenu.Iyer@Sun.COM 
729*11878SVenu.Iyer@Sun.COM 	if (ixgbe_check_acc_handle(ixgbe->osdep.reg_handle) != DDI_FM_OK) {
730*11878SVenu.Iyer@Sun.COM 		ddi_fm_service_impact(ixgbe->dip, DDI_SERVICE_DEGRADED);
731*11878SVenu.Iyer@Sun.COM 		return (EIO);
732*11878SVenu.Iyer@Sun.COM 	}
733*11878SVenu.Iyer@Sun.COM 
734*11878SVenu.Iyer@Sun.COM 	return (0);
735*11878SVenu.Iyer@Sun.COM }
736*11878SVenu.Iyer@Sun.COM 
737*11878SVenu.Iyer@Sun.COM /*
738*11878SVenu.Iyer@Sun.COM  * Retrieve a value for one of the statistics for a particular rx ring
739*11878SVenu.Iyer@Sun.COM  */
740*11878SVenu.Iyer@Sun.COM int
741*11878SVenu.Iyer@Sun.COM ixgbe_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
742*11878SVenu.Iyer@Sun.COM {
743*11878SVenu.Iyer@Sun.COM 	ixgbe_rx_ring_t	*rx_ring = (ixgbe_rx_ring_t *)rh;
744*11878SVenu.Iyer@Sun.COM 	ixgbe_t *ixgbe = rx_ring->ixgbe;
745*11878SVenu.Iyer@Sun.COM 
746*11878SVenu.Iyer@Sun.COM 	if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
747*11878SVenu.Iyer@Sun.COM 		return (ECANCELED);
748*11878SVenu.Iyer@Sun.COM 	}
749*11878SVenu.Iyer@Sun.COM 
750*11878SVenu.Iyer@Sun.COM 	switch (stat) {
751*11878SVenu.Iyer@Sun.COM 	case MAC_STAT_RBYTES:
752*11878SVenu.Iyer@Sun.COM 		*val = rx_ring->stat_rbytes;
753*11878SVenu.Iyer@Sun.COM 		break;
754*11878SVenu.Iyer@Sun.COM 
755*11878SVenu.Iyer@Sun.COM 	case MAC_STAT_IPACKETS:
756*11878SVenu.Iyer@Sun.COM 		*val = rx_ring->stat_ipackets;
757*11878SVenu.Iyer@Sun.COM 		break;
758*11878SVenu.Iyer@Sun.COM 
759*11878SVenu.Iyer@Sun.COM 	default:
760*11878SVenu.Iyer@Sun.COM 		*val = 0;
761*11878SVenu.Iyer@Sun.COM 		return (ENOTSUP);
762*11878SVenu.Iyer@Sun.COM 	}
763*11878SVenu.Iyer@Sun.COM 
764*11878SVenu.Iyer@Sun.COM 	return (0);
765*11878SVenu.Iyer@Sun.COM }
766*11878SVenu.Iyer@Sun.COM 
767*11878SVenu.Iyer@Sun.COM /*
768*11878SVenu.Iyer@Sun.COM  * Retrieve a value for one of the statistics for a particular tx ring
769*11878SVenu.Iyer@Sun.COM  */
770*11878SVenu.Iyer@Sun.COM int
771*11878SVenu.Iyer@Sun.COM ixgbe_tx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
772*11878SVenu.Iyer@Sun.COM {
773*11878SVenu.Iyer@Sun.COM 	ixgbe_tx_ring_t	*tx_ring = (ixgbe_tx_ring_t *)rh;
774*11878SVenu.Iyer@Sun.COM 	ixgbe_t *ixgbe = tx_ring->ixgbe;
775*11878SVenu.Iyer@Sun.COM 
776*11878SVenu.Iyer@Sun.COM 	if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
777*11878SVenu.Iyer@Sun.COM 		return (ECANCELED);
778*11878SVenu.Iyer@Sun.COM 	}
779*11878SVenu.Iyer@Sun.COM 
780*11878SVenu.Iyer@Sun.COM 	switch (stat) {
781*11878SVenu.Iyer@Sun.COM 	case MAC_STAT_OBYTES:
782*11878SVenu.Iyer@Sun.COM 		*val = tx_ring->stat_obytes;
783*11878SVenu.Iyer@Sun.COM 		break;
784*11878SVenu.Iyer@Sun.COM 
785*11878SVenu.Iyer@Sun.COM 	case MAC_STAT_OPACKETS:
786*11878SVenu.Iyer@Sun.COM 		*val = tx_ring->stat_opackets;
787*11878SVenu.Iyer@Sun.COM 		break;
788*11878SVenu.Iyer@Sun.COM 
789*11878SVenu.Iyer@Sun.COM 	default:
790*11878SVenu.Iyer@Sun.COM 		*val = 0;
791*11878SVenu.Iyer@Sun.COM 		return (ENOTSUP);
792*11878SVenu.Iyer@Sun.COM 	}
793*11878SVenu.Iyer@Sun.COM 
794*11878SVenu.Iyer@Sun.COM 	return (0);
795*11878SVenu.Iyer@Sun.COM }
796