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