xref: /onnv-gate/usr/src/uts/common/io/e1000g/e1000g_stat.c (revision 6735:ba4d622bb38a)
13526Sxy150489 /*
23526Sxy150489  * This file is provided under a CDDLv1 license.  When using or
33526Sxy150489  * redistributing this file, you may do so under this license.
43526Sxy150489  * In redistributing this file this license must be included
53526Sxy150489  * and no other modification of this header file is permitted.
63526Sxy150489  *
73526Sxy150489  * CDDL LICENSE SUMMARY
83526Sxy150489  *
95882Syy150190  * Copyright(c) 1999 - 2008 Intel Corporation. All rights reserved.
103526Sxy150489  *
113526Sxy150489  * The contents of this file are subject to the terms of Version
123526Sxy150489  * 1.0 of the Common Development and Distribution License (the "License").
133526Sxy150489  *
143526Sxy150489  * You should have received a copy of the License with this software.
153526Sxy150489  * You can obtain a copy of the License at
163526Sxy150489  *	http://www.opensolaris.org/os/licensing.
173526Sxy150489  * See the License for the specific language governing permissions
183526Sxy150489  * and limitations under the License.
193526Sxy150489  */
203526Sxy150489 
213526Sxy150489 /*
225882Syy150190  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
233526Sxy150489  * Use is subject to license terms of the CDDLv1.
243526Sxy150489  */
253526Sxy150489 
263526Sxy150489 #pragma ident	"%Z%%M%	%I%	%E% SMI"
273526Sxy150489 
283526Sxy150489 /*
293526Sxy150489  * **********************************************************************
303526Sxy150489  *									*
313526Sxy150489  * Module Name:  e1000g_stat.c						*
323526Sxy150489  *									*
334919Sxy150489  * Abstract: Functions for processing statistics			*
343526Sxy150489  *									*
353526Sxy150489  * **********************************************************************
363526Sxy150489  */
373526Sxy150489 #include "e1000g_sw.h"
383526Sxy150489 #include "e1000g_debug.h"
393526Sxy150489 
404919Sxy150489 static int e1000g_update_stats(kstat_t *ksp, int rw);
413526Sxy150489 
423526Sxy150489 /*
434919Sxy150489  * e1000_tbi_adjust_stats
444919Sxy150489  *
454919Sxy150489  * Adjusts statistic counters when a frame is accepted
464919Sxy150489  * under the TBI workaround. This function has been
474919Sxy150489  * adapted for Solaris from shared code.
483526Sxy150489  */
493526Sxy150489 void
504919Sxy150489 e1000_tbi_adjust_stats(struct e1000g *Adapter,
514919Sxy150489     uint32_t frame_len, uint8_t *mac_addr)
523526Sxy150489 {
534919Sxy150489 	struct e1000_hw *hw = &Adapter->shared;
544919Sxy150489 	uint32_t carry_bit;
554919Sxy150489 	p_e1000g_stat_t e1000g_ksp;
563526Sxy150489 
574919Sxy150489 	e1000g_ksp = (p_e1000g_stat_t)Adapter->e1000g_ksp->ks_data;
583526Sxy150489 
594919Sxy150489 	/* First adjust the frame length */
604919Sxy150489 	frame_len--;
614919Sxy150489 
623526Sxy150489 	/*
633526Sxy150489 	 * We need to adjust the statistics counters, since the hardware
643526Sxy150489 	 * counters overcount this packet as a CRC error and undercount
653526Sxy150489 	 * the packet as a good packet
663526Sxy150489 	 */
674919Sxy150489 	/* This packet should not be counted as a CRC error */
683526Sxy150489 	e1000g_ksp->Crcerrs.value.ul--;
694919Sxy150489 	/* This packet does count as a Good Packet Received */
703526Sxy150489 	e1000g_ksp->Gprc.value.ul++;
713526Sxy150489 
723526Sxy150489 	/*
733526Sxy150489 	 * Adjust the Good Octets received counters
743526Sxy150489 	 */
754919Sxy150489 	carry_bit = 0x80000000 & e1000g_ksp->Gorl.value.ul;
764919Sxy150489 	e1000g_ksp->Gorl.value.ul += frame_len;
773526Sxy150489 	/*
783526Sxy150489 	 * If the high bit of Gorcl (the low 32 bits of the Good Octets
793526Sxy150489 	 * Received Count) was one before the addition,
803526Sxy150489 	 * AND it is zero after, then we lost the carry out,
813526Sxy150489 	 * need to add one to Gorch (Good Octets Received Count High).
823526Sxy150489 	 * This could be simplified if all environments supported
833526Sxy150489 	 * 64-bit integers.
843526Sxy150489 	 */
854919Sxy150489 	if (carry_bit && ((e1000g_ksp->Gorl.value.ul & 0x80000000) == 0)) {
863526Sxy150489 		e1000g_ksp->Gorh.value.ul++;
873526Sxy150489 	}
883526Sxy150489 	/*
893526Sxy150489 	 * Is this a broadcast or multicast?  Check broadcast first,
903526Sxy150489 	 * since the test for a multicast frame will test positive on
913526Sxy150489 	 * a broadcast frame.
923526Sxy150489 	 */
934919Sxy150489 	if ((mac_addr[0] == (uint8_t)0xff) &&
944919Sxy150489 	    (mac_addr[1] == (uint8_t)0xff)) {
953526Sxy150489 		/*
963526Sxy150489 		 * Broadcast packet
973526Sxy150489 		 */
983526Sxy150489 		e1000g_ksp->Bprc.value.ul++;
994919Sxy150489 	} else if (*mac_addr & 0x01) {
1003526Sxy150489 		/*
1013526Sxy150489 		 * Multicast packet
1023526Sxy150489 		 */
1033526Sxy150489 		e1000g_ksp->Mprc.value.ul++;
1043526Sxy150489 	}
1054919Sxy150489 
106*6735Scc210113 	if (frame_len == Adapter->max_frame_size) {
1073526Sxy150489 		/*
1083526Sxy150489 		 * In this case, the hardware has overcounted the number of
1093526Sxy150489 		 * oversize frames.
1103526Sxy150489 		 */
1113526Sxy150489 		if (e1000g_ksp->Roc.value.ul > 0)
1123526Sxy150489 			e1000g_ksp->Roc.value.ul--;
1133526Sxy150489 	}
1143526Sxy150489 
1155882Syy150190 #ifdef E1000G_DEBUG
1163526Sxy150489 	/*
1173526Sxy150489 	 * Adjust the bin counters when the extra byte put the frame in the
1184919Sxy150489 	 * wrong bin. Remember that the frame_len was adjusted above.
1193526Sxy150489 	 */
1204919Sxy150489 	if (frame_len == 64) {
1213526Sxy150489 		e1000g_ksp->Prc64.value.ul++;
1223526Sxy150489 		e1000g_ksp->Prc127.value.ul--;
1234919Sxy150489 	} else if (frame_len == 127) {
1243526Sxy150489 		e1000g_ksp->Prc127.value.ul++;
1253526Sxy150489 		e1000g_ksp->Prc255.value.ul--;
1264919Sxy150489 	} else if (frame_len == 255) {
1273526Sxy150489 		e1000g_ksp->Prc255.value.ul++;
1283526Sxy150489 		e1000g_ksp->Prc511.value.ul--;
1294919Sxy150489 	} else if (frame_len == 511) {
1303526Sxy150489 		e1000g_ksp->Prc511.value.ul++;
1313526Sxy150489 		e1000g_ksp->Prc1023.value.ul--;
1324919Sxy150489 	} else if (frame_len == 1023) {
1333526Sxy150489 		e1000g_ksp->Prc1023.value.ul++;
1343526Sxy150489 		e1000g_ksp->Prc1522.value.ul--;
1354919Sxy150489 	} else if (frame_len == 1522) {
1363526Sxy150489 		e1000g_ksp->Prc1522.value.ul++;
1373526Sxy150489 	}
1385882Syy150190 #endif
1393526Sxy150489 }
1403526Sxy150489 
1413526Sxy150489 
1423526Sxy150489 /*
1434919Sxy150489  * e1000g_update_stats - update driver private kstat counters
1444919Sxy150489  *
1454919Sxy150489  * This routine will dump and reset the e1000's internal
1464919Sxy150489  * statistics counters. The current stats dump values will
1474919Sxy150489  * be sent to the kernel status area.
1483526Sxy150489  */
1493526Sxy150489 static int
1504919Sxy150489 e1000g_update_stats(kstat_t *ksp, int rw)
1513526Sxy150489 {
1523526Sxy150489 	struct e1000g *Adapter;
1534919Sxy150489 	struct e1000_hw *hw;
1544919Sxy150489 	p_e1000g_stat_t e1000g_ksp;
1554919Sxy150489 	e1000g_tx_ring_t *tx_ring;
1564919Sxy150489 	e1000g_rx_ring_t *rx_ring;
1573526Sxy150489 	uint64_t val;
1583526Sxy150489 	uint32_t low_val, high_val;
1593526Sxy150489 
1603526Sxy150489 	if (rw == KSTAT_WRITE)
1613526Sxy150489 		return (EACCES);
1623526Sxy150489 
1633526Sxy150489 	Adapter = (struct e1000g *)ksp->ks_private;
1643526Sxy150489 	ASSERT(Adapter != NULL);
1654919Sxy150489 	e1000g_ksp = (p_e1000g_stat_t)ksp->ks_data;
1663526Sxy150489 	ASSERT(e1000g_ksp != NULL);
1674919Sxy150489 	hw = &Adapter->shared;
1684919Sxy150489 
1694919Sxy150489 	tx_ring = Adapter->tx_ring;
1704919Sxy150489 	rx_ring = Adapter->rx_ring;
1714919Sxy150489 
1724919Sxy150489 	rw_enter(&Adapter->chip_lock, RW_WRITER);
1733526Sxy150489 
1743526Sxy150489 	e1000g_ksp->link_speed.value.ul = Adapter->link_speed;
1753526Sxy150489 	e1000g_ksp->reset_count.value.ul = Adapter->reset_count;
1764919Sxy150489 
1774919Sxy150489 	e1000g_ksp->rx_error.value.ul = rx_ring->stat_error;
1784919Sxy150489 	e1000g_ksp->rx_esballoc_fail.value.ul = rx_ring->stat_esballoc_fail;
1794919Sxy150489 	e1000g_ksp->rx_allocb_fail.value.ul = rx_ring->stat_allocb_fail;
1804919Sxy150489 
1814919Sxy150489 	e1000g_ksp->tx_no_swpkt.value.ul = tx_ring->stat_no_swpkt;
1824919Sxy150489 	e1000g_ksp->tx_no_desc.value.ul = tx_ring->stat_no_desc;
1834919Sxy150489 	e1000g_ksp->tx_send_fail.value.ul = tx_ring->stat_send_fail;
1844919Sxy150489 	e1000g_ksp->tx_reschedule.value.ul = tx_ring->stat_reschedule;
1854919Sxy150489 	e1000g_ksp->tx_over_size.value.ul = tx_ring->stat_over_size;
1863526Sxy150489 
1874919Sxy150489 #ifdef E1000G_DEBUG
1884919Sxy150489 	e1000g_ksp->rx_none.value.ul = rx_ring->stat_none;
1894919Sxy150489 	e1000g_ksp->rx_multi_desc.value.ul = rx_ring->stat_multi_desc;
1904919Sxy150489 	e1000g_ksp->rx_no_freepkt.value.ul = rx_ring->stat_no_freepkt;
1914919Sxy150489 	e1000g_ksp->rx_avail_freepkt.value.ul = rx_ring->avail_freepkt;
1924919Sxy150489 
1934919Sxy150489 	e1000g_ksp->tx_under_size.value.ul = tx_ring->stat_under_size;
1944919Sxy150489 	e1000g_ksp->tx_exceed_frags.value.ul = tx_ring->stat_exceed_frags;
1954919Sxy150489 	e1000g_ksp->tx_empty_frags.value.ul = tx_ring->stat_empty_frags;
1964919Sxy150489 	e1000g_ksp->tx_recycle.value.ul = tx_ring->stat_recycle;
1974919Sxy150489 	e1000g_ksp->tx_recycle_intr.value.ul = tx_ring->stat_recycle_intr;
1984919Sxy150489 	e1000g_ksp->tx_recycle_retry.value.ul = tx_ring->stat_recycle_retry;
1994919Sxy150489 	e1000g_ksp->tx_recycle_none.value.ul = tx_ring->stat_recycle_none;
2004919Sxy150489 	e1000g_ksp->tx_copy.value.ul = tx_ring->stat_copy;
2014919Sxy150489 	e1000g_ksp->tx_bind.value.ul = tx_ring->stat_bind;
2024919Sxy150489 	e1000g_ksp->tx_multi_copy.value.ul = tx_ring->stat_multi_copy;
2034919Sxy150489 	e1000g_ksp->tx_multi_cookie.value.ul = tx_ring->stat_multi_cookie;
2044919Sxy150489 	e1000g_ksp->tx_lack_desc.value.ul = tx_ring->stat_lack_desc;
2054919Sxy150489 #endif
2063526Sxy150489 
2073526Sxy150489 	/*
2083526Sxy150489 	 * Standard Stats
2093526Sxy150489 	 */
2104919Sxy150489 	e1000g_ksp->Mpc.value.ul += E1000_READ_REG(hw, E1000_MPC);
2114919Sxy150489 	e1000g_ksp->Rlec.value.ul += E1000_READ_REG(hw, E1000_RLEC);
2124919Sxy150489 	e1000g_ksp->Xonrxc.value.ul += E1000_READ_REG(hw, E1000_XONRXC);
2134919Sxy150489 	e1000g_ksp->Xontxc.value.ul += E1000_READ_REG(hw, E1000_XONTXC);
2144919Sxy150489 	e1000g_ksp->Xoffrxc.value.ul += E1000_READ_REG(hw, E1000_XOFFRXC);
2154919Sxy150489 	e1000g_ksp->Xofftxc.value.ul += E1000_READ_REG(hw, E1000_XOFFTXC);
2164919Sxy150489 	e1000g_ksp->Fcruc.value.ul += E1000_READ_REG(hw, E1000_FCRUC);
2173526Sxy150489 
2184919Sxy150489 	if ((hw->mac.type != e1000_ich8lan) &&
2194919Sxy150489 	    (hw->mac.type != e1000_ich9lan)) {
2204919Sxy150489 		e1000g_ksp->Symerrs.value.ul +=
2214919Sxy150489 		    E1000_READ_REG(hw, E1000_SYMERRS);
2225882Syy150190 #ifdef E1000G_DEBUG
2234919Sxy150489 		e1000g_ksp->Prc64.value.ul +=
2244919Sxy150489 		    E1000_READ_REG(hw, E1000_PRC64);
2254919Sxy150489 		e1000g_ksp->Prc127.value.ul +=
2264919Sxy150489 		    E1000_READ_REG(hw, E1000_PRC127);
2274919Sxy150489 		e1000g_ksp->Prc255.value.ul +=
2284919Sxy150489 		    E1000_READ_REG(hw, E1000_PRC255);
2294919Sxy150489 		e1000g_ksp->Prc511.value.ul +=
2304919Sxy150489 		    E1000_READ_REG(hw, E1000_PRC511);
2314919Sxy150489 		e1000g_ksp->Prc1023.value.ul +=
2324919Sxy150489 		    E1000_READ_REG(hw, E1000_PRC1023);
2334919Sxy150489 		e1000g_ksp->Prc1522.value.ul +=
2344919Sxy150489 		    E1000_READ_REG(hw, E1000_PRC1522);
2353526Sxy150489 
2364919Sxy150489 		e1000g_ksp->Ptc64.value.ul +=
2374919Sxy150489 		    E1000_READ_REG(hw, E1000_PTC64);
2384919Sxy150489 		e1000g_ksp->Ptc127.value.ul +=
2394919Sxy150489 		    E1000_READ_REG(hw, E1000_PTC127);
2404919Sxy150489 		e1000g_ksp->Ptc255.value.ul +=
2414919Sxy150489 		    E1000_READ_REG(hw, E1000_PTC255);
2424919Sxy150489 		e1000g_ksp->Ptc511.value.ul +=
2434919Sxy150489 		    E1000_READ_REG(hw, E1000_PTC511);
2444919Sxy150489 		e1000g_ksp->Ptc1023.value.ul +=
2454919Sxy150489 		    E1000_READ_REG(hw, E1000_PTC1023);
2464919Sxy150489 		e1000g_ksp->Ptc1522.value.ul +=
2474919Sxy150489 		    E1000_READ_REG(hw, E1000_PTC1522);
2485882Syy150190 #endif
2494919Sxy150489 	}
2503526Sxy150489 
2514919Sxy150489 	e1000g_ksp->Gprc.value.ul += E1000_READ_REG(hw, E1000_GPRC);
2524919Sxy150489 	e1000g_ksp->Gptc.value.ul += E1000_READ_REG(hw, E1000_GPTC);
2534919Sxy150489 	e1000g_ksp->Ruc.value.ul += E1000_READ_REG(hw, E1000_RUC);
2544919Sxy150489 	e1000g_ksp->Rfc.value.ul += E1000_READ_REG(hw, E1000_RFC);
2554919Sxy150489 	e1000g_ksp->Roc.value.ul += E1000_READ_REG(hw, E1000_ROC);
2564919Sxy150489 	e1000g_ksp->Rjc.value.ul += E1000_READ_REG(hw, E1000_RJC);
2574919Sxy150489 	e1000g_ksp->Tpr.value.ul += E1000_READ_REG(hw, E1000_TPR);
2584919Sxy150489 	e1000g_ksp->Tncrs.value.ul += E1000_READ_REG(hw, E1000_TNCRS);
2594919Sxy150489 	e1000g_ksp->Tsctc.value.ul += E1000_READ_REG(hw, E1000_TSCTC);
2604919Sxy150489 	e1000g_ksp->Tsctfc.value.ul += E1000_READ_REG(hw, E1000_TSCTFC);
2613526Sxy150489 
2624919Sxy150489 	/*
2634919Sxy150489 	 * Adaptive Calculations
2644919Sxy150489 	 */
2654919Sxy150489 	hw->mac.tx_packet_delta = E1000_READ_REG(hw, E1000_TPT);
2664919Sxy150489 	e1000g_ksp->Tpt.value.ul += hw->mac.tx_packet_delta;
2673526Sxy150489 
2683526Sxy150489 	/*
2693526Sxy150489 	 * The 64-bit register will reset whenever the upper
2703526Sxy150489 	 * 32 bits are read. So we need to read the lower
2713526Sxy150489 	 * 32 bits first, then read the upper 32 bits.
2723526Sxy150489 	 */
2734919Sxy150489 	low_val = E1000_READ_REG(hw, E1000_GORCL);
2744919Sxy150489 	high_val = E1000_READ_REG(hw, E1000_GORCH);
2753526Sxy150489 	val = (uint64_t)e1000g_ksp->Gorh.value.ul << 32 |
2763526Sxy150489 	    (uint64_t)e1000g_ksp->Gorl.value.ul;
2773526Sxy150489 	val += (uint64_t)high_val << 32 | (uint64_t)low_val;
2783526Sxy150489 	e1000g_ksp->Gorl.value.ul = (uint32_t)val;
2793526Sxy150489 	e1000g_ksp->Gorh.value.ul = (uint32_t)(val >> 32);
2803526Sxy150489 
2814919Sxy150489 	low_val = E1000_READ_REG(hw, E1000_GOTCL);
2824919Sxy150489 	high_val = E1000_READ_REG(hw, E1000_GOTCH);
2833526Sxy150489 	val = (uint64_t)e1000g_ksp->Goth.value.ul << 32 |
2843526Sxy150489 	    (uint64_t)e1000g_ksp->Gotl.value.ul;
2853526Sxy150489 	val += (uint64_t)high_val << 32 | (uint64_t)low_val;
2863526Sxy150489 	e1000g_ksp->Gotl.value.ul = (uint32_t)val;
2873526Sxy150489 	e1000g_ksp->Goth.value.ul = (uint32_t)(val >> 32);
2883526Sxy150489 
2894919Sxy150489 	low_val = E1000_READ_REG(hw, E1000_TORL);
2904919Sxy150489 	high_val = E1000_READ_REG(hw, E1000_TORH);
2913526Sxy150489 	val = (uint64_t)e1000g_ksp->Torh.value.ul << 32 |
2923526Sxy150489 	    (uint64_t)e1000g_ksp->Torl.value.ul;
2933526Sxy150489 	val += (uint64_t)high_val << 32 | (uint64_t)low_val;
2943526Sxy150489 	e1000g_ksp->Torl.value.ul = (uint32_t)val;
2953526Sxy150489 	e1000g_ksp->Torh.value.ul = (uint32_t)(val >> 32);
2963526Sxy150489 
2974919Sxy150489 	low_val = E1000_READ_REG(hw, E1000_TOTL);
2984919Sxy150489 	high_val = E1000_READ_REG(hw, E1000_TOTH);
2993526Sxy150489 	val = (uint64_t)e1000g_ksp->Toth.value.ul << 32 |
3003526Sxy150489 	    (uint64_t)e1000g_ksp->Totl.value.ul;
3013526Sxy150489 	val += (uint64_t)high_val << 32 | (uint64_t)low_val;
3023526Sxy150489 	e1000g_ksp->Totl.value.ul = (uint32_t)val;
3033526Sxy150489 	e1000g_ksp->Toth.value.ul = (uint32_t)(val >> 32);
3043526Sxy150489 
3054919Sxy150489 	rw_exit(&Adapter->chip_lock);
3063526Sxy150489 
3075273Sgl147354 	if (e1000g_check_acc_handle(Adapter->osdep.reg_handle) != DDI_FM_OK)
3085273Sgl147354 		ddi_fm_service_impact(Adapter->dip, DDI_SERVICE_UNAFFECTED);
3095273Sgl147354 
3103526Sxy150489 	return (0);
3113526Sxy150489 }
3123526Sxy150489 
3133526Sxy150489 int
3143526Sxy150489 e1000g_m_stat(void *arg, uint_t stat, uint64_t *val)
3153526Sxy150489 {
3163526Sxy150489 	struct e1000g *Adapter = (struct e1000g *)arg;
3174919Sxy150489 	struct e1000_hw *hw = &Adapter->shared;
3184919Sxy150489 	p_e1000g_stat_t e1000g_ksp;
3193526Sxy150489 	uint32_t low_val, high_val;
3203526Sxy150489 
3214919Sxy150489 	e1000g_ksp = (p_e1000g_stat_t)Adapter->e1000g_ksp->ks_data;
3224919Sxy150489 
3235082Syy150190 	rw_enter(&Adapter->chip_lock, RW_READER);
3243526Sxy150489 
3253526Sxy150489 	switch (stat) {
3263526Sxy150489 	case MAC_STAT_IFSPEED:
3273526Sxy150489 		*val = Adapter->link_speed * 1000000ull;
3283526Sxy150489 		break;
3293526Sxy150489 
3303526Sxy150489 	case MAC_STAT_MULTIRCV:
3313526Sxy150489 		e1000g_ksp->Mprc.value.ul +=
3324919Sxy150489 		    E1000_READ_REG(hw, E1000_MPRC);
3333526Sxy150489 		*val = e1000g_ksp->Mprc.value.ul;
3343526Sxy150489 		break;
3353526Sxy150489 
3363526Sxy150489 	case MAC_STAT_BRDCSTRCV:
3373526Sxy150489 		e1000g_ksp->Bprc.value.ul +=
3384919Sxy150489 		    E1000_READ_REG(hw, E1000_BPRC);
3393526Sxy150489 		*val = e1000g_ksp->Bprc.value.ul;
3403526Sxy150489 		break;
3413526Sxy150489 
3423526Sxy150489 	case MAC_STAT_MULTIXMT:
3433526Sxy150489 		e1000g_ksp->Mptc.value.ul +=
3444919Sxy150489 		    E1000_READ_REG(hw, E1000_MPTC);
3453526Sxy150489 		*val = e1000g_ksp->Mptc.value.ul;
3463526Sxy150489 		break;
3473526Sxy150489 
3483526Sxy150489 	case MAC_STAT_BRDCSTXMT:
3493526Sxy150489 		e1000g_ksp->Bptc.value.ul +=
3504919Sxy150489 		    E1000_READ_REG(hw, E1000_BPTC);
3513526Sxy150489 		*val = e1000g_ksp->Bptc.value.ul;
3523526Sxy150489 		break;
3533526Sxy150489 
3543526Sxy150489 	case MAC_STAT_NORCVBUF:
3553526Sxy150489 		e1000g_ksp->Rnbc.value.ul +=
3564919Sxy150489 		    E1000_READ_REG(hw, E1000_RNBC);
3573526Sxy150489 		*val = e1000g_ksp->Rnbc.value.ul;
3583526Sxy150489 		break;
3593526Sxy150489 
3603526Sxy150489 	case MAC_STAT_IERRORS:
3613526Sxy150489 		e1000g_ksp->Rxerrc.value.ul +=
3624919Sxy150489 		    E1000_READ_REG(hw, E1000_RXERRC);
3633526Sxy150489 		e1000g_ksp->Algnerrc.value.ul +=
3644919Sxy150489 		    E1000_READ_REG(hw, E1000_ALGNERRC);
3653526Sxy150489 		e1000g_ksp->Rlec.value.ul +=
3664919Sxy150489 		    E1000_READ_REG(hw, E1000_RLEC);
3673526Sxy150489 		e1000g_ksp->Crcerrs.value.ul +=
3684919Sxy150489 		    E1000_READ_REG(hw, E1000_CRCERRS);
3693526Sxy150489 		e1000g_ksp->Cexterr.value.ul +=
3704919Sxy150489 		    E1000_READ_REG(hw, E1000_CEXTERR);
3713526Sxy150489 		*val = e1000g_ksp->Rxerrc.value.ul +
3723526Sxy150489 		    e1000g_ksp->Algnerrc.value.ul +
3733526Sxy150489 		    e1000g_ksp->Rlec.value.ul +
3743526Sxy150489 		    e1000g_ksp->Crcerrs.value.ul +
3753526Sxy150489 		    e1000g_ksp->Cexterr.value.ul;
3763526Sxy150489 		break;
3773526Sxy150489 
3783526Sxy150489 	case MAC_STAT_NOXMTBUF:
3794919Sxy150489 		*val = Adapter->tx_ring->stat_no_desc;
3803526Sxy150489 		break;
3813526Sxy150489 
3823526Sxy150489 	case MAC_STAT_OERRORS:
3833526Sxy150489 		e1000g_ksp->Ecol.value.ul +=
3844919Sxy150489 		    E1000_READ_REG(hw, E1000_ECOL);
3853526Sxy150489 		*val = e1000g_ksp->Ecol.value.ul;
3863526Sxy150489 		break;
3873526Sxy150489 
3883526Sxy150489 	case MAC_STAT_COLLISIONS:
3893526Sxy150489 		e1000g_ksp->Colc.value.ul +=
3904919Sxy150489 		    E1000_READ_REG(hw, E1000_COLC);
3913526Sxy150489 		*val = e1000g_ksp->Colc.value.ul;
3923526Sxy150489 		break;
3933526Sxy150489 
3943526Sxy150489 	case MAC_STAT_RBYTES:
3953526Sxy150489 		/*
3963526Sxy150489 		 * The 64-bit register will reset whenever the upper
3973526Sxy150489 		 * 32 bits are read. So we need to read the lower
3983526Sxy150489 		 * 32 bits first, then read the upper 32 bits.
3993526Sxy150489 		 */
4004919Sxy150489 		low_val = E1000_READ_REG(hw, E1000_TORL);
4014919Sxy150489 		high_val = E1000_READ_REG(hw, E1000_TORH);
4023526Sxy150489 		*val = (uint64_t)e1000g_ksp->Torh.value.ul << 32 |
4033526Sxy150489 		    (uint64_t)e1000g_ksp->Torl.value.ul;
4043526Sxy150489 		*val += (uint64_t)high_val << 32 | (uint64_t)low_val;
4053526Sxy150489 
4063526Sxy150489 		e1000g_ksp->Torl.value.ul = (uint32_t)*val;
4073526Sxy150489 		e1000g_ksp->Torh.value.ul = (uint32_t)(*val >> 32);
4083526Sxy150489 		break;
4093526Sxy150489 
4103526Sxy150489 	case MAC_STAT_IPACKETS:
4113526Sxy150489 		e1000g_ksp->Tpr.value.ul +=
4124919Sxy150489 		    E1000_READ_REG(hw, E1000_TPR);
4133526Sxy150489 		*val = e1000g_ksp->Tpr.value.ul;
4143526Sxy150489 		break;
4153526Sxy150489 
4163526Sxy150489 	case MAC_STAT_OBYTES:
4173526Sxy150489 		/*
4183526Sxy150489 		 * The 64-bit register will reset whenever the upper
4193526Sxy150489 		 * 32 bits are read. So we need to read the lower
4203526Sxy150489 		 * 32 bits first, then read the upper 32 bits.
4213526Sxy150489 		 */
4224919Sxy150489 		low_val = E1000_READ_REG(hw, E1000_TOTL);
4234919Sxy150489 		high_val = E1000_READ_REG(hw, E1000_TOTH);
4243526Sxy150489 		*val = (uint64_t)e1000g_ksp->Toth.value.ul << 32 |
4253526Sxy150489 		    (uint64_t)e1000g_ksp->Totl.value.ul;
4263526Sxy150489 		*val += (uint64_t)high_val << 32 | (uint64_t)low_val;
4273526Sxy150489 
4283526Sxy150489 		e1000g_ksp->Totl.value.ul = (uint32_t)*val;
4293526Sxy150489 		e1000g_ksp->Toth.value.ul = (uint32_t)(*val >> 32);
4303526Sxy150489 		break;
4313526Sxy150489 
4323526Sxy150489 	case MAC_STAT_OPACKETS:
4333526Sxy150489 		e1000g_ksp->Tpt.value.ul +=
4344919Sxy150489 		    E1000_READ_REG(hw, E1000_TPT);
4353526Sxy150489 		*val = e1000g_ksp->Tpt.value.ul;
4363526Sxy150489 		break;
4373526Sxy150489 
4383526Sxy150489 	case ETHER_STAT_ALIGN_ERRORS:
4393526Sxy150489 		e1000g_ksp->Algnerrc.value.ul +=
4404919Sxy150489 		    E1000_READ_REG(hw, E1000_ALGNERRC);
4413526Sxy150489 		*val = e1000g_ksp->Algnerrc.value.ul;
4423526Sxy150489 		break;
4433526Sxy150489 
4443526Sxy150489 	case ETHER_STAT_FCS_ERRORS:
4453526Sxy150489 		e1000g_ksp->Crcerrs.value.ul +=
4464919Sxy150489 		    E1000_READ_REG(hw, E1000_CRCERRS);
4473526Sxy150489 		*val = e1000g_ksp->Crcerrs.value.ul;
4483526Sxy150489 		break;
4493526Sxy150489 
4503526Sxy150489 	case ETHER_STAT_SQE_ERRORS:
4513526Sxy150489 		e1000g_ksp->Sec.value.ul +=
4524919Sxy150489 		    E1000_READ_REG(hw, E1000_SEC);
4533526Sxy150489 		*val = e1000g_ksp->Sec.value.ul;
4543526Sxy150489 		break;
4553526Sxy150489 
4563526Sxy150489 	case ETHER_STAT_CARRIER_ERRORS:
4573526Sxy150489 		e1000g_ksp->Cexterr.value.ul +=
4584919Sxy150489 		    E1000_READ_REG(hw, E1000_CEXTERR);
4593526Sxy150489 		*val = e1000g_ksp->Cexterr.value.ul;
4603526Sxy150489 		break;
4613526Sxy150489 
4623526Sxy150489 	case ETHER_STAT_EX_COLLISIONS:
4633526Sxy150489 		e1000g_ksp->Ecol.value.ul +=
4644919Sxy150489 		    E1000_READ_REG(hw, E1000_ECOL);
4653526Sxy150489 		*val = e1000g_ksp->Ecol.value.ul;
4663526Sxy150489 		break;
4673526Sxy150489 
4683526Sxy150489 	case ETHER_STAT_TX_LATE_COLLISIONS:
4693526Sxy150489 		e1000g_ksp->Latecol.value.ul +=
4704919Sxy150489 		    E1000_READ_REG(hw, E1000_LATECOL);
4713526Sxy150489 		*val = e1000g_ksp->Latecol.value.ul;
4723526Sxy150489 		break;
4733526Sxy150489 
4743526Sxy150489 	case ETHER_STAT_DEFER_XMTS:
4753526Sxy150489 		e1000g_ksp->Dc.value.ul +=
4764919Sxy150489 		    E1000_READ_REG(hw, E1000_DC);
4773526Sxy150489 		*val = e1000g_ksp->Dc.value.ul;
4783526Sxy150489 		break;
4793526Sxy150489 
4803526Sxy150489 	case ETHER_STAT_FIRST_COLLISIONS:
4813526Sxy150489 		e1000g_ksp->Scc.value.ul +=
4824919Sxy150489 		    E1000_READ_REG(hw, E1000_SCC);
4833526Sxy150489 		*val = e1000g_ksp->Scc.value.ul;
4843526Sxy150489 		break;
4853526Sxy150489 
4863526Sxy150489 	case ETHER_STAT_MULTI_COLLISIONS:
4873526Sxy150489 		e1000g_ksp->Mcc.value.ul +=
4884919Sxy150489 		    E1000_READ_REG(hw, E1000_MCC);
4893526Sxy150489 		*val = e1000g_ksp->Mcc.value.ul;
4903526Sxy150489 		break;
4913526Sxy150489 
4923526Sxy150489 	case ETHER_STAT_MACRCV_ERRORS:
4933526Sxy150489 		e1000g_ksp->Rxerrc.value.ul +=
4944919Sxy150489 		    E1000_READ_REG(hw, E1000_RXERRC);
4953526Sxy150489 		*val = e1000g_ksp->Rxerrc.value.ul;
4963526Sxy150489 		break;
4973526Sxy150489 
4983526Sxy150489 	case ETHER_STAT_MACXMT_ERRORS:
4993526Sxy150489 		e1000g_ksp->Ecol.value.ul +=
5004919Sxy150489 		    E1000_READ_REG(hw, E1000_ECOL);
5013526Sxy150489 		*val = e1000g_ksp->Ecol.value.ul;
5023526Sxy150489 		break;
5033526Sxy150489 
5043526Sxy150489 	case ETHER_STAT_TOOLONG_ERRORS:
5053526Sxy150489 		e1000g_ksp->Roc.value.ul +=
5064919Sxy150489 		    E1000_READ_REG(hw, E1000_ROC);
5073526Sxy150489 		*val = e1000g_ksp->Roc.value.ul;
5083526Sxy150489 		break;
5093526Sxy150489 
5103526Sxy150489 	case ETHER_STAT_XCVR_ADDR:
5113526Sxy150489 		/* The Internal PHY's MDI address for each MAC is 1 */
5123526Sxy150489 		*val = 1;
5133526Sxy150489 		break;
5143526Sxy150489 
5153526Sxy150489 	case ETHER_STAT_XCVR_ID:
5165082Syy150190 		*val = hw->phy.id | hw->phy.revision;
5173526Sxy150489 		break;
5183526Sxy150489 
5193526Sxy150489 	case ETHER_STAT_XCVR_INUSE:
5203526Sxy150489 		switch (Adapter->link_speed) {
5213526Sxy150489 		case SPEED_1000:
5223526Sxy150489 			*val =
523*6735Scc210113 			    (hw->phy.media_type == e1000_media_type_copper) ?
5244919Sxy150489 			    XCVR_1000T : XCVR_1000X;
5253526Sxy150489 			break;
5263526Sxy150489 		case SPEED_100:
5273526Sxy150489 			*val =
528*6735Scc210113 			    (hw->phy.media_type == e1000_media_type_copper) ?
5295082Syy150190 			    (Adapter->phy_status & MII_SR_100T4_CAPS) ?
5304919Sxy150489 			    XCVR_100T4 : XCVR_100T2 : XCVR_100X;
5313526Sxy150489 			break;
5323526Sxy150489 		case SPEED_10:
5333526Sxy150489 			*val = XCVR_10;
5343526Sxy150489 			break;
5353526Sxy150489 		default:
5363526Sxy150489 			*val = XCVR_NONE;
5373526Sxy150489 			break;
5383526Sxy150489 		}
5393526Sxy150489 		break;
5403526Sxy150489 
5413526Sxy150489 	case ETHER_STAT_CAP_1000FDX:
5426394Scc210113 		*val = Adapter->param_1000fdx_cap;
5433526Sxy150489 		break;
5443526Sxy150489 
5453526Sxy150489 	case ETHER_STAT_CAP_1000HDX:
5466394Scc210113 		*val = Adapter->param_1000hdx_cap;
5473526Sxy150489 		break;
5483526Sxy150489 
5493526Sxy150489 	case ETHER_STAT_CAP_100FDX:
5506394Scc210113 		*val = Adapter->param_100fdx_cap;
5513526Sxy150489 		break;
5523526Sxy150489 
5533526Sxy150489 	case ETHER_STAT_CAP_100HDX:
5546394Scc210113 		*val = Adapter->param_100hdx_cap;
5553526Sxy150489 		break;
5563526Sxy150489 
5573526Sxy150489 	case ETHER_STAT_CAP_10FDX:
5586394Scc210113 		*val = Adapter->param_10fdx_cap;
5593526Sxy150489 		break;
5603526Sxy150489 
5613526Sxy150489 	case ETHER_STAT_CAP_10HDX:
5626394Scc210113 		*val = Adapter->param_10hdx_cap;
5633526Sxy150489 		break;
5643526Sxy150489 
5653526Sxy150489 	case ETHER_STAT_CAP_ASMPAUSE:
5666394Scc210113 		*val = Adapter->param_asym_pause_cap;
5673526Sxy150489 		break;
5683526Sxy150489 
5693526Sxy150489 	case ETHER_STAT_CAP_PAUSE:
5706394Scc210113 		*val = Adapter->param_pause_cap;
5713526Sxy150489 		break;
5723526Sxy150489 
5733526Sxy150489 	case ETHER_STAT_CAP_AUTONEG:
5746394Scc210113 		*val = Adapter->param_autoneg_cap;
5753526Sxy150489 		break;
5763526Sxy150489 
5773526Sxy150489 	case ETHER_STAT_ADV_CAP_1000FDX:
5786394Scc210113 		*val = Adapter->param_adv_1000fdx;
5793526Sxy150489 		break;
5803526Sxy150489 
5813526Sxy150489 	case ETHER_STAT_ADV_CAP_1000HDX:
5826394Scc210113 		*val = Adapter->param_adv_1000hdx;
5833526Sxy150489 		break;
5843526Sxy150489 
5853526Sxy150489 	case ETHER_STAT_ADV_CAP_100FDX:
5866394Scc210113 		*val = Adapter->param_adv_100fdx;
5873526Sxy150489 		break;
5883526Sxy150489 
5893526Sxy150489 	case ETHER_STAT_ADV_CAP_100HDX:
5906394Scc210113 		*val = Adapter->param_adv_100hdx;
5913526Sxy150489 		break;
5923526Sxy150489 
5933526Sxy150489 	case ETHER_STAT_ADV_CAP_10FDX:
5946394Scc210113 		*val = Adapter->param_adv_10fdx;
5953526Sxy150489 		break;
5963526Sxy150489 
5973526Sxy150489 	case ETHER_STAT_ADV_CAP_10HDX:
5986394Scc210113 		*val = Adapter->param_adv_10hdx;
5993526Sxy150489 		break;
6003526Sxy150489 
6013526Sxy150489 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
6026394Scc210113 		*val = Adapter->param_adv_asym_pause;
6033526Sxy150489 		break;
6043526Sxy150489 
6053526Sxy150489 	case ETHER_STAT_ADV_CAP_PAUSE:
6066394Scc210113 		*val = Adapter->param_adv_pause;
6073526Sxy150489 		break;
6083526Sxy150489 
6093526Sxy150489 	case ETHER_STAT_ADV_CAP_AUTONEG:
6104919Sxy150489 		*val = hw->mac.autoneg;
6113526Sxy150489 		break;
6123526Sxy150489 
6133526Sxy150489 	case ETHER_STAT_LP_CAP_1000FDX:
6146394Scc210113 		*val = Adapter->param_lp_1000fdx;
6153526Sxy150489 		break;
6163526Sxy150489 
6173526Sxy150489 	case ETHER_STAT_LP_CAP_1000HDX:
6186394Scc210113 		*val = Adapter->param_lp_1000hdx;
6193526Sxy150489 		break;
6203526Sxy150489 
6213526Sxy150489 	case ETHER_STAT_LP_CAP_100FDX:
6226394Scc210113 		*val = Adapter->param_lp_100fdx;
6233526Sxy150489 		break;
6243526Sxy150489 
6253526Sxy150489 	case ETHER_STAT_LP_CAP_100HDX:
6266394Scc210113 		*val = Adapter->param_lp_100hdx;
6273526Sxy150489 		break;
6283526Sxy150489 
6293526Sxy150489 	case ETHER_STAT_LP_CAP_10FDX:
6306394Scc210113 		*val = Adapter->param_lp_10fdx;
6313526Sxy150489 		break;
6323526Sxy150489 
6333526Sxy150489 	case ETHER_STAT_LP_CAP_10HDX:
6346394Scc210113 		*val = Adapter->param_lp_10hdx;
6353526Sxy150489 		break;
6363526Sxy150489 
6373526Sxy150489 	case ETHER_STAT_LP_CAP_ASMPAUSE:
6386394Scc210113 		*val = Adapter->param_lp_asym_pause;
6393526Sxy150489 		break;
6403526Sxy150489 
6413526Sxy150489 	case ETHER_STAT_LP_CAP_PAUSE:
6426394Scc210113 		*val = Adapter->param_lp_pause;
6433526Sxy150489 		break;
6443526Sxy150489 
6453526Sxy150489 	case ETHER_STAT_LP_CAP_AUTONEG:
6466394Scc210113 		*val = Adapter->param_lp_autoneg;
6473526Sxy150489 		break;
6483526Sxy150489 
6493526Sxy150489 	case ETHER_STAT_LINK_ASMPAUSE:
6506394Scc210113 		*val = Adapter->param_asym_pause_cap;
6513526Sxy150489 		break;
6523526Sxy150489 
6533526Sxy150489 	case ETHER_STAT_LINK_PAUSE:
6546394Scc210113 		*val = Adapter->param_pause_cap;
6553526Sxy150489 		break;
6563526Sxy150489 
6573526Sxy150489 	case ETHER_STAT_LINK_AUTONEG:
6586394Scc210113 		*val = hw->mac.autoneg;
6593526Sxy150489 		break;
6603526Sxy150489 
6613526Sxy150489 	case ETHER_STAT_LINK_DUPLEX:
6623526Sxy150489 		*val = (Adapter->link_duplex == FULL_DUPLEX) ?
6633526Sxy150489 		    LINK_DUPLEX_FULL : LINK_DUPLEX_HALF;
6643526Sxy150489 		break;
6653526Sxy150489 
6666394Scc210113 	case ETHER_STAT_CAP_100T4:
6676394Scc210113 		*val = Adapter->param_100t4_cap;
6686394Scc210113 		break;
6696394Scc210113 
6706394Scc210113 	case ETHER_STAT_ADV_CAP_100T4:
6716394Scc210113 		*val = Adapter->param_adv_100t4;
6726394Scc210113 		break;
6736394Scc210113 
6746394Scc210113 	case ETHER_STAT_LP_CAP_100T4:
6756394Scc210113 		*val = Adapter->param_lp_100t4;
6766394Scc210113 		break;
6776394Scc210113 
6783526Sxy150489 	default:
6794919Sxy150489 		rw_exit(&Adapter->chip_lock);
6803526Sxy150489 		return (ENOTSUP);
6813526Sxy150489 	}
6823526Sxy150489 
6834919Sxy150489 	rw_exit(&Adapter->chip_lock);
6844919Sxy150489 
6855273Sgl147354 	if (e1000g_check_acc_handle(Adapter->osdep.reg_handle) != DDI_FM_OK)
6865273Sgl147354 		ddi_fm_service_impact(Adapter->dip, DDI_SERVICE_UNAFFECTED);
6875273Sgl147354 
6883526Sxy150489 	return (0);
6893526Sxy150489 }
6903526Sxy150489 
6913526Sxy150489 /*
6924919Sxy150489  * e1000g_init_stats - initialize kstat data structures
6934919Sxy150489  *
6944919Sxy150489  * This routine will create and initialize the driver private
6954919Sxy150489  * statistics counters.
6963526Sxy150489  */
6973526Sxy150489 int
6984919Sxy150489 e1000g_init_stats(struct e1000g *Adapter)
6993526Sxy150489 {
7003526Sxy150489 	kstat_t *ksp;
7014919Sxy150489 	p_e1000g_stat_t e1000g_ksp;
7023526Sxy150489 
7033526Sxy150489 	/*
7043526Sxy150489 	 * Create and init kstat
7053526Sxy150489 	 */
7063526Sxy150489 	ksp = kstat_create(WSNAME, ddi_get_instance(Adapter->dip),
7073526Sxy150489 	    "statistics", "net", KSTAT_TYPE_NAMED,
7084919Sxy150489 	    sizeof (e1000g_stat_t) / sizeof (kstat_named_t), 0);
7093526Sxy150489 
7103526Sxy150489 	if (ksp == NULL) {
7113526Sxy150489 		e1000g_log(Adapter, CE_WARN,
7123526Sxy150489 		    "Could not create kernel statistics\n");
7133526Sxy150489 		return (DDI_FAILURE);
7143526Sxy150489 	}
7153526Sxy150489 
7163526Sxy150489 	Adapter->e1000g_ksp = ksp;	/* Fill in the Adapters ksp */
7173526Sxy150489 
7184919Sxy150489 	e1000g_ksp = (p_e1000g_stat_t)ksp->ks_data;
7193526Sxy150489 
7203526Sxy150489 	/*
7213526Sxy150489 	 * Initialize all the statistics
7223526Sxy150489 	 */
7233526Sxy150489 	kstat_named_init(&e1000g_ksp->link_speed, "link_speed",
7243526Sxy150489 	    KSTAT_DATA_ULONG);
7254919Sxy150489 	kstat_named_init(&e1000g_ksp->reset_count, "Reset Count",
7263526Sxy150489 	    KSTAT_DATA_ULONG);
7273526Sxy150489 
7283526Sxy150489 	kstat_named_init(&e1000g_ksp->rx_error, "Rx Error",
7293526Sxy150489 	    KSTAT_DATA_ULONG);
7303526Sxy150489 	kstat_named_init(&e1000g_ksp->rx_esballoc_fail, "Rx Desballoc Failure",
7313526Sxy150489 	    KSTAT_DATA_ULONG);
7323526Sxy150489 	kstat_named_init(&e1000g_ksp->rx_allocb_fail, "Rx Allocb Failure",
7333526Sxy150489 	    KSTAT_DATA_ULONG);
7343526Sxy150489 
7353526Sxy150489 	kstat_named_init(&e1000g_ksp->tx_no_desc, "Tx No Desc",
7363526Sxy150489 	    KSTAT_DATA_ULONG);
7373526Sxy150489 	kstat_named_init(&e1000g_ksp->tx_no_swpkt, "Tx No Buffer",
7383526Sxy150489 	    KSTAT_DATA_ULONG);
7394919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_send_fail, "Tx Send Failure",
7404919Sxy150489 	    KSTAT_DATA_ULONG);
7414919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_over_size, "Tx Pkt Over Size",
7424919Sxy150489 	    KSTAT_DATA_ULONG);
7434919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_reschedule, "Tx Reschedule",
7443526Sxy150489 	    KSTAT_DATA_ULONG);
7453526Sxy150489 
7464919Sxy150489 	kstat_named_init(&e1000g_ksp->Mpc, "Recv_Missed_Packets",
7474919Sxy150489 	    KSTAT_DATA_ULONG);
7484919Sxy150489 	kstat_named_init(&e1000g_ksp->Symerrs, "Recv_Symbol_Errors",
7494919Sxy150489 	    KSTAT_DATA_ULONG);
7504919Sxy150489 	kstat_named_init(&e1000g_ksp->Rlec, "Recv_Length_Errors",
7514919Sxy150489 	    KSTAT_DATA_ULONG);
7524919Sxy150489 	kstat_named_init(&e1000g_ksp->Xonrxc, "XONs_Recvd",
7534919Sxy150489 	    KSTAT_DATA_ULONG);
7544919Sxy150489 	kstat_named_init(&e1000g_ksp->Xontxc, "XONs_Xmitd",
7554919Sxy150489 	    KSTAT_DATA_ULONG);
7564919Sxy150489 	kstat_named_init(&e1000g_ksp->Xoffrxc, "XOFFs_Recvd",
7574919Sxy150489 	    KSTAT_DATA_ULONG);
7584919Sxy150489 	kstat_named_init(&e1000g_ksp->Xofftxc, "XOFFs_Xmitd",
7594919Sxy150489 	    KSTAT_DATA_ULONG);
7604919Sxy150489 	kstat_named_init(&e1000g_ksp->Fcruc, "Recv_Unsupport_FC_Pkts",
7614919Sxy150489 	    KSTAT_DATA_ULONG);
7625882Syy150190 #ifdef E1000G_DEBUG
7634919Sxy150489 	kstat_named_init(&e1000g_ksp->Prc64, "Pkts_Recvd_(  64b)",
7644919Sxy150489 	    KSTAT_DATA_ULONG);
7654919Sxy150489 	kstat_named_init(&e1000g_ksp->Prc127, "Pkts_Recvd_(  65- 127b)",
7664919Sxy150489 	    KSTAT_DATA_ULONG);
7674919Sxy150489 	kstat_named_init(&e1000g_ksp->Prc255, "Pkts_Recvd_( 127- 255b)",
7684919Sxy150489 	    KSTAT_DATA_ULONG);
7694919Sxy150489 	kstat_named_init(&e1000g_ksp->Prc511, "Pkts_Recvd_( 256- 511b)",
7704919Sxy150489 	    KSTAT_DATA_ULONG);
7714919Sxy150489 	kstat_named_init(&e1000g_ksp->Prc1023, "Pkts_Recvd_( 511-1023b)",
7724919Sxy150489 	    KSTAT_DATA_ULONG);
7734919Sxy150489 	kstat_named_init(&e1000g_ksp->Prc1522, "Pkts_Recvd_(1024-1522b)",
7744919Sxy150489 	    KSTAT_DATA_ULONG);
7755882Syy150190 #endif
7764919Sxy150489 	kstat_named_init(&e1000g_ksp->Gprc, "Good_Pkts_Recvd",
7774919Sxy150489 	    KSTAT_DATA_ULONG);
7784919Sxy150489 	kstat_named_init(&e1000g_ksp->Gptc, "Good_Pkts_Xmitd",
7794919Sxy150489 	    KSTAT_DATA_ULONG);
7804919Sxy150489 	kstat_named_init(&e1000g_ksp->Gorl, "Good_Octets_Recvd_Lo",
7814919Sxy150489 	    KSTAT_DATA_ULONG);
7824919Sxy150489 	kstat_named_init(&e1000g_ksp->Gorh, "Good_Octets_Recvd_Hi",
7834919Sxy150489 	    KSTAT_DATA_ULONG);
7844919Sxy150489 	kstat_named_init(&e1000g_ksp->Gotl, "Good_Octets_Xmitd_Lo",
7854919Sxy150489 	    KSTAT_DATA_ULONG);
7864919Sxy150489 	kstat_named_init(&e1000g_ksp->Goth, "Good_Octets_Xmitd_Hi",
7874919Sxy150489 	    KSTAT_DATA_ULONG);
7884919Sxy150489 	kstat_named_init(&e1000g_ksp->Ruc, "Recv_Undersize",
7894919Sxy150489 	    KSTAT_DATA_ULONG);
7904919Sxy150489 	kstat_named_init(&e1000g_ksp->Rfc, "Recv_Frag",
7914919Sxy150489 	    KSTAT_DATA_ULONG);
7924919Sxy150489 	kstat_named_init(&e1000g_ksp->Roc, "Recv_Oversize",
7934919Sxy150489 	    KSTAT_DATA_ULONG);
7944919Sxy150489 	kstat_named_init(&e1000g_ksp->Rjc, "Recv_Jabber",
7954919Sxy150489 	    KSTAT_DATA_ULONG);
7964919Sxy150489 	kstat_named_init(&e1000g_ksp->Torl, "Total_Octets_Recvd_Lo",
7974919Sxy150489 	    KSTAT_DATA_ULONG);
7984919Sxy150489 	kstat_named_init(&e1000g_ksp->Torh, "Total_Octets_Recvd_Hi",
7994919Sxy150489 	    KSTAT_DATA_ULONG);
8004919Sxy150489 	kstat_named_init(&e1000g_ksp->Totl, "Total_Octets_Xmitd_Lo",
8014919Sxy150489 	    KSTAT_DATA_ULONG);
8024919Sxy150489 	kstat_named_init(&e1000g_ksp->Toth, "Total_Octets_Xmitd_Hi",
8034919Sxy150489 	    KSTAT_DATA_ULONG);
8044919Sxy150489 	kstat_named_init(&e1000g_ksp->Tpr, "Total_Packets_Recvd",
8054919Sxy150489 	    KSTAT_DATA_ULONG);
8064919Sxy150489 	kstat_named_init(&e1000g_ksp->Tpt, "Total_Packets_Xmitd",
8074919Sxy150489 	    KSTAT_DATA_ULONG);
8085882Syy150190 #ifdef E1000G_DEBUG
8094919Sxy150489 	kstat_named_init(&e1000g_ksp->Ptc64, "Pkts_Xmitd_(  64b)",
8104919Sxy150489 	    KSTAT_DATA_ULONG);
8114919Sxy150489 	kstat_named_init(&e1000g_ksp->Ptc127, "Pkts_Xmitd_(  65- 127b)",
8124919Sxy150489 	    KSTAT_DATA_ULONG);
8134919Sxy150489 	kstat_named_init(&e1000g_ksp->Ptc255, "Pkts_Xmitd_( 128- 255b)",
8144919Sxy150489 	    KSTAT_DATA_ULONG);
8154919Sxy150489 	kstat_named_init(&e1000g_ksp->Ptc511, "Pkts_Xmitd_( 255- 511b)",
8164919Sxy150489 	    KSTAT_DATA_ULONG);
8174919Sxy150489 	kstat_named_init(&e1000g_ksp->Ptc1023, "Pkts_Xmitd_( 512-1023b)",
8184919Sxy150489 	    KSTAT_DATA_ULONG);
8194919Sxy150489 	kstat_named_init(&e1000g_ksp->Ptc1522, "Pkts_Xmitd_(1024-1522b)",
8204919Sxy150489 	    KSTAT_DATA_ULONG);
8215882Syy150190 #endif
8224919Sxy150489 	kstat_named_init(&e1000g_ksp->Tncrs, "Xmit_with_No_CRS",
8234919Sxy150489 	    KSTAT_DATA_ULONG);
8244919Sxy150489 	kstat_named_init(&e1000g_ksp->Tsctc, "Xmit_TCP_Seg_Contexts",
8254919Sxy150489 	    KSTAT_DATA_ULONG);
8264919Sxy150489 	kstat_named_init(&e1000g_ksp->Tsctfc, "Xmit_TCP_Seg_Contexts_Fail",
8274919Sxy150489 	    KSTAT_DATA_ULONG);
8283526Sxy150489 
8294919Sxy150489 #ifdef E1000G_DEBUG
8304919Sxy150489 	kstat_named_init(&e1000g_ksp->rx_none, "Rx No Data",
8314919Sxy150489 	    KSTAT_DATA_ULONG);
8324919Sxy150489 	kstat_named_init(&e1000g_ksp->rx_multi_desc, "Rx Span Multi Desc",
8334919Sxy150489 	    KSTAT_DATA_ULONG);
8344919Sxy150489 	kstat_named_init(&e1000g_ksp->rx_no_freepkt, "Rx Freelist Empty",
8354919Sxy150489 	    KSTAT_DATA_ULONG);
8364919Sxy150489 	kstat_named_init(&e1000g_ksp->rx_avail_freepkt, "Rx Freelist Avail",
8373526Sxy150489 	    KSTAT_DATA_ULONG);
8383526Sxy150489 
8393526Sxy150489 	kstat_named_init(&e1000g_ksp->tx_under_size, "Tx Pkt Under Size",
8403526Sxy150489 	    KSTAT_DATA_ULONG);
8413526Sxy150489 	kstat_named_init(&e1000g_ksp->tx_exceed_frags, "Tx Exceed Max Frags",
8423526Sxy150489 	    KSTAT_DATA_ULONG);
8434919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_empty_frags, "Tx Empty Frags",
8443526Sxy150489 	    KSTAT_DATA_ULONG);
8454919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_recycle, "Tx Recycle",
8463526Sxy150489 	    KSTAT_DATA_ULONG);
8474919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_recycle_intr, "Tx Recycle Intr",
8483526Sxy150489 	    KSTAT_DATA_ULONG);
8494919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_recycle_retry, "Tx Recycle Retry",
8503526Sxy150489 	    KSTAT_DATA_ULONG);
8514919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_recycle_none, "Tx Recycled None",
8523526Sxy150489 	    KSTAT_DATA_ULONG);
8534919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_copy, "Tx Send Copy",
8543526Sxy150489 	    KSTAT_DATA_ULONG);
8554919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_bind, "Tx Send Bind",
8563526Sxy150489 	    KSTAT_DATA_ULONG);
8574919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_multi_copy, "Tx Copy Multi Frags",
8583526Sxy150489 	    KSTAT_DATA_ULONG);
8594919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_multi_cookie, "Tx Bind Multi Cookies",
8603526Sxy150489 	    KSTAT_DATA_ULONG);
8614919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_lack_desc, "Tx Desc Insufficient",
8623526Sxy150489 	    KSTAT_DATA_ULONG);
8634919Sxy150489 #endif
8643526Sxy150489 
8653526Sxy150489 	/*
8663526Sxy150489 	 * Function to provide kernel stat update on demand
8673526Sxy150489 	 */
8684919Sxy150489 	ksp->ks_update = e1000g_update_stats;
8693526Sxy150489 
8703526Sxy150489 	/*
8713526Sxy150489 	 * Pointer into provider's raw statistics
8723526Sxy150489 	 */
8733526Sxy150489 	ksp->ks_private = (void *)Adapter;
8743526Sxy150489 
8753526Sxy150489 	/*
8763526Sxy150489 	 * Add kstat to systems kstat chain
8773526Sxy150489 	 */
8783526Sxy150489 	kstat_install(ksp);
8793526Sxy150489 
8803526Sxy150489 	return (DDI_SUCCESS);
8813526Sxy150489 }
882