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