xref: /illumos-gate/usr/src/uts/common/io/e1000g/e1000g_stat.c (revision 54e0d7a5e8285a3f01a0db8db1246ac7cac94d81)
1 /*
2  * This file is provided under a CDDLv1 license.  When using or
3  * redistributing this file, you may do so under this license.
4  * In redistributing this file this license must be included
5  * and no other modification of this header file is permitted.
6  *
7  * CDDL LICENSE SUMMARY
8  *
9  * Copyright(c) 1999 - 2009 Intel Corporation. All rights reserved.
10  *
11  * The contents of this file are subject to the terms of Version
12  * 1.0 of the Common Development and Distribution License (the "License").
13  *
14  * You should have received a copy of the License with this software.
15  * You can obtain a copy of the License at
16  *	http://www.opensolaris.org/os/licensing.
17  * See the License for the specific language governing permissions
18  * and limitations under the License.
19  */
20 
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * **********************************************************************
28  *									*
29  * Module Name:  e1000g_stat.c						*
30  *									*
31  * Abstract: Functions for processing statistics			*
32  *									*
33  * **********************************************************************
34  */
35 #include "e1000g_sw.h"
36 #include "e1000g_debug.h"
37 
38 static int e1000g_update_stats(kstat_t *ksp, int rw);
39 
40 /*
41  * e1000_tbi_adjust_stats
42  *
43  * Adjusts statistic counters when a frame is accepted
44  * under the TBI workaround. This function has been
45  * adapted for Solaris from shared code.
46  */
47 void
48 e1000_tbi_adjust_stats(struct e1000g *Adapter,
49     uint32_t frame_len, uint8_t *mac_addr)
50 {
51 	uint32_t carry_bit;
52 	p_e1000g_stat_t e1000g_ksp;
53 
54 	e1000g_ksp = (p_e1000g_stat_t)Adapter->e1000g_ksp->ks_data;
55 
56 	/* First adjust the frame length */
57 	frame_len--;
58 
59 	/*
60 	 * We need to adjust the statistics counters, since the hardware
61 	 * counters overcount this packet as a CRC error and undercount
62 	 * the packet as a good packet
63 	 */
64 	/* This packet should not be counted as a CRC error */
65 	e1000g_ksp->Crcerrs.value.ul--;
66 	/* This packet does count as a Good Packet Received */
67 	e1000g_ksp->Gprc.value.ul++;
68 
69 	/*
70 	 * Adjust the Good Octets received counters
71 	 */
72 	carry_bit = 0x80000000 & e1000g_ksp->Gorl.value.ul;
73 	e1000g_ksp->Gorl.value.ul += frame_len;
74 	/*
75 	 * If the high bit of Gorcl (the low 32 bits of the Good Octets
76 	 * Received Count) was one before the addition,
77 	 * AND it is zero after, then we lost the carry out,
78 	 * need to add one to Gorch (Good Octets Received Count High).
79 	 * This could be simplified if all environments supported
80 	 * 64-bit integers.
81 	 */
82 	if (carry_bit && ((e1000g_ksp->Gorl.value.ul & 0x80000000) == 0)) {
83 		e1000g_ksp->Gorh.value.ul++;
84 	}
85 	/*
86 	 * Is this a broadcast or multicast?  Check broadcast first,
87 	 * since the test for a multicast frame will test positive on
88 	 * a broadcast frame.
89 	 */
90 	if ((mac_addr[0] == (uint8_t)0xff) &&
91 	    (mac_addr[1] == (uint8_t)0xff)) {
92 		/*
93 		 * Broadcast packet
94 		 */
95 		e1000g_ksp->Bprc.value.ul++;
96 	} else if (*mac_addr & 0x01) {
97 		/*
98 		 * Multicast packet
99 		 */
100 		e1000g_ksp->Mprc.value.ul++;
101 	}
102 
103 	if (frame_len == Adapter->max_frame_size) {
104 		/*
105 		 * In this case, the hardware has overcounted the number of
106 		 * oversize frames.
107 		 */
108 		if (e1000g_ksp->Roc.value.ul > 0)
109 			e1000g_ksp->Roc.value.ul--;
110 	}
111 
112 #ifdef E1000G_DEBUG
113 	/*
114 	 * Adjust the bin counters when the extra byte put the frame in the
115 	 * wrong bin. Remember that the frame_len was adjusted above.
116 	 */
117 	if (frame_len == 64) {
118 		e1000g_ksp->Prc64.value.ul++;
119 		e1000g_ksp->Prc127.value.ul--;
120 	} else if (frame_len == 127) {
121 		e1000g_ksp->Prc127.value.ul++;
122 		e1000g_ksp->Prc255.value.ul--;
123 	} else if (frame_len == 255) {
124 		e1000g_ksp->Prc255.value.ul++;
125 		e1000g_ksp->Prc511.value.ul--;
126 	} else if (frame_len == 511) {
127 		e1000g_ksp->Prc511.value.ul++;
128 		e1000g_ksp->Prc1023.value.ul--;
129 	} else if (frame_len == 1023) {
130 		e1000g_ksp->Prc1023.value.ul++;
131 		e1000g_ksp->Prc1522.value.ul--;
132 	} else if (frame_len == 1522) {
133 		e1000g_ksp->Prc1522.value.ul++;
134 	}
135 #endif
136 }
137 
138 
139 /*
140  * e1000g_update_stats - update driver private kstat counters
141  *
142  * This routine will dump and reset the e1000's internal
143  * statistics counters. The current stats dump values will
144  * be sent to the kernel status area.
145  */
146 static int
147 e1000g_update_stats(kstat_t *ksp, int rw)
148 {
149 	struct e1000g *Adapter;
150 	struct e1000_hw *hw;
151 	p_e1000g_stat_t e1000g_ksp;
152 	e1000g_tx_ring_t *tx_ring;
153 	e1000g_rx_ring_t *rx_ring;
154 	e1000g_rx_data_t *rx_data;
155 	uint64_t val;
156 	uint32_t low_val, high_val;
157 
158 	if (rw == KSTAT_WRITE)
159 		return (EACCES);
160 
161 	Adapter = (struct e1000g *)ksp->ks_private;
162 	ASSERT(Adapter != NULL);
163 	e1000g_ksp = (p_e1000g_stat_t)ksp->ks_data;
164 	ASSERT(e1000g_ksp != NULL);
165 	hw = &Adapter->shared;
166 
167 	tx_ring = Adapter->tx_ring;
168 	rx_ring = Adapter->rx_ring;
169 	rx_data = rx_ring->rx_data;
170 
171 	rw_enter(&Adapter->chip_lock, RW_WRITER);
172 
173 	e1000g_ksp->link_speed.value.ul = Adapter->link_speed;
174 	e1000g_ksp->reset_count.value.ul = Adapter->reset_count;
175 
176 	e1000g_ksp->rx_error.value.ul = rx_ring->stat_error;
177 	e1000g_ksp->rx_allocb_fail.value.ul = rx_ring->stat_allocb_fail;
178 
179 	e1000g_ksp->tx_no_swpkt.value.ul = tx_ring->stat_no_swpkt;
180 	e1000g_ksp->tx_no_desc.value.ul = tx_ring->stat_no_desc;
181 	e1000g_ksp->tx_send_fail.value.ul = tx_ring->stat_send_fail;
182 	e1000g_ksp->tx_reschedule.value.ul = tx_ring->stat_reschedule;
183 	e1000g_ksp->tx_over_size.value.ul = tx_ring->stat_over_size;
184 
185 #ifdef E1000G_DEBUG
186 	e1000g_ksp->rx_none.value.ul = rx_ring->stat_none;
187 	e1000g_ksp->rx_multi_desc.value.ul = rx_ring->stat_multi_desc;
188 	e1000g_ksp->rx_no_freepkt.value.ul = rx_ring->stat_no_freepkt;
189 	if (rx_data != NULL)
190 		e1000g_ksp->rx_avail_freepkt.value.ul = rx_data->avail_freepkt;
191 
192 	e1000g_ksp->tx_under_size.value.ul = tx_ring->stat_under_size;
193 	e1000g_ksp->tx_exceed_frags.value.ul = tx_ring->stat_exceed_frags;
194 	e1000g_ksp->tx_empty_frags.value.ul = tx_ring->stat_empty_frags;
195 	e1000g_ksp->tx_recycle.value.ul = tx_ring->stat_recycle;
196 	e1000g_ksp->tx_recycle_intr.value.ul = tx_ring->stat_recycle_intr;
197 	e1000g_ksp->tx_recycle_retry.value.ul = tx_ring->stat_recycle_retry;
198 	e1000g_ksp->tx_recycle_none.value.ul = tx_ring->stat_recycle_none;
199 	e1000g_ksp->tx_copy.value.ul = tx_ring->stat_copy;
200 	e1000g_ksp->tx_bind.value.ul = tx_ring->stat_bind;
201 	e1000g_ksp->tx_multi_copy.value.ul = tx_ring->stat_multi_copy;
202 	e1000g_ksp->tx_multi_cookie.value.ul = tx_ring->stat_multi_cookie;
203 	e1000g_ksp->tx_lack_desc.value.ul = tx_ring->stat_lack_desc;
204 #endif
205 
206 	/*
207 	 * Standard Stats
208 	 */
209 	e1000g_ksp->Mpc.value.ul += E1000_READ_REG(hw, E1000_MPC);
210 	e1000g_ksp->Rlec.value.ul += E1000_READ_REG(hw, E1000_RLEC);
211 	e1000g_ksp->Xonrxc.value.ul += E1000_READ_REG(hw, E1000_XONRXC);
212 	e1000g_ksp->Xontxc.value.ul += E1000_READ_REG(hw, E1000_XONTXC);
213 	e1000g_ksp->Xoffrxc.value.ul += E1000_READ_REG(hw, E1000_XOFFRXC);
214 	e1000g_ksp->Xofftxc.value.ul += E1000_READ_REG(hw, E1000_XOFFTXC);
215 	e1000g_ksp->Fcruc.value.ul += E1000_READ_REG(hw, E1000_FCRUC);
216 
217 	if ((hw->mac.type != e1000_ich8lan) &&
218 	    (hw->mac.type != e1000_ich9lan) &&
219 	    (hw->mac.type != e1000_ich10lan)) {
220 		e1000g_ksp->Symerrs.value.ul +=
221 		    E1000_READ_REG(hw, E1000_SYMERRS);
222 #ifdef E1000G_DEBUG
223 		e1000g_ksp->Prc64.value.ul +=
224 		    E1000_READ_REG(hw, E1000_PRC64);
225 		e1000g_ksp->Prc127.value.ul +=
226 		    E1000_READ_REG(hw, E1000_PRC127);
227 		e1000g_ksp->Prc255.value.ul +=
228 		    E1000_READ_REG(hw, E1000_PRC255);
229 		e1000g_ksp->Prc511.value.ul +=
230 		    E1000_READ_REG(hw, E1000_PRC511);
231 		e1000g_ksp->Prc1023.value.ul +=
232 		    E1000_READ_REG(hw, E1000_PRC1023);
233 		e1000g_ksp->Prc1522.value.ul +=
234 		    E1000_READ_REG(hw, E1000_PRC1522);
235 
236 		e1000g_ksp->Ptc64.value.ul +=
237 		    E1000_READ_REG(hw, E1000_PTC64);
238 		e1000g_ksp->Ptc127.value.ul +=
239 		    E1000_READ_REG(hw, E1000_PTC127);
240 		e1000g_ksp->Ptc255.value.ul +=
241 		    E1000_READ_REG(hw, E1000_PTC255);
242 		e1000g_ksp->Ptc511.value.ul +=
243 		    E1000_READ_REG(hw, E1000_PTC511);
244 		e1000g_ksp->Ptc1023.value.ul +=
245 		    E1000_READ_REG(hw, E1000_PTC1023);
246 		e1000g_ksp->Ptc1522.value.ul +=
247 		    E1000_READ_REG(hw, E1000_PTC1522);
248 #endif
249 	}
250 
251 	e1000g_ksp->Gprc.value.ul += E1000_READ_REG(hw, E1000_GPRC);
252 	e1000g_ksp->Gptc.value.ul += E1000_READ_REG(hw, E1000_GPTC);
253 	e1000g_ksp->Ruc.value.ul += E1000_READ_REG(hw, E1000_RUC);
254 	e1000g_ksp->Rfc.value.ul += E1000_READ_REG(hw, E1000_RFC);
255 	e1000g_ksp->Roc.value.ul += E1000_READ_REG(hw, E1000_ROC);
256 	e1000g_ksp->Rjc.value.ul += E1000_READ_REG(hw, E1000_RJC);
257 	e1000g_ksp->Tpr.value.ul += E1000_READ_REG(hw, E1000_TPR);
258 	e1000g_ksp->Tncrs.value.ul += E1000_READ_REG(hw, E1000_TNCRS);
259 	e1000g_ksp->Tsctc.value.ul += E1000_READ_REG(hw, E1000_TSCTC);
260 	e1000g_ksp->Tsctfc.value.ul += E1000_READ_REG(hw, E1000_TSCTFC);
261 
262 	/*
263 	 * Adaptive Calculations
264 	 */
265 	hw->mac.tx_packet_delta = E1000_READ_REG(hw, E1000_TPT);
266 	e1000g_ksp->Tpt.value.ul += hw->mac.tx_packet_delta;
267 
268 	/*
269 	 * The 64-bit register will reset whenever the upper
270 	 * 32 bits are read. So we need to read the lower
271 	 * 32 bits first, then read the upper 32 bits.
272 	 */
273 	low_val = E1000_READ_REG(hw, E1000_GORCL);
274 	high_val = E1000_READ_REG(hw, E1000_GORCH);
275 	val = (uint64_t)e1000g_ksp->Gorh.value.ul << 32 |
276 	    (uint64_t)e1000g_ksp->Gorl.value.ul;
277 	val += (uint64_t)high_val << 32 | (uint64_t)low_val;
278 	e1000g_ksp->Gorl.value.ul = (uint32_t)val;
279 	e1000g_ksp->Gorh.value.ul = (uint32_t)(val >> 32);
280 
281 	low_val = E1000_READ_REG(hw, E1000_GOTCL);
282 	high_val = E1000_READ_REG(hw, E1000_GOTCH);
283 	val = (uint64_t)e1000g_ksp->Goth.value.ul << 32 |
284 	    (uint64_t)e1000g_ksp->Gotl.value.ul;
285 	val += (uint64_t)high_val << 32 | (uint64_t)low_val;
286 	e1000g_ksp->Gotl.value.ul = (uint32_t)val;
287 	e1000g_ksp->Goth.value.ul = (uint32_t)(val >> 32);
288 
289 	low_val = E1000_READ_REG(hw, E1000_TORL);
290 	high_val = E1000_READ_REG(hw, E1000_TORH);
291 	val = (uint64_t)e1000g_ksp->Torh.value.ul << 32 |
292 	    (uint64_t)e1000g_ksp->Torl.value.ul;
293 	val += (uint64_t)high_val << 32 | (uint64_t)low_val;
294 	e1000g_ksp->Torl.value.ul = (uint32_t)val;
295 	e1000g_ksp->Torh.value.ul = (uint32_t)(val >> 32);
296 
297 	low_val = E1000_READ_REG(hw, E1000_TOTL);
298 	high_val = E1000_READ_REG(hw, E1000_TOTH);
299 	val = (uint64_t)e1000g_ksp->Toth.value.ul << 32 |
300 	    (uint64_t)e1000g_ksp->Totl.value.ul;
301 	val += (uint64_t)high_val << 32 | (uint64_t)low_val;
302 	e1000g_ksp->Totl.value.ul = (uint32_t)val;
303 	e1000g_ksp->Toth.value.ul = (uint32_t)(val >> 32);
304 
305 	rw_exit(&Adapter->chip_lock);
306 
307 	if (e1000g_check_acc_handle(Adapter->osdep.reg_handle) != DDI_FM_OK)
308 		ddi_fm_service_impact(Adapter->dip, DDI_SERVICE_UNAFFECTED);
309 
310 	return (0);
311 }
312 
313 int
314 e1000g_m_stat(void *arg, uint_t stat, uint64_t *val)
315 {
316 	struct e1000g *Adapter = (struct e1000g *)arg;
317 	struct e1000_hw *hw = &Adapter->shared;
318 	p_e1000g_stat_t e1000g_ksp;
319 	uint32_t low_val, high_val;
320 
321 	e1000g_ksp = (p_e1000g_stat_t)Adapter->e1000g_ksp->ks_data;
322 
323 	rw_enter(&Adapter->chip_lock, RW_READER);
324 
325 	if (Adapter->e1000g_state & E1000G_SUSPENDED) {
326 		rw_exit(&Adapter->chip_lock);
327 		return (ECANCELED);
328 	}
329 
330 	switch (stat) {
331 	case MAC_STAT_IFSPEED:
332 		*val = Adapter->link_speed * 1000000ull;
333 		break;
334 
335 	case MAC_STAT_MULTIRCV:
336 		e1000g_ksp->Mprc.value.ul +=
337 		    E1000_READ_REG(hw, E1000_MPRC);
338 		*val = e1000g_ksp->Mprc.value.ul;
339 		break;
340 
341 	case MAC_STAT_BRDCSTRCV:
342 		e1000g_ksp->Bprc.value.ul +=
343 		    E1000_READ_REG(hw, E1000_BPRC);
344 		*val = e1000g_ksp->Bprc.value.ul;
345 		break;
346 
347 	case MAC_STAT_MULTIXMT:
348 		e1000g_ksp->Mptc.value.ul +=
349 		    E1000_READ_REG(hw, E1000_MPTC);
350 		*val = e1000g_ksp->Mptc.value.ul;
351 		break;
352 
353 	case MAC_STAT_BRDCSTXMT:
354 		e1000g_ksp->Bptc.value.ul +=
355 		    E1000_READ_REG(hw, E1000_BPTC);
356 		*val = e1000g_ksp->Bptc.value.ul;
357 		break;
358 
359 	case MAC_STAT_NORCVBUF:
360 		e1000g_ksp->Rnbc.value.ul +=
361 		    E1000_READ_REG(hw, E1000_RNBC);
362 		*val = e1000g_ksp->Rnbc.value.ul;
363 		break;
364 
365 	case MAC_STAT_IERRORS:
366 		e1000g_ksp->Rxerrc.value.ul +=
367 		    E1000_READ_REG(hw, E1000_RXERRC);
368 		e1000g_ksp->Algnerrc.value.ul +=
369 		    E1000_READ_REG(hw, E1000_ALGNERRC);
370 		e1000g_ksp->Rlec.value.ul +=
371 		    E1000_READ_REG(hw, E1000_RLEC);
372 		e1000g_ksp->Crcerrs.value.ul +=
373 		    E1000_READ_REG(hw, E1000_CRCERRS);
374 		e1000g_ksp->Cexterr.value.ul +=
375 		    E1000_READ_REG(hw, E1000_CEXTERR);
376 		*val = e1000g_ksp->Rxerrc.value.ul +
377 		    e1000g_ksp->Algnerrc.value.ul +
378 		    e1000g_ksp->Rlec.value.ul +
379 		    e1000g_ksp->Crcerrs.value.ul +
380 		    e1000g_ksp->Cexterr.value.ul;
381 		break;
382 
383 	case MAC_STAT_NOXMTBUF:
384 		*val = Adapter->tx_ring->stat_no_desc;
385 		break;
386 
387 	case MAC_STAT_OERRORS:
388 		e1000g_ksp->Ecol.value.ul +=
389 		    E1000_READ_REG(hw, E1000_ECOL);
390 		*val = e1000g_ksp->Ecol.value.ul;
391 		break;
392 
393 	case MAC_STAT_COLLISIONS:
394 		e1000g_ksp->Colc.value.ul +=
395 		    E1000_READ_REG(hw, E1000_COLC);
396 		*val = e1000g_ksp->Colc.value.ul;
397 		break;
398 
399 	case MAC_STAT_RBYTES:
400 		/*
401 		 * The 64-bit register will reset whenever the upper
402 		 * 32 bits are read. So we need to read the lower
403 		 * 32 bits first, then read the upper 32 bits.
404 		 */
405 		low_val = E1000_READ_REG(hw, E1000_TORL);
406 		high_val = E1000_READ_REG(hw, E1000_TORH);
407 		*val = (uint64_t)e1000g_ksp->Torh.value.ul << 32 |
408 		    (uint64_t)e1000g_ksp->Torl.value.ul;
409 		*val += (uint64_t)high_val << 32 | (uint64_t)low_val;
410 
411 		e1000g_ksp->Torl.value.ul = (uint32_t)*val;
412 		e1000g_ksp->Torh.value.ul = (uint32_t)(*val >> 32);
413 		break;
414 
415 	case MAC_STAT_IPACKETS:
416 		e1000g_ksp->Tpr.value.ul +=
417 		    E1000_READ_REG(hw, E1000_TPR);
418 		*val = e1000g_ksp->Tpr.value.ul;
419 		break;
420 
421 	case MAC_STAT_OBYTES:
422 		/*
423 		 * The 64-bit register will reset whenever the upper
424 		 * 32 bits are read. So we need to read the lower
425 		 * 32 bits first, then read the upper 32 bits.
426 		 */
427 		low_val = E1000_READ_REG(hw, E1000_TOTL);
428 		high_val = E1000_READ_REG(hw, E1000_TOTH);
429 		*val = (uint64_t)e1000g_ksp->Toth.value.ul << 32 |
430 		    (uint64_t)e1000g_ksp->Totl.value.ul;
431 		*val += (uint64_t)high_val << 32 | (uint64_t)low_val;
432 
433 		e1000g_ksp->Totl.value.ul = (uint32_t)*val;
434 		e1000g_ksp->Toth.value.ul = (uint32_t)(*val >> 32);
435 		break;
436 
437 	case MAC_STAT_OPACKETS:
438 		e1000g_ksp->Tpt.value.ul +=
439 		    E1000_READ_REG(hw, E1000_TPT);
440 		*val = e1000g_ksp->Tpt.value.ul;
441 		break;
442 
443 	case ETHER_STAT_ALIGN_ERRORS:
444 		e1000g_ksp->Algnerrc.value.ul +=
445 		    E1000_READ_REG(hw, E1000_ALGNERRC);
446 		*val = e1000g_ksp->Algnerrc.value.ul;
447 		break;
448 
449 	case ETHER_STAT_FCS_ERRORS:
450 		e1000g_ksp->Crcerrs.value.ul +=
451 		    E1000_READ_REG(hw, E1000_CRCERRS);
452 		*val = e1000g_ksp->Crcerrs.value.ul;
453 		break;
454 
455 	case ETHER_STAT_SQE_ERRORS:
456 		e1000g_ksp->Sec.value.ul +=
457 		    E1000_READ_REG(hw, E1000_SEC);
458 		*val = e1000g_ksp->Sec.value.ul;
459 		break;
460 
461 	case ETHER_STAT_CARRIER_ERRORS:
462 		e1000g_ksp->Cexterr.value.ul +=
463 		    E1000_READ_REG(hw, E1000_CEXTERR);
464 		*val = e1000g_ksp->Cexterr.value.ul;
465 		break;
466 
467 	case ETHER_STAT_EX_COLLISIONS:
468 		e1000g_ksp->Ecol.value.ul +=
469 		    E1000_READ_REG(hw, E1000_ECOL);
470 		*val = e1000g_ksp->Ecol.value.ul;
471 		break;
472 
473 	case ETHER_STAT_TX_LATE_COLLISIONS:
474 		e1000g_ksp->Latecol.value.ul +=
475 		    E1000_READ_REG(hw, E1000_LATECOL);
476 		*val = e1000g_ksp->Latecol.value.ul;
477 		break;
478 
479 	case ETHER_STAT_DEFER_XMTS:
480 		e1000g_ksp->Dc.value.ul +=
481 		    E1000_READ_REG(hw, E1000_DC);
482 		*val = e1000g_ksp->Dc.value.ul;
483 		break;
484 
485 	case ETHER_STAT_FIRST_COLLISIONS:
486 		e1000g_ksp->Scc.value.ul +=
487 		    E1000_READ_REG(hw, E1000_SCC);
488 		*val = e1000g_ksp->Scc.value.ul;
489 		break;
490 
491 	case ETHER_STAT_MULTI_COLLISIONS:
492 		e1000g_ksp->Mcc.value.ul +=
493 		    E1000_READ_REG(hw, E1000_MCC);
494 		*val = e1000g_ksp->Mcc.value.ul;
495 		break;
496 
497 	case ETHER_STAT_MACRCV_ERRORS:
498 		e1000g_ksp->Rxerrc.value.ul +=
499 		    E1000_READ_REG(hw, E1000_RXERRC);
500 		*val = e1000g_ksp->Rxerrc.value.ul;
501 		break;
502 
503 	case ETHER_STAT_MACXMT_ERRORS:
504 		e1000g_ksp->Ecol.value.ul +=
505 		    E1000_READ_REG(hw, E1000_ECOL);
506 		*val = e1000g_ksp->Ecol.value.ul;
507 		break;
508 
509 	case ETHER_STAT_TOOLONG_ERRORS:
510 		e1000g_ksp->Roc.value.ul +=
511 		    E1000_READ_REG(hw, E1000_ROC);
512 		*val = e1000g_ksp->Roc.value.ul;
513 		break;
514 
515 	case ETHER_STAT_XCVR_ADDR:
516 		/* The Internal PHY's MDI address for each MAC is 1 */
517 		*val = 1;
518 		break;
519 
520 	case ETHER_STAT_XCVR_ID:
521 		*val = hw->phy.id | hw->phy.revision;
522 		break;
523 
524 	case ETHER_STAT_XCVR_INUSE:
525 		switch (Adapter->link_speed) {
526 		case SPEED_1000:
527 			*val =
528 			    (hw->phy.media_type == e1000_media_type_copper) ?
529 			    XCVR_1000T : XCVR_1000X;
530 			break;
531 		case SPEED_100:
532 			*val =
533 			    (hw->phy.media_type == e1000_media_type_copper) ?
534 			    (Adapter->phy_status & MII_SR_100T4_CAPS) ?
535 			    XCVR_100T4 : XCVR_100T2 : XCVR_100X;
536 			break;
537 		case SPEED_10:
538 			*val = XCVR_10;
539 			break;
540 		default:
541 			*val = XCVR_NONE;
542 			break;
543 		}
544 		break;
545 
546 	case ETHER_STAT_CAP_1000FDX:
547 		*val = Adapter->param_1000fdx_cap;
548 		break;
549 
550 	case ETHER_STAT_CAP_1000HDX:
551 		*val = Adapter->param_1000hdx_cap;
552 		break;
553 
554 	case ETHER_STAT_CAP_100FDX:
555 		*val = Adapter->param_100fdx_cap;
556 		break;
557 
558 	case ETHER_STAT_CAP_100HDX:
559 		*val = Adapter->param_100hdx_cap;
560 		break;
561 
562 	case ETHER_STAT_CAP_10FDX:
563 		*val = Adapter->param_10fdx_cap;
564 		break;
565 
566 	case ETHER_STAT_CAP_10HDX:
567 		*val = Adapter->param_10hdx_cap;
568 		break;
569 
570 	case ETHER_STAT_CAP_ASMPAUSE:
571 		*val = Adapter->param_asym_pause_cap;
572 		break;
573 
574 	case ETHER_STAT_CAP_PAUSE:
575 		*val = Adapter->param_pause_cap;
576 		break;
577 
578 	case ETHER_STAT_CAP_AUTONEG:
579 		*val = Adapter->param_autoneg_cap;
580 		break;
581 
582 	case ETHER_STAT_ADV_CAP_1000FDX:
583 		*val = Adapter->param_adv_1000fdx;
584 		break;
585 
586 	case ETHER_STAT_ADV_CAP_1000HDX:
587 		*val = Adapter->param_adv_1000hdx;
588 		break;
589 
590 	case ETHER_STAT_ADV_CAP_100FDX:
591 		*val = Adapter->param_adv_100fdx;
592 		break;
593 
594 	case ETHER_STAT_ADV_CAP_100HDX:
595 		*val = Adapter->param_adv_100hdx;
596 		break;
597 
598 	case ETHER_STAT_ADV_CAP_10FDX:
599 		*val = Adapter->param_adv_10fdx;
600 		break;
601 
602 	case ETHER_STAT_ADV_CAP_10HDX:
603 		*val = Adapter->param_adv_10hdx;
604 		break;
605 
606 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
607 		*val = Adapter->param_adv_asym_pause;
608 		break;
609 
610 	case ETHER_STAT_ADV_CAP_PAUSE:
611 		*val = Adapter->param_adv_pause;
612 		break;
613 
614 	case ETHER_STAT_ADV_CAP_AUTONEG:
615 		*val = hw->mac.autoneg;
616 		break;
617 
618 	case ETHER_STAT_LP_CAP_1000FDX:
619 		*val = Adapter->param_lp_1000fdx;
620 		break;
621 
622 	case ETHER_STAT_LP_CAP_1000HDX:
623 		*val = Adapter->param_lp_1000hdx;
624 		break;
625 
626 	case ETHER_STAT_LP_CAP_100FDX:
627 		*val = Adapter->param_lp_100fdx;
628 		break;
629 
630 	case ETHER_STAT_LP_CAP_100HDX:
631 		*val = Adapter->param_lp_100hdx;
632 		break;
633 
634 	case ETHER_STAT_LP_CAP_10FDX:
635 		*val = Adapter->param_lp_10fdx;
636 		break;
637 
638 	case ETHER_STAT_LP_CAP_10HDX:
639 		*val = Adapter->param_lp_10hdx;
640 		break;
641 
642 	case ETHER_STAT_LP_CAP_ASMPAUSE:
643 		*val = Adapter->param_lp_asym_pause;
644 		break;
645 
646 	case ETHER_STAT_LP_CAP_PAUSE:
647 		*val = Adapter->param_lp_pause;
648 		break;
649 
650 	case ETHER_STAT_LP_CAP_AUTONEG:
651 		*val = Adapter->param_lp_autoneg;
652 		break;
653 
654 	case ETHER_STAT_LINK_ASMPAUSE:
655 		*val = Adapter->param_asym_pause_cap;
656 		break;
657 
658 	case ETHER_STAT_LINK_PAUSE:
659 		*val = Adapter->param_pause_cap;
660 		break;
661 
662 	case ETHER_STAT_LINK_AUTONEG:
663 		*val = hw->mac.autoneg;
664 		break;
665 
666 	case ETHER_STAT_LINK_DUPLEX:
667 		*val = (Adapter->link_duplex == FULL_DUPLEX) ?
668 		    LINK_DUPLEX_FULL : LINK_DUPLEX_HALF;
669 		break;
670 
671 	case ETHER_STAT_CAP_100T4:
672 		*val = Adapter->param_100t4_cap;
673 		break;
674 
675 	case ETHER_STAT_ADV_CAP_100T4:
676 		*val = Adapter->param_adv_100t4;
677 		break;
678 
679 	case ETHER_STAT_LP_CAP_100T4:
680 		*val = Adapter->param_lp_100t4;
681 		break;
682 
683 	default:
684 		rw_exit(&Adapter->chip_lock);
685 		return (ENOTSUP);
686 	}
687 
688 	rw_exit(&Adapter->chip_lock);
689 
690 	if (e1000g_check_acc_handle(Adapter->osdep.reg_handle) != DDI_FM_OK)
691 		ddi_fm_service_impact(Adapter->dip, DDI_SERVICE_UNAFFECTED);
692 
693 	return (0);
694 }
695 
696 /*
697  * e1000g_init_stats - initialize kstat data structures
698  *
699  * This routine will create and initialize the driver private
700  * statistics counters.
701  */
702 int
703 e1000g_init_stats(struct e1000g *Adapter)
704 {
705 	kstat_t *ksp;
706 	p_e1000g_stat_t e1000g_ksp;
707 
708 	/*
709 	 * Create and init kstat
710 	 */
711 	ksp = kstat_create(WSNAME, ddi_get_instance(Adapter->dip),
712 	    "statistics", "net", KSTAT_TYPE_NAMED,
713 	    sizeof (e1000g_stat_t) / sizeof (kstat_named_t), 0);
714 
715 	if (ksp == NULL) {
716 		e1000g_log(Adapter, CE_WARN,
717 		    "Could not create kernel statistics\n");
718 		return (DDI_FAILURE);
719 	}
720 
721 	Adapter->e1000g_ksp = ksp;	/* Fill in the Adapters ksp */
722 
723 	e1000g_ksp = (p_e1000g_stat_t)ksp->ks_data;
724 
725 	/*
726 	 * Initialize all the statistics
727 	 */
728 	kstat_named_init(&e1000g_ksp->link_speed, "link_speed",
729 	    KSTAT_DATA_ULONG);
730 	kstat_named_init(&e1000g_ksp->reset_count, "Reset Count",
731 	    KSTAT_DATA_ULONG);
732 
733 	kstat_named_init(&e1000g_ksp->rx_error, "Rx Error",
734 	    KSTAT_DATA_ULONG);
735 	kstat_named_init(&e1000g_ksp->rx_allocb_fail, "Rx Allocb Failure",
736 	    KSTAT_DATA_ULONG);
737 
738 	kstat_named_init(&e1000g_ksp->tx_no_desc, "Tx No Desc",
739 	    KSTAT_DATA_ULONG);
740 	kstat_named_init(&e1000g_ksp->tx_no_swpkt, "Tx No Buffer",
741 	    KSTAT_DATA_ULONG);
742 	kstat_named_init(&e1000g_ksp->tx_send_fail, "Tx Send Failure",
743 	    KSTAT_DATA_ULONG);
744 	kstat_named_init(&e1000g_ksp->tx_over_size, "Tx Pkt Over Size",
745 	    KSTAT_DATA_ULONG);
746 	kstat_named_init(&e1000g_ksp->tx_reschedule, "Tx Reschedule",
747 	    KSTAT_DATA_ULONG);
748 
749 	kstat_named_init(&e1000g_ksp->Mpc, "Recv_Missed_Packets",
750 	    KSTAT_DATA_ULONG);
751 	kstat_named_init(&e1000g_ksp->Symerrs, "Recv_Symbol_Errors",
752 	    KSTAT_DATA_ULONG);
753 	kstat_named_init(&e1000g_ksp->Rlec, "Recv_Length_Errors",
754 	    KSTAT_DATA_ULONG);
755 	kstat_named_init(&e1000g_ksp->Xonrxc, "XONs_Recvd",
756 	    KSTAT_DATA_ULONG);
757 	kstat_named_init(&e1000g_ksp->Xontxc, "XONs_Xmitd",
758 	    KSTAT_DATA_ULONG);
759 	kstat_named_init(&e1000g_ksp->Xoffrxc, "XOFFs_Recvd",
760 	    KSTAT_DATA_ULONG);
761 	kstat_named_init(&e1000g_ksp->Xofftxc, "XOFFs_Xmitd",
762 	    KSTAT_DATA_ULONG);
763 	kstat_named_init(&e1000g_ksp->Fcruc, "Recv_Unsupport_FC_Pkts",
764 	    KSTAT_DATA_ULONG);
765 #ifdef E1000G_DEBUG
766 	kstat_named_init(&e1000g_ksp->Prc64, "Pkts_Recvd_(  64b)",
767 	    KSTAT_DATA_ULONG);
768 	kstat_named_init(&e1000g_ksp->Prc127, "Pkts_Recvd_(  65- 127b)",
769 	    KSTAT_DATA_ULONG);
770 	kstat_named_init(&e1000g_ksp->Prc255, "Pkts_Recvd_( 127- 255b)",
771 	    KSTAT_DATA_ULONG);
772 	kstat_named_init(&e1000g_ksp->Prc511, "Pkts_Recvd_( 256- 511b)",
773 	    KSTAT_DATA_ULONG);
774 	kstat_named_init(&e1000g_ksp->Prc1023, "Pkts_Recvd_( 511-1023b)",
775 	    KSTAT_DATA_ULONG);
776 	kstat_named_init(&e1000g_ksp->Prc1522, "Pkts_Recvd_(1024-1522b)",
777 	    KSTAT_DATA_ULONG);
778 #endif
779 	kstat_named_init(&e1000g_ksp->Gprc, "Good_Pkts_Recvd",
780 	    KSTAT_DATA_ULONG);
781 	kstat_named_init(&e1000g_ksp->Gptc, "Good_Pkts_Xmitd",
782 	    KSTAT_DATA_ULONG);
783 	kstat_named_init(&e1000g_ksp->Gorl, "Good_Octets_Recvd_Lo",
784 	    KSTAT_DATA_ULONG);
785 	kstat_named_init(&e1000g_ksp->Gorh, "Good_Octets_Recvd_Hi",
786 	    KSTAT_DATA_ULONG);
787 	kstat_named_init(&e1000g_ksp->Gotl, "Good_Octets_Xmitd_Lo",
788 	    KSTAT_DATA_ULONG);
789 	kstat_named_init(&e1000g_ksp->Goth, "Good_Octets_Xmitd_Hi",
790 	    KSTAT_DATA_ULONG);
791 	kstat_named_init(&e1000g_ksp->Ruc, "Recv_Undersize",
792 	    KSTAT_DATA_ULONG);
793 	kstat_named_init(&e1000g_ksp->Rfc, "Recv_Frag",
794 	    KSTAT_DATA_ULONG);
795 	kstat_named_init(&e1000g_ksp->Roc, "Recv_Oversize",
796 	    KSTAT_DATA_ULONG);
797 	kstat_named_init(&e1000g_ksp->Rjc, "Recv_Jabber",
798 	    KSTAT_DATA_ULONG);
799 	kstat_named_init(&e1000g_ksp->Torl, "Total_Octets_Recvd_Lo",
800 	    KSTAT_DATA_ULONG);
801 	kstat_named_init(&e1000g_ksp->Torh, "Total_Octets_Recvd_Hi",
802 	    KSTAT_DATA_ULONG);
803 	kstat_named_init(&e1000g_ksp->Totl, "Total_Octets_Xmitd_Lo",
804 	    KSTAT_DATA_ULONG);
805 	kstat_named_init(&e1000g_ksp->Toth, "Total_Octets_Xmitd_Hi",
806 	    KSTAT_DATA_ULONG);
807 	kstat_named_init(&e1000g_ksp->Tpr, "Total_Packets_Recvd",
808 	    KSTAT_DATA_ULONG);
809 	kstat_named_init(&e1000g_ksp->Tpt, "Total_Packets_Xmitd",
810 	    KSTAT_DATA_ULONG);
811 #ifdef E1000G_DEBUG
812 	kstat_named_init(&e1000g_ksp->Ptc64, "Pkts_Xmitd_(  64b)",
813 	    KSTAT_DATA_ULONG);
814 	kstat_named_init(&e1000g_ksp->Ptc127, "Pkts_Xmitd_(  65- 127b)",
815 	    KSTAT_DATA_ULONG);
816 	kstat_named_init(&e1000g_ksp->Ptc255, "Pkts_Xmitd_( 128- 255b)",
817 	    KSTAT_DATA_ULONG);
818 	kstat_named_init(&e1000g_ksp->Ptc511, "Pkts_Xmitd_( 255- 511b)",
819 	    KSTAT_DATA_ULONG);
820 	kstat_named_init(&e1000g_ksp->Ptc1023, "Pkts_Xmitd_( 512-1023b)",
821 	    KSTAT_DATA_ULONG);
822 	kstat_named_init(&e1000g_ksp->Ptc1522, "Pkts_Xmitd_(1024-1522b)",
823 	    KSTAT_DATA_ULONG);
824 #endif
825 	kstat_named_init(&e1000g_ksp->Tncrs, "Xmit_with_No_CRS",
826 	    KSTAT_DATA_ULONG);
827 	kstat_named_init(&e1000g_ksp->Tsctc, "Xmit_TCP_Seg_Contexts",
828 	    KSTAT_DATA_ULONG);
829 	kstat_named_init(&e1000g_ksp->Tsctfc, "Xmit_TCP_Seg_Contexts_Fail",
830 	    KSTAT_DATA_ULONG);
831 
832 #ifdef E1000G_DEBUG
833 	kstat_named_init(&e1000g_ksp->rx_none, "Rx No Data",
834 	    KSTAT_DATA_ULONG);
835 	kstat_named_init(&e1000g_ksp->rx_multi_desc, "Rx Span Multi Desc",
836 	    KSTAT_DATA_ULONG);
837 	kstat_named_init(&e1000g_ksp->rx_no_freepkt, "Rx Freelist Empty",
838 	    KSTAT_DATA_ULONG);
839 	kstat_named_init(&e1000g_ksp->rx_avail_freepkt, "Rx Freelist Avail",
840 	    KSTAT_DATA_ULONG);
841 
842 	kstat_named_init(&e1000g_ksp->tx_under_size, "Tx Pkt Under Size",
843 	    KSTAT_DATA_ULONG);
844 	kstat_named_init(&e1000g_ksp->tx_exceed_frags, "Tx Exceed Max Frags",
845 	    KSTAT_DATA_ULONG);
846 	kstat_named_init(&e1000g_ksp->tx_empty_frags, "Tx Empty Frags",
847 	    KSTAT_DATA_ULONG);
848 	kstat_named_init(&e1000g_ksp->tx_recycle, "Tx Recycle",
849 	    KSTAT_DATA_ULONG);
850 	kstat_named_init(&e1000g_ksp->tx_recycle_intr, "Tx Recycle Intr",
851 	    KSTAT_DATA_ULONG);
852 	kstat_named_init(&e1000g_ksp->tx_recycle_retry, "Tx Recycle Retry",
853 	    KSTAT_DATA_ULONG);
854 	kstat_named_init(&e1000g_ksp->tx_recycle_none, "Tx Recycled None",
855 	    KSTAT_DATA_ULONG);
856 	kstat_named_init(&e1000g_ksp->tx_copy, "Tx Send Copy",
857 	    KSTAT_DATA_ULONG);
858 	kstat_named_init(&e1000g_ksp->tx_bind, "Tx Send Bind",
859 	    KSTAT_DATA_ULONG);
860 	kstat_named_init(&e1000g_ksp->tx_multi_copy, "Tx Copy Multi Frags",
861 	    KSTAT_DATA_ULONG);
862 	kstat_named_init(&e1000g_ksp->tx_multi_cookie, "Tx Bind Multi Cookies",
863 	    KSTAT_DATA_ULONG);
864 	kstat_named_init(&e1000g_ksp->tx_lack_desc, "Tx Desc Insufficient",
865 	    KSTAT_DATA_ULONG);
866 #endif
867 
868 	/*
869 	 * Function to provide kernel stat update on demand
870 	 */
871 	ksp->ks_update = e1000g_update_stats;
872 
873 	/*
874 	 * Pointer into provider's raw statistics
875 	 */
876 	ksp->ks_private = (void *)Adapter;
877 
878 	/*
879 	 * Add kstat to systems kstat chain
880 	 */
881 	kstat_install(ksp);
882 
883 	return (DDI_SUCCESS);
884 }
885