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