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.
9 * Copyright(c) 1999 - 2009 Intel Corporation. All rights reserved.
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").
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.
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Copyright 2012 David Höppner. All rights reserved.
24 * Use is subject to license terms.
28 * **********************************************************************
30 * Module Name: e1000g_stat.c *
32 * Abstract: Functions for processing statistics *
34 * **********************************************************************
36 #include "e1000g_sw.h"
37 #include "e1000g_debug.h"
39 static int e1000g_update_stats(kstat_t
*ksp
, int rw
);
40 static uint32_t e1000g_read_phy_stat(struct e1000_hw
*hw
, int reg
);
43 * e1000_tbi_adjust_stats
45 * Adjusts statistic counters when a frame is accepted
46 * under the TBI workaround. This function has been
47 * adapted for Solaris from shared code.
50 e1000_tbi_adjust_stats(struct e1000g
*Adapter
,
51 uint32_t frame_len
, uint8_t *mac_addr
)
54 p_e1000g_stat_t e1000g_ksp
;
56 e1000g_ksp
= (p_e1000g_stat_t
)Adapter
->e1000g_ksp
->ks_data
;
58 /* First adjust the frame length */
62 * We need to adjust the statistics counters, since the hardware
63 * counters overcount this packet as a CRC error and undercount
64 * the packet as a good packet
66 /* This packet should not be counted as a CRC error */
67 Adapter
->fcs_errors
--;
68 /* This packet does count as a Good Packet Received */
69 e1000g_ksp
->Gprc
.value
.ul
++;
72 * Adjust the Good Octets received counters
74 carry_bit
= 0x80000000 & e1000g_ksp
->Gorl
.value
.ul
;
75 e1000g_ksp
->Gorl
.value
.ul
+= frame_len
;
77 * If the high bit of Gorcl (the low 32 bits of the Good Octets
78 * Received Count) was one before the addition,
79 * AND it is zero after, then we lost the carry out,
80 * need to add one to Gorch (Good Octets Received Count High).
81 * This could be simplified if all environments supported
84 if (carry_bit
&& ((e1000g_ksp
->Gorl
.value
.ul
& 0x80000000) == 0)) {
85 e1000g_ksp
->Gorh
.value
.ul
++;
88 * Is this a broadcast or multicast? Check broadcast first,
89 * since the test for a multicast frame will test positive on
92 if ((mac_addr
[0] == (uint8_t)0xff) &&
93 (mac_addr
[1] == (uint8_t)0xff)) {
98 } else if (*mac_addr
& 0x01) {
105 if (frame_len
== Adapter
->max_frame_size
) {
107 * In this case, the hardware has overcounted the number of
110 if (Adapter
->toolong_errors
> 0)
111 Adapter
->toolong_errors
--;
116 * Adjust the bin counters when the extra byte put the frame in the
117 * wrong bin. Remember that the frame_len was adjusted above.
119 if (frame_len
== 64) {
120 e1000g_ksp
->Prc64
.value
.ul
++;
121 e1000g_ksp
->Prc127
.value
.ul
--;
122 } else if (frame_len
== 127) {
123 e1000g_ksp
->Prc127
.value
.ul
++;
124 e1000g_ksp
->Prc255
.value
.ul
--;
125 } else if (frame_len
== 255) {
126 e1000g_ksp
->Prc255
.value
.ul
++;
127 e1000g_ksp
->Prc511
.value
.ul
--;
128 } else if (frame_len
== 511) {
129 e1000g_ksp
->Prc511
.value
.ul
++;
130 e1000g_ksp
->Prc1023
.value
.ul
--;
131 } else if (frame_len
== 1023) {
132 e1000g_ksp
->Prc1023
.value
.ul
++;
133 e1000g_ksp
->Prc1522
.value
.ul
--;
134 } else if (frame_len
== 1522) {
135 e1000g_ksp
->Prc1522
.value
.ul
++;
142 * e1000g_update_stats - update driver private kstat counters
144 * This routine will dump and reset the e1000's internal
145 * statistics counters. The current stats dump values will
146 * be sent to the kernel status area.
149 e1000g_update_stats(kstat_t
*ksp
, int rw
)
151 struct e1000g
*Adapter
;
153 p_e1000g_stat_t e1000g_ksp
;
154 e1000g_tx_ring_t
*tx_ring
;
155 e1000g_rx_ring_t
*rx_ring
;
157 e1000g_rx_data_t
*rx_data
;
160 uint32_t low_val
, high_val
;
162 if (rw
== KSTAT_WRITE
)
165 Adapter
= (struct e1000g
*)ksp
->ks_private
;
166 ASSERT(Adapter
!= NULL
);
167 e1000g_ksp
= (p_e1000g_stat_t
)ksp
->ks_data
;
168 ASSERT(e1000g_ksp
!= NULL
);
169 hw
= &Adapter
->shared
;
171 tx_ring
= Adapter
->tx_ring
;
172 rx_ring
= Adapter
->rx_ring
;
174 rx_data
= rx_ring
->rx_data
;
177 rw_enter(&Adapter
->chip_lock
, RW_WRITER
);
179 e1000g_ksp
->reset_count
.value
.ul
= Adapter
->reset_count
;
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
;
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
;
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
;
196 e1000g_ksp
->rx_avail_freepkt
.value
.ul
= rx_data
->avail_freepkt
;
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
;
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
);
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
);
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
);
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
);
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
->Rfc
.value
.ul
+= E1000_READ_REG(hw
, E1000_RFC
);
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
);
266 * Adaptive Calculations
268 hw
->mac
.tx_packet_delta
= E1000_READ_REG(hw
, E1000_TPT
);
269 Adapter
->opackets
+= hw
->mac
.tx_packet_delta
;
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.
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);
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);
292 low_val
= E1000_READ_REG(hw
, E1000_TORL
);
293 high_val
= E1000_READ_REG(hw
, E1000_TORH
);
295 (uint64_t)high_val
<< 32 | (uint64_t)low_val
;
297 low_val
= E1000_READ_REG(hw
, E1000_TOTL
);
298 high_val
= E1000_READ_REG(hw
, E1000_TOTH
);
300 (uint64_t)high_val
<< 32 | (uint64_t)low_val
;
302 rw_exit(&Adapter
->chip_lock
);
304 if (e1000g_check_acc_handle(Adapter
->osdep
.reg_handle
) != DDI_FM_OK
) {
305 ddi_fm_service_impact(Adapter
->dip
, DDI_SERVICE_UNAFFECTED
);
313 e1000g_m_stat(void *arg
, uint_t stat
, uint64_t *val
)
315 struct e1000g
*Adapter
= (struct e1000g
*)arg
;
316 struct e1000_hw
*hw
= &Adapter
->shared
;
317 p_e1000g_stat_t e1000g_ksp
;
318 uint32_t low_val
, high_val
;
320 e1000g_ksp
= (p_e1000g_stat_t
)Adapter
->e1000g_ksp
->ks_data
;
322 rw_enter(&Adapter
->chip_lock
, RW_READER
);
324 if (Adapter
->e1000g_state
& E1000G_SUSPENDED
) {
325 rw_exit(&Adapter
->chip_lock
);
330 case MAC_STAT_IFSPEED
:
331 *val
= Adapter
->link_speed
* 1000000ull;
334 case MAC_STAT_MULTIRCV
:
336 E1000_READ_REG(hw
, E1000_MPRC
);
337 *val
= Adapter
->multircv
;
340 case MAC_STAT_BRDCSTRCV
:
341 Adapter
->brdcstrcv
+=
342 E1000_READ_REG(hw
, E1000_BPRC
);
343 *val
= Adapter
->brdcstrcv
;
346 case MAC_STAT_MULTIXMT
:
348 E1000_READ_REG(hw
, E1000_MPTC
);
349 *val
= Adapter
->multixmt
;
352 case MAC_STAT_BRDCSTXMT
:
353 Adapter
->brdcstxmt
+=
354 E1000_READ_REG(hw
, E1000_BPTC
);
355 *val
= Adapter
->brdcstxmt
;
358 case MAC_STAT_NORCVBUF
:
360 E1000_READ_REG(hw
, E1000_RNBC
);
361 *val
= Adapter
->norcvbuf
;
364 case MAC_STAT_IERRORS
:
365 Adapter
->macrcv_errors
+=
366 E1000_READ_REG(hw
, E1000_RXERRC
);
367 Adapter
->align_errors
+=
368 E1000_READ_REG(hw
, E1000_ALGNERRC
);
369 e1000g_ksp
->Rlec
.value
.ul
+=
370 E1000_READ_REG(hw
, E1000_RLEC
);
371 Adapter
->fcs_errors
+=
372 E1000_READ_REG(hw
, E1000_CRCERRS
);
373 Adapter
->carrier_errors
+=
374 E1000_READ_REG(hw
, E1000_CEXTERR
);
375 *val
= Adapter
->macrcv_errors
+
376 Adapter
->align_errors
+
377 e1000g_ksp
->Rlec
.value
.ul
+
378 Adapter
->fcs_errors
+
379 Adapter
->carrier_errors
;
382 case MAC_STAT_NOXMTBUF
:
383 *val
= Adapter
->tx_ring
->stat_no_desc
;
386 case MAC_STAT_OERRORS
:
388 e1000g_read_phy_stat(hw
, E1000_ECOL
);
389 *val
= Adapter
->oerrors
;
392 case MAC_STAT_COLLISIONS
:
393 Adapter
->collisions
+=
394 e1000g_read_phy_stat(hw
, E1000_COLC
);
395 *val
= Adapter
->collisions
;
398 case MAC_STAT_RBYTES
:
400 * The 64-bit register will reset whenever the upper
401 * 32 bits are read. So we need to read the lower
402 * 32 bits first, then read the upper 32 bits.
404 low_val
= E1000_READ_REG(hw
, E1000_TORL
);
405 high_val
= E1000_READ_REG(hw
, E1000_TORH
);
407 (uint64_t)high_val
<< 32 | (uint64_t)low_val
;
408 *val
= Adapter
->rbytes
;
411 case MAC_STAT_IPACKETS
:
413 E1000_READ_REG(hw
, E1000_TPR
);
414 *val
= Adapter
->ipackets
;
417 case MAC_STAT_OBYTES
:
419 * The 64-bit register will reset whenever the upper
420 * 32 bits are read. So we need to read the lower
421 * 32 bits first, then read the upper 32 bits.
423 low_val
= E1000_READ_REG(hw
, E1000_TOTL
);
424 high_val
= E1000_READ_REG(hw
, E1000_TOTH
);
426 (uint64_t)high_val
<< 32 | (uint64_t)low_val
;
427 *val
= Adapter
->obytes
;
430 case MAC_STAT_OPACKETS
:
432 E1000_READ_REG(hw
, E1000_TPT
);
433 *val
= Adapter
->opackets
;
436 case ETHER_STAT_ALIGN_ERRORS
:
437 Adapter
->align_errors
+=
438 E1000_READ_REG(hw
, E1000_ALGNERRC
);
439 *val
= Adapter
->align_errors
;
442 case ETHER_STAT_FCS_ERRORS
:
443 Adapter
->fcs_errors
+=
444 E1000_READ_REG(hw
, E1000_CRCERRS
);
445 *val
= Adapter
->fcs_errors
;
448 case ETHER_STAT_SQE_ERRORS
:
449 Adapter
->sqe_errors
+=
450 E1000_READ_REG(hw
, E1000_SEC
);
451 *val
= Adapter
->sqe_errors
;
454 case ETHER_STAT_CARRIER_ERRORS
:
455 Adapter
->carrier_errors
+=
456 E1000_READ_REG(hw
, E1000_CEXTERR
);
457 *val
= Adapter
->carrier_errors
;
460 case ETHER_STAT_EX_COLLISIONS
:
461 Adapter
->ex_collisions
+=
462 e1000g_read_phy_stat(hw
, E1000_ECOL
);
463 *val
= Adapter
->ex_collisions
;
466 case ETHER_STAT_TX_LATE_COLLISIONS
:
467 Adapter
->tx_late_collisions
+=
468 e1000g_read_phy_stat(hw
, E1000_LATECOL
);
469 *val
= Adapter
->tx_late_collisions
;
472 case ETHER_STAT_DEFER_XMTS
:
473 Adapter
->defer_xmts
+=
474 e1000g_read_phy_stat(hw
, E1000_DC
);
475 *val
= Adapter
->defer_xmts
;
478 case ETHER_STAT_FIRST_COLLISIONS
:
479 Adapter
->first_collisions
+=
480 e1000g_read_phy_stat(hw
, E1000_SCC
);
481 *val
= Adapter
->first_collisions
;
484 case ETHER_STAT_MULTI_COLLISIONS
:
485 Adapter
->multi_collisions
+=
486 e1000g_read_phy_stat(hw
, E1000_MCC
);
487 *val
= Adapter
->multi_collisions
;
490 case ETHER_STAT_MACRCV_ERRORS
:
491 Adapter
->macrcv_errors
+=
492 E1000_READ_REG(hw
, E1000_RXERRC
);
493 *val
= Adapter
->macrcv_errors
;
496 case ETHER_STAT_MACXMT_ERRORS
:
497 Adapter
->macxmt_errors
+=
498 e1000g_read_phy_stat(hw
, E1000_ECOL
);
499 *val
= Adapter
->macxmt_errors
;
502 case ETHER_STAT_TOOLONG_ERRORS
:
503 Adapter
->toolong_errors
+=
504 E1000_READ_REG(hw
, E1000_ROC
);
505 *val
= Adapter
->toolong_errors
;
508 case ETHER_STAT_TOOSHORT_ERRORS
:
509 Adapter
->tooshort_errors
+=
510 E1000_READ_REG(hw
, E1000_RUC
);
511 *val
= Adapter
->tooshort_errors
;
514 case ETHER_STAT_JABBER_ERRORS
:
515 Adapter
->jabber_errors
+=
516 E1000_READ_REG(hw
, E1000_RJC
);
517 *val
= Adapter
->jabber_errors
;
520 case ETHER_STAT_XCVR_ADDR
:
521 /* The Internal PHY's MDI address for each MAC is 1 */
525 case ETHER_STAT_XCVR_ID
:
526 *val
= hw
->phy
.id
| hw
->phy
.revision
;
529 case ETHER_STAT_XCVR_INUSE
:
530 switch (Adapter
->link_speed
) {
533 (hw
->phy
.media_type
== e1000_media_type_copper
) ?
534 XCVR_1000T
: XCVR_1000X
;
538 (hw
->phy
.media_type
== e1000_media_type_copper
) ?
539 (Adapter
->phy_status
& MII_SR_100T4_CAPS
) ?
540 XCVR_100T4
: XCVR_100T2
: XCVR_100X
;
551 case ETHER_STAT_CAP_1000FDX
:
552 *val
= Adapter
->param_1000fdx_cap
;
555 case ETHER_STAT_CAP_1000HDX
:
556 *val
= Adapter
->param_1000hdx_cap
;
559 case ETHER_STAT_CAP_100FDX
:
560 *val
= Adapter
->param_100fdx_cap
;
563 case ETHER_STAT_CAP_100HDX
:
564 *val
= Adapter
->param_100hdx_cap
;
567 case ETHER_STAT_CAP_10FDX
:
568 *val
= Adapter
->param_10fdx_cap
;
571 case ETHER_STAT_CAP_10HDX
:
572 *val
= Adapter
->param_10hdx_cap
;
575 case ETHER_STAT_CAP_ASMPAUSE
:
576 *val
= Adapter
->param_asym_pause_cap
;
579 case ETHER_STAT_CAP_PAUSE
:
580 *val
= Adapter
->param_pause_cap
;
583 case ETHER_STAT_CAP_AUTONEG
:
584 *val
= Adapter
->param_autoneg_cap
;
587 case ETHER_STAT_ADV_CAP_1000FDX
:
588 *val
= Adapter
->param_adv_1000fdx
;
591 case ETHER_STAT_ADV_CAP_1000HDX
:
592 *val
= Adapter
->param_adv_1000hdx
;
595 case ETHER_STAT_ADV_CAP_100FDX
:
596 *val
= Adapter
->param_adv_100fdx
;
599 case ETHER_STAT_ADV_CAP_100HDX
:
600 *val
= Adapter
->param_adv_100hdx
;
603 case ETHER_STAT_ADV_CAP_10FDX
:
604 *val
= Adapter
->param_adv_10fdx
;
607 case ETHER_STAT_ADV_CAP_10HDX
:
608 *val
= Adapter
->param_adv_10hdx
;
611 case ETHER_STAT_ADV_CAP_ASMPAUSE
:
612 *val
= Adapter
->param_adv_asym_pause
;
615 case ETHER_STAT_ADV_CAP_PAUSE
:
616 *val
= Adapter
->param_adv_pause
;
619 case ETHER_STAT_ADV_CAP_AUTONEG
:
620 *val
= hw
->mac
.autoneg
;
623 case ETHER_STAT_LP_CAP_1000FDX
:
624 *val
= Adapter
->param_lp_1000fdx
;
627 case ETHER_STAT_LP_CAP_1000HDX
:
628 *val
= Adapter
->param_lp_1000hdx
;
631 case ETHER_STAT_LP_CAP_100FDX
:
632 *val
= Adapter
->param_lp_100fdx
;
635 case ETHER_STAT_LP_CAP_100HDX
:
636 *val
= Adapter
->param_lp_100hdx
;
639 case ETHER_STAT_LP_CAP_10FDX
:
640 *val
= Adapter
->param_lp_10fdx
;
643 case ETHER_STAT_LP_CAP_10HDX
:
644 *val
= Adapter
->param_lp_10hdx
;
647 case ETHER_STAT_LP_CAP_ASMPAUSE
:
648 *val
= Adapter
->param_lp_asym_pause
;
651 case ETHER_STAT_LP_CAP_PAUSE
:
652 *val
= Adapter
->param_lp_pause
;
655 case ETHER_STAT_LP_CAP_AUTONEG
:
656 *val
= Adapter
->param_lp_autoneg
;
659 case ETHER_STAT_LINK_ASMPAUSE
:
660 *val
= Adapter
->param_asym_pause_cap
;
663 case ETHER_STAT_LINK_PAUSE
:
664 *val
= Adapter
->param_pause_cap
;
667 case ETHER_STAT_LINK_AUTONEG
:
668 *val
= hw
->mac
.autoneg
;
671 case ETHER_STAT_LINK_DUPLEX
:
672 *val
= (Adapter
->link_duplex
== FULL_DUPLEX
) ?
673 LINK_DUPLEX_FULL
: LINK_DUPLEX_HALF
;
676 case ETHER_STAT_CAP_100T4
:
677 *val
= Adapter
->param_100t4_cap
;
680 case ETHER_STAT_ADV_CAP_100T4
:
681 *val
= Adapter
->param_adv_100t4
;
684 case ETHER_STAT_LP_CAP_100T4
:
685 *val
= Adapter
->param_lp_100t4
;
689 rw_exit(&Adapter
->chip_lock
);
693 rw_exit(&Adapter
->chip_lock
);
695 if (e1000g_check_acc_handle(Adapter
->osdep
.reg_handle
) != DDI_FM_OK
) {
696 ddi_fm_service_impact(Adapter
->dip
, DDI_SERVICE_UNAFFECTED
);
704 * e1000g_init_stats - initialize kstat data structures
706 * This routine will create and initialize the driver private
707 * statistics counters.
710 e1000g_init_stats(struct e1000g
*Adapter
)
713 p_e1000g_stat_t e1000g_ksp
;
716 * Create and init kstat
718 ksp
= kstat_create(WSNAME
, ddi_get_instance(Adapter
->dip
),
719 "statistics", "net", KSTAT_TYPE_NAMED
,
720 sizeof (e1000g_stat_t
) / sizeof (kstat_named_t
), 0);
723 e1000g_log(Adapter
, CE_WARN
,
724 "Could not create kernel statistics\n");
725 return (DDI_FAILURE
);
728 Adapter
->e1000g_ksp
= ksp
; /* Fill in the Adapters ksp */
730 e1000g_ksp
= (p_e1000g_stat_t
)ksp
->ks_data
;
733 * Initialize all the statistics
735 kstat_named_init(&e1000g_ksp
->reset_count
, "Reset Count",
738 kstat_named_init(&e1000g_ksp
->rx_error
, "Rx Error",
740 kstat_named_init(&e1000g_ksp
->rx_allocb_fail
, "Rx Allocb Failure",
742 kstat_named_init(&e1000g_ksp
->rx_size_error
, "Rx Size Error",
745 kstat_named_init(&e1000g_ksp
->tx_no_desc
, "Tx No Desc",
747 kstat_named_init(&e1000g_ksp
->tx_no_swpkt
, "Tx No Buffer",
749 kstat_named_init(&e1000g_ksp
->tx_send_fail
, "Tx Send Failure",
751 kstat_named_init(&e1000g_ksp
->tx_over_size
, "Tx Pkt Over Size",
753 kstat_named_init(&e1000g_ksp
->tx_reschedule
, "Tx Reschedule",
756 kstat_named_init(&e1000g_ksp
->Mpc
, "Recv_Missed_Packets",
758 kstat_named_init(&e1000g_ksp
->Symerrs
, "Recv_Symbol_Errors",
760 kstat_named_init(&e1000g_ksp
->Rlec
, "Recv_Length_Errors",
762 kstat_named_init(&e1000g_ksp
->Xonrxc
, "XONs_Recvd",
764 kstat_named_init(&e1000g_ksp
->Xontxc
, "XONs_Xmitd",
766 kstat_named_init(&e1000g_ksp
->Xoffrxc
, "XOFFs_Recvd",
768 kstat_named_init(&e1000g_ksp
->Xofftxc
, "XOFFs_Xmitd",
770 kstat_named_init(&e1000g_ksp
->Fcruc
, "Recv_Unsupport_FC_Pkts",
773 kstat_named_init(&e1000g_ksp
->Prc64
, "Pkts_Recvd_( 64b)",
775 kstat_named_init(&e1000g_ksp
->Prc127
, "Pkts_Recvd_( 65- 127b)",
777 kstat_named_init(&e1000g_ksp
->Prc255
, "Pkts_Recvd_( 127- 255b)",
779 kstat_named_init(&e1000g_ksp
->Prc511
, "Pkts_Recvd_( 256- 511b)",
781 kstat_named_init(&e1000g_ksp
->Prc1023
, "Pkts_Recvd_( 511-1023b)",
783 kstat_named_init(&e1000g_ksp
->Prc1522
, "Pkts_Recvd_(1024-1522b)",
786 kstat_named_init(&e1000g_ksp
->Gprc
, "Good_Pkts_Recvd",
788 kstat_named_init(&e1000g_ksp
->Gptc
, "Good_Pkts_Xmitd",
790 kstat_named_init(&e1000g_ksp
->Gorl
, "Good_Octets_Recvd_Lo",
792 kstat_named_init(&e1000g_ksp
->Gorh
, "Good_Octets_Recvd_Hi",
794 kstat_named_init(&e1000g_ksp
->Gotl
, "Good_Octets_Xmitd_Lo",
796 kstat_named_init(&e1000g_ksp
->Goth
, "Good_Octets_Xmitd_Hi",
798 kstat_named_init(&e1000g_ksp
->Rfc
, "Recv_Frag",
801 kstat_named_init(&e1000g_ksp
->Ptc64
, "Pkts_Xmitd_( 64b)",
803 kstat_named_init(&e1000g_ksp
->Ptc127
, "Pkts_Xmitd_( 65- 127b)",
805 kstat_named_init(&e1000g_ksp
->Ptc255
, "Pkts_Xmitd_( 128- 255b)",
807 kstat_named_init(&e1000g_ksp
->Ptc511
, "Pkts_Xmitd_( 255- 511b)",
809 kstat_named_init(&e1000g_ksp
->Ptc1023
, "Pkts_Xmitd_( 512-1023b)",
811 kstat_named_init(&e1000g_ksp
->Ptc1522
, "Pkts_Xmitd_(1024-1522b)",
814 kstat_named_init(&e1000g_ksp
->Tncrs
, "Xmit_with_No_CRS",
816 kstat_named_init(&e1000g_ksp
->Tsctc
, "Xmit_TCP_Seg_Contexts",
818 kstat_named_init(&e1000g_ksp
->Tsctfc
, "Xmit_TCP_Seg_Contexts_Fail",
822 kstat_named_init(&e1000g_ksp
->rx_none
, "Rx No Data",
824 kstat_named_init(&e1000g_ksp
->rx_multi_desc
, "Rx Span Multi Desc",
826 kstat_named_init(&e1000g_ksp
->rx_no_freepkt
, "Rx Freelist Empty",
828 kstat_named_init(&e1000g_ksp
->rx_avail_freepkt
, "Rx Freelist Avail",
831 kstat_named_init(&e1000g_ksp
->tx_under_size
, "Tx Pkt Under Size",
833 kstat_named_init(&e1000g_ksp
->tx_exceed_frags
, "Tx Exceed Max Frags",
835 kstat_named_init(&e1000g_ksp
->tx_empty_frags
, "Tx Empty Frags",
837 kstat_named_init(&e1000g_ksp
->tx_recycle
, "Tx Recycle",
839 kstat_named_init(&e1000g_ksp
->tx_recycle_intr
, "Tx Recycle Intr",
841 kstat_named_init(&e1000g_ksp
->tx_recycle_retry
, "Tx Recycle Retry",
843 kstat_named_init(&e1000g_ksp
->tx_recycle_none
, "Tx Recycled None",
845 kstat_named_init(&e1000g_ksp
->tx_copy
, "Tx Send Copy",
847 kstat_named_init(&e1000g_ksp
->tx_bind
, "Tx Send Bind",
849 kstat_named_init(&e1000g_ksp
->tx_multi_copy
, "Tx Copy Multi Frags",
851 kstat_named_init(&e1000g_ksp
->tx_multi_cookie
, "Tx Bind Multi Cookies",
853 kstat_named_init(&e1000g_ksp
->tx_lack_desc
, "Tx Desc Insufficient",
858 * Function to provide kernel stat update on demand
860 ksp
->ks_update
= e1000g_update_stats
;
863 * Pointer into provider's raw statistics
865 ksp
->ks_private
= (void *)Adapter
;
868 * Add kstat to systems kstat chain
872 return (DDI_SUCCESS
);
876 * e1000g_read_phy_stat - read certain PHY statistics
878 * Certain statistics are read from MAC registers on some silicon types
879 * but are read from the PHY on other silicon types. This routine
880 * handles that difference as needed.
883 e1000g_read_phy_stat(struct e1000_hw
*hw
, int reg
)
885 uint16_t phy_low
, phy_high
;
888 /* get statistic from PHY in these cases */
889 if ((hw
->phy
.type
== e1000_phy_82578
) ||
890 (hw
->phy
.type
== e1000_phy_82577
)) {
894 (void) e1000_read_phy_reg(hw
, HV_SCC_UPPER
, &phy_high
);
895 (void) e1000_read_phy_reg(hw
, HV_SCC_LOWER
, &phy_low
);
896 val
= ((uint32_t)phy_high
<< 16) | (uint32_t)phy_low
;
900 (void) e1000_read_phy_reg(hw
, HV_MCC_UPPER
, &phy_high
);
901 (void) e1000_read_phy_reg(hw
, HV_MCC_LOWER
, &phy_low
);
902 val
= ((uint32_t)phy_high
<< 16) | (uint32_t)phy_low
;
906 (void) e1000_read_phy_reg(hw
, HV_ECOL_UPPER
, &phy_high
);
907 (void) e1000_read_phy_reg(hw
, HV_ECOL_LOWER
, &phy_low
);
908 val
= ((uint32_t)phy_high
<< 16) | (uint32_t)phy_low
;
912 (void) e1000_read_phy_reg(hw
, HV_COLC_UPPER
, &phy_high
);
913 (void) e1000_read_phy_reg(hw
, HV_COLC_LOWER
, &phy_low
);
914 val
= ((uint32_t)phy_high
<< 16) | (uint32_t)phy_low
;
918 (void) e1000_read_phy_reg(hw
, HV_LATECOL_UPPER
,
920 (void) e1000_read_phy_reg(hw
, HV_LATECOL_LOWER
,
922 val
= ((uint32_t)phy_high
<< 16) | (uint32_t)phy_low
;
926 (void) e1000_read_phy_reg(hw
, HV_DC_UPPER
, &phy_high
);
927 (void) e1000_read_phy_reg(hw
, HV_DC_LOWER
, &phy_low
);
928 val
= ((uint32_t)phy_high
<< 16) | (uint32_t)phy_low
;
932 (void) e1000_read_phy_reg(hw
, HV_TNCRS_UPPER
,
934 (void) e1000_read_phy_reg(hw
, HV_TNCRS_LOWER
,
936 val
= ((uint32_t)phy_high
<< 16) | (uint32_t)phy_low
;
943 /* get statistic from MAC otherwise */
945 val
= E1000_READ_REG(hw
, reg
);
952 * Retrieve a value for one of the statistics for a particular rx ring
955 e1000g_rx_ring_stat(mac_ring_driver_t rh
, uint_t stat
, uint64_t *val
)
957 e1000g_rx_ring_t
*rx_ring
= (e1000g_rx_ring_t
*)rh
;
958 struct e1000g
*Adapter
= rx_ring
->adapter
;
959 struct e1000_hw
*hw
= &Adapter
->shared
;
960 uint32_t low_val
, high_val
;
962 rw_enter(&Adapter
->chip_lock
, RW_READER
);
964 if (Adapter
->e1000g_state
& E1000G_SUSPENDED
) {
965 rw_exit(&Adapter
->chip_lock
);
970 case MAC_STAT_RBYTES
:
972 * The 64-bit register will reset whenever the upper
973 * 32 bits are read. So we need to read the lower
974 * 32 bits first, then read the upper 32 bits.
976 low_val
= E1000_READ_REG(hw
, E1000_TORL
);
977 high_val
= E1000_READ_REG(hw
, E1000_TORH
);
979 (uint64_t)high_val
<< 32 | (uint64_t)low_val
;
980 *val
= Adapter
->rbytes
;
983 case MAC_STAT_IPACKETS
:
985 E1000_READ_REG(hw
, E1000_TPR
);
986 *val
= Adapter
->ipackets
;
991 rw_exit(&Adapter
->chip_lock
);
995 rw_exit(&Adapter
->chip_lock
);
997 if (e1000g_check_acc_handle(Adapter
->osdep
.reg_handle
) != DDI_FM_OK
)
998 ddi_fm_service_impact(Adapter
->dip
, DDI_SERVICE_UNAFFECTED
);