xref: /illumos-gate/usr/src/uts/common/io/igb/igb_stat.c (revision c869993e)
1*c869993eSxy /*
2*c869993eSxy  * CDDL HEADER START
3*c869993eSxy  *
4*c869993eSxy  * Copyright(c) 2007-2008 Intel Corporation. All rights reserved.
5*c869993eSxy  * The contents of this file are subject to the terms of the
6*c869993eSxy  * Common Development and Distribution License (the "License").
7*c869993eSxy  * You may not use this file except in compliance with the License.
8*c869993eSxy  *
9*c869993eSxy  * You can obtain a copy of the license at:
10*c869993eSxy  *	http://www.opensolaris.org/os/licensing.
11*c869993eSxy  * See the License for the specific language governing permissions
12*c869993eSxy  * and limitations under the License.
13*c869993eSxy  *
14*c869993eSxy  * When using or redistributing this file, you may do so under the
15*c869993eSxy  * License only. No other modification of this header is permitted.
16*c869993eSxy  *
17*c869993eSxy  * If applicable, add the following below this CDDL HEADER, with the
18*c869993eSxy  * fields enclosed by brackets "[]" replaced with your own identifying
19*c869993eSxy  * information: Portions Copyright [yyyy] [name of copyright owner]
20*c869993eSxy  *
21*c869993eSxy  * CDDL HEADER END
22*c869993eSxy  */
23*c869993eSxy 
24*c869993eSxy /*
25*c869993eSxy  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
26*c869993eSxy  * Use is subject to license terms of the CDDL.
27*c869993eSxy  */
28*c869993eSxy 
29*c869993eSxy #pragma ident	"%Z%%M%	%I%	%E% SMI"
30*c869993eSxy 
31*c869993eSxy #include "igb_sw.h"
32*c869993eSxy 
33*c869993eSxy /*
34*c869993eSxy  * Update driver private statistics.
35*c869993eSxy  */
36*c869993eSxy static int
37*c869993eSxy igb_update_stats(kstat_t *ks, int rw)
38*c869993eSxy {
39*c869993eSxy 	igb_t *igb;
40*c869993eSxy 	struct e1000_hw *hw;
41*c869993eSxy 	igb_stat_t *igb_ks;
42*c869993eSxy 	uint32_t val_low, val_high;
43*c869993eSxy #ifdef IGB_DEBUG
44*c869993eSxy 	int i;
45*c869993eSxy #endif
46*c869993eSxy 
47*c869993eSxy 	if (rw == KSTAT_WRITE)
48*c869993eSxy 		return (EACCES);
49*c869993eSxy 
50*c869993eSxy 	igb = (igb_t *)ks->ks_private;
51*c869993eSxy 	igb_ks = (igb_stat_t *)ks->ks_data;
52*c869993eSxy 	hw = &igb->hw;
53*c869993eSxy 
54*c869993eSxy 	mutex_enter(&igb->gen_lock);
55*c869993eSxy 
56*c869993eSxy 	/*
57*c869993eSxy 	 * Basic information.
58*c869993eSxy 	 */
59*c869993eSxy 	igb_ks->link_speed.value.ui64 = igb->link_speed;
60*c869993eSxy 
61*c869993eSxy #ifdef IGB_DEBUG
62*c869993eSxy 	igb_ks->reset_count.value.ui64 = igb->reset_count;
63*c869993eSxy 
64*c869993eSxy 	igb_ks->rx_frame_error.value.ui64 = 0;
65*c869993eSxy 	igb_ks->rx_cksum_error.value.ui64 = 0;
66*c869993eSxy 	igb_ks->rx_exceed_pkt.value.ui64 = 0;
67*c869993eSxy 	for (i = 0; i < igb->num_rx_rings; i++) {
68*c869993eSxy 		igb_ks->rx_frame_error.value.ui64 +=
69*c869993eSxy 		    igb->rx_rings[i].stat_frame_error;
70*c869993eSxy 		igb_ks->rx_cksum_error.value.ui64 +=
71*c869993eSxy 		    igb->rx_rings[i].stat_cksum_error;
72*c869993eSxy 		igb_ks->rx_exceed_pkt.value.ui64 +=
73*c869993eSxy 		    igb->rx_rings[i].stat_exceed_pkt;
74*c869993eSxy 	}
75*c869993eSxy 
76*c869993eSxy 	igb_ks->tx_overload.value.ui64 = 0;
77*c869993eSxy 	igb_ks->tx_fail_no_tbd.value.ui64 = 0;
78*c869993eSxy 	igb_ks->tx_fail_no_tcb.value.ui64 = 0;
79*c869993eSxy 	igb_ks->tx_fail_dma_bind.value.ui64 = 0;
80*c869993eSxy 	igb_ks->tx_reschedule.value.ui64 = 0;
81*c869993eSxy 	for (i = 0; i < igb->num_tx_rings; i++) {
82*c869993eSxy 		igb_ks->tx_overload.value.ui64 +=
83*c869993eSxy 		    igb->tx_rings[i].stat_overload;
84*c869993eSxy 		igb_ks->tx_fail_no_tbd.value.ui64 +=
85*c869993eSxy 		    igb->tx_rings[i].stat_fail_no_tbd;
86*c869993eSxy 		igb_ks->tx_fail_no_tcb.value.ui64 +=
87*c869993eSxy 		    igb->tx_rings[i].stat_fail_no_tcb;
88*c869993eSxy 		igb_ks->tx_fail_dma_bind.value.ui64 +=
89*c869993eSxy 		    igb->tx_rings[i].stat_fail_dma_bind;
90*c869993eSxy 		igb_ks->tx_reschedule.value.ui64 +=
91*c869993eSxy 		    igb->tx_rings[i].stat_reschedule;
92*c869993eSxy 	}
93*c869993eSxy 
94*c869993eSxy 	/*
95*c869993eSxy 	 * Hardware calculated statistics.
96*c869993eSxy 	 */
97*c869993eSxy 	igb_ks->gprc.value.ul += E1000_READ_REG(hw, E1000_GPRC);
98*c869993eSxy 	igb_ks->gptc.value.ul += E1000_READ_REG(hw, E1000_GPTC);
99*c869993eSxy 	igb_ks->prc64.value.ul += E1000_READ_REG(hw, E1000_PRC64);
100*c869993eSxy 	igb_ks->prc127.value.ul += E1000_READ_REG(hw, E1000_PRC127);
101*c869993eSxy 	igb_ks->prc255.value.ul += E1000_READ_REG(hw, E1000_PRC255);
102*c869993eSxy 	igb_ks->prc511.value.ul += E1000_READ_REG(hw, E1000_PRC511);
103*c869993eSxy 	igb_ks->prc1023.value.ul += E1000_READ_REG(hw, E1000_PRC1023);
104*c869993eSxy 	igb_ks->prc1522.value.ul += E1000_READ_REG(hw, E1000_PRC1522);
105*c869993eSxy 	igb_ks->ptc64.value.ul += E1000_READ_REG(hw, E1000_PTC64);
106*c869993eSxy 	igb_ks->ptc127.value.ul += E1000_READ_REG(hw, E1000_PTC127);
107*c869993eSxy 	igb_ks->ptc255.value.ul += E1000_READ_REG(hw, E1000_PTC255);
108*c869993eSxy 	igb_ks->ptc511.value.ul += E1000_READ_REG(hw, E1000_PTC511);
109*c869993eSxy 	igb_ks->ptc1023.value.ul += E1000_READ_REG(hw, E1000_PTC1023);
110*c869993eSxy 	igb_ks->ptc1522.value.ul += E1000_READ_REG(hw, E1000_PTC1522);
111*c869993eSxy 
112*c869993eSxy 	/*
113*c869993eSxy 	 * The 64-bit register will reset whenever the upper
114*c869993eSxy 	 * 32 bits are read. So we need to read the lower
115*c869993eSxy 	 * 32 bits first, then read the upper 32 bits.
116*c869993eSxy 	 */
117*c869993eSxy 	val_low = E1000_READ_REG(hw, E1000_GORCL);
118*c869993eSxy 	val_high = E1000_READ_REG(hw, E1000_GORCH);
119*c869993eSxy 	igb_ks->gor.value.ui64 += (uint64_t)val_high << 32 | (uint64_t)val_low;
120*c869993eSxy 
121*c869993eSxy 	val_low = E1000_READ_REG(hw, E1000_GOTCL);
122*c869993eSxy 	val_high = E1000_READ_REG(hw, E1000_GOTCH);
123*c869993eSxy 	igb_ks->got.value.ui64 += (uint64_t)val_high << 32 | (uint64_t)val_low;
124*c869993eSxy #endif
125*c869993eSxy 
126*c869993eSxy 	igb_ks->symerrs.value.ui64 += E1000_READ_REG(hw, E1000_SYMERRS);
127*c869993eSxy 	igb_ks->mpc.value.ui64 += E1000_READ_REG(hw, E1000_MPC);
128*c869993eSxy 	igb_ks->rlec.value.ui64 += E1000_READ_REG(hw, E1000_RLEC);
129*c869993eSxy 	igb_ks->fcruc.value.ui64 += E1000_READ_REG(hw, E1000_FCRUC);
130*c869993eSxy 	igb_ks->rfc.value.ul += E1000_READ_REG(hw, E1000_RFC);
131*c869993eSxy 	igb_ks->tncrs.value.ul += E1000_READ_REG(hw, E1000_TNCRS);
132*c869993eSxy 	igb_ks->tsctc.value.ul += E1000_READ_REG(hw, E1000_TSCTC);
133*c869993eSxy 	igb_ks->tsctfc.value.ul += E1000_READ_REG(hw, E1000_TSCTFC);
134*c869993eSxy 	igb_ks->xonrxc.value.ui64 += E1000_READ_REG(hw, E1000_XONRXC);
135*c869993eSxy 	igb_ks->xontxc.value.ui64 += E1000_READ_REG(hw, E1000_XONTXC);
136*c869993eSxy 	igb_ks->xoffrxc.value.ui64 += E1000_READ_REG(hw, E1000_XOFFRXC);
137*c869993eSxy 	igb_ks->xofftxc.value.ui64 += E1000_READ_REG(hw, E1000_XOFFTXC);
138*c869993eSxy 
139*c869993eSxy 	mutex_exit(&igb->gen_lock);
140*c869993eSxy 
141*c869993eSxy 	return (0);
142*c869993eSxy }
143*c869993eSxy 
144*c869993eSxy /*
145*c869993eSxy  * Create and initialize the driver private statistics.
146*c869993eSxy  */
147*c869993eSxy int
148*c869993eSxy igb_init_stats(igb_t *igb)
149*c869993eSxy {
150*c869993eSxy 	kstat_t *ks;
151*c869993eSxy 	igb_stat_t *igb_ks;
152*c869993eSxy 
153*c869993eSxy 	/*
154*c869993eSxy 	 * Create and init kstat
155*c869993eSxy 	 */
156*c869993eSxy 	ks = kstat_create(MODULE_NAME, ddi_get_instance(igb->dip),
157*c869993eSxy 	    "statistics", "net", KSTAT_TYPE_NAMED,
158*c869993eSxy 	    sizeof (igb_stat_t) / sizeof (kstat_named_t), 0);
159*c869993eSxy 
160*c869993eSxy 	if (ks == NULL) {
161*c869993eSxy 		igb_error(igb,
162*c869993eSxy 		    "Could not create kernel statistics");
163*c869993eSxy 		return (IGB_FAILURE);
164*c869993eSxy 	}
165*c869993eSxy 
166*c869993eSxy 	igb->igb_ks = ks;
167*c869993eSxy 
168*c869993eSxy 	igb_ks = (igb_stat_t *)ks->ks_data;
169*c869993eSxy 
170*c869993eSxy 	/*
171*c869993eSxy 	 * Initialize all the statistics.
172*c869993eSxy 	 */
173*c869993eSxy 	kstat_named_init(&igb_ks->link_speed, "link_speed",
174*c869993eSxy 	    KSTAT_DATA_UINT64);
175*c869993eSxy 
176*c869993eSxy #ifdef IGB_DEBUG
177*c869993eSxy 	kstat_named_init(&igb_ks->reset_count, "reset_count",
178*c869993eSxy 	    KSTAT_DATA_UINT64);
179*c869993eSxy 	kstat_named_init(&igb_ks->rx_frame_error, "rx_frame_error",
180*c869993eSxy 	    KSTAT_DATA_UINT64);
181*c869993eSxy 	kstat_named_init(&igb_ks->rx_cksum_error, "rx_cksum_error",
182*c869993eSxy 	    KSTAT_DATA_UINT64);
183*c869993eSxy 	kstat_named_init(&igb_ks->rx_exceed_pkt, "rx_exceed_pkt",
184*c869993eSxy 	    KSTAT_DATA_UINT64);
185*c869993eSxy 	kstat_named_init(&igb_ks->tx_overload, "tx_overload",
186*c869993eSxy 	    KSTAT_DATA_UINT64);
187*c869993eSxy 	kstat_named_init(&igb_ks->tx_fail_no_tbd, "tx_fail_no_tbd",
188*c869993eSxy 	    KSTAT_DATA_UINT64);
189*c869993eSxy 	kstat_named_init(&igb_ks->tx_fail_no_tcb, "tx_fail_no_tcb",
190*c869993eSxy 	    KSTAT_DATA_UINT64);
191*c869993eSxy 	kstat_named_init(&igb_ks->tx_fail_dma_bind, "tx_fail_dma_bind",
192*c869993eSxy 	    KSTAT_DATA_UINT64);
193*c869993eSxy 	kstat_named_init(&igb_ks->tx_reschedule, "tx_reschedule",
194*c869993eSxy 	    KSTAT_DATA_UINT64);
195*c869993eSxy 
196*c869993eSxy 	kstat_named_init(&igb_ks->gprc, "good_pkts_recvd",
197*c869993eSxy 	    KSTAT_DATA_UINT64);
198*c869993eSxy 	kstat_named_init(&igb_ks->gptc, "good_pkts_xmitd",
199*c869993eSxy 	    KSTAT_DATA_UINT64);
200*c869993eSxy 	kstat_named_init(&igb_ks->gor, "good_octets_recvd",
201*c869993eSxy 	    KSTAT_DATA_UINT64);
202*c869993eSxy 	kstat_named_init(&igb_ks->got, "good_octets_xmitd",
203*c869993eSxy 	    KSTAT_DATA_UINT64);
204*c869993eSxy 	kstat_named_init(&igb_ks->prc64, "pkts_recvd_(  64b)",
205*c869993eSxy 	    KSTAT_DATA_UINT64);
206*c869993eSxy 	kstat_named_init(&igb_ks->prc127, "pkts_recvd_(  65- 127b)",
207*c869993eSxy 	    KSTAT_DATA_UINT64);
208*c869993eSxy 	kstat_named_init(&igb_ks->prc255, "pkts_recvd_( 127- 255b)",
209*c869993eSxy 	    KSTAT_DATA_UINT64);
210*c869993eSxy 	kstat_named_init(&igb_ks->prc511, "pkts_recvd_( 256- 511b)",
211*c869993eSxy 	    KSTAT_DATA_UINT64);
212*c869993eSxy 	kstat_named_init(&igb_ks->prc1023, "pkts_recvd_( 511-1023b)",
213*c869993eSxy 	    KSTAT_DATA_UINT64);
214*c869993eSxy 	kstat_named_init(&igb_ks->prc1522, "pkts_recvd_(1024-1522b)",
215*c869993eSxy 	    KSTAT_DATA_UINT64);
216*c869993eSxy 	kstat_named_init(&igb_ks->ptc64, "pkts_xmitd_(  64b)",
217*c869993eSxy 	    KSTAT_DATA_UINT64);
218*c869993eSxy 	kstat_named_init(&igb_ks->ptc127, "pkts_xmitd_(  65- 127b)",
219*c869993eSxy 	    KSTAT_DATA_UINT64);
220*c869993eSxy 	kstat_named_init(&igb_ks->ptc255, "pkts_xmitd_( 128- 255b)",
221*c869993eSxy 	    KSTAT_DATA_UINT64);
222*c869993eSxy 	kstat_named_init(&igb_ks->ptc511, "pkts_xmitd_( 255- 511b)",
223*c869993eSxy 	    KSTAT_DATA_UINT64);
224*c869993eSxy 	kstat_named_init(&igb_ks->ptc1023, "pkts_xmitd_( 512-1023b)",
225*c869993eSxy 	    KSTAT_DATA_UINT64);
226*c869993eSxy 	kstat_named_init(&igb_ks->ptc1522, "pkts_xmitd_(1024-1522b)",
227*c869993eSxy 	    KSTAT_DATA_UINT64);
228*c869993eSxy #endif
229*c869993eSxy 
230*c869993eSxy 	kstat_named_init(&igb_ks->symerrs, "recv_symbol_errors",
231*c869993eSxy 	    KSTAT_DATA_UINT64);
232*c869993eSxy 	kstat_named_init(&igb_ks->mpc, "recv_missed_packets",
233*c869993eSxy 	    KSTAT_DATA_UINT64);
234*c869993eSxy 	kstat_named_init(&igb_ks->rlec, "recv_length_errors",
235*c869993eSxy 	    KSTAT_DATA_UINT64);
236*c869993eSxy 	kstat_named_init(&igb_ks->fcruc, "recv_unsupport_FC_pkts",
237*c869993eSxy 	    KSTAT_DATA_UINT64);
238*c869993eSxy 	kstat_named_init(&igb_ks->rfc, "recv_frag",
239*c869993eSxy 	    KSTAT_DATA_UINT64);
240*c869993eSxy 	kstat_named_init(&igb_ks->tncrs, "xmit_with_no_CRS",
241*c869993eSxy 	    KSTAT_DATA_UINT64);
242*c869993eSxy 	kstat_named_init(&igb_ks->tsctc, "xmit_TCP_seg_contexts",
243*c869993eSxy 	    KSTAT_DATA_UINT64);
244*c869993eSxy 	kstat_named_init(&igb_ks->tsctfc, "xmit_TCP_seg_contexts_fail",
245*c869993eSxy 	    KSTAT_DATA_UINT64);
246*c869993eSxy 	kstat_named_init(&igb_ks->xonrxc, "XONs_recvd",
247*c869993eSxy 	    KSTAT_DATA_UINT64);
248*c869993eSxy 	kstat_named_init(&igb_ks->xontxc, "XONs_xmitd",
249*c869993eSxy 	    KSTAT_DATA_UINT64);
250*c869993eSxy 	kstat_named_init(&igb_ks->xoffrxc, "XOFFs_recvd",
251*c869993eSxy 	    KSTAT_DATA_UINT64);
252*c869993eSxy 	kstat_named_init(&igb_ks->xofftxc, "XOFFs_xmitd",
253*c869993eSxy 	    KSTAT_DATA_UINT64);
254*c869993eSxy 
255*c869993eSxy 	/*
256*c869993eSxy 	 * Function to provide kernel stat update on demand
257*c869993eSxy 	 */
258*c869993eSxy 	ks->ks_update = igb_update_stats;
259*c869993eSxy 
260*c869993eSxy 	ks->ks_private = (void *)igb;
261*c869993eSxy 
262*c869993eSxy 	/*
263*c869993eSxy 	 * Add kstat to systems kstat chain
264*c869993eSxy 	 */
265*c869993eSxy 	kstat_install(ks);
266*c869993eSxy 
267*c869993eSxy 	return (IGB_SUCCESS);
268*c869993eSxy }
269