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 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 	 * Function to provide kernel stat update on demand
471 	 */
472 	ks->ks_update = ixgbe_update_stats;
473 
474 	ks->ks_private = (void *)ixgbe;
475 
476 	/*
477 	 * Add kstat to systems kstat chain
478 	 */
479 	kstat_install(ks);
480 
481 	return (IXGBE_SUCCESS);
482 }
483 
484 /*
485  * Retrieve a value for one of the statistics.
486  */
487 int
488 ixgbe_m_stat(void *arg, uint_t stat, uint64_t *val)
489 {
490 	ixgbe_t *ixgbe = (ixgbe_t *)arg;
491 	struct ixgbe_hw *hw = &ixgbe->hw;
492 	ixgbe_stat_t *ixgbe_ks;
493 	int i;
494 	ixgbe_link_speed speeds = 0;
495 
496 	ixgbe_ks = (ixgbe_stat_t *)ixgbe->ixgbe_ks->ks_data;
497 
498 	mutex_enter(&ixgbe->gen_lock);
499 
500 	/*
501 	 * We cannot always rely on the common code maintaining
502 	 * hw->phy.speeds_supported, therefore we fall back to use the recorded
503 	 * supported speeds which were obtained during instance init in
504 	 * ixgbe_init_params().
505 	 */
506 	speeds = hw->phy.speeds_supported;
507 	if (speeds == 0)
508 		speeds = ixgbe->speeds_supported;
509 
510 	if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
511 		mutex_exit(&ixgbe->gen_lock);
512 		return (ECANCELED);
513 	}
514 
515 	switch (stat) {
516 	case MAC_STAT_IFSPEED:
517 		*val = ixgbe->link_speed * 1000000ull;
518 		break;
519 
520 	case MAC_STAT_MULTIRCV:
521 		ixgbe_ks->mprc.value.ui64 +=
522 		    IXGBE_READ_REG(hw, IXGBE_MPRC);
523 		*val = ixgbe_ks->mprc.value.ui64;
524 		break;
525 
526 	case MAC_STAT_BRDCSTRCV:
527 		ixgbe_ks->bprc.value.ui64 +=
528 		    IXGBE_READ_REG(hw, IXGBE_BPRC);
529 		*val = ixgbe_ks->bprc.value.ui64;
530 		break;
531 
532 	case MAC_STAT_MULTIXMT:
533 		ixgbe_ks->mptc.value.ui64 +=
534 		    IXGBE_READ_REG(hw, IXGBE_MPTC);
535 		*val = ixgbe_ks->mptc.value.ui64;
536 		break;
537 
538 	case MAC_STAT_BRDCSTXMT:
539 		ixgbe_ks->bptc.value.ui64 +=
540 		    IXGBE_READ_REG(hw, IXGBE_BPTC);
541 		*val = ixgbe_ks->bptc.value.ui64;
542 		break;
543 
544 	case MAC_STAT_NORCVBUF:
545 		for (i = 0; i < 8; i++) {
546 			ixgbe_ks->rnbc.value.ui64 +=
547 			    IXGBE_READ_REG(hw, IXGBE_RNBC(i));
548 		}
549 		*val = ixgbe_ks->rnbc.value.ui64;
550 		break;
551 
552 	case MAC_STAT_IERRORS:
553 		ixgbe_ks->crcerrs.value.ui64 +=
554 		    IXGBE_READ_REG(hw, IXGBE_CRCERRS);
555 		ixgbe_ks->illerrc.value.ui64 +=
556 		    IXGBE_READ_REG(hw, IXGBE_ILLERRC);
557 		ixgbe_ks->errbc.value.ui64 +=
558 		    IXGBE_READ_REG(hw, IXGBE_ERRBC);
559 		ixgbe_ks->rlec.value.ui64 +=
560 		    IXGBE_READ_REG(hw, IXGBE_RLEC);
561 		*val = ixgbe_ks->crcerrs.value.ui64 +
562 		    ixgbe_ks->illerrc.value.ui64 +
563 		    ixgbe_ks->errbc.value.ui64 +
564 		    ixgbe_ks->rlec.value.ui64;
565 		break;
566 
567 	case MAC_STAT_RBYTES:
568 		ixgbe_ks->tor.value.ui64 = 0;
569 		for (i = 0; i < 16; i++) {
570 			ixgbe_ks->qbrc[i].value.ui64 +=
571 			    IXGBE_READ_REG(hw, IXGBE_QBRC(i));
572 			ixgbe_ks->tor.value.ui64 +=
573 			    ixgbe_ks->qbrc[i].value.ui64;
574 		}
575 		*val = ixgbe_ks->tor.value.ui64;
576 		break;
577 
578 	case MAC_STAT_OBYTES:
579 		ixgbe_ks->tot.value.ui64 = 0;
580 		for (i = 0; i < 16; i++) {
581 			switch (hw->mac.type) {
582 			case ixgbe_mac_82598EB:
583 				ixgbe_ks->qbtc[i].value.ui64 +=
584 				    IXGBE_READ_REG(hw, IXGBE_QBTC(i));
585 				break;
586 
587 			case ixgbe_mac_82599EB:
588 			case ixgbe_mac_X540:
589 			case ixgbe_mac_X550:
590 			case ixgbe_mac_X550EM_x:
591 				ixgbe_ks->qbtc[i].value.ui64 +=
592 				    IXGBE_READ_REG(hw, IXGBE_QBTC_L(i));
593 				ixgbe_ks->qbtc[i].value.ui64 +=
594 				    ((uint64_t)((IXGBE_READ_REG(hw,
595 				    IXGBE_QBTC_H(i))) & 0xF) << 32);
596 				break;
597 
598 			default:
599 				break;
600 			}
601 			ixgbe_ks->tot.value.ui64 +=
602 			    ixgbe_ks->qbtc[i].value.ui64;
603 		}
604 		*val = ixgbe_ks->tot.value.ui64;
605 		break;
606 
607 	case MAC_STAT_IPACKETS:
608 		ixgbe_ks->tpr.value.ui64 +=
609 		    IXGBE_READ_REG(hw, IXGBE_TPR);
610 		*val = ixgbe_ks->tpr.value.ui64;
611 		break;
612 
613 	case MAC_STAT_OPACKETS:
614 		ixgbe_ks->tpt.value.ui64 +=
615 		    IXGBE_READ_REG(hw, IXGBE_TPT);
616 		*val = ixgbe_ks->tpt.value.ui64;
617 		break;
618 
619 	/* RFC 1643 stats */
620 	case ETHER_STAT_FCS_ERRORS:
621 		ixgbe_ks->crcerrs.value.ui64 +=
622 		    IXGBE_READ_REG(hw, IXGBE_CRCERRS);
623 		*val = ixgbe_ks->crcerrs.value.ui64;
624 		break;
625 
626 	case ETHER_STAT_TOOLONG_ERRORS:
627 		ixgbe_ks->roc.value.ui64 +=
628 		    IXGBE_READ_REG(hw, IXGBE_ROC);
629 		*val = ixgbe_ks->roc.value.ui64;
630 		break;
631 
632 	case ETHER_STAT_MACRCV_ERRORS:
633 		ixgbe_ks->crcerrs.value.ui64 +=
634 		    IXGBE_READ_REG(hw, IXGBE_CRCERRS);
635 		ixgbe_ks->illerrc.value.ui64 +=
636 		    IXGBE_READ_REG(hw, IXGBE_ILLERRC);
637 		ixgbe_ks->errbc.value.ui64 +=
638 		    IXGBE_READ_REG(hw, IXGBE_ERRBC);
639 		ixgbe_ks->rlec.value.ui64 +=
640 		    IXGBE_READ_REG(hw, IXGBE_RLEC);
641 		*val = ixgbe_ks->crcerrs.value.ui64 +
642 		    ixgbe_ks->illerrc.value.ui64 +
643 		    ixgbe_ks->errbc.value.ui64 +
644 		    ixgbe_ks->rlec.value.ui64;
645 		break;
646 
647 	/* MII/GMII stats */
648 	case ETHER_STAT_XCVR_ADDR:
649 		/* The Internal PHY's MDI address for each MAC is 1 */
650 		*val = 1;
651 		break;
652 
653 	case ETHER_STAT_XCVR_ID:
654 		*val = hw->phy.id;
655 		break;
656 
657 	case ETHER_STAT_XCVR_INUSE:
658 		switch (ixgbe->link_speed) {
659 		case IXGBE_LINK_SPEED_1GB_FULL:
660 			*val =
661 			    (hw->phy.media_type == ixgbe_media_type_copper) ?
662 			    XCVR_1000T : XCVR_1000X;
663 			break;
664 		case IXGBE_LINK_SPEED_100_FULL:
665 			*val = (hw->phy.media_type == ixgbe_media_type_copper) ?
666 			    XCVR_100T2 : XCVR_100X;
667 			break;
668 		default:
669 			*val = XCVR_NONE;
670 			break;
671 		}
672 		break;
673 
674 	case ETHER_STAT_CAP_10GFDX:
675 		*val = (speeds & IXGBE_LINK_SPEED_10GB_FULL) ? 1 : 0;
676 		break;
677 
678 	case ETHER_STAT_CAP_5000FDX:
679 		*val = (speeds & IXGBE_LINK_SPEED_5GB_FULL) ? 1 : 0;
680 		break;
681 
682 	case ETHER_STAT_CAP_2500FDX:
683 		*val = (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) ? 1 : 0;
684 		break;
685 
686 	case ETHER_STAT_CAP_1000FDX:
687 		*val = (speeds & IXGBE_LINK_SPEED_1GB_FULL) ? 1 : 0;
688 		break;
689 
690 	case ETHER_STAT_CAP_100FDX:
691 		*val = (speeds & IXGBE_LINK_SPEED_100_FULL) ? 1 : 0;
692 		break;
693 
694 	case ETHER_STAT_CAP_ASMPAUSE:
695 		*val = ixgbe->param_asym_pause_cap;
696 		break;
697 
698 	case ETHER_STAT_CAP_PAUSE:
699 		*val = ixgbe->param_pause_cap;
700 		break;
701 
702 	case ETHER_STAT_CAP_AUTONEG:
703 		*val = 1;
704 		break;
705 
706 	case ETHER_STAT_ADV_CAP_10GFDX:
707 		*val = ixgbe->param_adv_10000fdx_cap;
708 		break;
709 
710 	case ETHER_STAT_ADV_CAP_5000FDX:
711 		*val = ixgbe->param_adv_5000fdx_cap;
712 		break;
713 
714 	case ETHER_STAT_ADV_CAP_2500FDX:
715 		*val = ixgbe->param_adv_2500fdx_cap;
716 		break;
717 
718 	case ETHER_STAT_ADV_CAP_1000FDX:
719 		*val = ixgbe->param_adv_1000fdx_cap;
720 		break;
721 
722 	case ETHER_STAT_ADV_CAP_100FDX:
723 		*val = ixgbe->param_adv_100fdx_cap;
724 		break;
725 
726 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
727 		*val = ixgbe->param_adv_asym_pause_cap;
728 		break;
729 
730 	case ETHER_STAT_ADV_CAP_PAUSE:
731 		*val = ixgbe->param_adv_pause_cap;
732 		break;
733 
734 	case ETHER_STAT_ADV_CAP_AUTONEG:
735 		*val = ixgbe->param_adv_autoneg_cap;
736 		break;
737 
738 	case ETHER_STAT_LP_CAP_10GFDX:
739 		*val = ixgbe->param_lp_10000fdx_cap;
740 		break;
741 
742 	case ETHER_STAT_LP_CAP_5000FDX:
743 		*val = ixgbe->param_lp_5000fdx_cap;
744 		break;
745 
746 	case ETHER_STAT_LP_CAP_2500FDX:
747 		*val = ixgbe->param_lp_2500fdx_cap;
748 		break;
749 
750 	case ETHER_STAT_LP_CAP_1000FDX:
751 		*val = ixgbe->param_lp_1000fdx_cap;
752 		break;
753 
754 	case ETHER_STAT_LP_CAP_100FDX:
755 		*val = ixgbe->param_lp_100fdx_cap;
756 		break;
757 
758 	case ETHER_STAT_LP_CAP_ASMPAUSE:
759 		*val = ixgbe->param_lp_asym_pause_cap;
760 		break;
761 
762 	case ETHER_STAT_LP_CAP_PAUSE:
763 		*val = ixgbe->param_lp_pause_cap;
764 		break;
765 
766 	case ETHER_STAT_LP_CAP_AUTONEG:
767 		*val = ixgbe->param_lp_autoneg_cap;
768 		break;
769 
770 	case ETHER_STAT_LINK_ASMPAUSE:
771 		*val = ixgbe->param_asym_pause_cap;
772 		break;
773 
774 	case ETHER_STAT_LINK_PAUSE:
775 		*val = ixgbe->param_pause_cap;
776 		break;
777 
778 	case ETHER_STAT_LINK_AUTONEG:
779 		*val = ixgbe->param_adv_autoneg_cap;
780 		break;
781 
782 	case ETHER_STAT_LINK_DUPLEX:
783 		*val = ixgbe->link_duplex;
784 		break;
785 
786 	case ETHER_STAT_TOOSHORT_ERRORS:
787 		ixgbe_ks->ruc.value.ui64 +=
788 		    IXGBE_READ_REG(hw, IXGBE_RUC);
789 		*val = ixgbe_ks->ruc.value.ui64;
790 		break;
791 
792 	case ETHER_STAT_CAP_REMFAULT:
793 		*val = ixgbe->param_rem_fault;
794 		break;
795 
796 	case ETHER_STAT_ADV_REMFAULT:
797 		*val = ixgbe->param_adv_rem_fault;
798 		break;
799 
800 	case ETHER_STAT_LP_REMFAULT:
801 		*val = ixgbe->param_lp_rem_fault;
802 		break;
803 
804 	case ETHER_STAT_JABBER_ERRORS:
805 		ixgbe_ks->rjc.value.ui64 +=
806 		    IXGBE_READ_REG(hw, IXGBE_RJC);
807 		*val = ixgbe_ks->rjc.value.ui64;
808 		break;
809 
810 	default:
811 		mutex_exit(&ixgbe->gen_lock);
812 		return (ENOTSUP);
813 	}
814 
815 	mutex_exit(&ixgbe->gen_lock);
816 
817 	if (ixgbe_check_acc_handle(ixgbe->osdep.reg_handle) != DDI_FM_OK) {
818 		ddi_fm_service_impact(ixgbe->dip, DDI_SERVICE_DEGRADED);
819 		return (EIO);
820 	}
821 
822 	return (0);
823 }
824 
825 /*
826  * Retrieve a value for one of the statistics for a particular rx ring
827  */
828 int
829 ixgbe_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
830 {
831 	ixgbe_rx_ring_t	*rx_ring = (ixgbe_rx_ring_t *)rh;
832 	ixgbe_t *ixgbe = rx_ring->ixgbe;
833 
834 	if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
835 		return (ECANCELED);
836 	}
837 
838 	switch (stat) {
839 	case MAC_STAT_RBYTES:
840 		*val = rx_ring->stat_rbytes;
841 		break;
842 
843 	case MAC_STAT_IPACKETS:
844 		*val = rx_ring->stat_ipackets;
845 		break;
846 
847 	default:
848 		*val = 0;
849 		return (ENOTSUP);
850 	}
851 
852 	return (0);
853 }
854 
855 /*
856  * Retrieve a value for one of the statistics for a particular tx ring
857  */
858 int
859 ixgbe_tx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
860 {
861 	ixgbe_tx_ring_t	*tx_ring = (ixgbe_tx_ring_t *)rh;
862 	ixgbe_t *ixgbe = tx_ring->ixgbe;
863 
864 	if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
865 		return (ECANCELED);
866 	}
867 
868 	switch (stat) {
869 	case MAC_STAT_OBYTES:
870 		*val = tx_ring->stat_obytes;
871 		break;
872 
873 	case MAC_STAT_OPACKETS:
874 		*val = tx_ring->stat_opackets;
875 		break;
876 
877 	default:
878 		*val = 0;
879 		return (ENOTSUP);
880 	}
881 
882 	return (0);
883 }
884