xref: /illumos-gate/usr/src/uts/common/io/i40e/i40e_stats.c (revision 4c28a617e3922d92a58e813a5b955eb526b9c386)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
14  * Copyright 2016 Joyent, Inc.
15  */
16 
17 #include "i40e_sw.h"
18 
19 /*
20  * -------------------
21  * Statistics Overview
22  * -------------------
23  *
24  * As part of managing the driver and understanding what's going on, we keep
25  * track of statistics from two different sources:
26  *
27  *   - Statistics from the device
28  *   - Statistics maintained by the driver
29  *
30  * Generally, the hardware provides us traditional IETF and MIB Ethernet
31  * statistics, for example, the total packets in and out, various errors in
32  * packets, the negotiated status etc. The driver, on the other hand, primarily
33  * contains statistics around driver-specific issues, such as information about
34  * checksumming on receive and transmit and the data in and out of a specific
35  * ring.
36  *
37  * We export statistics in two different forms. The first form is the required
38  * GLDv3 endpoints, specifically:
39  *
40  *   - The general GLDv3 mc_getstat interface
41  *   - The GLDv3 ring mri_stat interface
42  *
43  * The second form that we export statistics is through kstats. kstats are
44  * exported in different ways. Particularly we arrange the kstats to monitor the
45  * layout of the device. Currently we have kstats which capture both the IEEE
46  * and driver-implementation specific stats. There are kstats for each of the
47  * following structures:
48  *
49  *   - Each physical function
50  *   - Each VSI
51  *   - Each Queue
52  *
53  * The PF's kstat is called 'pfstats' so as not to collide with other system
54  * provided kstats. Thus, for instance 0, usually the first PF, the full kstat
55  * would be: i40e:0:pfstats:.
56  *
57  * The kstat for each VSI is called vsi_%instance. So for the first PF, which is
58  * instance zero and the first vsi, which has id 0, it will be named vsi_0 and
59  * the full kstat would be i40e:0:vsi_0:.
60  *
61  * The kstat for each queue is trqpair_tx_%queue and trqpair_rx_%queue. Note
62  * that these are labeled based on their local index, which may mean that
63  * different instances have overlapping sets of queues. This isn't a problem as
64  * the kstats will always use the instance number of the pf to distinguish it in
65  * the kstat tuple.
66  *
67  * ---------------------
68  * Hardware Arrangements
69  * ---------------------
70  *
71  * The hardware keeps statistics at each physical function/MAC (PF) and it keeps
72  * statistics on each virtual station interface (VSI). Currently we only use one
73  * VSI per PF (see the i40e_main.c theory statement). The hardware has a limited
74  * number of statistics units available. While every PF is guaranteed to have a
75  * statistics unit, it is possible that we will run out for a given VSI. We'll
76  * have to figure out an appropriate strategy here when we end up supporting
77  * multiple VSIs.
78  *
79  * The hardware keeps these statistics as 32-bit and 48-bit counters. We are
80  * required to read them and then compute the differences between them. The
81  * 48-bit counters span more than one 32-bit register in the BAR. The hardware
82  * suggests that to read them, we perform 64-bit reads of the lower of the two
83  * registers that make up a 48-bit stat. The hardware guarantees that the reads
84  * of those two registers will be atomic and we'll get a consistent value, not a
85  * property it has for every read of two registers.
86  *
87  * For every kstat we have based on this, we have a corresponding uint64_t that
88  * we keep around as a base value in a separate structure. Whenever we read a
89  * value, we end up grabbing the current value, calculating a difference between
90  * the previously stored value and the current one, and updating the kstat with
91  * that difference. After which, we go through and update the base value that we
92  * stored. This is all encapsulated in i40e_stat_get_uint32() and
93  * i40e_stat_get_uint48().
94  *
95  * The only unfortunate thing here is that the hardware doesn't give us any kind
96  * of overflow counter. It just tries to make sure that the uint32_t and
97  * uint48_t counters are large enough to hopefully not overflow right away. This
98  * isn't the most reassuring statement and we should investigate ways of
99  * ensuring that if a system is active, but not actively measured, we don't lose
100  * data.
101  *
102  * The pf kstats data is stored in the i40e_t`i40e_pf_kstat. It is backed by the
103  * i40e_t`i40e_pf_stat structure. Similarly the VSI related kstat is in
104  * i40e_t`i40e_vsi_kstat and the data is backed in the i40e_t`i40e_vsi_stat. All
105  * of this data is protected by the i40e_stat_lock, which should be taken last,
106  * when acquiring locks.
107  */
108 
109 static void
110 i40e_stat_get_uint48(i40e_t *i40e, uintptr_t reg, kstat_named_t *kstat,
111     uint64_t *base, boolean_t init)
112 {
113 	i40e_hw_t *hw = &i40e->i40e_hw_space;
114 	uint64_t raw, delta;
115 
116 	ASSERT(MUTEX_HELD(&i40e->i40e_stat_lock));
117 
118 	raw = ddi_get64(i40e->i40e_osdep_space.ios_reg_handle,
119 	    (uint64_t *)((uintptr_t)hw->hw_addr + reg));
120 
121 	if (init == B_TRUE) {
122 		*base = raw;
123 		return;
124 	}
125 
126 	/*
127 	 * Check for wraparound, note that the counter is actually only 48-bits,
128 	 * even though it has two uint32_t regs present.
129 	 */
130 	if (raw >= *base) {
131 		delta = raw - *base;
132 	} else {
133 		delta = 0x1000000000000ULL - *base + raw;
134 	}
135 
136 	kstat->value.ui64 += delta;
137 	*base = raw;
138 }
139 
140 static void
141 i40e_stat_get_uint32(i40e_t *i40e, uintptr_t reg, kstat_named_t *kstat,
142     uint64_t *base, boolean_t init)
143 {
144 	i40e_hw_t *hw = &i40e->i40e_hw_space;
145 	uint64_t raw, delta;
146 
147 	ASSERT(MUTEX_HELD(&i40e->i40e_stat_lock));
148 
149 	raw = ddi_get32(i40e->i40e_osdep_space.ios_reg_handle,
150 	    (uint32_t *)((uintptr_t)hw->hw_addr + reg));
151 
152 	if (init == B_TRUE) {
153 		*base = raw;
154 		return;
155 	}
156 
157 	/*
158 	 * Watch out for wraparound as we only have a 32-bit counter.
159 	 */
160 	if (raw >= *base) {
161 		delta = raw - *base;
162 	} else {
163 		delta = 0x100000000ULL - *base + raw;
164 	}
165 
166 	kstat->value.ui64 += delta;
167 	*base = raw;
168 
169 }
170 
171 static void
172 i40e_stat_vsi_update(i40e_t *i40e, boolean_t init)
173 {
174 	i40e_vsi_stats_t *ivs;
175 	i40e_vsi_kstats_t *ivk;
176 	int id = i40e->i40e_vsi_stat_id;
177 
178 	ASSERT(i40e->i40e_vsi_kstat != NULL);
179 	ivs = &i40e->i40e_vsi_stat;
180 	ivk = i40e->i40e_vsi_kstat->ks_data;
181 
182 	mutex_enter(&i40e->i40e_stat_lock);
183 
184 	i40e_stat_get_uint48(i40e, I40E_GLV_GORCL(id), &ivk->ivk_rx_bytes,
185 	    &ivs->ivs_rx_bytes, init);
186 	i40e_stat_get_uint48(i40e, I40E_GLV_UPRCL(id), &ivk->ivk_rx_unicast,
187 	    &ivs->ivs_rx_unicast, init);
188 	i40e_stat_get_uint48(i40e, I40E_GLV_MPRCL(id), &ivk->ivk_rx_multicast,
189 	    &ivs->ivs_rx_multicast, init);
190 	i40e_stat_get_uint48(i40e, I40E_GLV_BPRCL(id), &ivk->ivk_rx_broadcast,
191 	    &ivs->ivs_rx_broadcast, init);
192 
193 	i40e_stat_get_uint32(i40e, I40E_GLV_RDPC(id), &ivk->ivk_rx_discards,
194 	    &ivs->ivs_rx_discards, init);
195 	i40e_stat_get_uint32(i40e, I40E_GLV_RUPP(id),
196 	    &ivk->ivk_rx_unknown_protocol,
197 	    &ivs->ivs_rx_unknown_protocol,
198 	    init);
199 
200 	i40e_stat_get_uint48(i40e, I40E_GLV_GOTCL(id), &ivk->ivk_tx_bytes,
201 	    &ivs->ivs_tx_bytes, init);
202 	i40e_stat_get_uint48(i40e, I40E_GLV_UPTCL(id), &ivk->ivk_tx_unicast,
203 	    &ivs->ivs_tx_unicast, init);
204 	i40e_stat_get_uint48(i40e, I40E_GLV_MPTCL(id), &ivk->ivk_tx_multicast,
205 	    &ivs->ivs_tx_multicast, init);
206 	i40e_stat_get_uint48(i40e, I40E_GLV_BPTCL(id), &ivk->ivk_tx_broadcast,
207 	    &ivs->ivs_tx_broadcast, init);
208 
209 	i40e_stat_get_uint32(i40e, I40E_GLV_TEPC(id), &ivk->ivk_tx_errors,
210 	    &ivs->ivs_tx_errors, init);
211 
212 	mutex_exit(&i40e->i40e_stat_lock);
213 
214 	/*
215 	 * We follow ixgbe's lead here and that if a kstat update didn't work
216 	 * 100% then we mark service unaffected as opposed to when fetching
217 	 * things for MAC directly.
218 	 */
219 	if (i40e_check_acc_handle(i40e->i40e_osdep_space.ios_reg_handle) !=
220 	    DDI_FM_OK) {
221 		ddi_fm_service_impact(i40e->i40e_dip, DDI_SERVICE_UNAFFECTED);
222 	}
223 }
224 
225 static int
226 i40e_stat_vsi_kstat_update(kstat_t *ksp, int rw)
227 {
228 	i40e_t *i40e;
229 
230 	if (rw == KSTAT_WRITE)
231 		return (EACCES);
232 
233 	i40e = ksp->ks_private;
234 	i40e_stat_vsi_update(i40e, B_FALSE);
235 	return (0);
236 }
237 
238 void
239 i40e_stat_vsi_fini(i40e_t *i40e)
240 {
241 	if (i40e->i40e_vsi_kstat != NULL) {
242 		kstat_delete(i40e->i40e_vsi_kstat);
243 		i40e->i40e_vsi_kstat = NULL;
244 	}
245 }
246 
247 boolean_t
248 i40e_stat_vsi_init(i40e_t *i40e)
249 {
250 	kstat_t *ksp;
251 	i40e_vsi_kstats_t *ivk;
252 	char buf[64];
253 
254 	(void) snprintf(buf, sizeof (buf), "vsi_%d", i40e->i40e_vsi_id);
255 
256 	ksp = kstat_create(I40E_MODULE_NAME, ddi_get_instance(i40e->i40e_dip),
257 	    buf, "net", KSTAT_TYPE_NAMED,
258 	    sizeof (i40e_vsi_kstats_t) / sizeof (kstat_named_t), 0);
259 
260 	if (ksp == NULL) {
261 		i40e_error(i40e, "Failed to create kstats for VSI %d",
262 		    i40e->i40e_vsi_id);
263 		return (B_FALSE);
264 	}
265 
266 	i40e->i40e_vsi_kstat = ksp;
267 	ivk = ksp->ks_data;
268 	ksp->ks_update = i40e_stat_vsi_kstat_update;
269 	ksp->ks_private = i40e;
270 
271 	kstat_named_init(&ivk->ivk_rx_bytes, "rx_bytes",
272 	    KSTAT_DATA_UINT64);
273 	kstat_named_init(&ivk->ivk_rx_unicast, "rx_unicast",
274 	    KSTAT_DATA_UINT64);
275 	kstat_named_init(&ivk->ivk_rx_multicast, "rx_multicast",
276 	    KSTAT_DATA_UINT64);
277 	kstat_named_init(&ivk->ivk_rx_broadcast, "rx_broadcast",
278 	    KSTAT_DATA_UINT64);
279 	kstat_named_init(&ivk->ivk_rx_discards, "rx_discards",
280 	    KSTAT_DATA_UINT64);
281 	kstat_named_init(&ivk->ivk_rx_unknown_protocol, "rx_unknown_protocol",
282 	    KSTAT_DATA_UINT64);
283 	kstat_named_init(&ivk->ivk_tx_bytes, "tx_bytes",
284 	    KSTAT_DATA_UINT64);
285 	kstat_named_init(&ivk->ivk_tx_unicast, "tx_unicast",
286 	    KSTAT_DATA_UINT64);
287 	kstat_named_init(&ivk->ivk_tx_multicast, "tx_multicast",
288 	    KSTAT_DATA_UINT64);
289 	kstat_named_init(&ivk->ivk_tx_broadcast, "tx_broadcast",
290 	    KSTAT_DATA_UINT64);
291 	kstat_named_init(&ivk->ivk_tx_errors, "tx_errors",
292 	    KSTAT_DATA_UINT64);
293 
294 	bzero(&i40e->i40e_vsi_stat, sizeof (i40e_vsi_stats_t));
295 	i40e_stat_vsi_update(i40e, B_TRUE);
296 	kstat_install(i40e->i40e_vsi_kstat);
297 
298 	return (B_TRUE);
299 }
300 
301 static void
302 i40e_stat_pf_update(i40e_t *i40e, boolean_t init)
303 {
304 	i40e_pf_stats_t *ips;
305 	i40e_pf_kstats_t *ipk;
306 	int port = i40e->i40e_hw_space.port;
307 	int i;
308 
309 	ASSERT(i40e->i40e_pf_kstat != NULL);
310 	ips = &i40e->i40e_pf_stat;
311 	ipk = i40e->i40e_pf_kstat->ks_data;
312 
313 	mutex_enter(&i40e->i40e_stat_lock);
314 
315 	/* 64-bit PCIe regs */
316 	i40e_stat_get_uint48(i40e, I40E_GLPRT_GORCL(port),
317 	    &ipk->ipk_rx_bytes, &ips->ips_rx_bytes, init);
318 	i40e_stat_get_uint48(i40e, I40E_GLPRT_UPRCL(port),
319 	    &ipk->ipk_rx_unicast, &ips->ips_rx_unicast, init);
320 	i40e_stat_get_uint48(i40e, I40E_GLPRT_MPRCL(port),
321 	    &ipk->ipk_rx_multicast, &ips->ips_rx_multicast, init);
322 	i40e_stat_get_uint48(i40e, I40E_GLPRT_BPRCL(port),
323 	    &ipk->ipk_rx_broadcast, &ips->ips_rx_broadcast, init);
324 	i40e_stat_get_uint48(i40e, I40E_GLPRT_GOTCL(port),
325 	    &ipk->ipk_tx_bytes, &ips->ips_tx_bytes, init);
326 	i40e_stat_get_uint48(i40e, I40E_GLPRT_UPTCL(port),
327 	    &ipk->ipk_tx_unicast, &ips->ips_tx_unicast, init);
328 	i40e_stat_get_uint48(i40e, I40E_GLPRT_MPTCL(port),
329 	    &ipk->ipk_tx_multicast, &ips->ips_tx_multicast, init);
330 	i40e_stat_get_uint48(i40e, I40E_GLPRT_BPTCL(port),
331 	    &ipk->ipk_tx_broadcast, &ips->ips_tx_broadcast, init);
332 
333 	i40e_stat_get_uint48(i40e, I40E_GLPRT_PRC64L(port),
334 	    &ipk->ipk_rx_size_64, &ips->ips_rx_size_64, init);
335 	i40e_stat_get_uint48(i40e, I40E_GLPRT_PRC127L(port),
336 	    &ipk->ipk_rx_size_127, &ips->ips_rx_size_127, init);
337 	i40e_stat_get_uint48(i40e, I40E_GLPRT_PRC255L(port),
338 	    &ipk->ipk_rx_size_255, &ips->ips_rx_size_255, init);
339 	i40e_stat_get_uint48(i40e, I40E_GLPRT_PRC511L(port),
340 	    &ipk->ipk_rx_size_511, &ips->ips_rx_size_511, init);
341 	i40e_stat_get_uint48(i40e, I40E_GLPRT_PRC1023L(port),
342 	    &ipk->ipk_rx_size_1023, &ips->ips_rx_size_1023, init);
343 	i40e_stat_get_uint48(i40e, I40E_GLPRT_PRC1522L(port),
344 	    &ipk->ipk_rx_size_1522, &ips->ips_rx_size_1522, init);
345 	i40e_stat_get_uint48(i40e, I40E_GLPRT_PRC9522L(port),
346 	    &ipk->ipk_rx_size_9522, &ips->ips_rx_size_9522, init);
347 
348 	i40e_stat_get_uint48(i40e, I40E_GLPRT_PTC64L(port),
349 	    &ipk->ipk_tx_size_64, &ips->ips_tx_size_64, init);
350 	i40e_stat_get_uint48(i40e, I40E_GLPRT_PTC127L(port),
351 	    &ipk->ipk_tx_size_127, &ips->ips_tx_size_127, init);
352 	i40e_stat_get_uint48(i40e, I40E_GLPRT_PTC255L(port),
353 	    &ipk->ipk_tx_size_255, &ips->ips_tx_size_255, init);
354 	i40e_stat_get_uint48(i40e, I40E_GLPRT_PTC511L(port),
355 	    &ipk->ipk_tx_size_511, &ips->ips_tx_size_511, init);
356 	i40e_stat_get_uint48(i40e, I40E_GLPRT_PTC1023L(port),
357 	    &ipk->ipk_tx_size_1023, &ips->ips_tx_size_1023, init);
358 	i40e_stat_get_uint48(i40e, I40E_GLPRT_PTC1522L(port),
359 	    &ipk->ipk_tx_size_1522, &ips->ips_tx_size_1522, init);
360 	i40e_stat_get_uint48(i40e, I40E_GLPRT_PTC9522L(port),
361 	    &ipk->ipk_tx_size_9522, &ips->ips_tx_size_9522, init);
362 
363 	/* 32-bit PCIe regs */
364 	i40e_stat_get_uint32(i40e, I40E_GLPRT_LXONRXC(port),
365 	    &ipk->ipk_link_xon_rx, &ips->ips_link_xon_rx, init);
366 	i40e_stat_get_uint32(i40e, I40E_GLPRT_LXOFFRXC(port),
367 	    &ipk->ipk_link_xoff_rx, &ips->ips_link_xoff_rx, init);
368 	i40e_stat_get_uint32(i40e, I40E_GLPRT_LXONTXC(port),
369 	    &ipk->ipk_link_xon_tx, &ips->ips_link_xon_tx, init);
370 	i40e_stat_get_uint32(i40e, I40E_GLPRT_LXOFFTXC(port),
371 	    &ipk->ipk_link_xoff_tx, &ips->ips_link_xoff_tx, init);
372 
373 	for (i = 0; i < 8; i++) {
374 		i40e_stat_get_uint32(i40e, I40E_GLPRT_PXONRXC(port, i),
375 		    &ipk->ipk_priority_xon_rx[i], &ips->ips_priority_xon_rx[i],
376 		    init);
377 		i40e_stat_get_uint32(i40e, I40E_GLPRT_PXOFFRXC(port, i),
378 		    &ipk->ipk_priority_xoff_rx[i],
379 		    &ips->ips_priority_xoff_rx[i],
380 		    init);
381 		i40e_stat_get_uint32(i40e, I40E_GLPRT_PXONTXC(port, i),
382 		    &ipk->ipk_priority_xon_tx[i], &ips->ips_priority_xon_tx[i],
383 		    init);
384 		i40e_stat_get_uint32(i40e, I40E_GLPRT_PXOFFTXC(port, i),
385 		    &ipk->ipk_priority_xoff_tx[i],
386 		    &ips->ips_priority_xoff_tx[i],
387 		    init);
388 		i40e_stat_get_uint32(i40e, I40E_GLPRT_RXON2OFFCNT(port, i),
389 		    &ipk->ipk_priority_xon_2_xoff[i],
390 		    &ips->ips_priority_xon_2_xoff[i],
391 		    init);
392 	}
393 
394 	i40e_stat_get_uint32(i40e, I40E_GLPRT_CRCERRS(port),
395 	    &ipk->ipk_crc_errors, &ips->ips_crc_errors, init);
396 	i40e_stat_get_uint32(i40e, I40E_GLPRT_ILLERRC(port),
397 	    &ipk->ipk_illegal_bytes, &ips->ips_illegal_bytes, init);
398 	i40e_stat_get_uint32(i40e, I40E_GLPRT_MLFC(port),
399 	    &ipk->ipk_mac_local_faults, &ips->ips_mac_local_faults, init);
400 	i40e_stat_get_uint32(i40e, I40E_GLPRT_MRFC(port),
401 	    &ipk->ipk_mac_remote_faults, &ips->ips_mac_remote_faults, init);
402 	i40e_stat_get_uint32(i40e, I40E_GLPRT_RLEC(port),
403 	    &ipk->ipk_rx_length_errors, &ips->ips_rx_length_errors, init);
404 	i40e_stat_get_uint32(i40e, I40E_GLPRT_RUC(port),
405 	    &ipk->ipk_rx_undersize, &ips->ips_rx_undersize, init);
406 	i40e_stat_get_uint32(i40e, I40E_GLPRT_RFC(port),
407 	    &ipk->ipk_rx_fragments, &ips->ips_rx_fragments, init);
408 	i40e_stat_get_uint32(i40e, I40E_GLPRT_ROC(port),
409 	    &ipk->ipk_rx_oversize, &ips->ips_rx_oversize, init);
410 	i40e_stat_get_uint32(i40e, I40E_GLPRT_RJC(port),
411 	    &ipk->ipk_rx_jabber, &ips->ips_rx_jabber, init);
412 	i40e_stat_get_uint32(i40e, I40E_GLPRT_RDPC(port),
413 	    &ipk->ipk_rx_discards, &ips->ips_rx_discards, init);
414 	i40e_stat_get_uint32(i40e, I40E_GLPRT_LDPC(port),
415 	    &ipk->ipk_rx_vm_discards, &ips->ips_rx_vm_discards, init);
416 	i40e_stat_get_uint32(i40e, I40E_GLPRT_MSPDC(port),
417 	    &ipk->ipk_rx_short_discards, &ips->ips_rx_short_discards, init);
418 	i40e_stat_get_uint32(i40e, I40E_GLPRT_TDOLD(port),
419 	    &ipk->ipk_tx_dropped_link_down, &ips->ips_tx_dropped_link_down,
420 	    init);
421 	i40e_stat_get_uint32(i40e, I40E_GLPRT_RUPP(port),
422 	    &ipk->ipk_rx_unknown_protocol, &ips->ips_rx_unknown_protocol, init);
423 
424 	/* 64-bit */
425 	i40e_stat_get_uint48(i40e, I40E_GL_RXERR1_L(port), &ipk->ipk_rx_err1,
426 	    &ips->ips_rx_err1, init);
427 	i40e_stat_get_uint48(i40e, I40E_GL_RXERR2_L(port), &ipk->ipk_rx_err2,
428 	    &ips->ips_rx_err2, init);
429 
430 	mutex_exit(&i40e->i40e_stat_lock);
431 
432 	/*
433 	 * We follow ixgbe's lead here and that if a kstat update didn't work
434 	 * 100% then we mark service unaffected as opposed to when fetching
435 	 * things for MAC directly.
436 	 */
437 	if (i40e_check_acc_handle(i40e->i40e_osdep_space.ios_reg_handle) !=
438 	    DDI_FM_OK) {
439 		ddi_fm_service_impact(i40e->i40e_dip, DDI_SERVICE_UNAFFECTED);
440 	}
441 }
442 
443 static int
444 i40e_stat_pf_kstat_update(kstat_t *ksp, int rw)
445 {
446 	i40e_t *i40e;
447 
448 	if (rw == KSTAT_WRITE)
449 		return (EACCES);
450 
451 	i40e = ksp->ks_private;
452 	i40e_stat_pf_update(i40e, B_FALSE);
453 	return (0);
454 }
455 
456 
457 static boolean_t
458 i40e_stat_pf_init(i40e_t *i40e)
459 {
460 	kstat_t *ksp;
461 	i40e_pf_kstats_t *ipk;
462 
463 	ksp = kstat_create(I40E_MODULE_NAME, ddi_get_instance(i40e->i40e_dip),
464 	    "pfstats", "net", KSTAT_TYPE_NAMED,
465 	    sizeof (i40e_pf_kstats_t) / sizeof (kstat_named_t), 0);
466 	if (ksp == NULL) {
467 		i40e_error(i40e, "Could not create kernel statistics.");
468 		return (B_FALSE);
469 	}
470 
471 	i40e->i40e_pf_kstat = ksp;
472 	ipk = ksp->ks_data;
473 	ksp->ks_update = i40e_stat_pf_kstat_update;
474 	ksp->ks_private = i40e;
475 
476 	kstat_named_init(&ipk->ipk_rx_bytes, "rx_bytes",
477 	    KSTAT_DATA_UINT64);
478 	kstat_named_init(&ipk->ipk_rx_unicast, "rx_unicast",
479 	    KSTAT_DATA_UINT64);
480 	kstat_named_init(&ipk->ipk_rx_multicast, "rx_multicast",
481 	    KSTAT_DATA_UINT64);
482 	kstat_named_init(&ipk->ipk_rx_broadcast, "rx_broadcast",
483 	    KSTAT_DATA_UINT64);
484 	kstat_named_init(&ipk->ipk_tx_bytes, "tx_bytes",
485 	    KSTAT_DATA_UINT64);
486 	kstat_named_init(&ipk->ipk_tx_unicast, "tx_unicast",
487 	    KSTAT_DATA_UINT64);
488 	kstat_named_init(&ipk->ipk_tx_multicast, "tx_multicast",
489 	    KSTAT_DATA_UINT64);
490 	kstat_named_init(&ipk->ipk_tx_broadcast, "tx_broadcast",
491 	    KSTAT_DATA_UINT64);
492 
493 	kstat_named_init(&ipk->ipk_rx_size_64, "rx_size_64",
494 	    KSTAT_DATA_UINT64);
495 	kstat_named_init(&ipk->ipk_rx_size_127, "rx_size_127",
496 	    KSTAT_DATA_UINT64);
497 	kstat_named_init(&ipk->ipk_rx_size_255, "rx_size_255",
498 	    KSTAT_DATA_UINT64);
499 	kstat_named_init(&ipk->ipk_rx_size_511, "rx_size_511",
500 	    KSTAT_DATA_UINT64);
501 	kstat_named_init(&ipk->ipk_rx_size_1023, "rx_size_1023",
502 	    KSTAT_DATA_UINT64);
503 	kstat_named_init(&ipk->ipk_rx_size_1522, "rx_size_1522",
504 	    KSTAT_DATA_UINT64);
505 	kstat_named_init(&ipk->ipk_rx_size_9522, "rx_size_9522",
506 	    KSTAT_DATA_UINT64);
507 
508 	kstat_named_init(&ipk->ipk_tx_size_64, "tx_size_64",
509 	    KSTAT_DATA_UINT64);
510 	kstat_named_init(&ipk->ipk_tx_size_127, "tx_size_127",
511 	    KSTAT_DATA_UINT64);
512 	kstat_named_init(&ipk->ipk_tx_size_255, "tx_size_255",
513 	    KSTAT_DATA_UINT64);
514 	kstat_named_init(&ipk->ipk_tx_size_511, "tx_size_511",
515 	    KSTAT_DATA_UINT64);
516 	kstat_named_init(&ipk->ipk_tx_size_1023, "tx_size_1023",
517 	    KSTAT_DATA_UINT64);
518 	kstat_named_init(&ipk->ipk_tx_size_1522, "tx_size_1522",
519 	    KSTAT_DATA_UINT64);
520 	kstat_named_init(&ipk->ipk_tx_size_9522, "tx_size_9522",
521 	    KSTAT_DATA_UINT64);
522 
523 	kstat_named_init(&ipk->ipk_link_xon_rx, "link_xon_rx",
524 	    KSTAT_DATA_UINT64);
525 	kstat_named_init(&ipk->ipk_link_xoff_rx, "link_xoff_rx",
526 	    KSTAT_DATA_UINT64);
527 	kstat_named_init(&ipk->ipk_link_xon_tx, "link_xon_tx",
528 	    KSTAT_DATA_UINT64);
529 	kstat_named_init(&ipk->ipk_link_xoff_tx, "link_xoff_tx",
530 	    KSTAT_DATA_UINT64);
531 
532 	kstat_named_init(&ipk->ipk_priority_xon_rx[0], "priority_xon_rx[0]",
533 	    KSTAT_DATA_UINT64);
534 	kstat_named_init(&ipk->ipk_priority_xoff_rx[0], "priority_xoff_rx[0]",
535 	    KSTAT_DATA_UINT64);
536 	kstat_named_init(&ipk->ipk_priority_xon_tx[0], "priority_xon_tx[0]",
537 	    KSTAT_DATA_UINT64);
538 	kstat_named_init(&ipk->ipk_priority_xoff_tx[0], "priority_xoff_tx[0]",
539 	    KSTAT_DATA_UINT64);
540 	kstat_named_init(&ipk->ipk_priority_xon_2_xoff[0],
541 	    "priority_xon_2_xoff[0]",
542 	    KSTAT_DATA_UINT64);
543 
544 	kstat_named_init(&ipk->ipk_priority_xon_rx[1], "priority_xon_rx[1]",
545 	    KSTAT_DATA_UINT64);
546 	kstat_named_init(&ipk->ipk_priority_xoff_rx[1], "priority_xoff_rx[1]",
547 	    KSTAT_DATA_UINT64);
548 	kstat_named_init(&ipk->ipk_priority_xon_tx[1], "priority_xon_tx[1]",
549 	    KSTAT_DATA_UINT64);
550 	kstat_named_init(&ipk->ipk_priority_xoff_tx[1], "priority_xoff_tx[1]",
551 	    KSTAT_DATA_UINT64);
552 	kstat_named_init(&ipk->ipk_priority_xon_2_xoff[1],
553 	    "priority_xon_2_xoff[1]",
554 	    KSTAT_DATA_UINT64);
555 
556 	kstat_named_init(&ipk->ipk_priority_xon_rx[2], "priority_xon_rx[2]",
557 	    KSTAT_DATA_UINT64);
558 	kstat_named_init(&ipk->ipk_priority_xoff_rx[2], "priority_xoff_rx[2]",
559 	    KSTAT_DATA_UINT64);
560 	kstat_named_init(&ipk->ipk_priority_xon_tx[2], "priority_xon_tx[2]",
561 	    KSTAT_DATA_UINT64);
562 	kstat_named_init(&ipk->ipk_priority_xoff_tx[2], "priority_xoff_tx[2]",
563 	    KSTAT_DATA_UINT64);
564 	kstat_named_init(&ipk->ipk_priority_xon_2_xoff[2],
565 	    "priority_xon_2_xoff[2]",
566 	    KSTAT_DATA_UINT64);
567 
568 	kstat_named_init(&ipk->ipk_priority_xon_rx[3], "priority_xon_rx[3]",
569 	    KSTAT_DATA_UINT64);
570 	kstat_named_init(&ipk->ipk_priority_xoff_rx[3], "priority_xoff_rx[3]",
571 	    KSTAT_DATA_UINT64);
572 	kstat_named_init(&ipk->ipk_priority_xon_tx[3], "priority_xon_tx[3]",
573 	    KSTAT_DATA_UINT64);
574 	kstat_named_init(&ipk->ipk_priority_xoff_tx[3], "priority_xoff_tx[3]",
575 	    KSTAT_DATA_UINT64);
576 	kstat_named_init(&ipk->ipk_priority_xon_2_xoff[3],
577 	    "priority_xon_2_xoff[3]",
578 	    KSTAT_DATA_UINT64);
579 
580 	kstat_named_init(&ipk->ipk_priority_xon_rx[4], "priority_xon_rx[4]",
581 	    KSTAT_DATA_UINT64);
582 	kstat_named_init(&ipk->ipk_priority_xoff_rx[4], "priority_xoff_rx[4]",
583 	    KSTAT_DATA_UINT64);
584 	kstat_named_init(&ipk->ipk_priority_xon_tx[4], "priority_xon_tx[4]",
585 	    KSTAT_DATA_UINT64);
586 	kstat_named_init(&ipk->ipk_priority_xoff_tx[4], "priority_xoff_tx[4]",
587 	    KSTAT_DATA_UINT64);
588 	kstat_named_init(&ipk->ipk_priority_xon_2_xoff[4],
589 	    "priority_xon_2_xoff[4]",
590 	    KSTAT_DATA_UINT64);
591 
592 	kstat_named_init(&ipk->ipk_priority_xon_rx[5], "priority_xon_rx[5]",
593 	    KSTAT_DATA_UINT64);
594 	kstat_named_init(&ipk->ipk_priority_xoff_rx[5], "priority_xoff_rx[5]",
595 	    KSTAT_DATA_UINT64);
596 	kstat_named_init(&ipk->ipk_priority_xon_tx[5], "priority_xon_tx[5]",
597 	    KSTAT_DATA_UINT64);
598 	kstat_named_init(&ipk->ipk_priority_xoff_tx[5], "priority_xoff_tx[5]",
599 	    KSTAT_DATA_UINT64);
600 	kstat_named_init(&ipk->ipk_priority_xon_2_xoff[5],
601 	    "priority_xon_2_xoff[5]",
602 	    KSTAT_DATA_UINT64);
603 
604 	kstat_named_init(&ipk->ipk_priority_xon_rx[6], "priority_xon_rx[6]",
605 	    KSTAT_DATA_UINT64);
606 	kstat_named_init(&ipk->ipk_priority_xoff_rx[6], "priority_xoff_rx[6]",
607 	    KSTAT_DATA_UINT64);
608 	kstat_named_init(&ipk->ipk_priority_xon_tx[6], "priority_xon_tx[6]",
609 	    KSTAT_DATA_UINT64);
610 	kstat_named_init(&ipk->ipk_priority_xoff_tx[6], "priority_xoff_tx[6]",
611 	    KSTAT_DATA_UINT64);
612 	kstat_named_init(&ipk->ipk_priority_xon_2_xoff[6],
613 	    "priority_xon_2_xoff[6]",
614 	    KSTAT_DATA_UINT64);
615 
616 	kstat_named_init(&ipk->ipk_priority_xon_rx[7], "priority_xon_rx[7]",
617 	    KSTAT_DATA_UINT64);
618 	kstat_named_init(&ipk->ipk_priority_xoff_rx[7], "priority_xoff_rx[7]",
619 	    KSTAT_DATA_UINT64);
620 	kstat_named_init(&ipk->ipk_priority_xon_tx[7], "priority_xon_tx[7]",
621 	    KSTAT_DATA_UINT64);
622 	kstat_named_init(&ipk->ipk_priority_xoff_tx[7], "priority_xoff_tx[7]",
623 	    KSTAT_DATA_UINT64);
624 	kstat_named_init(&ipk->ipk_priority_xon_2_xoff[7],
625 	    "priority_xon_2_xoff[7]",
626 	    KSTAT_DATA_UINT64);
627 
628 	kstat_named_init(&ipk->ipk_crc_errors, "crc_errors",
629 	    KSTAT_DATA_UINT64);
630 	kstat_named_init(&ipk->ipk_illegal_bytes, "illegal_bytes",
631 	    KSTAT_DATA_UINT64);
632 	kstat_named_init(&ipk->ipk_mac_local_faults, "mac_local_faults",
633 	    KSTAT_DATA_UINT64);
634 	kstat_named_init(&ipk->ipk_mac_remote_faults, "mac_remote_faults",
635 	    KSTAT_DATA_UINT64);
636 	kstat_named_init(&ipk->ipk_rx_length_errors, "rx_length_errors",
637 	    KSTAT_DATA_UINT64);
638 	kstat_named_init(&ipk->ipk_rx_undersize, "rx_undersize",
639 	    KSTAT_DATA_UINT64);
640 	kstat_named_init(&ipk->ipk_rx_fragments, "rx_fragments",
641 	    KSTAT_DATA_UINT64);
642 	kstat_named_init(&ipk->ipk_rx_oversize, "rx_oversize",
643 	    KSTAT_DATA_UINT64);
644 	kstat_named_init(&ipk->ipk_rx_jabber, "rx_jabber",
645 	    KSTAT_DATA_UINT64);
646 	kstat_named_init(&ipk->ipk_rx_discards, "rx_discards",
647 	    KSTAT_DATA_UINT64);
648 	kstat_named_init(&ipk->ipk_rx_vm_discards, "rx_vm_discards",
649 	    KSTAT_DATA_UINT64);
650 	kstat_named_init(&ipk->ipk_rx_short_discards, "rx_short_discards",
651 	    KSTAT_DATA_UINT64);
652 	kstat_named_init(&ipk->ipk_tx_dropped_link_down, "tx_dropped_link_down",
653 	    KSTAT_DATA_UINT64);
654 	kstat_named_init(&ipk->ipk_rx_unknown_protocol, "rx_unknown_protocol",
655 	    KSTAT_DATA_UINT64);
656 	kstat_named_init(&ipk->ipk_rx_err1, "rx_err1",
657 	    KSTAT_DATA_UINT64);
658 	kstat_named_init(&ipk->ipk_rx_err2, "rx_err2",
659 	    KSTAT_DATA_UINT64);
660 
661 
662 	bzero(&i40e->i40e_pf_stat, sizeof (i40e_pf_stats_t));
663 	i40e_stat_pf_update(i40e, B_TRUE);
664 
665 	kstat_install(i40e->i40e_pf_kstat);
666 
667 	return (B_TRUE);
668 }
669 
670 void
671 i40e_stats_fini(i40e_t *i40e)
672 {
673 	ASSERT(i40e->i40e_vsi_kstat == NULL);
674 	if (i40e->i40e_pf_kstat != NULL) {
675 		kstat_delete(i40e->i40e_pf_kstat);
676 		i40e->i40e_pf_kstat = NULL;
677 	}
678 
679 	mutex_destroy(&i40e->i40e_stat_lock);
680 }
681 
682 boolean_t
683 i40e_stats_init(i40e_t *i40e)
684 {
685 	mutex_init(&i40e->i40e_stat_lock, NULL, MUTEX_DRIVER, NULL);
686 	if (i40e_stat_pf_init(i40e) == B_FALSE) {
687 		mutex_destroy(&i40e->i40e_stat_lock);
688 		return (B_FALSE);
689 	}
690 
691 	return (B_TRUE);
692 }
693 
694 /*
695  * For Nemo/GLDv3.
696  */
697 int
698 i40e_m_stat(void *arg, uint_t stat, uint64_t *val)
699 {
700 	i40e_t *i40e = (i40e_t *)arg;
701 	i40e_hw_t *hw = &i40e->i40e_hw_space;
702 	int port = i40e->i40e_hw_space.port;
703 	i40e_pf_stats_t *ips;
704 	i40e_pf_kstats_t *ipk;
705 
706 
707 	ASSERT(i40e->i40e_pf_kstat != NULL);
708 	ips = &i40e->i40e_pf_stat;
709 	ipk = i40e->i40e_pf_kstat->ks_data;
710 
711 	/*
712 	 * We need both locks, as various stats are protected by different
713 	 * things here.
714 	 */
715 	mutex_enter(&i40e->i40e_general_lock);
716 
717 	if (i40e->i40e_state & I40E_SUSPENDED) {
718 		mutex_exit(&i40e->i40e_general_lock);
719 		return (ECANCELED);
720 	}
721 
722 	mutex_enter(&i40e->i40e_stat_lock);
723 
724 	/*
725 	 * Unfortunately the GLDv3 conflates two rather different things here.
726 	 * We're combining statistics about the physical port represented by
727 	 * this instance with statistics that describe the properties of the
728 	 * logical interface. As such, we're going to use the various aspects of
729 	 * the port to describe these stats as they represent what the physical
730 	 * instance is doing, even though that that means some tools may be
731 	 * confused and that to see the logical traffic on the interface itself
732 	 * sans VNICs and the like will require more work.
733 	 *
734 	 * Stats which are not listed in this switch statement are unimplemented
735 	 * at this time in hardware or don't currently apply to the device.
736 	 */
737 	switch (stat) {
738 	/* MIB-II stats (RFC 1213 and RFC 1573) */
739 	case MAC_STAT_IFSPEED:
740 		*val = i40e->i40e_link_speed * 1000000ull;
741 		break;
742 	case MAC_STAT_MULTIRCV:
743 		i40e_stat_get_uint48(i40e, I40E_GLPRT_MPRCL(port),
744 		    &ipk->ipk_rx_multicast, &ips->ips_rx_multicast, B_FALSE);
745 		*val = ipk->ipk_rx_multicast.value.ui64;
746 		break;
747 	case MAC_STAT_BRDCSTRCV:
748 		i40e_stat_get_uint48(i40e, I40E_GLPRT_BPRCL(port),
749 		    &ipk->ipk_rx_broadcast, &ips->ips_rx_broadcast, B_FALSE);
750 		*val = ipk->ipk_rx_broadcast.value.ui64;
751 		break;
752 	case MAC_STAT_MULTIXMT:
753 		i40e_stat_get_uint48(i40e, I40E_GLPRT_MPTCL(port),
754 		    &ipk->ipk_tx_multicast, &ips->ips_tx_multicast, B_FALSE);
755 		*val = ipk->ipk_tx_multicast.value.ui64;
756 		break;
757 	case MAC_STAT_BRDCSTXMT:
758 		i40e_stat_get_uint48(i40e, I40E_GLPRT_BPTCL(port),
759 		    &ipk->ipk_tx_broadcast, &ips->ips_tx_broadcast, B_FALSE);
760 		*val = ipk->ipk_tx_broadcast.value.ui64;
761 		break;
762 	case MAC_STAT_NORCVBUF:
763 		i40e_stat_get_uint32(i40e, I40E_GLPRT_RDPC(port),
764 		    &ipk->ipk_rx_discards, &ips->ips_rx_discards, B_FALSE);
765 		i40e_stat_get_uint32(i40e, I40E_GLPRT_LDPC(port),
766 		    &ipk->ipk_rx_vm_discards, &ips->ips_rx_vm_discards,
767 		    B_FALSE);
768 		*val = ipk->ipk_rx_discards.value.ui64 +
769 		    ipk->ipk_rx_vm_discards.value.ui64;
770 		break;
771 	/*
772 	 * Note, that some RXERR2 stats are also duplicated by the switch filter
773 	 * stats; however, since we're not using those at this time, it seems
774 	 * reasonable to include them.
775 	 */
776 	case MAC_STAT_IERRORS:
777 		i40e_stat_get_uint32(i40e, I40E_GLPRT_CRCERRS(port),
778 		    &ipk->ipk_crc_errors, &ips->ips_crc_errors, B_FALSE);
779 		i40e_stat_get_uint32(i40e, I40E_GLPRT_ILLERRC(port),
780 		    &ipk->ipk_illegal_bytes, &ips->ips_illegal_bytes, B_FALSE);
781 		i40e_stat_get_uint32(i40e, I40E_GLPRT_RLEC(port),
782 		    &ipk->ipk_rx_length_errors, &ips->ips_rx_length_errors,
783 		    B_FALSE);
784 		i40e_stat_get_uint48(i40e, I40E_GL_RXERR1_L(port),
785 		    &ipk->ipk_rx_err1, &ips->ips_rx_err1, B_FALSE);
786 		i40e_stat_get_uint48(i40e, I40E_GL_RXERR2_L(port),
787 		    &ipk->ipk_rx_err2, &ips->ips_rx_err2, B_FALSE);
788 
789 		*val = ipk->ipk_crc_errors.value.ui64 +
790 		    ipk->ipk_illegal_bytes.value.ui64 +
791 		    ipk->ipk_rx_length_errors.value.ui64 +
792 		    ipk->ipk_rx_err1.value.ui64 +
793 		    ipk->ipk_rx_err2.value.ui64;
794 		break;
795 	case MAC_STAT_UNKNOWNS:
796 		i40e_stat_get_uint32(i40e, I40E_GLPRT_RUPP(port),
797 		    &ipk->ipk_rx_unknown_protocol,
798 		    &ips->ips_rx_unknown_protocol,
799 		    B_FALSE);
800 		*val = ipk->ipk_rx_unknown_protocol.value.ui64;
801 		break;
802 	case MAC_STAT_RBYTES:
803 		i40e_stat_get_uint48(i40e, I40E_GLPRT_GORCL(port),
804 		    &ipk->ipk_rx_bytes, &ips->ips_rx_bytes, B_FALSE);
805 		*val = ipk->ipk_rx_bytes.value.ui64;
806 		break;
807 	case MAC_STAT_IPACKETS:
808 		i40e_stat_get_uint48(i40e, I40E_GLPRT_UPRCL(port),
809 		    &ipk->ipk_rx_unicast, &ips->ips_rx_unicast, B_FALSE);
810 		i40e_stat_get_uint48(i40e, I40E_GLPRT_MPRCL(port),
811 		    &ipk->ipk_rx_multicast, &ips->ips_rx_multicast, B_FALSE);
812 		i40e_stat_get_uint48(i40e, I40E_GLPRT_BPRCL(port),
813 		    &ipk->ipk_rx_broadcast, &ips->ips_rx_broadcast, B_FALSE);
814 		*val = ipk->ipk_rx_unicast.value.ui64 +
815 		    ipk->ipk_rx_multicast.value.ui64 +
816 		    ipk->ipk_rx_broadcast.value.ui64;
817 		break;
818 	case MAC_STAT_OBYTES:
819 		i40e_stat_get_uint48(i40e, I40E_GLPRT_GOTCL(port),
820 		    &ipk->ipk_tx_bytes, &ips->ips_tx_bytes, B_FALSE);
821 		*val = ipk->ipk_tx_bytes.value.ui64;
822 		break;
823 	case MAC_STAT_OPACKETS:
824 		i40e_stat_get_uint48(i40e, I40E_GLPRT_UPTCL(port),
825 		    &ipk->ipk_tx_unicast, &ips->ips_tx_unicast, B_FALSE);
826 		i40e_stat_get_uint48(i40e, I40E_GLPRT_MPTCL(port),
827 		    &ipk->ipk_tx_multicast, &ips->ips_tx_multicast, B_FALSE);
828 		i40e_stat_get_uint48(i40e, I40E_GLPRT_BPTCL(port),
829 		    &ipk->ipk_tx_broadcast, &ips->ips_tx_broadcast, B_FALSE);
830 		*val = ipk->ipk_tx_unicast.value.ui64 +
831 		    ipk->ipk_tx_multicast.value.ui64 +
832 		    ipk->ipk_tx_broadcast.value.ui64;
833 		break;
834 	case MAC_STAT_UNDERFLOWS:
835 		i40e_stat_get_uint32(i40e, I40E_GLPRT_RUC(port),
836 		    &ipk->ipk_rx_undersize, &ips->ips_rx_undersize, B_FALSE);
837 		i40e_stat_get_uint32(i40e, I40E_GLPRT_RFC(port),
838 		    &ipk->ipk_rx_fragments, &ips->ips_rx_fragments, B_FALSE);
839 		i40e_stat_get_uint32(i40e, I40E_GLPRT_MSPDC(port),
840 		    &ipk->ipk_rx_short_discards, &ips->ips_rx_short_discards,
841 		    B_FALSE);
842 		*val = ipk->ipk_rx_undersize.value.ui64 +
843 		    ipk->ipk_rx_fragments.value.ui64 +
844 		    ipk->ipk_rx_short_discards.value.ui64;
845 		break;
846 	case MAC_STAT_OVERFLOWS:
847 		i40e_stat_get_uint32(i40e, I40E_GLPRT_ROC(port),
848 		    &ipk->ipk_rx_oversize, &ips->ips_rx_oversize, B_FALSE);
849 		i40e_stat_get_uint32(i40e, I40E_GLPRT_RJC(port),
850 		    &ipk->ipk_rx_jabber, &ips->ips_rx_jabber, B_FALSE);
851 		*val = ipk->ipk_rx_oversize.value.ui64 +
852 		    ipk->ipk_rx_fragments.value.ui64;
853 		break;
854 
855 	/* RFC 1643 stats */
856 	case ETHER_STAT_FCS_ERRORS:
857 		i40e_stat_get_uint32(i40e, I40E_GLPRT_CRCERRS(port),
858 		    &ipk->ipk_crc_errors, &ips->ips_crc_errors, B_FALSE);
859 		*val = ipk->ipk_crc_errors.value.ui64;
860 		break;
861 	case ETHER_STAT_TOOLONG_ERRORS:
862 		i40e_stat_get_uint32(i40e, I40E_GLPRT_ROC(port),
863 		    &ipk->ipk_rx_oversize, &ips->ips_rx_oversize, B_FALSE);
864 		*val = ipk->ipk_rx_oversize.value.ui64;
865 		break;
866 	case ETHER_STAT_MACRCV_ERRORS:
867 		i40e_stat_get_uint32(i40e, I40E_GLPRT_ILLERRC(port),
868 		    &ipk->ipk_illegal_bytes, &ips->ips_illegal_bytes, B_FALSE);
869 		i40e_stat_get_uint32(i40e, I40E_GLPRT_RLEC(port),
870 		    &ipk->ipk_rx_length_errors, &ips->ips_rx_length_errors,
871 		    B_FALSE);
872 		i40e_stat_get_uint32(i40e, I40E_GLPRT_RFC(port),
873 		    &ipk->ipk_rx_fragments, &ips->ips_rx_fragments, B_FALSE);
874 		*val = ipk->ipk_illegal_bytes.value.ui64 +
875 		    ipk->ipk_rx_length_errors.value.ui64 +
876 		    ipk->ipk_rx_fragments.value.ui64;
877 		break;
878 	/* MII/GMII stats */
879 
880 	/*
881 	 * The receiver address is apparently the same as the port number.
882 	 */
883 	case ETHER_STAT_XCVR_ADDR:
884 		/* The Receiver address is apparently the same as the port */
885 		*val = i40e->i40e_hw_space.port;
886 		break;
887 	case ETHER_STAT_XCVR_ID:
888 		switch (hw->phy.media_type) {
889 		case I40E_MEDIA_TYPE_BASET:
890 			/*
891 			 * Transform the data here into the ID. Note, generally
892 			 * the revision is left out.
893 			 */
894 			*val = i40e->i40e_phy.phy_id[3] << 24 |
895 			    i40e->i40e_phy.phy_id[2] << 16 |
896 			    i40e->i40e_phy.phy_id[1] << 8;
897 			break;
898 		case I40E_MEDIA_TYPE_FIBER:
899 		case I40E_MEDIA_TYPE_BACKPLANE:
900 		case I40E_MEDIA_TYPE_CX4:
901 		case I40E_MEDIA_TYPE_DA:
902 		case I40E_MEDIA_TYPE_VIRTUAL:
903 			*val = i40e->i40e_phy.phy_id[0] |
904 			    i40e->i40e_phy.phy_id[1] << 8 |
905 			    i40e->i40e_phy.phy_id[2] << 16;
906 			break;
907 		case I40E_MEDIA_TYPE_UNKNOWN:
908 		default:
909 			goto unimpl;
910 		}
911 		break;
912 	case ETHER_STAT_XCVR_INUSE:
913 		switch (hw->phy.link_info.phy_type) {
914 		case I40E_PHY_TYPE_100BASE_TX:
915 			*val = XCVR_100T2;
916 			break;
917 		case I40E_PHY_TYPE_1000BASE_T:
918 			*val = XCVR_1000T;
919 			break;
920 		default:
921 			*val = XCVR_UNDEFINED;
922 			break;
923 		}
924 		break;
925 
926 	/*
927 	 * This group answers the question of do we support a given speed in
928 	 * theory.
929 	 */
930 	case ETHER_STAT_CAP_100FDX:
931 		*val = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_100MB) != 0;
932 		break;
933 	case ETHER_STAT_CAP_1000FDX:
934 		*val = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_1GB) != 0;
935 		break;
936 	case ETHER_STAT_CAP_10GFDX:
937 		*val = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_10GB) != 0;
938 		break;
939 	case ETHER_STAT_CAP_25GFDX:
940 		*val = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_25GB) != 0;
941 		break;
942 	case ETHER_STAT_CAP_40GFDX:
943 		*val = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_40GB) != 0;
944 		break;
945 
946 	/*
947 	 * These ask are we currently advertising these speeds and abilities.
948 	 * Until we support setting these because we're working with a copper
949 	 * PHY, then the only things we advertise are based on the link PHY
950 	 * speeds. In other words, we advertise everything we support.
951 	 */
952 	case ETHER_STAT_ADV_CAP_100FDX:
953 		*val = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_100MB) != 0;
954 		break;
955 	case ETHER_STAT_ADV_CAP_1000FDX:
956 		*val = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_1GB) != 0;
957 		break;
958 	case ETHER_STAT_ADV_CAP_10GFDX:
959 		*val = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_10GB) != 0;
960 		break;
961 	case ETHER_STAT_ADV_CAP_25GFDX:
962 		*val = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_25GB) != 0;
963 		break;
964 	case ETHER_STAT_ADV_CAP_40GFDX:
965 		*val = (i40e->i40e_phy.link_speed & I40E_LINK_SPEED_40GB) != 0;
966 		break;
967 
968 	/*
969 	 * These ask if the peer supports these speeds, e.g. what did they tell
970 	 * us in auto-negotiation. Unfortunately, hardware doesn't appear to
971 	 * give us a way to determine whether or not they actually support
972 	 * something, only what they have enabled. This means that all we can
973 	 * tell the user is the speed that we're currently at, unfortunately.
974 	 */
975 	case ETHER_STAT_LP_CAP_100FDX:
976 		*val = i40e->i40e_link_speed == 100;
977 		break;
978 	case ETHER_STAT_LP_CAP_1000FDX:
979 		*val = i40e->i40e_link_speed == 1000;
980 		break;
981 	case ETHER_STAT_LP_CAP_10GFDX:
982 		*val = i40e->i40e_link_speed == 10000;
983 		break;
984 	case ETHER_STAT_LP_CAP_25GFDX:
985 		*val = i40e->i40e_link_speed == 25000;
986 		break;
987 	case ETHER_STAT_LP_CAP_40GFDX:
988 		*val = i40e->i40e_link_speed == 40000;
989 		break;
990 
991 	/*
992 	 * Statistics for unsupported speeds. Note that these often have the
993 	 * same constraints as the other ones. For example, we can't answer the
994 	 * question of the ETHER_STAT_LP_CAP family because hardware doesn't
995 	 * give us any way of knowing whether or not it does.
996 	 */
997 	case ETHER_STAT_CAP_100HDX:
998 	case ETHER_STAT_CAP_1000HDX:
999 	case ETHER_STAT_CAP_10FDX:
1000 	case ETHER_STAT_CAP_10HDX:
1001 	case ETHER_STAT_CAP_100T4:
1002 	case ETHER_STAT_CAP_100GFDX:
1003 	case ETHER_STAT_CAP_50GFDX:
1004 	case ETHER_STAT_CAP_2500FDX:
1005 	case ETHER_STAT_CAP_5000FDX:
1006 	case ETHER_STAT_ADV_CAP_1000HDX:
1007 	case ETHER_STAT_ADV_CAP_100HDX:
1008 	case ETHER_STAT_ADV_CAP_10FDX:
1009 	case ETHER_STAT_ADV_CAP_10HDX:
1010 	case ETHER_STAT_ADV_CAP_100T4:
1011 	case ETHER_STAT_ADV_CAP_100GFDX:
1012 	case ETHER_STAT_ADV_CAP_50GFDX:
1013 	case ETHER_STAT_ADV_CAP_2500FDX:
1014 	case ETHER_STAT_ADV_CAP_5000FDX:
1015 	case ETHER_STAT_LP_CAP_1000HDX:
1016 	case ETHER_STAT_LP_CAP_100HDX:
1017 	case ETHER_STAT_LP_CAP_10FDX:
1018 	case ETHER_STAT_LP_CAP_10HDX:
1019 	case ETHER_STAT_LP_CAP_100T4:
1020 	case ETHER_STAT_LP_CAP_100GFDX:
1021 	case ETHER_STAT_LP_CAP_50GFDX:
1022 	case ETHER_STAT_LP_CAP_2500FDX:
1023 	case ETHER_STAT_LP_CAP_5000FDX:
1024 		*val = 0;
1025 		break;
1026 
1027 	case ETHER_STAT_LINK_DUPLEX:
1028 		*val = i40e->i40e_link_duplex;
1029 		break;
1030 	case ETHER_STAT_TOOSHORT_ERRORS:
1031 		i40e_stat_get_uint32(i40e, I40E_GLPRT_RUC(port),
1032 		    &ipk->ipk_rx_undersize, &ips->ips_rx_undersize, B_FALSE);
1033 
1034 		i40e_stat_get_uint32(i40e, I40E_GLPRT_MSPDC(port),
1035 		    &ipk->ipk_rx_short_discards, &ips->ips_rx_short_discards,
1036 		    B_FALSE);
1037 		*val = ipk->ipk_rx_undersize.value.ui64 +
1038 		    ipk->ipk_rx_short_discards.value.ui64;
1039 		break;
1040 	case ETHER_STAT_JABBER_ERRORS:
1041 		i40e_stat_get_uint32(i40e, I40E_GLPRT_RJC(port),
1042 		    &ipk->ipk_rx_jabber, &ips->ips_rx_jabber, B_FALSE);
1043 		*val = ipk->ipk_rx_jabber.value.ui64;
1044 		break;
1045 
1046 	/*
1047 	 * Non-Link speed related capabilities.
1048 	 */
1049 	case ETHER_STAT_CAP_AUTONEG:
1050 		*val = 1;
1051 		break;
1052 
1053 	case ETHER_STAT_ADV_CAP_AUTONEG:
1054 		*val = 1;
1055 		break;
1056 
1057 	case ETHER_STAT_LP_CAP_AUTONEG:
1058 		*val = (hw->phy.link_info.an_info & I40E_AQ_LP_AN_ABILITY) != 0;
1059 		break;
1060 
1061 	case ETHER_STAT_LINK_AUTONEG:
1062 		*val = 1;
1063 		break;
1064 
1065 	/*
1066 	 * Note that while the hardware does support the pause functionality, at
1067 	 * this time we do not use it at all and effectively disable it.
1068 	 */
1069 	case ETHER_STAT_CAP_ASMPAUSE:
1070 		*val = (i40e->i40e_phy.abilities &
1071 		    I40E_AQ_PHY_FLAG_PAUSE_RX) != 0;
1072 		break;
1073 	case ETHER_STAT_CAP_PAUSE:
1074 		*val = (i40e->i40e_phy.abilities &
1075 		    I40E_AQ_PHY_FLAG_PAUSE_TX) != 0;
1076 		break;
1077 
1078 	/*
1079 	 * Because we don't support these at this time, they are always
1080 	 * hard-coded to zero.
1081 	 */
1082 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
1083 	case ETHER_STAT_ADV_CAP_PAUSE:
1084 		*val = 0;
1085 		break;
1086 
1087 	/*
1088 	 * Like the other LP fields, we can only answer the question have we
1089 	 * enabled it, not whether the other end actually supports it.
1090 	 */
1091 	case ETHER_STAT_LP_CAP_ASMPAUSE:
1092 	case ETHER_STAT_LINK_ASMPAUSE:
1093 		*val = (hw->phy.link_info.an_info & I40E_AQ_LINK_PAUSE_RX) != 0;
1094 		break;
1095 	case ETHER_STAT_LP_CAP_PAUSE:
1096 	case ETHER_STAT_LINK_PAUSE:
1097 		*val = (hw->phy.link_info.an_info & I40E_AQ_LINK_PAUSE_TX) != 0;
1098 		break;
1099 
1100 	default:
1101 	unimpl:
1102 		mutex_exit(&i40e->i40e_stat_lock);
1103 		mutex_exit(&i40e->i40e_general_lock);
1104 		return (ENOTSUP);
1105 	}
1106 
1107 	mutex_exit(&i40e->i40e_stat_lock);
1108 	mutex_exit(&i40e->i40e_general_lock);
1109 
1110 	if (i40e_check_acc_handle(i40e->i40e_osdep_space.ios_reg_handle) !=
1111 	    DDI_FM_OK) {
1112 		ddi_fm_service_impact(i40e->i40e_dip, DDI_SERVICE_DEGRADED);
1113 		return (EIO);
1114 	}
1115 
1116 	return (0);
1117 }
1118 
1119 int
1120 i40e_rx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
1121 {
1122 	i40e_trqpair_t *itrq = (i40e_trqpair_t *)rh;
1123 	i40e_t *i40e = itrq->itrq_i40e;
1124 
1125 	if (i40e->i40e_state & I40E_SUSPENDED) {
1126 		return (ECANCELED);
1127 	}
1128 
1129 	switch (stat) {
1130 	case MAC_STAT_RBYTES:
1131 		*val = itrq->itrq_rxstat.irxs_bytes.value.ui64;
1132 		break;
1133 	case MAC_STAT_IPACKETS:
1134 		*val = itrq->itrq_rxstat.irxs_packets.value.ui64;
1135 		break;
1136 	default:
1137 		*val = 0;
1138 		return (ENOTSUP);
1139 	}
1140 
1141 	return (0);
1142 }
1143 
1144 int
1145 i40e_tx_ring_stat(mac_ring_driver_t rh, uint_t stat, uint64_t *val)
1146 {
1147 	i40e_trqpair_t *itrq = (i40e_trqpair_t *)rh;
1148 	i40e_t *i40e = itrq->itrq_i40e;
1149 
1150 	if (i40e->i40e_state & I40E_SUSPENDED) {
1151 		return (ECANCELED);
1152 	}
1153 
1154 	switch (stat) {
1155 	case MAC_STAT_OBYTES:
1156 		*val = itrq->itrq_txstat.itxs_bytes.value.ui64;
1157 		break;
1158 	case MAC_STAT_OPACKETS:
1159 		*val = itrq->itrq_txstat.itxs_packets.value.ui64;
1160 		break;
1161 	default:
1162 		*val = 0;
1163 		return (ENOTSUP);
1164 	}
1165 
1166 	return (0);
1167 }
1168 
1169 /*
1170  * When we end up refactoring all off the queue assignments and have non-static
1171  * queue to VSI mappings, then we may need to revisit the general locking
1172  * strategy that we employ and have the kstat creation / deletion be part of the
1173  * ring start and stop routines.
1174  */
1175 void
1176 i40e_stats_trqpair_fini(i40e_trqpair_t *itrq)
1177 {
1178 	if (itrq->itrq_txkstat != NULL) {
1179 		kstat_delete(itrq->itrq_txkstat);
1180 		itrq->itrq_txkstat = NULL;
1181 	}
1182 
1183 	if (itrq->itrq_rxkstat != NULL) {
1184 		kstat_delete(itrq->itrq_rxkstat);
1185 		itrq->itrq_rxkstat = NULL;
1186 	}
1187 }
1188 
1189 boolean_t
1190 i40e_stats_trqpair_init(i40e_trqpair_t *itrq)
1191 {
1192 	char buf[128];
1193 	i40e_t *i40e = itrq->itrq_i40e;
1194 	i40e_txq_stat_t *tsp = &itrq->itrq_txstat;
1195 	i40e_rxq_stat_t *rsp = &itrq->itrq_rxstat;
1196 
1197 	(void) snprintf(buf, sizeof (buf), "trqpair_tx_%d", itrq->itrq_index);
1198 	itrq->itrq_txkstat = kstat_create(I40E_MODULE_NAME,
1199 	    ddi_get_instance(i40e->i40e_dip), buf, "net", KSTAT_TYPE_NAMED,
1200 	    sizeof (i40e_txq_stat_t) / sizeof (kstat_named_t),
1201 	    KSTAT_FLAG_VIRTUAL);
1202 
1203 	if (itrq->itrq_txkstat == NULL)
1204 		return (B_FALSE);
1205 
1206 	(void) snprintf(buf, sizeof (buf), "trqpair_rx_%d", itrq->itrq_index);
1207 	itrq->itrq_rxkstat = kstat_create(I40E_MODULE_NAME,
1208 	    ddi_get_instance(i40e->i40e_dip), buf, "net", KSTAT_TYPE_NAMED,
1209 	    sizeof (i40e_rxq_stat_t) / sizeof (kstat_named_t),
1210 	    KSTAT_FLAG_VIRTUAL);
1211 
1212 	if (itrq->itrq_rxkstat == NULL) {
1213 		kstat_delete(itrq->itrq_txkstat);
1214 		itrq->itrq_txkstat = NULL;
1215 		return (B_FALSE);
1216 	}
1217 
1218 	itrq->itrq_txkstat->ks_data = &itrq->itrq_txstat;
1219 	itrq->itrq_rxkstat->ks_data = &itrq->itrq_rxstat;
1220 
1221 	kstat_named_init(&tsp->itxs_bytes, "tx_bytes",
1222 	    KSTAT_DATA_UINT64);
1223 	tsp->itxs_bytes.value.ui64 = 0;
1224 	kstat_named_init(&tsp->itxs_packets, "tx_packets",
1225 	    KSTAT_DATA_UINT64);
1226 	tsp->itxs_packets.value.ui64 = 0;
1227 	kstat_named_init(&tsp->itxs_descriptors, "tx_descriptors",
1228 	    KSTAT_DATA_UINT64);
1229 	tsp->itxs_descriptors.value.ui64 = 0;
1230 	kstat_named_init(&tsp->itxs_recycled, "tx_recycled",
1231 	    KSTAT_DATA_UINT64);
1232 	tsp->itxs_recycled.value.ui64 = 0;
1233 
1234 	kstat_named_init(&tsp->itxs_hck_meoifail, "tx_hck_meoifail",
1235 	    KSTAT_DATA_UINT64);
1236 	tsp->itxs_hck_meoifail.value.ui64 = 0;
1237 	kstat_named_init(&tsp->itxs_hck_nol2info, "tx_hck_nol2info",
1238 	    KSTAT_DATA_UINT64);
1239 	tsp->itxs_hck_nol2info.value.ui64 = 0;
1240 	kstat_named_init(&tsp->itxs_hck_nol3info, "tx_hck_nol3info",
1241 	    KSTAT_DATA_UINT64);
1242 	tsp->itxs_hck_nol3info.value.ui64 = 0;
1243 	kstat_named_init(&tsp->itxs_hck_nol4info, "tx_hck_nol4info",
1244 	    KSTAT_DATA_UINT64);
1245 	tsp->itxs_hck_nol4info.value.ui64 = 0;
1246 	kstat_named_init(&tsp->itxs_hck_badl3, "tx_hck_badl3",
1247 	    KSTAT_DATA_UINT64);
1248 	tsp->itxs_hck_badl3.value.ui64 = 0;
1249 	kstat_named_init(&tsp->itxs_hck_badl4, "tx_hck_badl4",
1250 	    KSTAT_DATA_UINT64);
1251 	tsp->itxs_hck_badl4.value.ui64 = 0;
1252 	kstat_named_init(&tsp->itxs_err_notcb, "tx_err_notcb",
1253 	    KSTAT_DATA_UINT64);
1254 	tsp->itxs_err_notcb.value.ui64 = 0;
1255 	kstat_named_init(&tsp->itxs_err_nodescs, "tx_err_nodescs",
1256 	    KSTAT_DATA_UINT64);
1257 	tsp->itxs_err_nodescs.value.ui64 = 0;
1258 	kstat_named_init(&tsp->itxs_err_context, "tx_err_context",
1259 	    KSTAT_DATA_UINT64);
1260 	tsp->itxs_err_context.value.ui64 = 0;
1261 	kstat_named_init(&tsp->itxs_num_unblocked, "tx_num_unblocked",
1262 	    KSTAT_DATA_UINT64);
1263 	tsp->itxs_num_unblocked.value.ui64 = 0;
1264 
1265 
1266 	kstat_named_init(&rsp->irxs_bytes, "rx_bytes",
1267 	    KSTAT_DATA_UINT64);
1268 	rsp->irxs_bytes.value.ui64 = 0;
1269 	kstat_named_init(&rsp->irxs_packets, "rx_packets",
1270 	    KSTAT_DATA_UINT64);
1271 	rsp->irxs_packets.value.ui64 = 0;
1272 	kstat_named_init(&rsp->irxs_rx_desc_error, "rx_desc_error",
1273 	    KSTAT_DATA_UINT64);
1274 	rsp->irxs_rx_desc_error.value.ui64 = 0;
1275 	kstat_named_init(&rsp->irxs_rx_intr_limit, "rx_intr_limit",
1276 	    KSTAT_DATA_UINT64);
1277 	rsp->irxs_rx_intr_limit.value.ui64 = 0;
1278 	kstat_named_init(&rsp->irxs_rx_bind_norcb, "rx_bind_norcb",
1279 	    KSTAT_DATA_UINT64);
1280 	rsp->irxs_rx_bind_norcb.value.ui64 = 0;
1281 	kstat_named_init(&rsp->irxs_rx_bind_nomp, "rx_bind_nomp",
1282 	    KSTAT_DATA_UINT64);
1283 	rsp->irxs_rx_bind_nomp.value.ui64 = 0;
1284 	kstat_named_init(&rsp->irxs_rx_copy_nomem, "rx_copy_nomem",
1285 	    KSTAT_DATA_UINT64);
1286 	rsp->irxs_rx_copy_nomem.value.ui64 = 0;
1287 	kstat_named_init(&rsp->irxs_hck_v4hdrok, "rx_hck_v4hdrok",
1288 	    KSTAT_DATA_UINT64);
1289 	rsp->irxs_hck_v4hdrok.value.ui64 = 0;
1290 	kstat_named_init(&rsp->irxs_hck_l4hdrok, "rx_hck_l4hdrok",
1291 	    KSTAT_DATA_UINT64);
1292 	rsp->irxs_hck_l4hdrok.value.ui64 = 0;
1293 	kstat_named_init(&rsp->irxs_hck_unknown, "rx_hck_unknown",
1294 	    KSTAT_DATA_UINT64);
1295 	rsp->irxs_hck_unknown.value.ui64 = 0;
1296 	kstat_named_init(&rsp->irxs_hck_nol3l4p, "rx_hck_nol3l4p",
1297 	    KSTAT_DATA_UINT64);
1298 	rsp->irxs_hck_nol3l4p.value.ui64 = 0;
1299 	kstat_named_init(&rsp->irxs_hck_iperr, "rx_hck_iperr",
1300 	    KSTAT_DATA_UINT64);
1301 	rsp->irxs_hck_iperr.value.ui64 = 0;
1302 	kstat_named_init(&rsp->irxs_hck_eiperr, "rx_hck_eiperr",
1303 	    KSTAT_DATA_UINT64);
1304 	rsp->irxs_hck_eiperr.value.ui64 = 0;
1305 	kstat_named_init(&rsp->irxs_hck_l4err, "rx_hck_l4err",
1306 	    KSTAT_DATA_UINT64);
1307 	rsp->irxs_hck_l4err.value.ui64 = 0;
1308 	kstat_named_init(&rsp->irxs_hck_v6skip, "rx_hck_v6skip",
1309 	    KSTAT_DATA_UINT64);
1310 	rsp->irxs_hck_v6skip.value.ui64 = 0;
1311 	kstat_named_init(&rsp->irxs_hck_set, "rx_hck_set",
1312 	    KSTAT_DATA_UINT64);
1313 	rsp->irxs_hck_set.value.ui64 = 0;
1314 	kstat_named_init(&rsp->irxs_hck_miss, "rx_hck_miss",
1315 	    KSTAT_DATA_UINT64);
1316 	rsp->irxs_hck_miss.value.ui64 = 0;
1317 
1318 	kstat_install(itrq->itrq_txkstat);
1319 	kstat_install(itrq->itrq_rxkstat);
1320 
1321 	return (B_TRUE);
1322 }
1323