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