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