xref: /illumos-gate/usr/src/uts/common/io/ixgbe/ixgbe_stat.c (revision 48ed61a721b0db9229d5bad4d87f5b019867fbf1)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright(c) 2007-2010 Intel Corporation. All rights reserved.
24  */
25 
26 /*
27  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
29  * Copyright 2016 OmniTI Computer Consulting, Inc. All rights reserved.
30  * Copyright (c) 2017, Joyent, Inc.
31  */
32 
33 #include "ixgbe_sw.h"
34 
35 /*
36  * Update driver private statistics.
37  */
38 static int
39 ixgbe_update_stats(kstat_t *ks, int rw)
40 {
41 	ixgbe_t *ixgbe;
42 	struct ixgbe_hw *hw;
43 	ixgbe_stat_t *ixgbe_ks;
44 	int i;
45 
46 	if (rw == KSTAT_WRITE)
47 		return (EACCES);
48 
49 	ixgbe = (ixgbe_t *)ks->ks_private;
50 	ixgbe_ks = (ixgbe_stat_t *)ks->ks_data;
51 	hw = &ixgbe->hw;
52 
53 	mutex_enter(&ixgbe->gen_lock);
54 
55 	/*
56 	 * Basic information
57 	 */
58 	ixgbe_ks->link_speed.value.ui64 = ixgbe->link_speed;
59 	ixgbe_ks->reset_count.value.ui64 = ixgbe->reset_count;
60 	ixgbe_ks->lroc.value.ui64 = ixgbe->lro_pkt_count;
61 
62 	ixgbe_ks->rx_frame_error.value.ui64 = 0;
63 	ixgbe_ks->rx_cksum_error.value.ui64 = 0;
64 	ixgbe_ks->rx_exceed_pkt.value.ui64 = 0;
65 	for (i = 0; i < ixgbe->num_rx_rings; i++) {
66 		ixgbe_ks->rx_frame_error.value.ui64 +=
67 		    ixgbe->rx_rings[i].stat_frame_error;
68 		ixgbe_ks->rx_cksum_error.value.ui64 +=
69 		    ixgbe->rx_rings[i].stat_cksum_error;
70 		ixgbe_ks->rx_exceed_pkt.value.ui64 +=
71 		    ixgbe->rx_rings[i].stat_exceed_pkt;
72 	}
73 
74 	ixgbe_ks->tx_overload.value.ui64 = 0;
75 	ixgbe_ks->tx_fail_no_tbd.value.ui64 = 0;
76 	ixgbe_ks->tx_fail_no_tcb.value.ui64 = 0;
77 	ixgbe_ks->tx_fail_dma_bind.value.ui64 = 0;
78 	ixgbe_ks->tx_reschedule.value.ui64 = 0;
79 	ixgbe_ks->tx_break_tbd_limit.value.ui64 = 0;
80 	ixgbe_ks->tx_lso_header_fail.value.ui64 = 0;
81 	for (i = 0; i < ixgbe->num_tx_rings; i++) {
82 		ixgbe_ks->tx_overload.value.ui64 +=
83 		    ixgbe->tx_rings[i].stat_overload;
84 		ixgbe_ks->tx_fail_no_tbd.value.ui64 +=
85 		    ixgbe->tx_rings[i].stat_fail_no_tbd;
86 		ixgbe_ks->tx_fail_no_tcb.value.ui64 +=
87 		    ixgbe->tx_rings[i].stat_fail_no_tcb;
88 		ixgbe_ks->tx_fail_dma_bind.value.ui64 +=
89 		    ixgbe->tx_rings[i].stat_fail_dma_bind;
90 		ixgbe_ks->tx_reschedule.value.ui64 +=
91 		    ixgbe->tx_rings[i].stat_reschedule;
92 		ixgbe_ks->tx_break_tbd_limit.value.ui64 +=
93 		    ixgbe->tx_rings[i].stat_break_tbd_limit;
94 		ixgbe_ks->tx_lso_header_fail.value.ui64 +=
95 		    ixgbe->tx_rings[i].stat_lso_header_fail;
96 	}
97 
98 	/*
99 	 * Hardware calculated statistics.
100 	 */
101 	ixgbe_ks->gprc.value.ui64 = 0;
102 	ixgbe_ks->gptc.value.ui64 = 0;
103 	ixgbe_ks->tor.value.ui64 = 0;
104 	ixgbe_ks->tot.value.ui64 = 0;
105 	for (i = 0; i < 16; i++) {
106 		ixgbe_ks->qprc[i].value.ui64 +=
107 		    IXGBE_READ_REG(hw, IXGBE_QPRC(i));
108 		ixgbe_ks->gprc.value.ui64 += ixgbe_ks->qprc[i].value.ui64;
109 		ixgbe_ks->qptc[i].value.ui64 +=
110 		    IXGBE_READ_REG(hw, IXGBE_QPTC(i));
111 		ixgbe_ks->gptc.value.ui64 += ixgbe_ks->qptc[i].value.ui64;
112 		ixgbe_ks->qbrc[i].value.ui64 +=
113 		    IXGBE_READ_REG(hw, IXGBE_QBRC(i));
114 		ixgbe_ks->tor.value.ui64 += ixgbe_ks->qbrc[i].value.ui64;
115 		switch (hw->mac.type) {
116 		case ixgbe_mac_82598EB:
117 			ixgbe_ks->qbtc[i].value.ui64 +=
118 			    IXGBE_READ_REG(hw, IXGBE_QBTC(i));
119 			break;
120 
121 		case ixgbe_mac_82599EB:
122 		case ixgbe_mac_X540:
123 		case ixgbe_mac_X550:
124 		case ixgbe_mac_X550EM_x:
125 		case ixgbe_mac_X550EM_a:
126 			ixgbe_ks->qbtc[i].value.ui64 +=
127 			    IXGBE_READ_REG(hw, IXGBE_QBTC_L(i));
128 			ixgbe_ks->qbtc[i].value.ui64 +=
129 			    ((uint64_t)((IXGBE_READ_REG(hw,
130 			    IXGBE_QBTC_H(i))) & 0xF) << 32);
131 			break;
132 
133 		default:
134 			break;
135 		}
136 		ixgbe_ks->tot.value.ui64 += ixgbe_ks->qbtc[i].value.ui64;
137 	}
138 	/*
139 	 * This is a Workaround:
140 	 * Currently h/w GORCH, GOTCH, TORH registers are not
141 	 * correctly implemented. We found that the values in
142 	 * these registers are same as those in corresponding
143 	 * *L registers (i.e. GORCL, GOTCL, and TORL). Here the
144 	 * gor and got stat data will not be retrieved through
145 	 * GORC{H/L} and GOTC{H/L} registers but be obtained by
146 	 * simply assigning tor/tot stat data, so the gor/got
147 	 * stat data will not be accurate.
148 	 */
149 	ixgbe_ks->gor.value.ui64 = ixgbe_ks->tor.value.ui64;
150 	ixgbe_ks->got.value.ui64 = ixgbe_ks->tot.value.ui64;
151 
152 	ixgbe_ks->prc64.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC64);
153 	ixgbe_ks->prc127.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC127);
154 	ixgbe_ks->prc255.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC255);
155 	ixgbe_ks->prc511.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC511);
156 	ixgbe_ks->prc1023.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC1023);
157 	ixgbe_ks->prc1522.value.ul += IXGBE_READ_REG(hw, IXGBE_PRC1522);
158 	ixgbe_ks->ptc64.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC64);
159 	ixgbe_ks->ptc127.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC127);
160 	ixgbe_ks->ptc255.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC255);
161 	ixgbe_ks->ptc511.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC511);
162 	ixgbe_ks->ptc1023.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC1023);
163 	ixgbe_ks->ptc1522.value.ul += IXGBE_READ_REG(hw, IXGBE_PTC1522);
164 
165 	ixgbe_ks->mspdc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_MSPDC);
166 	for (i = 0; i < 8; i++)
167 		ixgbe_ks->mpc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_MPC(i));
168 	ixgbe_ks->mlfc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_MLFC);
169 	ixgbe_ks->mrfc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_MRFC);
170 	ixgbe_ks->rlec.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RLEC);
171 	ixgbe_ks->lxontxc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_LXONTXC);
172 	switch (hw->mac.type) {
173 	case ixgbe_mac_82598EB:
174 		ixgbe_ks->lxonrxc.value.ui64 += IXGBE_READ_REG(hw,
175 		    IXGBE_LXONRXC);
176 		break;
177 
178 	case ixgbe_mac_82599EB:
179 	case ixgbe_mac_X540:
180 	case ixgbe_mac_X550:
181 	case ixgbe_mac_X550EM_x:
182 	case ixgbe_mac_X550EM_a:
183 		ixgbe_ks->lxonrxc.value.ui64 += IXGBE_READ_REG(hw,
184 		    IXGBE_LXONRXCNT);
185 		break;
186 
187 	default:
188 		break;
189 	}
190 	ixgbe_ks->lxofftxc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
191 	switch (hw->mac.type) {
192 	case ixgbe_mac_82598EB:
193 		ixgbe_ks->lxoffrxc.value.ui64 += IXGBE_READ_REG(hw,
194 		    IXGBE_LXOFFRXC);
195 		break;
196 
197 	case ixgbe_mac_82599EB:
198 	case ixgbe_mac_X540:
199 	case ixgbe_mac_X550:
200 	case ixgbe_mac_X550EM_x:
201 	case ixgbe_mac_X550EM_a:
202 		ixgbe_ks->lxoffrxc.value.ui64 += IXGBE_READ_REG(hw,
203 		    IXGBE_LXOFFRXCNT);
204 		break;
205 
206 	default:
207 		break;
208 	}
209 	ixgbe_ks->ruc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RUC);
210 	ixgbe_ks->rfc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RFC);
211 	ixgbe_ks->roc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_ROC);
212 	ixgbe_ks->rjc.value.ui64 += IXGBE_READ_REG(hw, IXGBE_RJC);
213 
214 	mutex_exit(&ixgbe->gen_lock);
215 
216 	if (ixgbe_check_acc_handle(ixgbe->osdep.reg_handle) != DDI_FM_OK)
217 		ddi_fm_service_impact(ixgbe->dip, DDI_SERVICE_UNAFFECTED);
218 
219 	return (0);
220 }
221 
222 /*
223  * Create and initialize the driver private statistics.
224  */
225 int
226 ixgbe_init_stats(ixgbe_t *ixgbe)
227 {
228 	kstat_t *ks;
229 	ixgbe_stat_t *ixgbe_ks;
230 
231 	/*
232 	 * Create and init kstat
233 	 */
234 	ks = kstat_create(MODULE_NAME, ddi_get_instance(ixgbe->dip),
235 	    "statistics", "net", KSTAT_TYPE_NAMED,
236 	    sizeof (ixgbe_stat_t) / sizeof (kstat_named_t), 0);
237 
238 	if (ks == NULL) {
239 		ixgbe_error(ixgbe,
240 		    "Could not create kernel statistics");
241 		return (IXGBE_FAILURE);
242 	}
243 
244 	ixgbe->ixgbe_ks = ks;
245 
246 	ixgbe_ks = (ixgbe_stat_t *)ks->ks_data;
247 
248 	/*
249 	 * Initialize all the statistics.
250 	 */
251 	kstat_named_init(&ixgbe_ks->link_speed, "link_speed",
252 	    KSTAT_DATA_UINT64);
253 	kstat_named_init(&ixgbe_ks->reset_count, "reset_count",
254 	    KSTAT_DATA_UINT64);
255 
256 	kstat_named_init(&ixgbe_ks->rx_frame_error, "rx_frame_error",
257 	    KSTAT_DATA_UINT64);
258 	kstat_named_init(&ixgbe_ks->rx_cksum_error, "rx_cksum_error",
259 	    KSTAT_DATA_UINT64);
260 	kstat_named_init(&ixgbe_ks->rx_exceed_pkt, "rx_exceed_pkt",
261 	    KSTAT_DATA_UINT64);
262 	kstat_named_init(&ixgbe_ks->tx_overload, "tx_overload",
263 	    KSTAT_DATA_UINT64);
264 	kstat_named_init(&ixgbe_ks->tx_fail_no_tbd, "tx_fail_no_tbd",
265 	    KSTAT_DATA_UINT64);
266 	kstat_named_init(&ixgbe_ks->tx_fail_no_tcb, "tx_fail_no_tcb",
267 	    KSTAT_DATA_UINT64);
268 	kstat_named_init(&ixgbe_ks->tx_fail_dma_bind, "tx_fail_dma_bind",
269 	    KSTAT_DATA_UINT64);
270 	kstat_named_init(&ixgbe_ks->tx_reschedule, "tx_reschedule",
271 	    KSTAT_DATA_UINT64);
272 	kstat_named_init(&ixgbe_ks->tx_break_tbd_limit, "tx_break_tbd_limit",
273 	    KSTAT_DATA_UINT64);
274 	kstat_named_init(&ixgbe_ks->tx_lso_header_fail, "tx_lso_header_fail",
275 	    KSTAT_DATA_UINT64);
276 
277 	kstat_named_init(&ixgbe_ks->gprc, "good_pkts_recvd",
278 	    KSTAT_DATA_UINT64);
279 	kstat_named_init(&ixgbe_ks->gptc, "good_pkts_xmitd",
280 	    KSTAT_DATA_UINT64);
281 	kstat_named_init(&ixgbe_ks->gor, "good_octets_recvd",
282 	    KSTAT_DATA_UINT64);
283 	kstat_named_init(&ixgbe_ks->got, "good_octets_xmitd",
284 	    KSTAT_DATA_UINT64);
285 	kstat_named_init(&ixgbe_ks->prc64, "pkts_recvd_(  64b)",
286 	    KSTAT_DATA_UINT64);
287 	kstat_named_init(&ixgbe_ks->prc127, "pkts_recvd_(  65- 127b)",
288 	    KSTAT_DATA_UINT64);
289 	kstat_named_init(&ixgbe_ks->prc255, "pkts_recvd_( 127- 255b)",
290 	    KSTAT_DATA_UINT64);
291 	kstat_named_init(&ixgbe_ks->prc511, "pkts_recvd_( 256- 511b)",
292 	    KSTAT_DATA_UINT64);
293 	kstat_named_init(&ixgbe_ks->prc1023, "pkts_recvd_( 511-1023b)",
294 	    KSTAT_DATA_UINT64);
295 	kstat_named_init(&ixgbe_ks->prc1522, "pkts_recvd_(1024-1522b)",
296 	    KSTAT_DATA_UINT64);
297 	kstat_named_init(&ixgbe_ks->ptc64, "pkts_xmitd_(  64b)",
298 	    KSTAT_DATA_UINT64);
299 	kstat_named_init(&ixgbe_ks->ptc127, "pkts_xmitd_(  65- 127b)",
300 	    KSTAT_DATA_UINT64);
301 	kstat_named_init(&ixgbe_ks->ptc255, "pkts_xmitd_( 128- 255b)",
302 	    KSTAT_DATA_UINT64);
303 	kstat_named_init(&ixgbe_ks->ptc511, "pkts_xmitd_( 255- 511b)",
304 	    KSTAT_DATA_UINT64);
305 	kstat_named_init(&ixgbe_ks->ptc1023, "pkts_xmitd_( 512-1023b)",
306 	    KSTAT_DATA_UINT64);
307 	kstat_named_init(&ixgbe_ks->ptc1522, "pkts_xmitd_(1024-1522b)",
308 	    KSTAT_DATA_UINT64);
309 
310 	kstat_named_init(&ixgbe_ks->qprc[0], "queue_pkts_recvd [ 0]",
311 	    KSTAT_DATA_UINT64);
312 	kstat_named_init(&ixgbe_ks->qprc[1], "queue_pkts_recvd [ 1]",
313 	    KSTAT_DATA_UINT64);
314 	kstat_named_init(&ixgbe_ks->qprc[2], "queue_pkts_recvd [ 2]",
315 	    KSTAT_DATA_UINT64);
316 	kstat_named_init(&ixgbe_ks->qprc[3], "queue_pkts_recvd [ 3]",
317 	    KSTAT_DATA_UINT64);
318 	kstat_named_init(&ixgbe_ks->qprc[4], "queue_pkts_recvd [ 4]",
319 	    KSTAT_DATA_UINT64);
320 	kstat_named_init(&ixgbe_ks->qprc[5], "queue_pkts_recvd [ 5]",
321 	    KSTAT_DATA_UINT64);
322 	kstat_named_init(&ixgbe_ks->qprc[6], "queue_pkts_recvd [ 6]",
323 	    KSTAT_DATA_UINT64);
324 	kstat_named_init(&ixgbe_ks->qprc[7], "queue_pkts_recvd [ 7]",
325 	    KSTAT_DATA_UINT64);
326 	kstat_named_init(&ixgbe_ks->qprc[8], "queue_pkts_recvd [ 8]",
327 	    KSTAT_DATA_UINT64);
328 	kstat_named_init(&ixgbe_ks->qprc[9], "queue_pkts_recvd [ 9]",
329 	    KSTAT_DATA_UINT64);
330 	kstat_named_init(&ixgbe_ks->qprc[10], "queue_pkts_recvd [10]",
331 	    KSTAT_DATA_UINT64);
332 	kstat_named_init(&ixgbe_ks->qprc[11], "queue_pkts_recvd [11]",
333 	    KSTAT_DATA_UINT64);
334 	kstat_named_init(&ixgbe_ks->qprc[12], "queue_pkts_recvd [12]",
335 	    KSTAT_DATA_UINT64);
336 	kstat_named_init(&ixgbe_ks->qprc[13], "queue_pkts_recvd [13]",
337 	    KSTAT_DATA_UINT64);
338 	kstat_named_init(&ixgbe_ks->qprc[14], "queue_pkts_recvd [14]",
339 	    KSTAT_DATA_UINT64);
340 	kstat_named_init(&ixgbe_ks->qprc[15], "queue_pkts_recvd [15]",
341 	    KSTAT_DATA_UINT64);
342 
343 	kstat_named_init(&ixgbe_ks->qptc[0], "queue_pkts_xmitd [ 0]",
344 	    KSTAT_DATA_UINT64);
345 	kstat_named_init(&ixgbe_ks->qptc[1], "queue_pkts_xmitd [ 1]",
346 	    KSTAT_DATA_UINT64);
347 	kstat_named_init(&ixgbe_ks->qptc[2], "queue_pkts_xmitd [ 2]",
348 	    KSTAT_DATA_UINT64);
349 	kstat_named_init(&ixgbe_ks->qptc[3], "queue_pkts_xmitd [ 3]",
350 	    KSTAT_DATA_UINT64);
351 	kstat_named_init(&ixgbe_ks->qptc[4], "queue_pkts_xmitd [ 4]",
352 	    KSTAT_DATA_UINT64);
353 	kstat_named_init(&ixgbe_ks->qptc[5], "queue_pkts_xmitd [ 5]",
354 	    KSTAT_DATA_UINT64);
355 	kstat_named_init(&ixgbe_ks->qptc[6], "queue_pkts_xmitd [ 6]",
356 	    KSTAT_DATA_UINT64);
357 	kstat_named_init(&ixgbe_ks->qptc[7], "queue_pkts_xmitd [ 7]",
358 	    KSTAT_DATA_UINT64);
359 	kstat_named_init(&ixgbe_ks->qptc[8], "queue_pkts_xmitd [ 8]",
360 	    KSTAT_DATA_UINT64);
361 	kstat_named_init(&ixgbe_ks->qptc[9], "queue_pkts_xmitd [ 9]",
362 	    KSTAT_DATA_UINT64);
363 	kstat_named_init(&ixgbe_ks->qptc[10], "queue_pkts_xmitd [10]",
364 	    KSTAT_DATA_UINT64);
365 	kstat_named_init(&ixgbe_ks->qptc[11], "queue_pkts_xmitd [11]",
366 	    KSTAT_DATA_UINT64);
367 	kstat_named_init(&ixgbe_ks->qptc[12], "queue_pkts_xmitd [12]",
368 	    KSTAT_DATA_UINT64);
369 	kstat_named_init(&ixgbe_ks->qptc[13], "queue_pkts_xmitd [13]",
370 	    KSTAT_DATA_UINT64);
371 	kstat_named_init(&ixgbe_ks->qptc[14], "queue_pkts_xmitd [14]",
372 	    KSTAT_DATA_UINT64);
373 	kstat_named_init(&ixgbe_ks->qptc[15], "queue_pkts_xmitd [15]",
374 	    KSTAT_DATA_UINT64);
375 
376 	kstat_named_init(&ixgbe_ks->qbrc[0], "queue_bytes_recvd [ 0]",
377 	    KSTAT_DATA_UINT64);
378 	kstat_named_init(&ixgbe_ks->qbrc[1], "queue_bytes_recvd [ 1]",
379 	    KSTAT_DATA_UINT64);
380 	kstat_named_init(&ixgbe_ks->qbrc[2], "queue_bytes_recvd [ 2]",
381 	    KSTAT_DATA_UINT64);
382 	kstat_named_init(&ixgbe_ks->qbrc[3], "queue_bytes_recvd [ 3]",
383 	    KSTAT_DATA_UINT64);
384 	kstat_named_init(&ixgbe_ks->qbrc[4], "queue_bytes_recvd [ 4]",
385 	    KSTAT_DATA_UINT64);
386 	kstat_named_init(&ixgbe_ks->qbrc[5], "queue_bytes_recvd [ 5]",
387 	    KSTAT_DATA_UINT64);
388 	kstat_named_init(&ixgbe_ks->qbrc[6], "queue_bytes_recvd [ 6]",
389 	    KSTAT_DATA_UINT64);
390 	kstat_named_init(&ixgbe_ks->qbrc[7], "queue_bytes_recvd [ 7]",
391 	    KSTAT_DATA_UINT64);
392 	kstat_named_init(&ixgbe_ks->qbrc[8], "queue_bytes_recvd [ 8]",
393 	    KSTAT_DATA_UINT64);
394 	kstat_named_init(&ixgbe_ks->qbrc[9], "queue_bytes_recvd [ 9]",
395 	    KSTAT_DATA_UINT64);
396 	kstat_named_init(&ixgbe_ks->qbrc[10], "queue_bytes_recvd [10]",
397 	    KSTAT_DATA_UINT64);
398 	kstat_named_init(&ixgbe_ks->qbrc[11], "queue_bytes_recvd [11]",
399 	    KSTAT_DATA_UINT64);
400 	kstat_named_init(&ixgbe_ks->qbrc[12], "queue_bytes_recvd [12]",
401 	    KSTAT_DATA_UINT64);
402 	kstat_named_init(&ixgbe_ks->qbrc[13], "queue_bytes_recvd [13]",
403 	    KSTAT_DATA_UINT64);
404 	kstat_named_init(&ixgbe_ks->qbrc[14], "queue_bytes_recvd [14]",
405 	    KSTAT_DATA_UINT64);
406 	kstat_named_init(&ixgbe_ks->qbrc[15], "queue_bytes_recvd [15]",
407 	    KSTAT_DATA_UINT64);
408 
409 	kstat_named_init(&ixgbe_ks->qbtc[0], "queue_bytes_xmitd [ 0]",
410 	    KSTAT_DATA_UINT64);
411 	kstat_named_init(&ixgbe_ks->qbtc[1], "queue_bytes_xmitd [ 1]",
412 	    KSTAT_DATA_UINT64);
413 	kstat_named_init(&ixgbe_ks->qbtc[2], "queue_bytes_xmitd [ 2]",
414 	    KSTAT_DATA_UINT64);
415 	kstat_named_init(&ixgbe_ks->qbtc[3], "queue_bytes_xmitd [ 3]",
416 	    KSTAT_DATA_UINT64);
417 	kstat_named_init(&ixgbe_ks->qbtc[4], "queue_bytes_xmitd [ 4]",
418 	    KSTAT_DATA_UINT64);
419 	kstat_named_init(&ixgbe_ks->qbtc[5], "queue_bytes_xmitd [ 5]",
420 	    KSTAT_DATA_UINT64);
421 	kstat_named_init(&ixgbe_ks->qbtc[6], "queue_bytes_xmitd [ 6]",
422 	    KSTAT_DATA_UINT64);
423 	kstat_named_init(&ixgbe_ks->qbtc[7], "queue_bytes_xmitd [ 7]",
424 	    KSTAT_DATA_UINT64);
425 	kstat_named_init(&ixgbe_ks->qbtc[8], "queue_bytes_xmitd [ 8]",
426 	    KSTAT_DATA_UINT64);
427 	kstat_named_init(&ixgbe_ks->qbtc[9], "queue_bytes_xmitd [ 9]",
428 	    KSTAT_DATA_UINT64);
429 	kstat_named_init(&ixgbe_ks->qbtc[10], "queue_bytes_xmitd [10]",
430 	    KSTAT_DATA_UINT64);
431 	kstat_named_init(&ixgbe_ks->qbtc[11], "queue_bytes_xmitd [11]",
432 	    KSTAT_DATA_UINT64);
433 	kstat_named_init(&ixgbe_ks->qbtc[12], "queue_bytes_xmitd [12]",
434 	    KSTAT_DATA_UINT64);
435 	kstat_named_init(&ixgbe_ks->qbtc[13], "queue_bytes_xmitd [13]",
436 	    KSTAT_DATA_UINT64);
437 	kstat_named_init(&ixgbe_ks->qbtc[14], "queue_bytes_xmitd [14]",
438 	    KSTAT_DATA_UINT64);
439 	kstat_named_init(&ixgbe_ks->qbtc[15], "queue_bytes_xmitd [15]",
440 	    KSTAT_DATA_UINT64);
441 
442 	kstat_named_init(&ixgbe_ks->mspdc, "mac_short_packet_discard",
443 	    KSTAT_DATA_UINT64);
444 	kstat_named_init(&ixgbe_ks->mpc, "missed_packets",
445 	    KSTAT_DATA_UINT64);
446 	kstat_named_init(&ixgbe_ks->mlfc, "mac_local_fault",
447 	    KSTAT_DATA_UINT64);
448 	kstat_named_init(&ixgbe_ks->mrfc, "mac_remote_fault",
449 	    KSTAT_DATA_UINT64);
450 	kstat_named_init(&ixgbe_ks->rlec, "recv_length_err",
451 	    KSTAT_DATA_UINT64);
452 	kstat_named_init(&ixgbe_ks->lxontxc, "link_xon_xmitd",
453 	    KSTAT_DATA_UINT64);
454 	kstat_named_init(&ixgbe_ks->lxonrxc, "link_xon_recvd",
455 	    KSTAT_DATA_UINT64);
456 	kstat_named_init(&ixgbe_ks->lxofftxc, "link_xoff_xmitd",
457 	    KSTAT_DATA_UINT64);
458 	kstat_named_init(&ixgbe_ks->lxoffrxc, "link_xoff_recvd",
459 	    KSTAT_DATA_UINT64);
460 	kstat_named_init(&ixgbe_ks->ruc, "recv_undersize",
461 	    KSTAT_DATA_UINT64);
462 	kstat_named_init(&ixgbe_ks->rfc, "recv_fragment",
463 	    KSTAT_DATA_UINT64);
464 	kstat_named_init(&ixgbe_ks->roc, "recv_oversize",
465 	    KSTAT_DATA_UINT64);
466 	kstat_named_init(&ixgbe_ks->rjc, "recv_jabber",
467 	    KSTAT_DATA_UINT64);
468 	kstat_named_init(&ixgbe_ks->rnbc, "recv_no_buffer",
469 	    KSTAT_DATA_UINT64);
470 	kstat_named_init(&ixgbe_ks->lroc, "lro_pkt_count",
471 	    KSTAT_DATA_UINT64);
472 
473 	kstat_named_init(&ixgbe_ks->dev_gone, "device_gone",
474 	    KSTAT_DATA_UINT64);
475 	/*
476 	 * Function to provide kernel stat update on demand
477 	 */
478 	ks->ks_update = ixgbe_update_stats;
479 
480 	ks->ks_private = (void *)ixgbe;
481 
482 	/*
483 	 * Add kstat to systems kstat chain
484 	 */
485 	kstat_install(ks);
486 
487 	return (IXGBE_SUCCESS);
488 }
489 
490 /*
491  * Retrieve a value for one of the statistics.
492  */
493 int
494 ixgbe_m_stat(void *arg, uint_t stat, uint64_t *val)
495 {
496 	ixgbe_t *ixgbe = (ixgbe_t *)arg;
497 	struct ixgbe_hw *hw = &ixgbe->hw;
498 	ixgbe_stat_t *ixgbe_ks;
499 	int i;
500 	ixgbe_link_speed speeds = 0;
501 
502 	ixgbe_ks = (ixgbe_stat_t *)ixgbe->ixgbe_ks->ks_data;
503 
504 	mutex_enter(&ixgbe->gen_lock);
505 
506 	/*
507 	 * We cannot always rely on the common code maintaining
508 	 * hw->phy.speeds_supported, therefore we fall back to use the recorded
509 	 * supported speeds which were obtained during instance init in
510 	 * ixgbe_init_params().
511 	 */
512 	speeds = hw->phy.speeds_supported;
513 	if (speeds == 0)
514 		speeds = ixgbe->speeds_supported;
515 
516 	if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
517 		mutex_exit(&ixgbe->gen_lock);
518 		return (ECANCELED);
519 	}
520 
521 	switch (stat) {
522 	case MAC_STAT_IFSPEED:
523 		*val = ixgbe->link_speed * 1000000ull;
524 		break;
525 
526 	case MAC_STAT_MULTIRCV:
527 		ixgbe_ks->mprc.value.ui64 +=
528 		    IXGBE_READ_REG(hw, IXGBE_MPRC);
529 		*val = ixgbe_ks->mprc.value.ui64;
530 		break;
531 
532 	case MAC_STAT_BRDCSTRCV:
533 		ixgbe_ks->bprc.value.ui64 +=
534 		    IXGBE_READ_REG(hw, IXGBE_BPRC);
535 		*val = ixgbe_ks->bprc.value.ui64;
536 		break;
537 
538 	case MAC_STAT_MULTIXMT:
539 		ixgbe_ks->mptc.value.ui64 +=
540 		    IXGBE_READ_REG(hw, IXGBE_MPTC);
541 		*val = ixgbe_ks->mptc.value.ui64;
542 		break;
543 
544 	case MAC_STAT_BRDCSTXMT:
545 		ixgbe_ks->bptc.value.ui64 +=
546 		    IXGBE_READ_REG(hw, IXGBE_BPTC);
547 		*val = ixgbe_ks->bptc.value.ui64;
548 		break;
549 
550 	case MAC_STAT_NORCVBUF:
551 		for (i = 0; i < 8; i++) {
552 			ixgbe_ks->rnbc.value.ui64 +=
553 			    IXGBE_READ_REG(hw, IXGBE_RNBC(i));
554 		}
555 		*val = ixgbe_ks->rnbc.value.ui64;
556 		break;
557 
558 	case MAC_STAT_IERRORS:
559 		ixgbe_ks->crcerrs.value.ui64 +=
560 		    IXGBE_READ_REG(hw, IXGBE_CRCERRS);
561 		ixgbe_ks->illerrc.value.ui64 +=
562 		    IXGBE_READ_REG(hw, IXGBE_ILLERRC);
563 		ixgbe_ks->errbc.value.ui64 +=
564 		    IXGBE_READ_REG(hw, IXGBE_ERRBC);
565 		ixgbe_ks->rlec.value.ui64 +=
566 		    IXGBE_READ_REG(hw, IXGBE_RLEC);
567 		*val = ixgbe_ks->crcerrs.value.ui64 +
568 		    ixgbe_ks->illerrc.value.ui64 +
569 		    ixgbe_ks->errbc.value.ui64 +
570 		    ixgbe_ks->rlec.value.ui64;
571 		break;
572 
573 	case MAC_STAT_RBYTES:
574 		ixgbe_ks->tor.value.ui64 = 0;
575 		for (i = 0; i < 16; i++) {
576 			ixgbe_ks->qbrc[i].value.ui64 +=
577 			    IXGBE_READ_REG(hw, IXGBE_QBRC(i));
578 			ixgbe_ks->tor.value.ui64 +=
579 			    ixgbe_ks->qbrc[i].value.ui64;
580 		}
581 		*val = ixgbe_ks->tor.value.ui64;
582 		break;
583 
584 	case MAC_STAT_OBYTES:
585 		ixgbe_ks->tot.value.ui64 = 0;
586 		for (i = 0; i < 16; i++) {
587 			switch (hw->mac.type) {
588 			case ixgbe_mac_82598EB:
589 				ixgbe_ks->qbtc[i].value.ui64 +=
590 				    IXGBE_READ_REG(hw, IXGBE_QBTC(i));
591 				break;
592 
593 			case ixgbe_mac_82599EB:
594 			case ixgbe_mac_X540:
595 			case ixgbe_mac_X550:
596 			case ixgbe_mac_X550EM_x:
597 			case ixgbe_mac_X550EM_a:
598 				ixgbe_ks->qbtc[i].value.ui64 +=
599 				    IXGBE_READ_REG(hw, IXGBE_QBTC_L(i));
600 				ixgbe_ks->qbtc[i].value.ui64 +=
601 				    ((uint64_t)((IXGBE_READ_REG(hw,
602 				    IXGBE_QBTC_H(i))) & 0xF) << 32);
603 				break;
604 
605 			default:
606 				break;
607 			}
608 			ixgbe_ks->tot.value.ui64 +=
609 			    ixgbe_ks->qbtc[i].value.ui64;
610 		}
611 		*val = ixgbe_ks->tot.value.ui64;
612 		break;
613 
614 	case MAC_STAT_IPACKETS:
615 		ixgbe_ks->tpr.value.ui64 +=
616 		    IXGBE_READ_REG(hw, IXGBE_TPR);
617 		*val = ixgbe_ks->tpr.value.ui64;
618 		break;
619 
620 	case MAC_STAT_OPACKETS:
621 		ixgbe_ks->tpt.value.ui64 +=
622 		    IXGBE_READ_REG(hw, IXGBE_TPT);
623 		*val = ixgbe_ks->tpt.value.ui64;
624 		break;
625 
626 	/* RFC 1643 stats */
627 	case ETHER_STAT_FCS_ERRORS:
628 		ixgbe_ks->crcerrs.value.ui64 +=
629 		    IXGBE_READ_REG(hw, IXGBE_CRCERRS);
630 		*val = ixgbe_ks->crcerrs.value.ui64;
631 		break;
632 
633 	case ETHER_STAT_TOOLONG_ERRORS:
634 		ixgbe_ks->roc.value.ui64 +=
635 		    IXGBE_READ_REG(hw, IXGBE_ROC);
636 		*val = ixgbe_ks->roc.value.ui64;
637 		break;
638 
639 	case ETHER_STAT_MACRCV_ERRORS:
640 		ixgbe_ks->crcerrs.value.ui64 +=
641 		    IXGBE_READ_REG(hw, IXGBE_CRCERRS);
642 		ixgbe_ks->illerrc.value.ui64 +=
643 		    IXGBE_READ_REG(hw, IXGBE_ILLERRC);
644 		ixgbe_ks->errbc.value.ui64 +=
645 		    IXGBE_READ_REG(hw, IXGBE_ERRBC);
646 		ixgbe_ks->rlec.value.ui64 +=
647 		    IXGBE_READ_REG(hw, IXGBE_RLEC);
648 		*val = ixgbe_ks->crcerrs.value.ui64 +
649 		    ixgbe_ks->illerrc.value.ui64 +
650 		    ixgbe_ks->errbc.value.ui64 +
651 		    ixgbe_ks->rlec.value.ui64;
652 		break;
653 
654 	/* MII/GMII stats */
655 	case ETHER_STAT_XCVR_ADDR:
656 		/* The Internal PHY's MDI address for each MAC is 1 */
657 		*val = 1;
658 		break;
659 
660 	case ETHER_STAT_XCVR_ID:
661 		*val = hw->phy.id;
662 		break;
663 
664 	case ETHER_STAT_XCVR_INUSE:
665 		switch (ixgbe->link_speed) {
666 		case IXGBE_LINK_SPEED_1GB_FULL:
667 			*val =
668 			    (hw->phy.media_type == ixgbe_media_type_copper) ?
669 			    XCVR_1000T : XCVR_1000X;
670 			break;
671 		case IXGBE_LINK_SPEED_100_FULL:
672 			*val = (hw->phy.media_type == ixgbe_media_type_copper) ?
673 			    XCVR_100T2 : XCVR_100X;
674 			break;
675 		default:
676 			*val = XCVR_NONE;
677 			break;
678 		}
679 		break;
680 
681 	case ETHER_STAT_CAP_10GFDX:
682 		*val = (speeds & IXGBE_LINK_SPEED_10GB_FULL) ? 1 : 0;
683 		break;
684 
685 	case ETHER_STAT_CAP_5000FDX:
686 		*val = (speeds & IXGBE_LINK_SPEED_5GB_FULL) ? 1 : 0;
687 		break;
688 
689 	case ETHER_STAT_CAP_2500FDX:
690 		*val = (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) ? 1 : 0;
691 		break;
692 
693 	case ETHER_STAT_CAP_1000FDX:
694 		*val = (speeds & IXGBE_LINK_SPEED_1GB_FULL) ? 1 : 0;
695 		break;
696 
697 	case ETHER_STAT_CAP_100FDX:
698 		*val = (speeds & IXGBE_LINK_SPEED_100_FULL) ? 1 : 0;
699 		break;
700 
701 	case ETHER_STAT_CAP_ASMPAUSE:
702 		*val = ixgbe->param_asym_pause_cap;
703 		break;
704 
705 	case ETHER_STAT_CAP_PAUSE:
706 		*val = ixgbe->param_pause_cap;
707 		break;
708 
709 	case ETHER_STAT_CAP_AUTONEG:
710 		*val = 1;
711 		break;
712 
713 	case ETHER_STAT_ADV_CAP_10GFDX:
714 		*val = ixgbe->param_adv_10000fdx_cap;
715 		break;
716 
717 	case ETHER_STAT_ADV_CAP_5000FDX:
718 		*val = ixgbe->param_adv_5000fdx_cap;
719 		break;
720 
721 	case ETHER_STAT_ADV_CAP_2500FDX:
722 		*val = ixgbe->param_adv_2500fdx_cap;
723 		break;
724 
725 	case ETHER_STAT_ADV_CAP_1000FDX:
726 		*val = ixgbe->param_adv_1000fdx_cap;
727 		break;
728 
729 	case ETHER_STAT_ADV_CAP_100FDX:
730 		*val = ixgbe->param_adv_100fdx_cap;
731 		break;
732 
733 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
734 		*val = ixgbe->param_adv_asym_pause_cap;
735 		break;
736 
737 	case ETHER_STAT_ADV_CAP_PAUSE:
738 		*val = ixgbe->param_adv_pause_cap;
739 		break;
740 
741 	case ETHER_STAT_ADV_CAP_AUTONEG:
742 		*val = ixgbe->param_adv_autoneg_cap;
743 		break;
744 
745 	case ETHER_STAT_LP_CAP_10GFDX:
746 		*val = ixgbe->param_lp_10000fdx_cap;
747 		break;
748 
749 	case ETHER_STAT_LP_CAP_5000FDX:
750 		*val = ixgbe->param_lp_5000fdx_cap;
751 		break;
752 
753 	case ETHER_STAT_LP_CAP_2500FDX:
754 		*val = ixgbe->param_lp_2500fdx_cap;
755 		break;
756 
757 	case ETHER_STAT_LP_CAP_1000FDX:
758 		*val = ixgbe->param_lp_1000fdx_cap;
759 		break;
760 
761 	case ETHER_STAT_LP_CAP_100FDX:
762 		*val = ixgbe->param_lp_100fdx_cap;
763 		break;
764 
765 	case ETHER_STAT_LP_CAP_ASMPAUSE:
766 		*val = ixgbe->param_lp_asym_pause_cap;
767 		break;
768 
769 	case ETHER_STAT_LP_CAP_PAUSE:
770 		*val = ixgbe->param_lp_pause_cap;
771 		break;
772 
773 	case ETHER_STAT_LP_CAP_AUTONEG:
774 		*val = ixgbe->param_lp_autoneg_cap;
775 		break;
776 
777 	case ETHER_STAT_LINK_ASMPAUSE:
778 		*val = ixgbe->param_asym_pause_cap;
779 		break;
780 
781 	case ETHER_STAT_LINK_PAUSE:
782 		*val = ixgbe->param_pause_cap;
783 		break;
784 
785 	case ETHER_STAT_LINK_AUTONEG:
786 		*val = ixgbe->param_adv_autoneg_cap;
787 		break;
788 
789 	case ETHER_STAT_LINK_DUPLEX:
790 		*val = ixgbe->link_duplex;
791 		break;
792 
793 	case ETHER_STAT_TOOSHORT_ERRORS:
794 		ixgbe_ks->ruc.value.ui64 +=
795 		    IXGBE_READ_REG(hw, IXGBE_RUC);
796 		*val = ixgbe_ks->ruc.value.ui64;
797 		break;
798 
799 	case ETHER_STAT_CAP_REMFAULT:
800 		*val = ixgbe->param_rem_fault;
801 		break;
802 
803 	case ETHER_STAT_ADV_REMFAULT:
804 		*val = ixgbe->param_adv_rem_fault;
805 		break;
806 
807 	case ETHER_STAT_LP_REMFAULT:
808 		*val = ixgbe->param_lp_rem_fault;
809 		break;
810 
811 	case ETHER_STAT_JABBER_ERRORS:
812 		ixgbe_ks->rjc.value.ui64 +=
813 		    IXGBE_READ_REG(hw, IXGBE_RJC);
814 		*val = ixgbe_ks->rjc.value.ui64;
815 		break;
816 
817 	default:
818 		mutex_exit(&ixgbe->gen_lock);
819 		return (ENOTSUP);
820 	}
821 
822 	mutex_exit(&ixgbe->gen_lock);
823 
824 	if (ixgbe_check_acc_handle(ixgbe->osdep.reg_handle) != DDI_FM_OK) {
825 		ddi_fm_service_impact(ixgbe->dip, DDI_SERVICE_DEGRADED);
826 		return (EIO);
827 	}
828 
829 	return (0);
830 }
831 
832 /*
833  * Retrieve a value for one of the statistics for a particular rx ring
834  */
835 int
836 ixgbe_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
837 {
838 	ixgbe_rx_ring_t	*rx_ring = (ixgbe_rx_ring_t *)rh;
839 	ixgbe_t *ixgbe = rx_ring->ixgbe;
840 
841 	if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
842 		return (ECANCELED);
843 	}
844 
845 	switch (stat) {
846 	case MAC_STAT_RBYTES:
847 		*val = rx_ring->stat_rbytes;
848 		break;
849 
850 	case MAC_STAT_IPACKETS:
851 		*val = rx_ring->stat_ipackets;
852 		break;
853 
854 	default:
855 		*val = 0;
856 		return (ENOTSUP);
857 	}
858 
859 	return (0);
860 }
861 
862 /*
863  * Retrieve a value for one of the statistics for a particular tx ring
864  */
865 int
866 ixgbe_tx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
867 {
868 	ixgbe_tx_ring_t	*tx_ring = (ixgbe_tx_ring_t *)rh;
869 	ixgbe_t *ixgbe = tx_ring->ixgbe;
870 
871 	if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
872 		return (ECANCELED);
873 	}
874 
875 	switch (stat) {
876 	case MAC_STAT_OBYTES:
877 		*val = tx_ring->stat_obytes;
878 		break;
879 
880 	case MAC_STAT_OPACKETS:
881 		*val = tx_ring->stat_opackets;
882 		break;
883 
884 	default:
885 		*val = 0;
886 		return (ENOTSUP);
887 	}
888 
889 	return (0);
890 }
891