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