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