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
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.
13 * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
14 * Copyright 2016 Joyent, Inc.
24 * As part of managing the driver and understanding what's going on, we keep
25 * track of statistics from two different sources:
27 * - Statistics from the device
28 * - Statistics maintained by the driver
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
37 * We export statistics in two different forms. The first form is the required
38 * GLDv3 endpoints, specifically:
40 * - The general GLDv3 mc_getstat interface
41 * - The GLDv3 ring mri_stat interface
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:
49 * - Each physical function
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:.
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:.
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
67 * ---------------------
68 * Hardware Arrangements
69 * ---------------------
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
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.
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().
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
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.
110 i40e_stat_get_uint48(i40e_t
*i40e
, uintptr_t reg
, kstat_named_t
*kstat
,
111 uint64_t *base
, boolean_t init
)
113 i40e_hw_t
*hw
= &i40e
->i40e_hw_space
;
116 ASSERT(MUTEX_HELD(&i40e
->i40e_stat_lock
));
118 raw
= ddi_get64(i40e
->i40e_osdep_space
.ios_reg_handle
,
119 (uint64_t *)((uintptr_t)hw
->hw_addr
+ reg
));
121 if (init
== B_TRUE
) {
127 * Check for wraparound, note that the counter is actually only 48-bits,
128 * even though it has two uint32_t regs present.
133 delta
= 0x1000000000000ULL
- *base
+ raw
;
136 kstat
->value
.ui64
+= delta
;
141 i40e_stat_get_uint32(i40e_t
*i40e
, uintptr_t reg
, kstat_named_t
*kstat
,
142 uint64_t *base
, boolean_t init
)
144 i40e_hw_t
*hw
= &i40e
->i40e_hw_space
;
147 ASSERT(MUTEX_HELD(&i40e
->i40e_stat_lock
));
149 raw
= ddi_get32(i40e
->i40e_osdep_space
.ios_reg_handle
,
150 (uint32_t *)((uintptr_t)hw
->hw_addr
+ reg
));
152 if (init
== B_TRUE
) {
158 * Watch out for wraparound as we only have a 32-bit counter.
163 delta
= 0x100000000ULL
- *base
+ raw
;
166 kstat
->value
.ui64
+= delta
;
172 i40e_stat_vsi_update(i40e_t
*i40e
, boolean_t init
)
174 i40e_vsi_stats_t
*ivs
;
175 i40e_vsi_kstats_t
*ivk
;
176 int id
= i40e
->i40e_vsi_stat_id
;
178 ASSERT(i40e
->i40e_vsi_kstat
!= NULL
);
179 ivs
= &i40e
->i40e_vsi_stat
;
180 ivk
= i40e
->i40e_vsi_kstat
->ks_data
;
182 mutex_enter(&i40e
->i40e_stat_lock
);
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
);
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
,
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
);
209 i40e_stat_get_uint32(i40e
, I40E_GLV_TEPC(id
), &ivk
->ivk_tx_errors
,
210 &ivs
->ivs_tx_errors
, init
);
212 mutex_exit(&i40e
->i40e_stat_lock
);
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.
219 if (i40e_check_acc_handle(i40e
->i40e_osdep_space
.ios_reg_handle
) !=
221 ddi_fm_service_impact(i40e
->i40e_dip
, DDI_SERVICE_UNAFFECTED
);
226 i40e_stat_vsi_kstat_update(kstat_t
*ksp
, int rw
)
230 if (rw
== KSTAT_WRITE
)
233 i40e
= ksp
->ks_private
;
234 i40e_stat_vsi_update(i40e
, B_FALSE
);
239 i40e_stat_vsi_fini(i40e_t
*i40e
)
241 if (i40e
->i40e_vsi_kstat
!= NULL
) {
242 kstat_delete(i40e
->i40e_vsi_kstat
);
243 i40e
->i40e_vsi_kstat
= NULL
;
248 i40e_stat_vsi_init(i40e_t
*i40e
)
251 i40e_vsi_kstats_t
*ivk
;
254 (void) snprintf(buf
, sizeof (buf
), "vsi_%d", i40e
->i40e_vsi_id
);
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);
261 i40e_error(i40e
, "Failed to create kstats for VSI %d",
266 i40e
->i40e_vsi_kstat
= ksp
;
268 ksp
->ks_update
= i40e_stat_vsi_kstat_update
;
269 ksp
->ks_private
= i40e
;
271 kstat_named_init(&ivk
->ivk_rx_bytes
, "rx_bytes",
273 kstat_named_init(&ivk
->ivk_rx_unicast
, "rx_unicast",
275 kstat_named_init(&ivk
->ivk_rx_multicast
, "rx_multicast",
277 kstat_named_init(&ivk
->ivk_rx_broadcast
, "rx_broadcast",
279 kstat_named_init(&ivk
->ivk_rx_discards
, "rx_discards",
281 kstat_named_init(&ivk
->ivk_rx_unknown_protocol
, "rx_unknown_protocol",
283 kstat_named_init(&ivk
->ivk_tx_bytes
, "tx_bytes",
285 kstat_named_init(&ivk
->ivk_tx_unicast
, "tx_unicast",
287 kstat_named_init(&ivk
->ivk_tx_multicast
, "tx_multicast",
289 kstat_named_init(&ivk
->ivk_tx_broadcast
, "tx_broadcast",
291 kstat_named_init(&ivk
->ivk_tx_errors
, "tx_errors",
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
);
302 i40e_stat_pf_update(i40e_t
*i40e
, boolean_t init
)
304 i40e_pf_stats_t
*ips
;
305 i40e_pf_kstats_t
*ipk
;
306 int port
= i40e
->i40e_hw_space
.port
;
309 ASSERT(i40e
->i40e_pf_kstat
!= NULL
);
310 ips
= &i40e
->i40e_pf_stat
;
311 ipk
= i40e
->i40e_pf_kstat
->ks_data
;
313 mutex_enter(&i40e
->i40e_stat_lock
);
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
);
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
);
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
);
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
);
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
],
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
],
381 i40e_stat_get_uint32(i40e
, I40E_GLPRT_PXONTXC(port
, i
),
382 &ipk
->ipk_priority_xon_tx
[i
], &ips
->ips_priority_xon_tx
[i
],
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
],
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
],
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
,
421 i40e_stat_get_uint32(i40e
, I40E_GLPRT_RUPP(port
),
422 &ipk
->ipk_rx_unknown_protocol
, &ips
->ips_rx_unknown_protocol
, init
);
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
);
430 mutex_exit(&i40e
->i40e_stat_lock
);
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.
437 if (i40e_check_acc_handle(i40e
->i40e_osdep_space
.ios_reg_handle
) !=
439 ddi_fm_service_impact(i40e
->i40e_dip
, DDI_SERVICE_UNAFFECTED
);
444 i40e_stat_pf_kstat_update(kstat_t
*ksp
, int rw
)
448 if (rw
== KSTAT_WRITE
)
451 i40e
= ksp
->ks_private
;
452 i40e_stat_pf_update(i40e
, B_FALSE
);
458 i40e_stat_pf_init(i40e_t
*i40e
)
461 i40e_pf_kstats_t
*ipk
;
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);
467 i40e_error(i40e
, "Could not create kernel statistics.");
471 i40e
->i40e_pf_kstat
= ksp
;
473 ksp
->ks_update
= i40e_stat_pf_kstat_update
;
474 ksp
->ks_private
= i40e
;
476 kstat_named_init(&ipk
->ipk_rx_bytes
, "rx_bytes",
478 kstat_named_init(&ipk
->ipk_rx_unicast
, "rx_unicast",
480 kstat_named_init(&ipk
->ipk_rx_multicast
, "rx_multicast",
482 kstat_named_init(&ipk
->ipk_rx_broadcast
, "rx_broadcast",
484 kstat_named_init(&ipk
->ipk_tx_bytes
, "tx_bytes",
486 kstat_named_init(&ipk
->ipk_tx_unicast
, "tx_unicast",
488 kstat_named_init(&ipk
->ipk_tx_multicast
, "tx_multicast",
490 kstat_named_init(&ipk
->ipk_tx_broadcast
, "tx_broadcast",
493 kstat_named_init(&ipk
->ipk_rx_size_64
, "rx_size_64",
495 kstat_named_init(&ipk
->ipk_rx_size_127
, "rx_size_127",
497 kstat_named_init(&ipk
->ipk_rx_size_255
, "rx_size_255",
499 kstat_named_init(&ipk
->ipk_rx_size_511
, "rx_size_511",
501 kstat_named_init(&ipk
->ipk_rx_size_1023
, "rx_size_1023",
503 kstat_named_init(&ipk
->ipk_rx_size_1522
, "rx_size_1522",
505 kstat_named_init(&ipk
->ipk_rx_size_9522
, "rx_size_9522",
508 kstat_named_init(&ipk
->ipk_tx_size_64
, "tx_size_64",
510 kstat_named_init(&ipk
->ipk_tx_size_127
, "tx_size_127",
512 kstat_named_init(&ipk
->ipk_tx_size_255
, "tx_size_255",
514 kstat_named_init(&ipk
->ipk_tx_size_511
, "tx_size_511",
516 kstat_named_init(&ipk
->ipk_tx_size_1023
, "tx_size_1023",
518 kstat_named_init(&ipk
->ipk_tx_size_1522
, "tx_size_1522",
520 kstat_named_init(&ipk
->ipk_tx_size_9522
, "tx_size_9522",
523 kstat_named_init(&ipk
->ipk_link_xon_rx
, "link_xon_rx",
525 kstat_named_init(&ipk
->ipk_link_xoff_rx
, "link_xoff_rx",
527 kstat_named_init(&ipk
->ipk_link_xon_tx
, "link_xon_tx",
529 kstat_named_init(&ipk
->ipk_link_xoff_tx
, "link_xoff_tx",
532 kstat_named_init(&ipk
->ipk_priority_xon_rx
[0], "priority_xon_rx[0]",
534 kstat_named_init(&ipk
->ipk_priority_xoff_rx
[0], "priority_xoff_rx[0]",
536 kstat_named_init(&ipk
->ipk_priority_xon_tx
[0], "priority_xon_tx[0]",
538 kstat_named_init(&ipk
->ipk_priority_xoff_tx
[0], "priority_xoff_tx[0]",
540 kstat_named_init(&ipk
->ipk_priority_xon_2_xoff
[0],
541 "priority_xon_2_xoff[0]",
544 kstat_named_init(&ipk
->ipk_priority_xon_rx
[1], "priority_xon_rx[1]",
546 kstat_named_init(&ipk
->ipk_priority_xoff_rx
[1], "priority_xoff_rx[1]",
548 kstat_named_init(&ipk
->ipk_priority_xon_tx
[1], "priority_xon_tx[1]",
550 kstat_named_init(&ipk
->ipk_priority_xoff_tx
[1], "priority_xoff_tx[1]",
552 kstat_named_init(&ipk
->ipk_priority_xon_2_xoff
[1],
553 "priority_xon_2_xoff[1]",
556 kstat_named_init(&ipk
->ipk_priority_xon_rx
[2], "priority_xon_rx[2]",
558 kstat_named_init(&ipk
->ipk_priority_xoff_rx
[2], "priority_xoff_rx[2]",
560 kstat_named_init(&ipk
->ipk_priority_xon_tx
[2], "priority_xon_tx[2]",
562 kstat_named_init(&ipk
->ipk_priority_xoff_tx
[2], "priority_xoff_tx[2]",
564 kstat_named_init(&ipk
->ipk_priority_xon_2_xoff
[2],
565 "priority_xon_2_xoff[2]",
568 kstat_named_init(&ipk
->ipk_priority_xon_rx
[3], "priority_xon_rx[3]",
570 kstat_named_init(&ipk
->ipk_priority_xoff_rx
[3], "priority_xoff_rx[3]",
572 kstat_named_init(&ipk
->ipk_priority_xon_tx
[3], "priority_xon_tx[3]",
574 kstat_named_init(&ipk
->ipk_priority_xoff_tx
[3], "priority_xoff_tx[3]",
576 kstat_named_init(&ipk
->ipk_priority_xon_2_xoff
[3],
577 "priority_xon_2_xoff[3]",
580 kstat_named_init(&ipk
->ipk_priority_xon_rx
[4], "priority_xon_rx[4]",
582 kstat_named_init(&ipk
->ipk_priority_xoff_rx
[4], "priority_xoff_rx[4]",
584 kstat_named_init(&ipk
->ipk_priority_xon_tx
[4], "priority_xon_tx[4]",
586 kstat_named_init(&ipk
->ipk_priority_xoff_tx
[4], "priority_xoff_tx[4]",
588 kstat_named_init(&ipk
->ipk_priority_xon_2_xoff
[4],
589 "priority_xon_2_xoff[4]",
592 kstat_named_init(&ipk
->ipk_priority_xon_rx
[5], "priority_xon_rx[5]",
594 kstat_named_init(&ipk
->ipk_priority_xoff_rx
[5], "priority_xoff_rx[5]",
596 kstat_named_init(&ipk
->ipk_priority_xon_tx
[5], "priority_xon_tx[5]",
598 kstat_named_init(&ipk
->ipk_priority_xoff_tx
[5], "priority_xoff_tx[5]",
600 kstat_named_init(&ipk
->ipk_priority_xon_2_xoff
[5],
601 "priority_xon_2_xoff[5]",
604 kstat_named_init(&ipk
->ipk_priority_xon_rx
[6], "priority_xon_rx[6]",
606 kstat_named_init(&ipk
->ipk_priority_xoff_rx
[6], "priority_xoff_rx[6]",
608 kstat_named_init(&ipk
->ipk_priority_xon_tx
[6], "priority_xon_tx[6]",
610 kstat_named_init(&ipk
->ipk_priority_xoff_tx
[6], "priority_xoff_tx[6]",
612 kstat_named_init(&ipk
->ipk_priority_xon_2_xoff
[6],
613 "priority_xon_2_xoff[6]",
616 kstat_named_init(&ipk
->ipk_priority_xon_rx
[7], "priority_xon_rx[7]",
618 kstat_named_init(&ipk
->ipk_priority_xoff_rx
[7], "priority_xoff_rx[7]",
620 kstat_named_init(&ipk
->ipk_priority_xon_tx
[7], "priority_xon_tx[7]",
622 kstat_named_init(&ipk
->ipk_priority_xoff_tx
[7], "priority_xoff_tx[7]",
624 kstat_named_init(&ipk
->ipk_priority_xon_2_xoff
[7],
625 "priority_xon_2_xoff[7]",
628 kstat_named_init(&ipk
->ipk_crc_errors
, "crc_errors",
630 kstat_named_init(&ipk
->ipk_illegal_bytes
, "illegal_bytes",
632 kstat_named_init(&ipk
->ipk_mac_local_faults
, "mac_local_faults",
634 kstat_named_init(&ipk
->ipk_mac_remote_faults
, "mac_remote_faults",
636 kstat_named_init(&ipk
->ipk_rx_length_errors
, "rx_length_errors",
638 kstat_named_init(&ipk
->ipk_rx_undersize
, "rx_undersize",
640 kstat_named_init(&ipk
->ipk_rx_fragments
, "rx_fragments",
642 kstat_named_init(&ipk
->ipk_rx_oversize
, "rx_oversize",
644 kstat_named_init(&ipk
->ipk_rx_jabber
, "rx_jabber",
646 kstat_named_init(&ipk
->ipk_rx_discards
, "rx_discards",
648 kstat_named_init(&ipk
->ipk_rx_vm_discards
, "rx_vm_discards",
650 kstat_named_init(&ipk
->ipk_rx_short_discards
, "rx_short_discards",
652 kstat_named_init(&ipk
->ipk_tx_dropped_link_down
, "tx_dropped_link_down",
654 kstat_named_init(&ipk
->ipk_rx_unknown_protocol
, "rx_unknown_protocol",
656 kstat_named_init(&ipk
->ipk_rx_err1
, "rx_err1",
658 kstat_named_init(&ipk
->ipk_rx_err2
, "rx_err2",
662 bzero(&i40e
->i40e_pf_stat
, sizeof (i40e_pf_stats_t
));
663 i40e_stat_pf_update(i40e
, B_TRUE
);
665 kstat_install(i40e
->i40e_pf_kstat
);
671 i40e_stats_fini(i40e_t
*i40e
)
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
;
679 mutex_destroy(&i40e
->i40e_stat_lock
);
683 i40e_stats_init(i40e_t
*i40e
)
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
);
698 i40e_m_stat(void *arg
, uint_t stat
, uint64_t *val
)
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
;
707 ASSERT(i40e
->i40e_pf_kstat
!= NULL
);
708 ips
= &i40e
->i40e_pf_stat
;
709 ipk
= i40e
->i40e_pf_kstat
->ks_data
;
712 * We need both locks, as various stats are protected by different
715 mutex_enter(&i40e
->i40e_general_lock
);
717 if (i40e
->i40e_state
& I40E_SUSPENDED
) {
718 mutex_exit(&i40e
->i40e_general_lock
);
722 mutex_enter(&i40e
->i40e_stat_lock
);
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.
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.
738 /* MIB-II stats (RFC 1213 and RFC 1573) */
739 case MAC_STAT_IFSPEED
:
740 *val
= i40e
->i40e_link_speed
* 1000000ull;
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
;
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
;
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
;
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
;
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
,
768 *val
= ipk
->ipk_rx_discards
.value
.ui64
+
769 ipk
->ipk_rx_vm_discards
.value
.ui64
;
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.
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
,
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
);
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
;
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
,
800 *val
= ipk
->ipk_rx_unknown_protocol
.value
.ui64
;
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
;
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
;
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
;
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
;
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
,
842 *val
= ipk
->ipk_rx_undersize
.value
.ui64
+
843 ipk
->ipk_rx_fragments
.value
.ui64
+
844 ipk
->ipk_rx_short_discards
.value
.ui64
;
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
;
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
;
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
;
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
,
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
;
881 * The receiver address is apparently the same as the port number.
883 case ETHER_STAT_XCVR_ADDR
:
884 /* The Receiver address is apparently the same as the port */
885 *val
= i40e
->i40e_hw_space
.port
;
887 case ETHER_STAT_XCVR_ID
:
888 switch (hw
->phy
.media_type
) {
889 case I40E_MEDIA_TYPE_BASET
:
891 * Transform the data here into the ID. Note, generally
892 * the revision is left out.
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;
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;
907 case I40E_MEDIA_TYPE_UNKNOWN
:
912 case ETHER_STAT_XCVR_INUSE
:
913 switch (hw
->phy
.link_info
.phy_type
) {
914 case I40E_PHY_TYPE_100BASE_TX
:
917 case I40E_PHY_TYPE_1000BASE_T
:
921 *val
= XCVR_UNDEFINED
;
927 * This group answers the question of do we support a given speed in
930 case ETHER_STAT_CAP_100FDX
:
931 *val
= (i40e
->i40e_phy
.link_speed
& I40E_LINK_SPEED_100MB
) != 0;
933 case ETHER_STAT_CAP_1000FDX
:
934 *val
= (i40e
->i40e_phy
.link_speed
& I40E_LINK_SPEED_1GB
) != 0;
936 case ETHER_STAT_CAP_10GFDX
:
937 *val
= (i40e
->i40e_phy
.link_speed
& I40E_LINK_SPEED_10GB
) != 0;
939 case ETHER_STAT_CAP_25GFDX
:
940 *val
= (i40e
->i40e_phy
.link_speed
& I40E_LINK_SPEED_25GB
) != 0;
942 case ETHER_STAT_CAP_40GFDX
:
943 *val
= (i40e
->i40e_phy
.link_speed
& I40E_LINK_SPEED_40GB
) != 0;
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.
952 case ETHER_STAT_ADV_CAP_100FDX
:
953 *val
= (i40e
->i40e_phy
.link_speed
& I40E_LINK_SPEED_100MB
) != 0;
955 case ETHER_STAT_ADV_CAP_1000FDX
:
956 *val
= (i40e
->i40e_phy
.link_speed
& I40E_LINK_SPEED_1GB
) != 0;
958 case ETHER_STAT_ADV_CAP_10GFDX
:
959 *val
= (i40e
->i40e_phy
.link_speed
& I40E_LINK_SPEED_10GB
) != 0;
961 case ETHER_STAT_ADV_CAP_25GFDX
:
962 *val
= (i40e
->i40e_phy
.link_speed
& I40E_LINK_SPEED_25GB
) != 0;
964 case ETHER_STAT_ADV_CAP_40GFDX
:
965 *val
= (i40e
->i40e_phy
.link_speed
& I40E_LINK_SPEED_40GB
) != 0;
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.
975 case ETHER_STAT_LP_CAP_100FDX
:
976 *val
= i40e
->i40e_link_speed
== 100;
978 case ETHER_STAT_LP_CAP_1000FDX
:
979 *val
= i40e
->i40e_link_speed
== 1000;
981 case ETHER_STAT_LP_CAP_10GFDX
:
982 *val
= i40e
->i40e_link_speed
== 10000;
984 case ETHER_STAT_LP_CAP_25GFDX
:
985 *val
= i40e
->i40e_link_speed
== 25000;
987 case ETHER_STAT_LP_CAP_40GFDX
:
988 *val
= i40e
->i40e_link_speed
== 40000;
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.
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
:
1027 case ETHER_STAT_LINK_DUPLEX
:
1028 *val
= i40e
->i40e_link_duplex
;
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
);
1034 i40e_stat_get_uint32(i40e
, I40E_GLPRT_MSPDC(port
),
1035 &ipk
->ipk_rx_short_discards
, &ips
->ips_rx_short_discards
,
1037 *val
= ipk
->ipk_rx_undersize
.value
.ui64
+
1038 ipk
->ipk_rx_short_discards
.value
.ui64
;
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
;
1047 * Non-Link speed related capabilities.
1049 case ETHER_STAT_CAP_AUTONEG
:
1053 case ETHER_STAT_ADV_CAP_AUTONEG
:
1057 case ETHER_STAT_LP_CAP_AUTONEG
:
1058 *val
= (hw
->phy
.link_info
.an_info
& I40E_AQ_LP_AN_ABILITY
) != 0;
1061 case ETHER_STAT_LINK_AUTONEG
:
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.
1069 case ETHER_STAT_CAP_ASMPAUSE
:
1070 *val
= (i40e
->i40e_phy
.abilities
&
1071 I40E_AQ_PHY_FLAG_PAUSE_RX
) != 0;
1073 case ETHER_STAT_CAP_PAUSE
:
1074 *val
= (i40e
->i40e_phy
.abilities
&
1075 I40E_AQ_PHY_FLAG_PAUSE_TX
) != 0;
1079 * Because we don't support these at this time, they are always
1080 * hard-coded to zero.
1082 case ETHER_STAT_ADV_CAP_ASMPAUSE
:
1083 case ETHER_STAT_ADV_CAP_PAUSE
:
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.
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;
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;
1102 mutex_exit(&i40e
->i40e_stat_lock
);
1103 mutex_exit(&i40e
->i40e_general_lock
);
1107 mutex_exit(&i40e
->i40e_stat_lock
);
1108 mutex_exit(&i40e
->i40e_general_lock
);
1110 if (i40e_check_acc_handle(i40e
->i40e_osdep_space
.ios_reg_handle
) !=
1112 ddi_fm_service_impact(i40e
->i40e_dip
, DDI_SERVICE_DEGRADED
);
1120 i40e_rx_ring_stat(mac_ring_driver_t rh
, uint_t stat
, uint64_t *val
)
1122 i40e_trqpair_t
*itrq
= (i40e_trqpair_t
*)rh
;
1123 i40e_t
*i40e
= itrq
->itrq_i40e
;
1125 if (i40e
->i40e_state
& I40E_SUSPENDED
) {
1130 case MAC_STAT_RBYTES
:
1131 *val
= itrq
->itrq_rxstat
.irxs_bytes
.value
.ui64
;
1133 case MAC_STAT_IPACKETS
:
1134 *val
= itrq
->itrq_rxstat
.irxs_packets
.value
.ui64
;
1145 i40e_tx_ring_stat(mac_ring_driver_t rh
, uint_t stat
, uint64_t *val
)
1147 i40e_trqpair_t
*itrq
= (i40e_trqpair_t
*)rh
;
1148 i40e_t
*i40e
= itrq
->itrq_i40e
;
1150 if (i40e
->i40e_state
& I40E_SUSPENDED
) {
1155 case MAC_STAT_OBYTES
:
1156 *val
= itrq
->itrq_txstat
.itxs_bytes
.value
.ui64
;
1158 case MAC_STAT_OPACKETS
:
1159 *val
= itrq
->itrq_txstat
.itxs_packets
.value
.ui64
;
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.
1176 i40e_stats_trqpair_fini(i40e_trqpair_t
*itrq
)
1178 if (itrq
->itrq_txkstat
!= NULL
) {
1179 kstat_delete(itrq
->itrq_txkstat
);
1180 itrq
->itrq_txkstat
= NULL
;
1183 if (itrq
->itrq_rxkstat
!= NULL
) {
1184 kstat_delete(itrq
->itrq_rxkstat
);
1185 itrq
->itrq_rxkstat
= NULL
;
1190 i40e_stats_trqpair_init(i40e_trqpair_t
*itrq
)
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
;
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
);
1203 if (itrq
->itrq_txkstat
== NULL
)
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
);
1212 if (itrq
->itrq_rxkstat
== NULL
) {
1213 kstat_delete(itrq
->itrq_txkstat
);
1214 itrq
->itrq_txkstat
= NULL
;
1218 itrq
->itrq_txkstat
->ks_data
= &itrq
->itrq_txstat
;
1219 itrq
->itrq_rxkstat
->ks_data
= &itrq
->itrq_rxstat
;
1221 kstat_named_init(&tsp
->itxs_bytes
, "tx_bytes",
1223 tsp
->itxs_bytes
.value
.ui64
= 0;
1224 kstat_named_init(&tsp
->itxs_packets
, "tx_packets",
1226 tsp
->itxs_packets
.value
.ui64
= 0;
1227 kstat_named_init(&tsp
->itxs_descriptors
, "tx_descriptors",
1229 tsp
->itxs_descriptors
.value
.ui64
= 0;
1230 kstat_named_init(&tsp
->itxs_recycled
, "tx_recycled",
1232 tsp
->itxs_recycled
.value
.ui64
= 0;
1234 kstat_named_init(&tsp
->itxs_hck_meoifail
, "tx_hck_meoifail",
1236 tsp
->itxs_hck_meoifail
.value
.ui64
= 0;
1237 kstat_named_init(&tsp
->itxs_hck_nol2info
, "tx_hck_nol2info",
1239 tsp
->itxs_hck_nol2info
.value
.ui64
= 0;
1240 kstat_named_init(&tsp
->itxs_hck_nol3info
, "tx_hck_nol3info",
1242 tsp
->itxs_hck_nol3info
.value
.ui64
= 0;
1243 kstat_named_init(&tsp
->itxs_hck_nol4info
, "tx_hck_nol4info",
1245 tsp
->itxs_hck_nol4info
.value
.ui64
= 0;
1246 kstat_named_init(&tsp
->itxs_hck_badl3
, "tx_hck_badl3",
1248 tsp
->itxs_hck_badl3
.value
.ui64
= 0;
1249 kstat_named_init(&tsp
->itxs_hck_badl4
, "tx_hck_badl4",
1251 tsp
->itxs_hck_badl4
.value
.ui64
= 0;
1252 kstat_named_init(&tsp
->itxs_err_notcb
, "tx_err_notcb",
1254 tsp
->itxs_err_notcb
.value
.ui64
= 0;
1255 kstat_named_init(&tsp
->itxs_err_nodescs
, "tx_err_nodescs",
1257 tsp
->itxs_err_nodescs
.value
.ui64
= 0;
1258 kstat_named_init(&tsp
->itxs_err_context
, "tx_err_context",
1260 tsp
->itxs_err_context
.value
.ui64
= 0;
1261 kstat_named_init(&tsp
->itxs_num_unblocked
, "tx_num_unblocked",
1263 tsp
->itxs_num_unblocked
.value
.ui64
= 0;
1266 kstat_named_init(&rsp
->irxs_bytes
, "rx_bytes",
1268 rsp
->irxs_bytes
.value
.ui64
= 0;
1269 kstat_named_init(&rsp
->irxs_packets
, "rx_packets",
1271 rsp
->irxs_packets
.value
.ui64
= 0;
1272 kstat_named_init(&rsp
->irxs_rx_desc_error
, "rx_desc_error",
1274 rsp
->irxs_rx_desc_error
.value
.ui64
= 0;
1275 kstat_named_init(&rsp
->irxs_rx_intr_limit
, "rx_intr_limit",
1277 rsp
->irxs_rx_intr_limit
.value
.ui64
= 0;
1278 kstat_named_init(&rsp
->irxs_rx_bind_norcb
, "rx_bind_norcb",
1280 rsp
->irxs_rx_bind_norcb
.value
.ui64
= 0;
1281 kstat_named_init(&rsp
->irxs_rx_bind_nomp
, "rx_bind_nomp",
1283 rsp
->irxs_rx_bind_nomp
.value
.ui64
= 0;
1284 kstat_named_init(&rsp
->irxs_rx_copy_nomem
, "rx_copy_nomem",
1286 rsp
->irxs_rx_copy_nomem
.value
.ui64
= 0;
1287 kstat_named_init(&rsp
->irxs_hck_v4hdrok
, "rx_hck_v4hdrok",
1289 rsp
->irxs_hck_v4hdrok
.value
.ui64
= 0;
1290 kstat_named_init(&rsp
->irxs_hck_l4hdrok
, "rx_hck_l4hdrok",
1292 rsp
->irxs_hck_l4hdrok
.value
.ui64
= 0;
1293 kstat_named_init(&rsp
->irxs_hck_unknown
, "rx_hck_unknown",
1295 rsp
->irxs_hck_unknown
.value
.ui64
= 0;
1296 kstat_named_init(&rsp
->irxs_hck_nol3l4p
, "rx_hck_nol3l4p",
1298 rsp
->irxs_hck_nol3l4p
.value
.ui64
= 0;
1299 kstat_named_init(&rsp
->irxs_hck_iperr
, "rx_hck_iperr",
1301 rsp
->irxs_hck_iperr
.value
.ui64
= 0;
1302 kstat_named_init(&rsp
->irxs_hck_eiperr
, "rx_hck_eiperr",
1304 rsp
->irxs_hck_eiperr
.value
.ui64
= 0;
1305 kstat_named_init(&rsp
->irxs_hck_l4err
, "rx_hck_l4err",
1307 rsp
->irxs_hck_l4err
.value
.ui64
= 0;
1308 kstat_named_init(&rsp
->irxs_hck_v6skip
, "rx_hck_v6skip",
1310 rsp
->irxs_hck_v6skip
.value
.ui64
= 0;
1311 kstat_named_init(&rsp
->irxs_hck_set
, "rx_hck_set",
1313 rsp
->irxs_hck_set
.value
.ui64
= 0;
1314 kstat_named_init(&rsp
->irxs_hck_miss
, "rx_hck_miss",
1316 rsp
->irxs_hck_miss
.value
.ui64
= 0;
1318 kstat_install(itrq
->itrq_txkstat
);
1319 kstat_install(itrq
->itrq_rxkstat
);