xref: /onnv-gate/usr/src/uts/common/io/e1000g/e1000g_stat.c (revision 7607:49c460c685fa)
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 /*
273526Sxy150489  * **********************************************************************
283526Sxy150489  *									*
293526Sxy150489  * Module Name:  e1000g_stat.c						*
303526Sxy150489  *									*
314919Sxy150489  * Abstract: Functions for processing statistics			*
323526Sxy150489  *									*
333526Sxy150489  * **********************************************************************
343526Sxy150489  */
353526Sxy150489 #include "e1000g_sw.h"
363526Sxy150489 #include "e1000g_debug.h"
373526Sxy150489 
384919Sxy150489 static int e1000g_update_stats(kstat_t *ksp, int rw);
393526Sxy150489 
403526Sxy150489 /*
414919Sxy150489  * e1000_tbi_adjust_stats
424919Sxy150489  *
434919Sxy150489  * Adjusts statistic counters when a frame is accepted
444919Sxy150489  * under the TBI workaround. This function has been
454919Sxy150489  * adapted for Solaris from shared code.
463526Sxy150489  */
473526Sxy150489 void
484919Sxy150489 e1000_tbi_adjust_stats(struct e1000g *Adapter,
494919Sxy150489     uint32_t frame_len, uint8_t *mac_addr)
503526Sxy150489 {
514919Sxy150489 	uint32_t carry_bit;
524919Sxy150489 	p_e1000g_stat_t e1000g_ksp;
533526Sxy150489 
544919Sxy150489 	e1000g_ksp = (p_e1000g_stat_t)Adapter->e1000g_ksp->ks_data;
553526Sxy150489 
564919Sxy150489 	/* First adjust the frame length */
574919Sxy150489 	frame_len--;
584919Sxy150489 
593526Sxy150489 	/*
603526Sxy150489 	 * We need to adjust the statistics counters, since the hardware
613526Sxy150489 	 * counters overcount this packet as a CRC error and undercount
623526Sxy150489 	 * the packet as a good packet
633526Sxy150489 	 */
644919Sxy150489 	/* This packet should not be counted as a CRC error */
653526Sxy150489 	e1000g_ksp->Crcerrs.value.ul--;
664919Sxy150489 	/* This packet does count as a Good Packet Received */
673526Sxy150489 	e1000g_ksp->Gprc.value.ul++;
683526Sxy150489 
693526Sxy150489 	/*
703526Sxy150489 	 * Adjust the Good Octets received counters
713526Sxy150489 	 */
724919Sxy150489 	carry_bit = 0x80000000 & e1000g_ksp->Gorl.value.ul;
734919Sxy150489 	e1000g_ksp->Gorl.value.ul += frame_len;
743526Sxy150489 	/*
753526Sxy150489 	 * If the high bit of Gorcl (the low 32 bits of the Good Octets
763526Sxy150489 	 * Received Count) was one before the addition,
773526Sxy150489 	 * AND it is zero after, then we lost the carry out,
783526Sxy150489 	 * need to add one to Gorch (Good Octets Received Count High).
793526Sxy150489 	 * This could be simplified if all environments supported
803526Sxy150489 	 * 64-bit integers.
813526Sxy150489 	 */
824919Sxy150489 	if (carry_bit && ((e1000g_ksp->Gorl.value.ul & 0x80000000) == 0)) {
833526Sxy150489 		e1000g_ksp->Gorh.value.ul++;
843526Sxy150489 	}
853526Sxy150489 	/*
863526Sxy150489 	 * Is this a broadcast or multicast?  Check broadcast first,
873526Sxy150489 	 * since the test for a multicast frame will test positive on
883526Sxy150489 	 * a broadcast frame.
893526Sxy150489 	 */
904919Sxy150489 	if ((mac_addr[0] == (uint8_t)0xff) &&
914919Sxy150489 	    (mac_addr[1] == (uint8_t)0xff)) {
923526Sxy150489 		/*
933526Sxy150489 		 * Broadcast packet
943526Sxy150489 		 */
953526Sxy150489 		e1000g_ksp->Bprc.value.ul++;
964919Sxy150489 	} else if (*mac_addr & 0x01) {
973526Sxy150489 		/*
983526Sxy150489 		 * Multicast packet
993526Sxy150489 		 */
1003526Sxy150489 		e1000g_ksp->Mprc.value.ul++;
1013526Sxy150489 	}
1024919Sxy150489 
1036735Scc210113 	if (frame_len == Adapter->max_frame_size) {
1043526Sxy150489 		/*
1053526Sxy150489 		 * In this case, the hardware has overcounted the number of
1063526Sxy150489 		 * oversize frames.
1073526Sxy150489 		 */
1083526Sxy150489 		if (e1000g_ksp->Roc.value.ul > 0)
1093526Sxy150489 			e1000g_ksp->Roc.value.ul--;
1103526Sxy150489 	}
1113526Sxy150489 
1125882Syy150190 #ifdef E1000G_DEBUG
1133526Sxy150489 	/*
1143526Sxy150489 	 * Adjust the bin counters when the extra byte put the frame in the
1154919Sxy150489 	 * wrong bin. Remember that the frame_len was adjusted above.
1163526Sxy150489 	 */
1174919Sxy150489 	if (frame_len == 64) {
1183526Sxy150489 		e1000g_ksp->Prc64.value.ul++;
1193526Sxy150489 		e1000g_ksp->Prc127.value.ul--;
1204919Sxy150489 	} else if (frame_len == 127) {
1213526Sxy150489 		e1000g_ksp->Prc127.value.ul++;
1223526Sxy150489 		e1000g_ksp->Prc255.value.ul--;
1234919Sxy150489 	} else if (frame_len == 255) {
1243526Sxy150489 		e1000g_ksp->Prc255.value.ul++;
1253526Sxy150489 		e1000g_ksp->Prc511.value.ul--;
1264919Sxy150489 	} else if (frame_len == 511) {
1273526Sxy150489 		e1000g_ksp->Prc511.value.ul++;
1283526Sxy150489 		e1000g_ksp->Prc1023.value.ul--;
1294919Sxy150489 	} else if (frame_len == 1023) {
1303526Sxy150489 		e1000g_ksp->Prc1023.value.ul++;
1313526Sxy150489 		e1000g_ksp->Prc1522.value.ul--;
1324919Sxy150489 	} else if (frame_len == 1522) {
1333526Sxy150489 		e1000g_ksp->Prc1522.value.ul++;
1343526Sxy150489 	}
1355882Syy150190 #endif
1363526Sxy150489 }
1373526Sxy150489 
1383526Sxy150489 
1393526Sxy150489 /*
1404919Sxy150489  * e1000g_update_stats - update driver private kstat counters
1414919Sxy150489  *
1424919Sxy150489  * This routine will dump and reset the e1000's internal
1434919Sxy150489  * statistics counters. The current stats dump values will
1444919Sxy150489  * be sent to the kernel status area.
1453526Sxy150489  */
1463526Sxy150489 static int
1474919Sxy150489 e1000g_update_stats(kstat_t *ksp, int rw)
1483526Sxy150489 {
1493526Sxy150489 	struct e1000g *Adapter;
1504919Sxy150489 	struct e1000_hw *hw;
1514919Sxy150489 	p_e1000g_stat_t e1000g_ksp;
1524919Sxy150489 	e1000g_tx_ring_t *tx_ring;
1534919Sxy150489 	e1000g_rx_ring_t *rx_ring;
1543526Sxy150489 	uint64_t val;
1553526Sxy150489 	uint32_t low_val, high_val;
1563526Sxy150489 
1573526Sxy150489 	if (rw == KSTAT_WRITE)
1583526Sxy150489 		return (EACCES);
1593526Sxy150489 
1603526Sxy150489 	Adapter = (struct e1000g *)ksp->ks_private;
1613526Sxy150489 	ASSERT(Adapter != NULL);
1624919Sxy150489 	e1000g_ksp = (p_e1000g_stat_t)ksp->ks_data;
1633526Sxy150489 	ASSERT(e1000g_ksp != NULL);
1644919Sxy150489 	hw = &Adapter->shared;
1654919Sxy150489 
1664919Sxy150489 	tx_ring = Adapter->tx_ring;
1674919Sxy150489 	rx_ring = Adapter->rx_ring;
1684919Sxy150489 
1694919Sxy150489 	rw_enter(&Adapter->chip_lock, RW_WRITER);
1703526Sxy150489 
1713526Sxy150489 	e1000g_ksp->link_speed.value.ul = Adapter->link_speed;
1723526Sxy150489 	e1000g_ksp->reset_count.value.ul = Adapter->reset_count;
1734919Sxy150489 
1744919Sxy150489 	e1000g_ksp->rx_error.value.ul = rx_ring->stat_error;
1754919Sxy150489 	e1000g_ksp->rx_esballoc_fail.value.ul = rx_ring->stat_esballoc_fail;
1764919Sxy150489 	e1000g_ksp->rx_allocb_fail.value.ul = rx_ring->stat_allocb_fail;
1774919Sxy150489 
1784919Sxy150489 	e1000g_ksp->tx_no_swpkt.value.ul = tx_ring->stat_no_swpkt;
1794919Sxy150489 	e1000g_ksp->tx_no_desc.value.ul = tx_ring->stat_no_desc;
1804919Sxy150489 	e1000g_ksp->tx_send_fail.value.ul = tx_ring->stat_send_fail;
1814919Sxy150489 	e1000g_ksp->tx_reschedule.value.ul = tx_ring->stat_reschedule;
1824919Sxy150489 	e1000g_ksp->tx_over_size.value.ul = tx_ring->stat_over_size;
1833526Sxy150489 
1844919Sxy150489 #ifdef E1000G_DEBUG
1854919Sxy150489 	e1000g_ksp->rx_none.value.ul = rx_ring->stat_none;
1864919Sxy150489 	e1000g_ksp->rx_multi_desc.value.ul = rx_ring->stat_multi_desc;
1874919Sxy150489 	e1000g_ksp->rx_no_freepkt.value.ul = rx_ring->stat_no_freepkt;
1884919Sxy150489 	e1000g_ksp->rx_avail_freepkt.value.ul = rx_ring->avail_freepkt;
1894919Sxy150489 
1904919Sxy150489 	e1000g_ksp->tx_under_size.value.ul = tx_ring->stat_under_size;
1914919Sxy150489 	e1000g_ksp->tx_exceed_frags.value.ul = tx_ring->stat_exceed_frags;
1924919Sxy150489 	e1000g_ksp->tx_empty_frags.value.ul = tx_ring->stat_empty_frags;
1934919Sxy150489 	e1000g_ksp->tx_recycle.value.ul = tx_ring->stat_recycle;
1944919Sxy150489 	e1000g_ksp->tx_recycle_intr.value.ul = tx_ring->stat_recycle_intr;
1954919Sxy150489 	e1000g_ksp->tx_recycle_retry.value.ul = tx_ring->stat_recycle_retry;
1964919Sxy150489 	e1000g_ksp->tx_recycle_none.value.ul = tx_ring->stat_recycle_none;
1974919Sxy150489 	e1000g_ksp->tx_copy.value.ul = tx_ring->stat_copy;
1984919Sxy150489 	e1000g_ksp->tx_bind.value.ul = tx_ring->stat_bind;
1994919Sxy150489 	e1000g_ksp->tx_multi_copy.value.ul = tx_ring->stat_multi_copy;
2004919Sxy150489 	e1000g_ksp->tx_multi_cookie.value.ul = tx_ring->stat_multi_cookie;
2014919Sxy150489 	e1000g_ksp->tx_lack_desc.value.ul = tx_ring->stat_lack_desc;
2024919Sxy150489 #endif
2033526Sxy150489 
2043526Sxy150489 	/*
2053526Sxy150489 	 * Standard Stats
2063526Sxy150489 	 */
2074919Sxy150489 	e1000g_ksp->Mpc.value.ul += E1000_READ_REG(hw, E1000_MPC);
2084919Sxy150489 	e1000g_ksp->Rlec.value.ul += E1000_READ_REG(hw, E1000_RLEC);
2094919Sxy150489 	e1000g_ksp->Xonrxc.value.ul += E1000_READ_REG(hw, E1000_XONRXC);
2104919Sxy150489 	e1000g_ksp->Xontxc.value.ul += E1000_READ_REG(hw, E1000_XONTXC);
2114919Sxy150489 	e1000g_ksp->Xoffrxc.value.ul += E1000_READ_REG(hw, E1000_XOFFRXC);
2124919Sxy150489 	e1000g_ksp->Xofftxc.value.ul += E1000_READ_REG(hw, E1000_XOFFTXC);
2134919Sxy150489 	e1000g_ksp->Fcruc.value.ul += E1000_READ_REG(hw, E1000_FCRUC);
2143526Sxy150489 
2154919Sxy150489 	if ((hw->mac.type != e1000_ich8lan) &&
216*7607STed.You@Sun.COM 	    (hw->mac.type != e1000_ich9lan) &&
217*7607STed.You@Sun.COM 	    (hw->mac.type != e1000_ich10lan)) {
2184919Sxy150489 		e1000g_ksp->Symerrs.value.ul +=
2194919Sxy150489 		    E1000_READ_REG(hw, E1000_SYMERRS);
2205882Syy150190 #ifdef E1000G_DEBUG
2214919Sxy150489 		e1000g_ksp->Prc64.value.ul +=
2224919Sxy150489 		    E1000_READ_REG(hw, E1000_PRC64);
2234919Sxy150489 		e1000g_ksp->Prc127.value.ul +=
2244919Sxy150489 		    E1000_READ_REG(hw, E1000_PRC127);
2254919Sxy150489 		e1000g_ksp->Prc255.value.ul +=
2264919Sxy150489 		    E1000_READ_REG(hw, E1000_PRC255);
2274919Sxy150489 		e1000g_ksp->Prc511.value.ul +=
2284919Sxy150489 		    E1000_READ_REG(hw, E1000_PRC511);
2294919Sxy150489 		e1000g_ksp->Prc1023.value.ul +=
2304919Sxy150489 		    E1000_READ_REG(hw, E1000_PRC1023);
2314919Sxy150489 		e1000g_ksp->Prc1522.value.ul +=
2324919Sxy150489 		    E1000_READ_REG(hw, E1000_PRC1522);
2333526Sxy150489 
2344919Sxy150489 		e1000g_ksp->Ptc64.value.ul +=
2354919Sxy150489 		    E1000_READ_REG(hw, E1000_PTC64);
2364919Sxy150489 		e1000g_ksp->Ptc127.value.ul +=
2374919Sxy150489 		    E1000_READ_REG(hw, E1000_PTC127);
2384919Sxy150489 		e1000g_ksp->Ptc255.value.ul +=
2394919Sxy150489 		    E1000_READ_REG(hw, E1000_PTC255);
2404919Sxy150489 		e1000g_ksp->Ptc511.value.ul +=
2414919Sxy150489 		    E1000_READ_REG(hw, E1000_PTC511);
2424919Sxy150489 		e1000g_ksp->Ptc1023.value.ul +=
2434919Sxy150489 		    E1000_READ_REG(hw, E1000_PTC1023);
2444919Sxy150489 		e1000g_ksp->Ptc1522.value.ul +=
2454919Sxy150489 		    E1000_READ_REG(hw, E1000_PTC1522);
2465882Syy150190 #endif
2474919Sxy150489 	}
2483526Sxy150489 
2494919Sxy150489 	e1000g_ksp->Gprc.value.ul += E1000_READ_REG(hw, E1000_GPRC);
2504919Sxy150489 	e1000g_ksp->Gptc.value.ul += E1000_READ_REG(hw, E1000_GPTC);
2514919Sxy150489 	e1000g_ksp->Ruc.value.ul += E1000_READ_REG(hw, E1000_RUC);
2524919Sxy150489 	e1000g_ksp->Rfc.value.ul += E1000_READ_REG(hw, E1000_RFC);
2534919Sxy150489 	e1000g_ksp->Roc.value.ul += E1000_READ_REG(hw, E1000_ROC);
2544919Sxy150489 	e1000g_ksp->Rjc.value.ul += E1000_READ_REG(hw, E1000_RJC);
2554919Sxy150489 	e1000g_ksp->Tpr.value.ul += E1000_READ_REG(hw, E1000_TPR);
2564919Sxy150489 	e1000g_ksp->Tncrs.value.ul += E1000_READ_REG(hw, E1000_TNCRS);
2574919Sxy150489 	e1000g_ksp->Tsctc.value.ul += E1000_READ_REG(hw, E1000_TSCTC);
2584919Sxy150489 	e1000g_ksp->Tsctfc.value.ul += E1000_READ_REG(hw, E1000_TSCTFC);
2593526Sxy150489 
2604919Sxy150489 	/*
2614919Sxy150489 	 * Adaptive Calculations
2624919Sxy150489 	 */
2634919Sxy150489 	hw->mac.tx_packet_delta = E1000_READ_REG(hw, E1000_TPT);
2644919Sxy150489 	e1000g_ksp->Tpt.value.ul += hw->mac.tx_packet_delta;
2653526Sxy150489 
2663526Sxy150489 	/*
2673526Sxy150489 	 * The 64-bit register will reset whenever the upper
2683526Sxy150489 	 * 32 bits are read. So we need to read the lower
2693526Sxy150489 	 * 32 bits first, then read the upper 32 bits.
2703526Sxy150489 	 */
2714919Sxy150489 	low_val = E1000_READ_REG(hw, E1000_GORCL);
2724919Sxy150489 	high_val = E1000_READ_REG(hw, E1000_GORCH);
2733526Sxy150489 	val = (uint64_t)e1000g_ksp->Gorh.value.ul << 32 |
2743526Sxy150489 	    (uint64_t)e1000g_ksp->Gorl.value.ul;
2753526Sxy150489 	val += (uint64_t)high_val << 32 | (uint64_t)low_val;
2763526Sxy150489 	e1000g_ksp->Gorl.value.ul = (uint32_t)val;
2773526Sxy150489 	e1000g_ksp->Gorh.value.ul = (uint32_t)(val >> 32);
2783526Sxy150489 
2794919Sxy150489 	low_val = E1000_READ_REG(hw, E1000_GOTCL);
2804919Sxy150489 	high_val = E1000_READ_REG(hw, E1000_GOTCH);
2813526Sxy150489 	val = (uint64_t)e1000g_ksp->Goth.value.ul << 32 |
2823526Sxy150489 	    (uint64_t)e1000g_ksp->Gotl.value.ul;
2833526Sxy150489 	val += (uint64_t)high_val << 32 | (uint64_t)low_val;
2843526Sxy150489 	e1000g_ksp->Gotl.value.ul = (uint32_t)val;
2853526Sxy150489 	e1000g_ksp->Goth.value.ul = (uint32_t)(val >> 32);
2863526Sxy150489 
2874919Sxy150489 	low_val = E1000_READ_REG(hw, E1000_TORL);
2884919Sxy150489 	high_val = E1000_READ_REG(hw, E1000_TORH);
2893526Sxy150489 	val = (uint64_t)e1000g_ksp->Torh.value.ul << 32 |
2903526Sxy150489 	    (uint64_t)e1000g_ksp->Torl.value.ul;
2913526Sxy150489 	val += (uint64_t)high_val << 32 | (uint64_t)low_val;
2923526Sxy150489 	e1000g_ksp->Torl.value.ul = (uint32_t)val;
2933526Sxy150489 	e1000g_ksp->Torh.value.ul = (uint32_t)(val >> 32);
2943526Sxy150489 
2954919Sxy150489 	low_val = E1000_READ_REG(hw, E1000_TOTL);
2964919Sxy150489 	high_val = E1000_READ_REG(hw, E1000_TOTH);
2973526Sxy150489 	val = (uint64_t)e1000g_ksp->Toth.value.ul << 32 |
2983526Sxy150489 	    (uint64_t)e1000g_ksp->Totl.value.ul;
2993526Sxy150489 	val += (uint64_t)high_val << 32 | (uint64_t)low_val;
3003526Sxy150489 	e1000g_ksp->Totl.value.ul = (uint32_t)val;
3013526Sxy150489 	e1000g_ksp->Toth.value.ul = (uint32_t)(val >> 32);
3023526Sxy150489 
3034919Sxy150489 	rw_exit(&Adapter->chip_lock);
3043526Sxy150489 
3055273Sgl147354 	if (e1000g_check_acc_handle(Adapter->osdep.reg_handle) != DDI_FM_OK)
3065273Sgl147354 		ddi_fm_service_impact(Adapter->dip, DDI_SERVICE_UNAFFECTED);
3075273Sgl147354 
3083526Sxy150489 	return (0);
3093526Sxy150489 }
3103526Sxy150489 
3113526Sxy150489 int
3123526Sxy150489 e1000g_m_stat(void *arg, uint_t stat, uint64_t *val)
3133526Sxy150489 {
3143526Sxy150489 	struct e1000g *Adapter = (struct e1000g *)arg;
3154919Sxy150489 	struct e1000_hw *hw = &Adapter->shared;
3164919Sxy150489 	p_e1000g_stat_t e1000g_ksp;
3173526Sxy150489 	uint32_t low_val, high_val;
3183526Sxy150489 
3194919Sxy150489 	e1000g_ksp = (p_e1000g_stat_t)Adapter->e1000g_ksp->ks_data;
3204919Sxy150489 
3215082Syy150190 	rw_enter(&Adapter->chip_lock, RW_READER);
3223526Sxy150489 
3233526Sxy150489 	switch (stat) {
3243526Sxy150489 	case MAC_STAT_IFSPEED:
3253526Sxy150489 		*val = Adapter->link_speed * 1000000ull;
3263526Sxy150489 		break;
3273526Sxy150489 
3283526Sxy150489 	case MAC_STAT_MULTIRCV:
3293526Sxy150489 		e1000g_ksp->Mprc.value.ul +=
3304919Sxy150489 		    E1000_READ_REG(hw, E1000_MPRC);
3313526Sxy150489 		*val = e1000g_ksp->Mprc.value.ul;
3323526Sxy150489 		break;
3333526Sxy150489 
3343526Sxy150489 	case MAC_STAT_BRDCSTRCV:
3353526Sxy150489 		e1000g_ksp->Bprc.value.ul +=
3364919Sxy150489 		    E1000_READ_REG(hw, E1000_BPRC);
3373526Sxy150489 		*val = e1000g_ksp->Bprc.value.ul;
3383526Sxy150489 		break;
3393526Sxy150489 
3403526Sxy150489 	case MAC_STAT_MULTIXMT:
3413526Sxy150489 		e1000g_ksp->Mptc.value.ul +=
3424919Sxy150489 		    E1000_READ_REG(hw, E1000_MPTC);
3433526Sxy150489 		*val = e1000g_ksp->Mptc.value.ul;
3443526Sxy150489 		break;
3453526Sxy150489 
3463526Sxy150489 	case MAC_STAT_BRDCSTXMT:
3473526Sxy150489 		e1000g_ksp->Bptc.value.ul +=
3484919Sxy150489 		    E1000_READ_REG(hw, E1000_BPTC);
3493526Sxy150489 		*val = e1000g_ksp->Bptc.value.ul;
3503526Sxy150489 		break;
3513526Sxy150489 
3523526Sxy150489 	case MAC_STAT_NORCVBUF:
3533526Sxy150489 		e1000g_ksp->Rnbc.value.ul +=
3544919Sxy150489 		    E1000_READ_REG(hw, E1000_RNBC);
3553526Sxy150489 		*val = e1000g_ksp->Rnbc.value.ul;
3563526Sxy150489 		break;
3573526Sxy150489 
3583526Sxy150489 	case MAC_STAT_IERRORS:
3593526Sxy150489 		e1000g_ksp->Rxerrc.value.ul +=
3604919Sxy150489 		    E1000_READ_REG(hw, E1000_RXERRC);
3613526Sxy150489 		e1000g_ksp->Algnerrc.value.ul +=
3624919Sxy150489 		    E1000_READ_REG(hw, E1000_ALGNERRC);
3633526Sxy150489 		e1000g_ksp->Rlec.value.ul +=
3644919Sxy150489 		    E1000_READ_REG(hw, E1000_RLEC);
3653526Sxy150489 		e1000g_ksp->Crcerrs.value.ul +=
3664919Sxy150489 		    E1000_READ_REG(hw, E1000_CRCERRS);
3673526Sxy150489 		e1000g_ksp->Cexterr.value.ul +=
3684919Sxy150489 		    E1000_READ_REG(hw, E1000_CEXTERR);
3693526Sxy150489 		*val = e1000g_ksp->Rxerrc.value.ul +
3703526Sxy150489 		    e1000g_ksp->Algnerrc.value.ul +
3713526Sxy150489 		    e1000g_ksp->Rlec.value.ul +
3723526Sxy150489 		    e1000g_ksp->Crcerrs.value.ul +
3733526Sxy150489 		    e1000g_ksp->Cexterr.value.ul;
3743526Sxy150489 		break;
3753526Sxy150489 
3763526Sxy150489 	case MAC_STAT_NOXMTBUF:
3774919Sxy150489 		*val = Adapter->tx_ring->stat_no_desc;
3783526Sxy150489 		break;
3793526Sxy150489 
3803526Sxy150489 	case MAC_STAT_OERRORS:
3813526Sxy150489 		e1000g_ksp->Ecol.value.ul +=
3824919Sxy150489 		    E1000_READ_REG(hw, E1000_ECOL);
3833526Sxy150489 		*val = e1000g_ksp->Ecol.value.ul;
3843526Sxy150489 		break;
3853526Sxy150489 
3863526Sxy150489 	case MAC_STAT_COLLISIONS:
3873526Sxy150489 		e1000g_ksp->Colc.value.ul +=
3884919Sxy150489 		    E1000_READ_REG(hw, E1000_COLC);
3893526Sxy150489 		*val = e1000g_ksp->Colc.value.ul;
3903526Sxy150489 		break;
3913526Sxy150489 
3923526Sxy150489 	case MAC_STAT_RBYTES:
3933526Sxy150489 		/*
3943526Sxy150489 		 * The 64-bit register will reset whenever the upper
3953526Sxy150489 		 * 32 bits are read. So we need to read the lower
3963526Sxy150489 		 * 32 bits first, then read the upper 32 bits.
3973526Sxy150489 		 */
3984919Sxy150489 		low_val = E1000_READ_REG(hw, E1000_TORL);
3994919Sxy150489 		high_val = E1000_READ_REG(hw, E1000_TORH);
4003526Sxy150489 		*val = (uint64_t)e1000g_ksp->Torh.value.ul << 32 |
4013526Sxy150489 		    (uint64_t)e1000g_ksp->Torl.value.ul;
4023526Sxy150489 		*val += (uint64_t)high_val << 32 | (uint64_t)low_val;
4033526Sxy150489 
4043526Sxy150489 		e1000g_ksp->Torl.value.ul = (uint32_t)*val;
4053526Sxy150489 		e1000g_ksp->Torh.value.ul = (uint32_t)(*val >> 32);
4063526Sxy150489 		break;
4073526Sxy150489 
4083526Sxy150489 	case MAC_STAT_IPACKETS:
4093526Sxy150489 		e1000g_ksp->Tpr.value.ul +=
4104919Sxy150489 		    E1000_READ_REG(hw, E1000_TPR);
4113526Sxy150489 		*val = e1000g_ksp->Tpr.value.ul;
4123526Sxy150489 		break;
4133526Sxy150489 
4143526Sxy150489 	case MAC_STAT_OBYTES:
4153526Sxy150489 		/*
4163526Sxy150489 		 * The 64-bit register will reset whenever the upper
4173526Sxy150489 		 * 32 bits are read. So we need to read the lower
4183526Sxy150489 		 * 32 bits first, then read the upper 32 bits.
4193526Sxy150489 		 */
4204919Sxy150489 		low_val = E1000_READ_REG(hw, E1000_TOTL);
4214919Sxy150489 		high_val = E1000_READ_REG(hw, E1000_TOTH);
4223526Sxy150489 		*val = (uint64_t)e1000g_ksp->Toth.value.ul << 32 |
4233526Sxy150489 		    (uint64_t)e1000g_ksp->Totl.value.ul;
4243526Sxy150489 		*val += (uint64_t)high_val << 32 | (uint64_t)low_val;
4253526Sxy150489 
4263526Sxy150489 		e1000g_ksp->Totl.value.ul = (uint32_t)*val;
4273526Sxy150489 		e1000g_ksp->Toth.value.ul = (uint32_t)(*val >> 32);
4283526Sxy150489 		break;
4293526Sxy150489 
4303526Sxy150489 	case MAC_STAT_OPACKETS:
4313526Sxy150489 		e1000g_ksp->Tpt.value.ul +=
4324919Sxy150489 		    E1000_READ_REG(hw, E1000_TPT);
4333526Sxy150489 		*val = e1000g_ksp->Tpt.value.ul;
4343526Sxy150489 		break;
4353526Sxy150489 
4363526Sxy150489 	case ETHER_STAT_ALIGN_ERRORS:
4373526Sxy150489 		e1000g_ksp->Algnerrc.value.ul +=
4384919Sxy150489 		    E1000_READ_REG(hw, E1000_ALGNERRC);
4393526Sxy150489 		*val = e1000g_ksp->Algnerrc.value.ul;
4403526Sxy150489 		break;
4413526Sxy150489 
4423526Sxy150489 	case ETHER_STAT_FCS_ERRORS:
4433526Sxy150489 		e1000g_ksp->Crcerrs.value.ul +=
4444919Sxy150489 		    E1000_READ_REG(hw, E1000_CRCERRS);
4453526Sxy150489 		*val = e1000g_ksp->Crcerrs.value.ul;
4463526Sxy150489 		break;
4473526Sxy150489 
4483526Sxy150489 	case ETHER_STAT_SQE_ERRORS:
4493526Sxy150489 		e1000g_ksp->Sec.value.ul +=
4504919Sxy150489 		    E1000_READ_REG(hw, E1000_SEC);
4513526Sxy150489 		*val = e1000g_ksp->Sec.value.ul;
4523526Sxy150489 		break;
4533526Sxy150489 
4543526Sxy150489 	case ETHER_STAT_CARRIER_ERRORS:
4553526Sxy150489 		e1000g_ksp->Cexterr.value.ul +=
4564919Sxy150489 		    E1000_READ_REG(hw, E1000_CEXTERR);
4573526Sxy150489 		*val = e1000g_ksp->Cexterr.value.ul;
4583526Sxy150489 		break;
4593526Sxy150489 
4603526Sxy150489 	case ETHER_STAT_EX_COLLISIONS:
4613526Sxy150489 		e1000g_ksp->Ecol.value.ul +=
4624919Sxy150489 		    E1000_READ_REG(hw, E1000_ECOL);
4633526Sxy150489 		*val = e1000g_ksp->Ecol.value.ul;
4643526Sxy150489 		break;
4653526Sxy150489 
4663526Sxy150489 	case ETHER_STAT_TX_LATE_COLLISIONS:
4673526Sxy150489 		e1000g_ksp->Latecol.value.ul +=
4684919Sxy150489 		    E1000_READ_REG(hw, E1000_LATECOL);
4693526Sxy150489 		*val = e1000g_ksp->Latecol.value.ul;
4703526Sxy150489 		break;
4713526Sxy150489 
4723526Sxy150489 	case ETHER_STAT_DEFER_XMTS:
4733526Sxy150489 		e1000g_ksp->Dc.value.ul +=
4744919Sxy150489 		    E1000_READ_REG(hw, E1000_DC);
4753526Sxy150489 		*val = e1000g_ksp->Dc.value.ul;
4763526Sxy150489 		break;
4773526Sxy150489 
4783526Sxy150489 	case ETHER_STAT_FIRST_COLLISIONS:
4793526Sxy150489 		e1000g_ksp->Scc.value.ul +=
4804919Sxy150489 		    E1000_READ_REG(hw, E1000_SCC);
4813526Sxy150489 		*val = e1000g_ksp->Scc.value.ul;
4823526Sxy150489 		break;
4833526Sxy150489 
4843526Sxy150489 	case ETHER_STAT_MULTI_COLLISIONS:
4853526Sxy150489 		e1000g_ksp->Mcc.value.ul +=
4864919Sxy150489 		    E1000_READ_REG(hw, E1000_MCC);
4873526Sxy150489 		*val = e1000g_ksp->Mcc.value.ul;
4883526Sxy150489 		break;
4893526Sxy150489 
4903526Sxy150489 	case ETHER_STAT_MACRCV_ERRORS:
4913526Sxy150489 		e1000g_ksp->Rxerrc.value.ul +=
4924919Sxy150489 		    E1000_READ_REG(hw, E1000_RXERRC);
4933526Sxy150489 		*val = e1000g_ksp->Rxerrc.value.ul;
4943526Sxy150489 		break;
4953526Sxy150489 
4963526Sxy150489 	case ETHER_STAT_MACXMT_ERRORS:
4973526Sxy150489 		e1000g_ksp->Ecol.value.ul +=
4984919Sxy150489 		    E1000_READ_REG(hw, E1000_ECOL);
4993526Sxy150489 		*val = e1000g_ksp->Ecol.value.ul;
5003526Sxy150489 		break;
5013526Sxy150489 
5023526Sxy150489 	case ETHER_STAT_TOOLONG_ERRORS:
5033526Sxy150489 		e1000g_ksp->Roc.value.ul +=
5044919Sxy150489 		    E1000_READ_REG(hw, E1000_ROC);
5053526Sxy150489 		*val = e1000g_ksp->Roc.value.ul;
5063526Sxy150489 		break;
5073526Sxy150489 
5083526Sxy150489 	case ETHER_STAT_XCVR_ADDR:
5093526Sxy150489 		/* The Internal PHY's MDI address for each MAC is 1 */
5103526Sxy150489 		*val = 1;
5113526Sxy150489 		break;
5123526Sxy150489 
5133526Sxy150489 	case ETHER_STAT_XCVR_ID:
5145082Syy150190 		*val = hw->phy.id | hw->phy.revision;
5153526Sxy150489 		break;
5163526Sxy150489 
5173526Sxy150489 	case ETHER_STAT_XCVR_INUSE:
5183526Sxy150489 		switch (Adapter->link_speed) {
5193526Sxy150489 		case SPEED_1000:
5203526Sxy150489 			*val =
5216735Scc210113 			    (hw->phy.media_type == e1000_media_type_copper) ?
5224919Sxy150489 			    XCVR_1000T : XCVR_1000X;
5233526Sxy150489 			break;
5243526Sxy150489 		case SPEED_100:
5253526Sxy150489 			*val =
5266735Scc210113 			    (hw->phy.media_type == e1000_media_type_copper) ?
5275082Syy150190 			    (Adapter->phy_status & MII_SR_100T4_CAPS) ?
5284919Sxy150489 			    XCVR_100T4 : XCVR_100T2 : XCVR_100X;
5293526Sxy150489 			break;
5303526Sxy150489 		case SPEED_10:
5313526Sxy150489 			*val = XCVR_10;
5323526Sxy150489 			break;
5333526Sxy150489 		default:
5343526Sxy150489 			*val = XCVR_NONE;
5353526Sxy150489 			break;
5363526Sxy150489 		}
5373526Sxy150489 		break;
5383526Sxy150489 
5393526Sxy150489 	case ETHER_STAT_CAP_1000FDX:
5406394Scc210113 		*val = Adapter->param_1000fdx_cap;
5413526Sxy150489 		break;
5423526Sxy150489 
5433526Sxy150489 	case ETHER_STAT_CAP_1000HDX:
5446394Scc210113 		*val = Adapter->param_1000hdx_cap;
5453526Sxy150489 		break;
5463526Sxy150489 
5473526Sxy150489 	case ETHER_STAT_CAP_100FDX:
5486394Scc210113 		*val = Adapter->param_100fdx_cap;
5493526Sxy150489 		break;
5503526Sxy150489 
5513526Sxy150489 	case ETHER_STAT_CAP_100HDX:
5526394Scc210113 		*val = Adapter->param_100hdx_cap;
5533526Sxy150489 		break;
5543526Sxy150489 
5553526Sxy150489 	case ETHER_STAT_CAP_10FDX:
5566394Scc210113 		*val = Adapter->param_10fdx_cap;
5573526Sxy150489 		break;
5583526Sxy150489 
5593526Sxy150489 	case ETHER_STAT_CAP_10HDX:
5606394Scc210113 		*val = Adapter->param_10hdx_cap;
5613526Sxy150489 		break;
5623526Sxy150489 
5633526Sxy150489 	case ETHER_STAT_CAP_ASMPAUSE:
5646394Scc210113 		*val = Adapter->param_asym_pause_cap;
5653526Sxy150489 		break;
5663526Sxy150489 
5673526Sxy150489 	case ETHER_STAT_CAP_PAUSE:
5686394Scc210113 		*val = Adapter->param_pause_cap;
5693526Sxy150489 		break;
5703526Sxy150489 
5713526Sxy150489 	case ETHER_STAT_CAP_AUTONEG:
5726394Scc210113 		*val = Adapter->param_autoneg_cap;
5733526Sxy150489 		break;
5743526Sxy150489 
5753526Sxy150489 	case ETHER_STAT_ADV_CAP_1000FDX:
5766394Scc210113 		*val = Adapter->param_adv_1000fdx;
5773526Sxy150489 		break;
5783526Sxy150489 
5793526Sxy150489 	case ETHER_STAT_ADV_CAP_1000HDX:
5806394Scc210113 		*val = Adapter->param_adv_1000hdx;
5813526Sxy150489 		break;
5823526Sxy150489 
5833526Sxy150489 	case ETHER_STAT_ADV_CAP_100FDX:
5846394Scc210113 		*val = Adapter->param_adv_100fdx;
5853526Sxy150489 		break;
5863526Sxy150489 
5873526Sxy150489 	case ETHER_STAT_ADV_CAP_100HDX:
5886394Scc210113 		*val = Adapter->param_adv_100hdx;
5893526Sxy150489 		break;
5903526Sxy150489 
5913526Sxy150489 	case ETHER_STAT_ADV_CAP_10FDX:
5926394Scc210113 		*val = Adapter->param_adv_10fdx;
5933526Sxy150489 		break;
5943526Sxy150489 
5953526Sxy150489 	case ETHER_STAT_ADV_CAP_10HDX:
5966394Scc210113 		*val = Adapter->param_adv_10hdx;
5973526Sxy150489 		break;
5983526Sxy150489 
5993526Sxy150489 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
6006394Scc210113 		*val = Adapter->param_adv_asym_pause;
6013526Sxy150489 		break;
6023526Sxy150489 
6033526Sxy150489 	case ETHER_STAT_ADV_CAP_PAUSE:
6046394Scc210113 		*val = Adapter->param_adv_pause;
6053526Sxy150489 		break;
6063526Sxy150489 
6073526Sxy150489 	case ETHER_STAT_ADV_CAP_AUTONEG:
6084919Sxy150489 		*val = hw->mac.autoneg;
6093526Sxy150489 		break;
6103526Sxy150489 
6113526Sxy150489 	case ETHER_STAT_LP_CAP_1000FDX:
6126394Scc210113 		*val = Adapter->param_lp_1000fdx;
6133526Sxy150489 		break;
6143526Sxy150489 
6153526Sxy150489 	case ETHER_STAT_LP_CAP_1000HDX:
6166394Scc210113 		*val = Adapter->param_lp_1000hdx;
6173526Sxy150489 		break;
6183526Sxy150489 
6193526Sxy150489 	case ETHER_STAT_LP_CAP_100FDX:
6206394Scc210113 		*val = Adapter->param_lp_100fdx;
6213526Sxy150489 		break;
6223526Sxy150489 
6233526Sxy150489 	case ETHER_STAT_LP_CAP_100HDX:
6246394Scc210113 		*val = Adapter->param_lp_100hdx;
6253526Sxy150489 		break;
6263526Sxy150489 
6273526Sxy150489 	case ETHER_STAT_LP_CAP_10FDX:
6286394Scc210113 		*val = Adapter->param_lp_10fdx;
6293526Sxy150489 		break;
6303526Sxy150489 
6313526Sxy150489 	case ETHER_STAT_LP_CAP_10HDX:
6326394Scc210113 		*val = Adapter->param_lp_10hdx;
6333526Sxy150489 		break;
6343526Sxy150489 
6353526Sxy150489 	case ETHER_STAT_LP_CAP_ASMPAUSE:
6366394Scc210113 		*val = Adapter->param_lp_asym_pause;
6373526Sxy150489 		break;
6383526Sxy150489 
6393526Sxy150489 	case ETHER_STAT_LP_CAP_PAUSE:
6406394Scc210113 		*val = Adapter->param_lp_pause;
6413526Sxy150489 		break;
6423526Sxy150489 
6433526Sxy150489 	case ETHER_STAT_LP_CAP_AUTONEG:
6446394Scc210113 		*val = Adapter->param_lp_autoneg;
6453526Sxy150489 		break;
6463526Sxy150489 
6473526Sxy150489 	case ETHER_STAT_LINK_ASMPAUSE:
6486394Scc210113 		*val = Adapter->param_asym_pause_cap;
6493526Sxy150489 		break;
6503526Sxy150489 
6513526Sxy150489 	case ETHER_STAT_LINK_PAUSE:
6526394Scc210113 		*val = Adapter->param_pause_cap;
6533526Sxy150489 		break;
6543526Sxy150489 
6553526Sxy150489 	case ETHER_STAT_LINK_AUTONEG:
6566394Scc210113 		*val = hw->mac.autoneg;
6573526Sxy150489 		break;
6583526Sxy150489 
6593526Sxy150489 	case ETHER_STAT_LINK_DUPLEX:
6603526Sxy150489 		*val = (Adapter->link_duplex == FULL_DUPLEX) ?
6613526Sxy150489 		    LINK_DUPLEX_FULL : LINK_DUPLEX_HALF;
6623526Sxy150489 		break;
6633526Sxy150489 
6646394Scc210113 	case ETHER_STAT_CAP_100T4:
6656394Scc210113 		*val = Adapter->param_100t4_cap;
6666394Scc210113 		break;
6676394Scc210113 
6686394Scc210113 	case ETHER_STAT_ADV_CAP_100T4:
6696394Scc210113 		*val = Adapter->param_adv_100t4;
6706394Scc210113 		break;
6716394Scc210113 
6726394Scc210113 	case ETHER_STAT_LP_CAP_100T4:
6736394Scc210113 		*val = Adapter->param_lp_100t4;
6746394Scc210113 		break;
6756394Scc210113 
6763526Sxy150489 	default:
6774919Sxy150489 		rw_exit(&Adapter->chip_lock);
6783526Sxy150489 		return (ENOTSUP);
6793526Sxy150489 	}
6803526Sxy150489 
6814919Sxy150489 	rw_exit(&Adapter->chip_lock);
6824919Sxy150489 
6835273Sgl147354 	if (e1000g_check_acc_handle(Adapter->osdep.reg_handle) != DDI_FM_OK)
6845273Sgl147354 		ddi_fm_service_impact(Adapter->dip, DDI_SERVICE_UNAFFECTED);
6855273Sgl147354 
6863526Sxy150489 	return (0);
6873526Sxy150489 }
6883526Sxy150489 
6893526Sxy150489 /*
6904919Sxy150489  * e1000g_init_stats - initialize kstat data structures
6914919Sxy150489  *
6924919Sxy150489  * This routine will create and initialize the driver private
6934919Sxy150489  * statistics counters.
6943526Sxy150489  */
6953526Sxy150489 int
6964919Sxy150489 e1000g_init_stats(struct e1000g *Adapter)
6973526Sxy150489 {
6983526Sxy150489 	kstat_t *ksp;
6994919Sxy150489 	p_e1000g_stat_t e1000g_ksp;
7003526Sxy150489 
7013526Sxy150489 	/*
7023526Sxy150489 	 * Create and init kstat
7033526Sxy150489 	 */
7043526Sxy150489 	ksp = kstat_create(WSNAME, ddi_get_instance(Adapter->dip),
7053526Sxy150489 	    "statistics", "net", KSTAT_TYPE_NAMED,
7064919Sxy150489 	    sizeof (e1000g_stat_t) / sizeof (kstat_named_t), 0);
7073526Sxy150489 
7083526Sxy150489 	if (ksp == NULL) {
7093526Sxy150489 		e1000g_log(Adapter, CE_WARN,
7103526Sxy150489 		    "Could not create kernel statistics\n");
7113526Sxy150489 		return (DDI_FAILURE);
7123526Sxy150489 	}
7133526Sxy150489 
7143526Sxy150489 	Adapter->e1000g_ksp = ksp;	/* Fill in the Adapters ksp */
7153526Sxy150489 
7164919Sxy150489 	e1000g_ksp = (p_e1000g_stat_t)ksp->ks_data;
7173526Sxy150489 
7183526Sxy150489 	/*
7193526Sxy150489 	 * Initialize all the statistics
7203526Sxy150489 	 */
7213526Sxy150489 	kstat_named_init(&e1000g_ksp->link_speed, "link_speed",
7223526Sxy150489 	    KSTAT_DATA_ULONG);
7234919Sxy150489 	kstat_named_init(&e1000g_ksp->reset_count, "Reset Count",
7243526Sxy150489 	    KSTAT_DATA_ULONG);
7253526Sxy150489 
7263526Sxy150489 	kstat_named_init(&e1000g_ksp->rx_error, "Rx Error",
7273526Sxy150489 	    KSTAT_DATA_ULONG);
7283526Sxy150489 	kstat_named_init(&e1000g_ksp->rx_esballoc_fail, "Rx Desballoc Failure",
7293526Sxy150489 	    KSTAT_DATA_ULONG);
7303526Sxy150489 	kstat_named_init(&e1000g_ksp->rx_allocb_fail, "Rx Allocb Failure",
7313526Sxy150489 	    KSTAT_DATA_ULONG);
7323526Sxy150489 
7333526Sxy150489 	kstat_named_init(&e1000g_ksp->tx_no_desc, "Tx No Desc",
7343526Sxy150489 	    KSTAT_DATA_ULONG);
7353526Sxy150489 	kstat_named_init(&e1000g_ksp->tx_no_swpkt, "Tx No Buffer",
7363526Sxy150489 	    KSTAT_DATA_ULONG);
7374919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_send_fail, "Tx Send Failure",
7384919Sxy150489 	    KSTAT_DATA_ULONG);
7394919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_over_size, "Tx Pkt Over Size",
7404919Sxy150489 	    KSTAT_DATA_ULONG);
7414919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_reschedule, "Tx Reschedule",
7423526Sxy150489 	    KSTAT_DATA_ULONG);
7433526Sxy150489 
7444919Sxy150489 	kstat_named_init(&e1000g_ksp->Mpc, "Recv_Missed_Packets",
7454919Sxy150489 	    KSTAT_DATA_ULONG);
7464919Sxy150489 	kstat_named_init(&e1000g_ksp->Symerrs, "Recv_Symbol_Errors",
7474919Sxy150489 	    KSTAT_DATA_ULONG);
7484919Sxy150489 	kstat_named_init(&e1000g_ksp->Rlec, "Recv_Length_Errors",
7494919Sxy150489 	    KSTAT_DATA_ULONG);
7504919Sxy150489 	kstat_named_init(&e1000g_ksp->Xonrxc, "XONs_Recvd",
7514919Sxy150489 	    KSTAT_DATA_ULONG);
7524919Sxy150489 	kstat_named_init(&e1000g_ksp->Xontxc, "XONs_Xmitd",
7534919Sxy150489 	    KSTAT_DATA_ULONG);
7544919Sxy150489 	kstat_named_init(&e1000g_ksp->Xoffrxc, "XOFFs_Recvd",
7554919Sxy150489 	    KSTAT_DATA_ULONG);
7564919Sxy150489 	kstat_named_init(&e1000g_ksp->Xofftxc, "XOFFs_Xmitd",
7574919Sxy150489 	    KSTAT_DATA_ULONG);
7584919Sxy150489 	kstat_named_init(&e1000g_ksp->Fcruc, "Recv_Unsupport_FC_Pkts",
7594919Sxy150489 	    KSTAT_DATA_ULONG);
7605882Syy150190 #ifdef E1000G_DEBUG
7614919Sxy150489 	kstat_named_init(&e1000g_ksp->Prc64, "Pkts_Recvd_(  64b)",
7624919Sxy150489 	    KSTAT_DATA_ULONG);
7634919Sxy150489 	kstat_named_init(&e1000g_ksp->Prc127, "Pkts_Recvd_(  65- 127b)",
7644919Sxy150489 	    KSTAT_DATA_ULONG);
7654919Sxy150489 	kstat_named_init(&e1000g_ksp->Prc255, "Pkts_Recvd_( 127- 255b)",
7664919Sxy150489 	    KSTAT_DATA_ULONG);
7674919Sxy150489 	kstat_named_init(&e1000g_ksp->Prc511, "Pkts_Recvd_( 256- 511b)",
7684919Sxy150489 	    KSTAT_DATA_ULONG);
7694919Sxy150489 	kstat_named_init(&e1000g_ksp->Prc1023, "Pkts_Recvd_( 511-1023b)",
7704919Sxy150489 	    KSTAT_DATA_ULONG);
7714919Sxy150489 	kstat_named_init(&e1000g_ksp->Prc1522, "Pkts_Recvd_(1024-1522b)",
7724919Sxy150489 	    KSTAT_DATA_ULONG);
7735882Syy150190 #endif
7744919Sxy150489 	kstat_named_init(&e1000g_ksp->Gprc, "Good_Pkts_Recvd",
7754919Sxy150489 	    KSTAT_DATA_ULONG);
7764919Sxy150489 	kstat_named_init(&e1000g_ksp->Gptc, "Good_Pkts_Xmitd",
7774919Sxy150489 	    KSTAT_DATA_ULONG);
7784919Sxy150489 	kstat_named_init(&e1000g_ksp->Gorl, "Good_Octets_Recvd_Lo",
7794919Sxy150489 	    KSTAT_DATA_ULONG);
7804919Sxy150489 	kstat_named_init(&e1000g_ksp->Gorh, "Good_Octets_Recvd_Hi",
7814919Sxy150489 	    KSTAT_DATA_ULONG);
7824919Sxy150489 	kstat_named_init(&e1000g_ksp->Gotl, "Good_Octets_Xmitd_Lo",
7834919Sxy150489 	    KSTAT_DATA_ULONG);
7844919Sxy150489 	kstat_named_init(&e1000g_ksp->Goth, "Good_Octets_Xmitd_Hi",
7854919Sxy150489 	    KSTAT_DATA_ULONG);
7864919Sxy150489 	kstat_named_init(&e1000g_ksp->Ruc, "Recv_Undersize",
7874919Sxy150489 	    KSTAT_DATA_ULONG);
7884919Sxy150489 	kstat_named_init(&e1000g_ksp->Rfc, "Recv_Frag",
7894919Sxy150489 	    KSTAT_DATA_ULONG);
7904919Sxy150489 	kstat_named_init(&e1000g_ksp->Roc, "Recv_Oversize",
7914919Sxy150489 	    KSTAT_DATA_ULONG);
7924919Sxy150489 	kstat_named_init(&e1000g_ksp->Rjc, "Recv_Jabber",
7934919Sxy150489 	    KSTAT_DATA_ULONG);
7944919Sxy150489 	kstat_named_init(&e1000g_ksp->Torl, "Total_Octets_Recvd_Lo",
7954919Sxy150489 	    KSTAT_DATA_ULONG);
7964919Sxy150489 	kstat_named_init(&e1000g_ksp->Torh, "Total_Octets_Recvd_Hi",
7974919Sxy150489 	    KSTAT_DATA_ULONG);
7984919Sxy150489 	kstat_named_init(&e1000g_ksp->Totl, "Total_Octets_Xmitd_Lo",
7994919Sxy150489 	    KSTAT_DATA_ULONG);
8004919Sxy150489 	kstat_named_init(&e1000g_ksp->Toth, "Total_Octets_Xmitd_Hi",
8014919Sxy150489 	    KSTAT_DATA_ULONG);
8024919Sxy150489 	kstat_named_init(&e1000g_ksp->Tpr, "Total_Packets_Recvd",
8034919Sxy150489 	    KSTAT_DATA_ULONG);
8044919Sxy150489 	kstat_named_init(&e1000g_ksp->Tpt, "Total_Packets_Xmitd",
8054919Sxy150489 	    KSTAT_DATA_ULONG);
8065882Syy150190 #ifdef E1000G_DEBUG
8074919Sxy150489 	kstat_named_init(&e1000g_ksp->Ptc64, "Pkts_Xmitd_(  64b)",
8084919Sxy150489 	    KSTAT_DATA_ULONG);
8094919Sxy150489 	kstat_named_init(&e1000g_ksp->Ptc127, "Pkts_Xmitd_(  65- 127b)",
8104919Sxy150489 	    KSTAT_DATA_ULONG);
8114919Sxy150489 	kstat_named_init(&e1000g_ksp->Ptc255, "Pkts_Xmitd_( 128- 255b)",
8124919Sxy150489 	    KSTAT_DATA_ULONG);
8134919Sxy150489 	kstat_named_init(&e1000g_ksp->Ptc511, "Pkts_Xmitd_( 255- 511b)",
8144919Sxy150489 	    KSTAT_DATA_ULONG);
8154919Sxy150489 	kstat_named_init(&e1000g_ksp->Ptc1023, "Pkts_Xmitd_( 512-1023b)",
8164919Sxy150489 	    KSTAT_DATA_ULONG);
8174919Sxy150489 	kstat_named_init(&e1000g_ksp->Ptc1522, "Pkts_Xmitd_(1024-1522b)",
8184919Sxy150489 	    KSTAT_DATA_ULONG);
8195882Syy150190 #endif
8204919Sxy150489 	kstat_named_init(&e1000g_ksp->Tncrs, "Xmit_with_No_CRS",
8214919Sxy150489 	    KSTAT_DATA_ULONG);
8224919Sxy150489 	kstat_named_init(&e1000g_ksp->Tsctc, "Xmit_TCP_Seg_Contexts",
8234919Sxy150489 	    KSTAT_DATA_ULONG);
8244919Sxy150489 	kstat_named_init(&e1000g_ksp->Tsctfc, "Xmit_TCP_Seg_Contexts_Fail",
8254919Sxy150489 	    KSTAT_DATA_ULONG);
8263526Sxy150489 
8274919Sxy150489 #ifdef E1000G_DEBUG
8284919Sxy150489 	kstat_named_init(&e1000g_ksp->rx_none, "Rx No Data",
8294919Sxy150489 	    KSTAT_DATA_ULONG);
8304919Sxy150489 	kstat_named_init(&e1000g_ksp->rx_multi_desc, "Rx Span Multi Desc",
8314919Sxy150489 	    KSTAT_DATA_ULONG);
8324919Sxy150489 	kstat_named_init(&e1000g_ksp->rx_no_freepkt, "Rx Freelist Empty",
8334919Sxy150489 	    KSTAT_DATA_ULONG);
8344919Sxy150489 	kstat_named_init(&e1000g_ksp->rx_avail_freepkt, "Rx Freelist Avail",
8353526Sxy150489 	    KSTAT_DATA_ULONG);
8363526Sxy150489 
8373526Sxy150489 	kstat_named_init(&e1000g_ksp->tx_under_size, "Tx Pkt Under Size",
8383526Sxy150489 	    KSTAT_DATA_ULONG);
8393526Sxy150489 	kstat_named_init(&e1000g_ksp->tx_exceed_frags, "Tx Exceed Max Frags",
8403526Sxy150489 	    KSTAT_DATA_ULONG);
8414919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_empty_frags, "Tx Empty Frags",
8423526Sxy150489 	    KSTAT_DATA_ULONG);
8434919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_recycle, "Tx Recycle",
8443526Sxy150489 	    KSTAT_DATA_ULONG);
8454919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_recycle_intr, "Tx Recycle Intr",
8463526Sxy150489 	    KSTAT_DATA_ULONG);
8474919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_recycle_retry, "Tx Recycle Retry",
8483526Sxy150489 	    KSTAT_DATA_ULONG);
8494919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_recycle_none, "Tx Recycled None",
8503526Sxy150489 	    KSTAT_DATA_ULONG);
8514919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_copy, "Tx Send Copy",
8523526Sxy150489 	    KSTAT_DATA_ULONG);
8534919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_bind, "Tx Send Bind",
8543526Sxy150489 	    KSTAT_DATA_ULONG);
8554919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_multi_copy, "Tx Copy Multi Frags",
8563526Sxy150489 	    KSTAT_DATA_ULONG);
8574919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_multi_cookie, "Tx Bind Multi Cookies",
8583526Sxy150489 	    KSTAT_DATA_ULONG);
8594919Sxy150489 	kstat_named_init(&e1000g_ksp->tx_lack_desc, "Tx Desc Insufficient",
8603526Sxy150489 	    KSTAT_DATA_ULONG);
8614919Sxy150489 #endif
8623526Sxy150489 
8633526Sxy150489 	/*
8643526Sxy150489 	 * Function to provide kernel stat update on demand
8653526Sxy150489 	 */
8664919Sxy150489 	ksp->ks_update = e1000g_update_stats;
8673526Sxy150489 
8683526Sxy150489 	/*
8693526Sxy150489 	 * Pointer into provider's raw statistics
8703526Sxy150489 	 */
8713526Sxy150489 	ksp->ks_private = (void *)Adapter;
8723526Sxy150489 
8733526Sxy150489 	/*
8743526Sxy150489 	 * Add kstat to systems kstat chain
8753526Sxy150489 	 */
8763526Sxy150489 	kstat_install(ksp);
8773526Sxy150489 
8783526Sxy150489 	return (DDI_SUCCESS);
8793526Sxy150489 }
880