xref: /titanic_44/usr/src/uts/common/io/e1000g/e1000g_stat.c (revision 2b4a78020b9c38d1b95e2f3fefa6d6e4be382d1f)
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 /*
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 	uint64_t val;
155 	uint32_t low_val, high_val;
156 
157 	if (rw == KSTAT_WRITE)
158 		return (EACCES);
159 
160 	Adapter = (struct e1000g *)ksp->ks_private;
161 	ASSERT(Adapter != NULL);
162 	e1000g_ksp = (p_e1000g_stat_t)ksp->ks_data;
163 	ASSERT(e1000g_ksp != NULL);
164 	hw = &Adapter->shared;
165 
166 	tx_ring = Adapter->tx_ring;
167 	rx_ring = Adapter->rx_ring;
168 
169 	rw_enter(&Adapter->chip_lock, RW_WRITER);
170 
171 	e1000g_ksp->link_speed.value.ul = Adapter->link_speed;
172 	e1000g_ksp->reset_count.value.ul = Adapter->reset_count;
173 
174 	e1000g_ksp->rx_error.value.ul = rx_ring->stat_error;
175 	e1000g_ksp->rx_esballoc_fail.value.ul = rx_ring->stat_esballoc_fail;
176 	e1000g_ksp->rx_allocb_fail.value.ul = rx_ring->stat_allocb_fail;
177 
178 	e1000g_ksp->tx_no_swpkt.value.ul = tx_ring->stat_no_swpkt;
179 	e1000g_ksp->tx_no_desc.value.ul = tx_ring->stat_no_desc;
180 	e1000g_ksp->tx_send_fail.value.ul = tx_ring->stat_send_fail;
181 	e1000g_ksp->tx_reschedule.value.ul = tx_ring->stat_reschedule;
182 	e1000g_ksp->tx_over_size.value.ul = tx_ring->stat_over_size;
183 
184 #ifdef E1000G_DEBUG
185 	e1000g_ksp->rx_none.value.ul = rx_ring->stat_none;
186 	e1000g_ksp->rx_multi_desc.value.ul = rx_ring->stat_multi_desc;
187 	e1000g_ksp->rx_no_freepkt.value.ul = rx_ring->stat_no_freepkt;
188 	e1000g_ksp->rx_avail_freepkt.value.ul = rx_ring->avail_freepkt;
189 
190 	e1000g_ksp->tx_under_size.value.ul = tx_ring->stat_under_size;
191 	e1000g_ksp->tx_exceed_frags.value.ul = tx_ring->stat_exceed_frags;
192 	e1000g_ksp->tx_empty_frags.value.ul = tx_ring->stat_empty_frags;
193 	e1000g_ksp->tx_recycle.value.ul = tx_ring->stat_recycle;
194 	e1000g_ksp->tx_recycle_intr.value.ul = tx_ring->stat_recycle_intr;
195 	e1000g_ksp->tx_recycle_retry.value.ul = tx_ring->stat_recycle_retry;
196 	e1000g_ksp->tx_recycle_none.value.ul = tx_ring->stat_recycle_none;
197 	e1000g_ksp->tx_copy.value.ul = tx_ring->stat_copy;
198 	e1000g_ksp->tx_bind.value.ul = tx_ring->stat_bind;
199 	e1000g_ksp->tx_multi_copy.value.ul = tx_ring->stat_multi_copy;
200 	e1000g_ksp->tx_multi_cookie.value.ul = tx_ring->stat_multi_cookie;
201 	e1000g_ksp->tx_lack_desc.value.ul = tx_ring->stat_lack_desc;
202 #endif
203 
204 	/*
205 	 * Standard Stats
206 	 */
207 	e1000g_ksp->Mpc.value.ul += E1000_READ_REG(hw, E1000_MPC);
208 	e1000g_ksp->Rlec.value.ul += E1000_READ_REG(hw, E1000_RLEC);
209 	e1000g_ksp->Xonrxc.value.ul += E1000_READ_REG(hw, E1000_XONRXC);
210 	e1000g_ksp->Xontxc.value.ul += E1000_READ_REG(hw, E1000_XONTXC);
211 	e1000g_ksp->Xoffrxc.value.ul += E1000_READ_REG(hw, E1000_XOFFRXC);
212 	e1000g_ksp->Xofftxc.value.ul += E1000_READ_REG(hw, E1000_XOFFTXC);
213 	e1000g_ksp->Fcruc.value.ul += E1000_READ_REG(hw, E1000_FCRUC);
214 
215 	if ((hw->mac.type != e1000_ich8lan) &&
216 	    (hw->mac.type != e1000_ich9lan) &&
217 	    (hw->mac.type != e1000_ich10lan)) {
218 		e1000g_ksp->Symerrs.value.ul +=
219 		    E1000_READ_REG(hw, E1000_SYMERRS);
220 #ifdef E1000G_DEBUG
221 		e1000g_ksp->Prc64.value.ul +=
222 		    E1000_READ_REG(hw, E1000_PRC64);
223 		e1000g_ksp->Prc127.value.ul +=
224 		    E1000_READ_REG(hw, E1000_PRC127);
225 		e1000g_ksp->Prc255.value.ul +=
226 		    E1000_READ_REG(hw, E1000_PRC255);
227 		e1000g_ksp->Prc511.value.ul +=
228 		    E1000_READ_REG(hw, E1000_PRC511);
229 		e1000g_ksp->Prc1023.value.ul +=
230 		    E1000_READ_REG(hw, E1000_PRC1023);
231 		e1000g_ksp->Prc1522.value.ul +=
232 		    E1000_READ_REG(hw, E1000_PRC1522);
233 
234 		e1000g_ksp->Ptc64.value.ul +=
235 		    E1000_READ_REG(hw, E1000_PTC64);
236 		e1000g_ksp->Ptc127.value.ul +=
237 		    E1000_READ_REG(hw, E1000_PTC127);
238 		e1000g_ksp->Ptc255.value.ul +=
239 		    E1000_READ_REG(hw, E1000_PTC255);
240 		e1000g_ksp->Ptc511.value.ul +=
241 		    E1000_READ_REG(hw, E1000_PTC511);
242 		e1000g_ksp->Ptc1023.value.ul +=
243 		    E1000_READ_REG(hw, E1000_PTC1023);
244 		e1000g_ksp->Ptc1522.value.ul +=
245 		    E1000_READ_REG(hw, E1000_PTC1522);
246 #endif
247 	}
248 
249 	e1000g_ksp->Gprc.value.ul += E1000_READ_REG(hw, E1000_GPRC);
250 	e1000g_ksp->Gptc.value.ul += E1000_READ_REG(hw, E1000_GPTC);
251 	e1000g_ksp->Ruc.value.ul += E1000_READ_REG(hw, E1000_RUC);
252 	e1000g_ksp->Rfc.value.ul += E1000_READ_REG(hw, E1000_RFC);
253 	e1000g_ksp->Roc.value.ul += E1000_READ_REG(hw, E1000_ROC);
254 	e1000g_ksp->Rjc.value.ul += E1000_READ_REG(hw, E1000_RJC);
255 	e1000g_ksp->Tpr.value.ul += E1000_READ_REG(hw, E1000_TPR);
256 	e1000g_ksp->Tncrs.value.ul += E1000_READ_REG(hw, E1000_TNCRS);
257 	e1000g_ksp->Tsctc.value.ul += E1000_READ_REG(hw, E1000_TSCTC);
258 	e1000g_ksp->Tsctfc.value.ul += E1000_READ_REG(hw, E1000_TSCTFC);
259 
260 	/*
261 	 * Adaptive Calculations
262 	 */
263 	hw->mac.tx_packet_delta = E1000_READ_REG(hw, E1000_TPT);
264 	e1000g_ksp->Tpt.value.ul += hw->mac.tx_packet_delta;
265 
266 	/*
267 	 * The 64-bit register will reset whenever the upper
268 	 * 32 bits are read. So we need to read the lower
269 	 * 32 bits first, then read the upper 32 bits.
270 	 */
271 	low_val = E1000_READ_REG(hw, E1000_GORCL);
272 	high_val = E1000_READ_REG(hw, E1000_GORCH);
273 	val = (uint64_t)e1000g_ksp->Gorh.value.ul << 32 |
274 	    (uint64_t)e1000g_ksp->Gorl.value.ul;
275 	val += (uint64_t)high_val << 32 | (uint64_t)low_val;
276 	e1000g_ksp->Gorl.value.ul = (uint32_t)val;
277 	e1000g_ksp->Gorh.value.ul = (uint32_t)(val >> 32);
278 
279 	low_val = E1000_READ_REG(hw, E1000_GOTCL);
280 	high_val = E1000_READ_REG(hw, E1000_GOTCH);
281 	val = (uint64_t)e1000g_ksp->Goth.value.ul << 32 |
282 	    (uint64_t)e1000g_ksp->Gotl.value.ul;
283 	val += (uint64_t)high_val << 32 | (uint64_t)low_val;
284 	e1000g_ksp->Gotl.value.ul = (uint32_t)val;
285 	e1000g_ksp->Goth.value.ul = (uint32_t)(val >> 32);
286 
287 	low_val = E1000_READ_REG(hw, E1000_TORL);
288 	high_val = E1000_READ_REG(hw, E1000_TORH);
289 	val = (uint64_t)e1000g_ksp->Torh.value.ul << 32 |
290 	    (uint64_t)e1000g_ksp->Torl.value.ul;
291 	val += (uint64_t)high_val << 32 | (uint64_t)low_val;
292 	e1000g_ksp->Torl.value.ul = (uint32_t)val;
293 	e1000g_ksp->Torh.value.ul = (uint32_t)(val >> 32);
294 
295 	low_val = E1000_READ_REG(hw, E1000_TOTL);
296 	high_val = E1000_READ_REG(hw, E1000_TOTH);
297 	val = (uint64_t)e1000g_ksp->Toth.value.ul << 32 |
298 	    (uint64_t)e1000g_ksp->Totl.value.ul;
299 	val += (uint64_t)high_val << 32 | (uint64_t)low_val;
300 	e1000g_ksp->Totl.value.ul = (uint32_t)val;
301 	e1000g_ksp->Toth.value.ul = (uint32_t)(val >> 32);
302 
303 	rw_exit(&Adapter->chip_lock);
304 
305 	if (e1000g_check_acc_handle(Adapter->osdep.reg_handle) != DDI_FM_OK)
306 		ddi_fm_service_impact(Adapter->dip, DDI_SERVICE_UNAFFECTED);
307 
308 	return (0);
309 }
310 
311 int
312 e1000g_m_stat(void *arg, uint_t stat, uint64_t *val)
313 {
314 	struct e1000g *Adapter = (struct e1000g *)arg;
315 	struct e1000_hw *hw = &Adapter->shared;
316 	p_e1000g_stat_t e1000g_ksp;
317 	uint32_t low_val, high_val;
318 
319 	e1000g_ksp = (p_e1000g_stat_t)Adapter->e1000g_ksp->ks_data;
320 
321 	rw_enter(&Adapter->chip_lock, RW_READER);
322 
323 	switch (stat) {
324 	case MAC_STAT_IFSPEED:
325 		*val = Adapter->link_speed * 1000000ull;
326 		break;
327 
328 	case MAC_STAT_MULTIRCV:
329 		e1000g_ksp->Mprc.value.ul +=
330 		    E1000_READ_REG(hw, E1000_MPRC);
331 		*val = e1000g_ksp->Mprc.value.ul;
332 		break;
333 
334 	case MAC_STAT_BRDCSTRCV:
335 		e1000g_ksp->Bprc.value.ul +=
336 		    E1000_READ_REG(hw, E1000_BPRC);
337 		*val = e1000g_ksp->Bprc.value.ul;
338 		break;
339 
340 	case MAC_STAT_MULTIXMT:
341 		e1000g_ksp->Mptc.value.ul +=
342 		    E1000_READ_REG(hw, E1000_MPTC);
343 		*val = e1000g_ksp->Mptc.value.ul;
344 		break;
345 
346 	case MAC_STAT_BRDCSTXMT:
347 		e1000g_ksp->Bptc.value.ul +=
348 		    E1000_READ_REG(hw, E1000_BPTC);
349 		*val = e1000g_ksp->Bptc.value.ul;
350 		break;
351 
352 	case MAC_STAT_NORCVBUF:
353 		e1000g_ksp->Rnbc.value.ul +=
354 		    E1000_READ_REG(hw, E1000_RNBC);
355 		*val = e1000g_ksp->Rnbc.value.ul;
356 		break;
357 
358 	case MAC_STAT_IERRORS:
359 		e1000g_ksp->Rxerrc.value.ul +=
360 		    E1000_READ_REG(hw, E1000_RXERRC);
361 		e1000g_ksp->Algnerrc.value.ul +=
362 		    E1000_READ_REG(hw, E1000_ALGNERRC);
363 		e1000g_ksp->Rlec.value.ul +=
364 		    E1000_READ_REG(hw, E1000_RLEC);
365 		e1000g_ksp->Crcerrs.value.ul +=
366 		    E1000_READ_REG(hw, E1000_CRCERRS);
367 		e1000g_ksp->Cexterr.value.ul +=
368 		    E1000_READ_REG(hw, E1000_CEXTERR);
369 		*val = e1000g_ksp->Rxerrc.value.ul +
370 		    e1000g_ksp->Algnerrc.value.ul +
371 		    e1000g_ksp->Rlec.value.ul +
372 		    e1000g_ksp->Crcerrs.value.ul +
373 		    e1000g_ksp->Cexterr.value.ul;
374 		break;
375 
376 	case MAC_STAT_NOXMTBUF:
377 		*val = Adapter->tx_ring->stat_no_desc;
378 		break;
379 
380 	case MAC_STAT_OERRORS:
381 		e1000g_ksp->Ecol.value.ul +=
382 		    E1000_READ_REG(hw, E1000_ECOL);
383 		*val = e1000g_ksp->Ecol.value.ul;
384 		break;
385 
386 	case MAC_STAT_COLLISIONS:
387 		e1000g_ksp->Colc.value.ul +=
388 		    E1000_READ_REG(hw, E1000_COLC);
389 		*val = e1000g_ksp->Colc.value.ul;
390 		break;
391 
392 	case MAC_STAT_RBYTES:
393 		/*
394 		 * The 64-bit register will reset whenever the upper
395 		 * 32 bits are read. So we need to read the lower
396 		 * 32 bits first, then read the upper 32 bits.
397 		 */
398 		low_val = E1000_READ_REG(hw, E1000_TORL);
399 		high_val = E1000_READ_REG(hw, E1000_TORH);
400 		*val = (uint64_t)e1000g_ksp->Torh.value.ul << 32 |
401 		    (uint64_t)e1000g_ksp->Torl.value.ul;
402 		*val += (uint64_t)high_val << 32 | (uint64_t)low_val;
403 
404 		e1000g_ksp->Torl.value.ul = (uint32_t)*val;
405 		e1000g_ksp->Torh.value.ul = (uint32_t)(*val >> 32);
406 		break;
407 
408 	case MAC_STAT_IPACKETS:
409 		e1000g_ksp->Tpr.value.ul +=
410 		    E1000_READ_REG(hw, E1000_TPR);
411 		*val = e1000g_ksp->Tpr.value.ul;
412 		break;
413 
414 	case MAC_STAT_OBYTES:
415 		/*
416 		 * The 64-bit register will reset whenever the upper
417 		 * 32 bits are read. So we need to read the lower
418 		 * 32 bits first, then read the upper 32 bits.
419 		 */
420 		low_val = E1000_READ_REG(hw, E1000_TOTL);
421 		high_val = E1000_READ_REG(hw, E1000_TOTH);
422 		*val = (uint64_t)e1000g_ksp->Toth.value.ul << 32 |
423 		    (uint64_t)e1000g_ksp->Totl.value.ul;
424 		*val += (uint64_t)high_val << 32 | (uint64_t)low_val;
425 
426 		e1000g_ksp->Totl.value.ul = (uint32_t)*val;
427 		e1000g_ksp->Toth.value.ul = (uint32_t)(*val >> 32);
428 		break;
429 
430 	case MAC_STAT_OPACKETS:
431 		e1000g_ksp->Tpt.value.ul +=
432 		    E1000_READ_REG(hw, E1000_TPT);
433 		*val = e1000g_ksp->Tpt.value.ul;
434 		break;
435 
436 	case ETHER_STAT_ALIGN_ERRORS:
437 		e1000g_ksp->Algnerrc.value.ul +=
438 		    E1000_READ_REG(hw, E1000_ALGNERRC);
439 		*val = e1000g_ksp->Algnerrc.value.ul;
440 		break;
441 
442 	case ETHER_STAT_FCS_ERRORS:
443 		e1000g_ksp->Crcerrs.value.ul +=
444 		    E1000_READ_REG(hw, E1000_CRCERRS);
445 		*val = e1000g_ksp->Crcerrs.value.ul;
446 		break;
447 
448 	case ETHER_STAT_SQE_ERRORS:
449 		e1000g_ksp->Sec.value.ul +=
450 		    E1000_READ_REG(hw, E1000_SEC);
451 		*val = e1000g_ksp->Sec.value.ul;
452 		break;
453 
454 	case ETHER_STAT_CARRIER_ERRORS:
455 		e1000g_ksp->Cexterr.value.ul +=
456 		    E1000_READ_REG(hw, E1000_CEXTERR);
457 		*val = e1000g_ksp->Cexterr.value.ul;
458 		break;
459 
460 	case ETHER_STAT_EX_COLLISIONS:
461 		e1000g_ksp->Ecol.value.ul +=
462 		    E1000_READ_REG(hw, E1000_ECOL);
463 		*val = e1000g_ksp->Ecol.value.ul;
464 		break;
465 
466 	case ETHER_STAT_TX_LATE_COLLISIONS:
467 		e1000g_ksp->Latecol.value.ul +=
468 		    E1000_READ_REG(hw, E1000_LATECOL);
469 		*val = e1000g_ksp->Latecol.value.ul;
470 		break;
471 
472 	case ETHER_STAT_DEFER_XMTS:
473 		e1000g_ksp->Dc.value.ul +=
474 		    E1000_READ_REG(hw, E1000_DC);
475 		*val = e1000g_ksp->Dc.value.ul;
476 		break;
477 
478 	case ETHER_STAT_FIRST_COLLISIONS:
479 		e1000g_ksp->Scc.value.ul +=
480 		    E1000_READ_REG(hw, E1000_SCC);
481 		*val = e1000g_ksp->Scc.value.ul;
482 		break;
483 
484 	case ETHER_STAT_MULTI_COLLISIONS:
485 		e1000g_ksp->Mcc.value.ul +=
486 		    E1000_READ_REG(hw, E1000_MCC);
487 		*val = e1000g_ksp->Mcc.value.ul;
488 		break;
489 
490 	case ETHER_STAT_MACRCV_ERRORS:
491 		e1000g_ksp->Rxerrc.value.ul +=
492 		    E1000_READ_REG(hw, E1000_RXERRC);
493 		*val = e1000g_ksp->Rxerrc.value.ul;
494 		break;
495 
496 	case ETHER_STAT_MACXMT_ERRORS:
497 		e1000g_ksp->Ecol.value.ul +=
498 		    E1000_READ_REG(hw, E1000_ECOL);
499 		*val = e1000g_ksp->Ecol.value.ul;
500 		break;
501 
502 	case ETHER_STAT_TOOLONG_ERRORS:
503 		e1000g_ksp->Roc.value.ul +=
504 		    E1000_READ_REG(hw, E1000_ROC);
505 		*val = e1000g_ksp->Roc.value.ul;
506 		break;
507 
508 	case ETHER_STAT_XCVR_ADDR:
509 		/* The Internal PHY's MDI address for each MAC is 1 */
510 		*val = 1;
511 		break;
512 
513 	case ETHER_STAT_XCVR_ID:
514 		*val = hw->phy.id | hw->phy.revision;
515 		break;
516 
517 	case ETHER_STAT_XCVR_INUSE:
518 		switch (Adapter->link_speed) {
519 		case SPEED_1000:
520 			*val =
521 			    (hw->phy.media_type == e1000_media_type_copper) ?
522 			    XCVR_1000T : XCVR_1000X;
523 			break;
524 		case SPEED_100:
525 			*val =
526 			    (hw->phy.media_type == e1000_media_type_copper) ?
527 			    (Adapter->phy_status & MII_SR_100T4_CAPS) ?
528 			    XCVR_100T4 : XCVR_100T2 : XCVR_100X;
529 			break;
530 		case SPEED_10:
531 			*val = XCVR_10;
532 			break;
533 		default:
534 			*val = XCVR_NONE;
535 			break;
536 		}
537 		break;
538 
539 	case ETHER_STAT_CAP_1000FDX:
540 		*val = Adapter->param_1000fdx_cap;
541 		break;
542 
543 	case ETHER_STAT_CAP_1000HDX:
544 		*val = Adapter->param_1000hdx_cap;
545 		break;
546 
547 	case ETHER_STAT_CAP_100FDX:
548 		*val = Adapter->param_100fdx_cap;
549 		break;
550 
551 	case ETHER_STAT_CAP_100HDX:
552 		*val = Adapter->param_100hdx_cap;
553 		break;
554 
555 	case ETHER_STAT_CAP_10FDX:
556 		*val = Adapter->param_10fdx_cap;
557 		break;
558 
559 	case ETHER_STAT_CAP_10HDX:
560 		*val = Adapter->param_10hdx_cap;
561 		break;
562 
563 	case ETHER_STAT_CAP_ASMPAUSE:
564 		*val = Adapter->param_asym_pause_cap;
565 		break;
566 
567 	case ETHER_STAT_CAP_PAUSE:
568 		*val = Adapter->param_pause_cap;
569 		break;
570 
571 	case ETHER_STAT_CAP_AUTONEG:
572 		*val = Adapter->param_autoneg_cap;
573 		break;
574 
575 	case ETHER_STAT_ADV_CAP_1000FDX:
576 		*val = Adapter->param_adv_1000fdx;
577 		break;
578 
579 	case ETHER_STAT_ADV_CAP_1000HDX:
580 		*val = Adapter->param_adv_1000hdx;
581 		break;
582 
583 	case ETHER_STAT_ADV_CAP_100FDX:
584 		*val = Adapter->param_adv_100fdx;
585 		break;
586 
587 	case ETHER_STAT_ADV_CAP_100HDX:
588 		*val = Adapter->param_adv_100hdx;
589 		break;
590 
591 	case ETHER_STAT_ADV_CAP_10FDX:
592 		*val = Adapter->param_adv_10fdx;
593 		break;
594 
595 	case ETHER_STAT_ADV_CAP_10HDX:
596 		*val = Adapter->param_adv_10hdx;
597 		break;
598 
599 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
600 		*val = Adapter->param_adv_asym_pause;
601 		break;
602 
603 	case ETHER_STAT_ADV_CAP_PAUSE:
604 		*val = Adapter->param_adv_pause;
605 		break;
606 
607 	case ETHER_STAT_ADV_CAP_AUTONEG:
608 		*val = hw->mac.autoneg;
609 		break;
610 
611 	case ETHER_STAT_LP_CAP_1000FDX:
612 		*val = Adapter->param_lp_1000fdx;
613 		break;
614 
615 	case ETHER_STAT_LP_CAP_1000HDX:
616 		*val = Adapter->param_lp_1000hdx;
617 		break;
618 
619 	case ETHER_STAT_LP_CAP_100FDX:
620 		*val = Adapter->param_lp_100fdx;
621 		break;
622 
623 	case ETHER_STAT_LP_CAP_100HDX:
624 		*val = Adapter->param_lp_100hdx;
625 		break;
626 
627 	case ETHER_STAT_LP_CAP_10FDX:
628 		*val = Adapter->param_lp_10fdx;
629 		break;
630 
631 	case ETHER_STAT_LP_CAP_10HDX:
632 		*val = Adapter->param_lp_10hdx;
633 		break;
634 
635 	case ETHER_STAT_LP_CAP_ASMPAUSE:
636 		*val = Adapter->param_lp_asym_pause;
637 		break;
638 
639 	case ETHER_STAT_LP_CAP_PAUSE:
640 		*val = Adapter->param_lp_pause;
641 		break;
642 
643 	case ETHER_STAT_LP_CAP_AUTONEG:
644 		*val = Adapter->param_lp_autoneg;
645 		break;
646 
647 	case ETHER_STAT_LINK_ASMPAUSE:
648 		*val = Adapter->param_asym_pause_cap;
649 		break;
650 
651 	case ETHER_STAT_LINK_PAUSE:
652 		*val = Adapter->param_pause_cap;
653 		break;
654 
655 	case ETHER_STAT_LINK_AUTONEG:
656 		*val = hw->mac.autoneg;
657 		break;
658 
659 	case ETHER_STAT_LINK_DUPLEX:
660 		*val = (Adapter->link_duplex == FULL_DUPLEX) ?
661 		    LINK_DUPLEX_FULL : LINK_DUPLEX_HALF;
662 		break;
663 
664 	case ETHER_STAT_CAP_100T4:
665 		*val = Adapter->param_100t4_cap;
666 		break;
667 
668 	case ETHER_STAT_ADV_CAP_100T4:
669 		*val = Adapter->param_adv_100t4;
670 		break;
671 
672 	case ETHER_STAT_LP_CAP_100T4:
673 		*val = Adapter->param_lp_100t4;
674 		break;
675 
676 	default:
677 		rw_exit(&Adapter->chip_lock);
678 		return (ENOTSUP);
679 	}
680 
681 	rw_exit(&Adapter->chip_lock);
682 
683 	if (e1000g_check_acc_handle(Adapter->osdep.reg_handle) != DDI_FM_OK)
684 		ddi_fm_service_impact(Adapter->dip, DDI_SERVICE_UNAFFECTED);
685 
686 	return (0);
687 }
688 
689 /*
690  * e1000g_init_stats - initialize kstat data structures
691  *
692  * This routine will create and initialize the driver private
693  * statistics counters.
694  */
695 int
696 e1000g_init_stats(struct e1000g *Adapter)
697 {
698 	kstat_t *ksp;
699 	p_e1000g_stat_t e1000g_ksp;
700 
701 	/*
702 	 * Create and init kstat
703 	 */
704 	ksp = kstat_create(WSNAME, ddi_get_instance(Adapter->dip),
705 	    "statistics", "net", KSTAT_TYPE_NAMED,
706 	    sizeof (e1000g_stat_t) / sizeof (kstat_named_t), 0);
707 
708 	if (ksp == NULL) {
709 		e1000g_log(Adapter, CE_WARN,
710 		    "Could not create kernel statistics\n");
711 		return (DDI_FAILURE);
712 	}
713 
714 	Adapter->e1000g_ksp = ksp;	/* Fill in the Adapters ksp */
715 
716 	e1000g_ksp = (p_e1000g_stat_t)ksp->ks_data;
717 
718 	/*
719 	 * Initialize all the statistics
720 	 */
721 	kstat_named_init(&e1000g_ksp->link_speed, "link_speed",
722 	    KSTAT_DATA_ULONG);
723 	kstat_named_init(&e1000g_ksp->reset_count, "Reset Count",
724 	    KSTAT_DATA_ULONG);
725 
726 	kstat_named_init(&e1000g_ksp->rx_error, "Rx Error",
727 	    KSTAT_DATA_ULONG);
728 	kstat_named_init(&e1000g_ksp->rx_esballoc_fail, "Rx Desballoc Failure",
729 	    KSTAT_DATA_ULONG);
730 	kstat_named_init(&e1000g_ksp->rx_allocb_fail, "Rx Allocb Failure",
731 	    KSTAT_DATA_ULONG);
732 
733 	kstat_named_init(&e1000g_ksp->tx_no_desc, "Tx No Desc",
734 	    KSTAT_DATA_ULONG);
735 	kstat_named_init(&e1000g_ksp->tx_no_swpkt, "Tx No Buffer",
736 	    KSTAT_DATA_ULONG);
737 	kstat_named_init(&e1000g_ksp->tx_send_fail, "Tx Send Failure",
738 	    KSTAT_DATA_ULONG);
739 	kstat_named_init(&e1000g_ksp->tx_over_size, "Tx Pkt Over Size",
740 	    KSTAT_DATA_ULONG);
741 	kstat_named_init(&e1000g_ksp->tx_reschedule, "Tx Reschedule",
742 	    KSTAT_DATA_ULONG);
743 
744 	kstat_named_init(&e1000g_ksp->Mpc, "Recv_Missed_Packets",
745 	    KSTAT_DATA_ULONG);
746 	kstat_named_init(&e1000g_ksp->Symerrs, "Recv_Symbol_Errors",
747 	    KSTAT_DATA_ULONG);
748 	kstat_named_init(&e1000g_ksp->Rlec, "Recv_Length_Errors",
749 	    KSTAT_DATA_ULONG);
750 	kstat_named_init(&e1000g_ksp->Xonrxc, "XONs_Recvd",
751 	    KSTAT_DATA_ULONG);
752 	kstat_named_init(&e1000g_ksp->Xontxc, "XONs_Xmitd",
753 	    KSTAT_DATA_ULONG);
754 	kstat_named_init(&e1000g_ksp->Xoffrxc, "XOFFs_Recvd",
755 	    KSTAT_DATA_ULONG);
756 	kstat_named_init(&e1000g_ksp->Xofftxc, "XOFFs_Xmitd",
757 	    KSTAT_DATA_ULONG);
758 	kstat_named_init(&e1000g_ksp->Fcruc, "Recv_Unsupport_FC_Pkts",
759 	    KSTAT_DATA_ULONG);
760 #ifdef E1000G_DEBUG
761 	kstat_named_init(&e1000g_ksp->Prc64, "Pkts_Recvd_(  64b)",
762 	    KSTAT_DATA_ULONG);
763 	kstat_named_init(&e1000g_ksp->Prc127, "Pkts_Recvd_(  65- 127b)",
764 	    KSTAT_DATA_ULONG);
765 	kstat_named_init(&e1000g_ksp->Prc255, "Pkts_Recvd_( 127- 255b)",
766 	    KSTAT_DATA_ULONG);
767 	kstat_named_init(&e1000g_ksp->Prc511, "Pkts_Recvd_( 256- 511b)",
768 	    KSTAT_DATA_ULONG);
769 	kstat_named_init(&e1000g_ksp->Prc1023, "Pkts_Recvd_( 511-1023b)",
770 	    KSTAT_DATA_ULONG);
771 	kstat_named_init(&e1000g_ksp->Prc1522, "Pkts_Recvd_(1024-1522b)",
772 	    KSTAT_DATA_ULONG);
773 #endif
774 	kstat_named_init(&e1000g_ksp->Gprc, "Good_Pkts_Recvd",
775 	    KSTAT_DATA_ULONG);
776 	kstat_named_init(&e1000g_ksp->Gptc, "Good_Pkts_Xmitd",
777 	    KSTAT_DATA_ULONG);
778 	kstat_named_init(&e1000g_ksp->Gorl, "Good_Octets_Recvd_Lo",
779 	    KSTAT_DATA_ULONG);
780 	kstat_named_init(&e1000g_ksp->Gorh, "Good_Octets_Recvd_Hi",
781 	    KSTAT_DATA_ULONG);
782 	kstat_named_init(&e1000g_ksp->Gotl, "Good_Octets_Xmitd_Lo",
783 	    KSTAT_DATA_ULONG);
784 	kstat_named_init(&e1000g_ksp->Goth, "Good_Octets_Xmitd_Hi",
785 	    KSTAT_DATA_ULONG);
786 	kstat_named_init(&e1000g_ksp->Ruc, "Recv_Undersize",
787 	    KSTAT_DATA_ULONG);
788 	kstat_named_init(&e1000g_ksp->Rfc, "Recv_Frag",
789 	    KSTAT_DATA_ULONG);
790 	kstat_named_init(&e1000g_ksp->Roc, "Recv_Oversize",
791 	    KSTAT_DATA_ULONG);
792 	kstat_named_init(&e1000g_ksp->Rjc, "Recv_Jabber",
793 	    KSTAT_DATA_ULONG);
794 	kstat_named_init(&e1000g_ksp->Torl, "Total_Octets_Recvd_Lo",
795 	    KSTAT_DATA_ULONG);
796 	kstat_named_init(&e1000g_ksp->Torh, "Total_Octets_Recvd_Hi",
797 	    KSTAT_DATA_ULONG);
798 	kstat_named_init(&e1000g_ksp->Totl, "Total_Octets_Xmitd_Lo",
799 	    KSTAT_DATA_ULONG);
800 	kstat_named_init(&e1000g_ksp->Toth, "Total_Octets_Xmitd_Hi",
801 	    KSTAT_DATA_ULONG);
802 	kstat_named_init(&e1000g_ksp->Tpr, "Total_Packets_Recvd",
803 	    KSTAT_DATA_ULONG);
804 	kstat_named_init(&e1000g_ksp->Tpt, "Total_Packets_Xmitd",
805 	    KSTAT_DATA_ULONG);
806 #ifdef E1000G_DEBUG
807 	kstat_named_init(&e1000g_ksp->Ptc64, "Pkts_Xmitd_(  64b)",
808 	    KSTAT_DATA_ULONG);
809 	kstat_named_init(&e1000g_ksp->Ptc127, "Pkts_Xmitd_(  65- 127b)",
810 	    KSTAT_DATA_ULONG);
811 	kstat_named_init(&e1000g_ksp->Ptc255, "Pkts_Xmitd_( 128- 255b)",
812 	    KSTAT_DATA_ULONG);
813 	kstat_named_init(&e1000g_ksp->Ptc511, "Pkts_Xmitd_( 255- 511b)",
814 	    KSTAT_DATA_ULONG);
815 	kstat_named_init(&e1000g_ksp->Ptc1023, "Pkts_Xmitd_( 512-1023b)",
816 	    KSTAT_DATA_ULONG);
817 	kstat_named_init(&e1000g_ksp->Ptc1522, "Pkts_Xmitd_(1024-1522b)",
818 	    KSTAT_DATA_ULONG);
819 #endif
820 	kstat_named_init(&e1000g_ksp->Tncrs, "Xmit_with_No_CRS",
821 	    KSTAT_DATA_ULONG);
822 	kstat_named_init(&e1000g_ksp->Tsctc, "Xmit_TCP_Seg_Contexts",
823 	    KSTAT_DATA_ULONG);
824 	kstat_named_init(&e1000g_ksp->Tsctfc, "Xmit_TCP_Seg_Contexts_Fail",
825 	    KSTAT_DATA_ULONG);
826 
827 #ifdef E1000G_DEBUG
828 	kstat_named_init(&e1000g_ksp->rx_none, "Rx No Data",
829 	    KSTAT_DATA_ULONG);
830 	kstat_named_init(&e1000g_ksp->rx_multi_desc, "Rx Span Multi Desc",
831 	    KSTAT_DATA_ULONG);
832 	kstat_named_init(&e1000g_ksp->rx_no_freepkt, "Rx Freelist Empty",
833 	    KSTAT_DATA_ULONG);
834 	kstat_named_init(&e1000g_ksp->rx_avail_freepkt, "Rx Freelist Avail",
835 	    KSTAT_DATA_ULONG);
836 
837 	kstat_named_init(&e1000g_ksp->tx_under_size, "Tx Pkt Under Size",
838 	    KSTAT_DATA_ULONG);
839 	kstat_named_init(&e1000g_ksp->tx_exceed_frags, "Tx Exceed Max Frags",
840 	    KSTAT_DATA_ULONG);
841 	kstat_named_init(&e1000g_ksp->tx_empty_frags, "Tx Empty Frags",
842 	    KSTAT_DATA_ULONG);
843 	kstat_named_init(&e1000g_ksp->tx_recycle, "Tx Recycle",
844 	    KSTAT_DATA_ULONG);
845 	kstat_named_init(&e1000g_ksp->tx_recycle_intr, "Tx Recycle Intr",
846 	    KSTAT_DATA_ULONG);
847 	kstat_named_init(&e1000g_ksp->tx_recycle_retry, "Tx Recycle Retry",
848 	    KSTAT_DATA_ULONG);
849 	kstat_named_init(&e1000g_ksp->tx_recycle_none, "Tx Recycled None",
850 	    KSTAT_DATA_ULONG);
851 	kstat_named_init(&e1000g_ksp->tx_copy, "Tx Send Copy",
852 	    KSTAT_DATA_ULONG);
853 	kstat_named_init(&e1000g_ksp->tx_bind, "Tx Send Bind",
854 	    KSTAT_DATA_ULONG);
855 	kstat_named_init(&e1000g_ksp->tx_multi_copy, "Tx Copy Multi Frags",
856 	    KSTAT_DATA_ULONG);
857 	kstat_named_init(&e1000g_ksp->tx_multi_cookie, "Tx Bind Multi Cookies",
858 	    KSTAT_DATA_ULONG);
859 	kstat_named_init(&e1000g_ksp->tx_lack_desc, "Tx Desc Insufficient",
860 	    KSTAT_DATA_ULONG);
861 #endif
862 
863 	/*
864 	 * Function to provide kernel stat update on demand
865 	 */
866 	ksp->ks_update = e1000g_update_stats;
867 
868 	/*
869 	 * Pointer into provider's raw statistics
870 	 */
871 	ksp->ks_private = (void *)Adapter;
872 
873 	/*
874 	 * Add kstat to systems kstat chain
875 	 */
876 	kstat_install(ksp);
877 
878 	return (DDI_SUCCESS);
879 }
880