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