1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
14 * Copyright 2016 Joyent, Inc.
15 */
16
17 #include "i40e_sw.h"
18
19 /*
20 * -------------------
21 * Statistics Overview
22 * -------------------
23 *
24 * As part of managing the driver and understanding what's going on, we keep
25 * track of statistics from two different sources:
26 *
27 * - Statistics from the device
28 * - Statistics maintained by the driver
29 *
30 * Generally, the hardware provides us traditional IETF and MIB Ethernet
31 * statistics, for example, the total packets in and out, various errors in
32 * packets, the negotiated status etc. The driver, on the other hand, primarily
33 * contains statistics around driver-specific issues, such as information about
34 * checksumming on receive and transmit and the data in and out of a specific
52 *
53 * The PF's kstat is called 'pfstats' so as not to collide with other system
54 * provided kstats. Thus, for instance 0, usually the first PF, the full kstat
55 * would be: i40e:0:pfstats:.
56 *
57 * The kstat for each VSI is called vsi_%instance. So for the first PF, which is
58 * instance zero and the first vsi, which has id 0, it will be named vsi_0 and
59 * the full kstat would be i40e:0:vsi_0:.
60 *
61 * The kstat for each queue is trqpair_tx_%queue and trqpair_rx_%queue. Note
62 * that these are labeled based on their local index, which may mean that
63 * different instances have overlapping sets of queues. This isn't a problem as
64 * the kstats will always use the instance number of the pf to distinguish it in
65 * the kstat tuple.
66 *
67 * ---------------------
68 * Hardware Arrangements
69 * ---------------------
70 *
71 * The hardware keeps statistics at each physical function/MAC (PF) and it keeps
72 * statistics on each virtual station interface (VSI). Currently we only use one
73 * VSI per PF (see the i40e_main.c theory statement). The hardware has a limited
74 * number of statistics units available. While every PF is guaranteed to have a
75 * statistics unit, it is possible that we will run out for a given VSI. We'll
76 * have to figure out an appropriate strategy here when we end up supporting
77 * multiple VSIs.
78 *
79 * The hardware keeps these statistics as 32-bit and 48-bit counters. We are
80 * required to read them and then compute the differences between them. The
81 * 48-bit counters span more than one 32-bit register in the BAR. The hardware
82 * suggests that to read them, we perform 64-bit reads of the lower of the two
83 * registers that make up a 48-bit stat. The hardware guarantees that the reads
84 * of those two registers will be atomic and we'll get a consistent value, not a
85 * property it has for every read of two registers.
86 *
87 * For every kstat we have based on this, we have a corresponding uint64_t that
88 * we keep around as a base value in a separate structure. Whenever we read a
89 * value, we end up grabbing the current value, calculating a difference between
90 * the previously stored value and the current one, and updating the kstat with
91 * that difference. After which, we go through and update the base value that we
92 * stored. This is all encapsulated in i40e_stat_get_uint32() and
93 * i40e_stat_get_uint48().
94 *
95 * The only unfortunate thing here is that the hardware doesn't give us any kind
96 * of overflow counter. It just tries to make sure that the uint32_t and
97 * uint48_t counters are large enough to hopefully not overflow right away. This
98 * isn't the most reassuring statement and we should investigate ways of
99 * ensuring that if a system is active, but not actively measured, we don't lose
100 * data.
101 *
102 * The pf kstats data is stored in the i40e_t`i40e_pf_kstat. It is backed by the
103 * i40e_t`i40e_pf_stat structure. Similarly the VSI related kstat is in
104 * i40e_t`i40e_vsi_kstat and the data is backed in the i40e_t`i40e_vsi_stat. All
105 * of this data is protected by the i40e_stat_lock, which should be taken last,
106 * when acquiring locks.
107 */
108
109 static void
110 i40e_stat_get_uint48(i40e_t *i40e, uintptr_t reg, kstat_named_t *kstat,
111 uint64_t *base, boolean_t init)
112 {
113 i40e_hw_t *hw = &i40e->i40e_hw_space;
114 uint64_t raw, delta;
115
116 ASSERT(MUTEX_HELD(&i40e->i40e_stat_lock));
117
118 raw = ddi_get64(i40e->i40e_osdep_space.ios_reg_handle,
119 (uint64_t *)((uintptr_t)hw->hw_addr + reg));
120
121 if (init == B_TRUE) {
122 *base = raw;
123 return;
124 }
125
126 /*
152 if (init == B_TRUE) {
153 *base = raw;
154 return;
155 }
156
157 /*
158 * Watch out for wraparound as we only have a 32-bit counter.
159 */
160 if (raw >= *base) {
161 delta = raw - *base;
162 } else {
163 delta = 0x100000000ULL - *base + raw;
164 }
165
166 kstat->value.ui64 += delta;
167 *base = raw;
168
169 }
170
171 static void
172 i40e_stat_vsi_update(i40e_t *i40e, boolean_t init)
173 {
174 i40e_vsi_stats_t *ivs;
175 i40e_vsi_kstats_t *ivk;
176 int id = i40e->i40e_vsi_stat_id;
177
178 ASSERT(i40e->i40e_vsi_kstat != NULL);
179 ivs = &i40e->i40e_vsi_stat;
180 ivk = i40e->i40e_vsi_kstat->ks_data;
181
182 mutex_enter(&i40e->i40e_stat_lock);
183
184 i40e_stat_get_uint48(i40e, I40E_GLV_GORCL(id), &ivk->ivk_rx_bytes,
185 &ivs->ivs_rx_bytes, init);
186 i40e_stat_get_uint48(i40e, I40E_GLV_UPRCL(id), &ivk->ivk_rx_unicast,
187 &ivs->ivs_rx_unicast, init);
188 i40e_stat_get_uint48(i40e, I40E_GLV_MPRCL(id), &ivk->ivk_rx_multicast,
189 &ivs->ivs_rx_multicast, init);
190 i40e_stat_get_uint48(i40e, I40E_GLV_BPRCL(id), &ivk->ivk_rx_broadcast,
191 &ivs->ivs_rx_broadcast, init);
192
193 i40e_stat_get_uint32(i40e, I40E_GLV_RDPC(id), &ivk->ivk_rx_discards,
194 &ivs->ivs_rx_discards, init);
195 i40e_stat_get_uint32(i40e, I40E_GLV_RUPP(id),
196 &ivk->ivk_rx_unknown_protocol,
197 &ivs->ivs_rx_unknown_protocol,
198 init);
199
200 i40e_stat_get_uint48(i40e, I40E_GLV_GOTCL(id), &ivk->ivk_tx_bytes,
214 /*
215 * We follow ixgbe's lead here and that if a kstat update didn't work
216 * 100% then we mark service unaffected as opposed to when fetching
217 * things for MAC directly.
218 */
219 if (i40e_check_acc_handle(i40e->i40e_osdep_space.ios_reg_handle) !=
220 DDI_FM_OK) {
221 ddi_fm_service_impact(i40e->i40e_dip, DDI_SERVICE_UNAFFECTED);
222 }
223 }
224
225 static int
226 i40e_stat_vsi_kstat_update(kstat_t *ksp, int rw)
227 {
228 i40e_t *i40e;
229
230 if (rw == KSTAT_WRITE)
231 return (EACCES);
232
233 i40e = ksp->ks_private;
234 i40e_stat_vsi_update(i40e, B_FALSE);
235 return (0);
236 }
237
238 void
239 i40e_stat_vsi_fini(i40e_t *i40e)
240 {
241 if (i40e->i40e_vsi_kstat != NULL) {
242 kstat_delete(i40e->i40e_vsi_kstat);
243 i40e->i40e_vsi_kstat = NULL;
244 }
245 }
246
247 boolean_t
248 i40e_stat_vsi_init(i40e_t *i40e)
249 {
250 kstat_t *ksp;
251 i40e_vsi_kstats_t *ivk;
252 char buf[64];
253
254 (void) snprintf(buf, sizeof (buf), "vsi_%d", i40e->i40e_vsi_id);
255
256 ksp = kstat_create(I40E_MODULE_NAME, ddi_get_instance(i40e->i40e_dip),
257 buf, "net", KSTAT_TYPE_NAMED,
258 sizeof (i40e_vsi_kstats_t) / sizeof (kstat_named_t), 0);
259
260 if (ksp == NULL) {
261 i40e_error(i40e, "Failed to create kstats for VSI %d",
262 i40e->i40e_vsi_id);
263 return (B_FALSE);
264 }
265
266 i40e->i40e_vsi_kstat = ksp;
267 ivk = ksp->ks_data;
268 ksp->ks_update = i40e_stat_vsi_kstat_update;
269 ksp->ks_private = i40e;
270
271 kstat_named_init(&ivk->ivk_rx_bytes, "rx_bytes",
272 KSTAT_DATA_UINT64);
273 kstat_named_init(&ivk->ivk_rx_unicast, "rx_unicast",
274 KSTAT_DATA_UINT64);
275 kstat_named_init(&ivk->ivk_rx_multicast, "rx_multicast",
276 KSTAT_DATA_UINT64);
277 kstat_named_init(&ivk->ivk_rx_broadcast, "rx_broadcast",
278 KSTAT_DATA_UINT64);
279 kstat_named_init(&ivk->ivk_rx_discards, "rx_discards",
280 KSTAT_DATA_UINT64);
281 kstat_named_init(&ivk->ivk_rx_unknown_protocol, "rx_unknown_protocol",
282 KSTAT_DATA_UINT64);
283 kstat_named_init(&ivk->ivk_tx_bytes, "tx_bytes",
284 KSTAT_DATA_UINT64);
285 kstat_named_init(&ivk->ivk_tx_unicast, "tx_unicast",
286 KSTAT_DATA_UINT64);
287 kstat_named_init(&ivk->ivk_tx_multicast, "tx_multicast",
288 KSTAT_DATA_UINT64);
289 kstat_named_init(&ivk->ivk_tx_broadcast, "tx_broadcast",
290 KSTAT_DATA_UINT64);
291 kstat_named_init(&ivk->ivk_tx_errors, "tx_errors",
292 KSTAT_DATA_UINT64);
293
294 bzero(&i40e->i40e_vsi_stat, sizeof (i40e_vsi_stats_t));
295 i40e_stat_vsi_update(i40e, B_TRUE);
296 kstat_install(i40e->i40e_vsi_kstat);
297
298 return (B_TRUE);
299 }
300
301 static void
302 i40e_stat_pf_update(i40e_t *i40e, boolean_t init)
303 {
304 i40e_pf_stats_t *ips;
305 i40e_pf_kstats_t *ipk;
306 int port = i40e->i40e_hw_space.port;
307 int i;
308
309 ASSERT(i40e->i40e_pf_kstat != NULL);
310 ips = &i40e->i40e_pf_stat;
311 ipk = i40e->i40e_pf_kstat->ks_data;
312
313 mutex_enter(&i40e->i40e_stat_lock);
314
315 /* 64-bit PCIe regs */
316 i40e_stat_get_uint48(i40e, I40E_GLPRT_GORCL(port),
653 KSTAT_DATA_UINT64);
654 kstat_named_init(&ipk->ipk_rx_unknown_protocol, "rx_unknown_protocol",
655 KSTAT_DATA_UINT64);
656 kstat_named_init(&ipk->ipk_rx_err1, "rx_err1",
657 KSTAT_DATA_UINT64);
658 kstat_named_init(&ipk->ipk_rx_err2, "rx_err2",
659 KSTAT_DATA_UINT64);
660
661
662 bzero(&i40e->i40e_pf_stat, sizeof (i40e_pf_stats_t));
663 i40e_stat_pf_update(i40e, B_TRUE);
664
665 kstat_install(i40e->i40e_pf_kstat);
666
667 return (B_TRUE);
668 }
669
670 void
671 i40e_stats_fini(i40e_t *i40e)
672 {
673 ASSERT(i40e->i40e_vsi_kstat == NULL);
674 if (i40e->i40e_pf_kstat != NULL) {
675 kstat_delete(i40e->i40e_pf_kstat);
676 i40e->i40e_pf_kstat = NULL;
677 }
678
679 mutex_destroy(&i40e->i40e_stat_lock);
680 }
681
682 boolean_t
683 i40e_stats_init(i40e_t *i40e)
684 {
685 mutex_init(&i40e->i40e_stat_lock, NULL, MUTEX_DRIVER, NULL);
686 if (i40e_stat_pf_init(i40e) == B_FALSE) {
687 mutex_destroy(&i40e->i40e_stat_lock);
688 return (B_FALSE);
689 }
690
691 return (B_TRUE);
692 }
693
1213 kstat_delete(itrq->itrq_txkstat);
1214 itrq->itrq_txkstat = NULL;
1215 return (B_FALSE);
1216 }
1217
1218 itrq->itrq_txkstat->ks_data = &itrq->itrq_txstat;
1219 itrq->itrq_rxkstat->ks_data = &itrq->itrq_rxstat;
1220
1221 kstat_named_init(&tsp->itxs_bytes, "tx_bytes",
1222 KSTAT_DATA_UINT64);
1223 tsp->itxs_bytes.value.ui64 = 0;
1224 kstat_named_init(&tsp->itxs_packets, "tx_packets",
1225 KSTAT_DATA_UINT64);
1226 tsp->itxs_packets.value.ui64 = 0;
1227 kstat_named_init(&tsp->itxs_descriptors, "tx_descriptors",
1228 KSTAT_DATA_UINT64);
1229 tsp->itxs_descriptors.value.ui64 = 0;
1230 kstat_named_init(&tsp->itxs_recycled, "tx_recycled",
1231 KSTAT_DATA_UINT64);
1232 tsp->itxs_recycled.value.ui64 = 0;
1233
1234 kstat_named_init(&tsp->itxs_hck_meoifail, "tx_hck_meoifail",
1235 KSTAT_DATA_UINT64);
1236 tsp->itxs_hck_meoifail.value.ui64 = 0;
1237 kstat_named_init(&tsp->itxs_hck_nol2info, "tx_hck_nol2info",
1238 KSTAT_DATA_UINT64);
1239 tsp->itxs_hck_nol2info.value.ui64 = 0;
1240 kstat_named_init(&tsp->itxs_hck_nol3info, "tx_hck_nol3info",
1241 KSTAT_DATA_UINT64);
1242 tsp->itxs_hck_nol3info.value.ui64 = 0;
1243 kstat_named_init(&tsp->itxs_hck_nol4info, "tx_hck_nol4info",
1244 KSTAT_DATA_UINT64);
1245 tsp->itxs_hck_nol4info.value.ui64 = 0;
1246 kstat_named_init(&tsp->itxs_hck_badl3, "tx_hck_badl3",
1247 KSTAT_DATA_UINT64);
1248 tsp->itxs_hck_badl3.value.ui64 = 0;
1249 kstat_named_init(&tsp->itxs_hck_badl4, "tx_hck_badl4",
1250 KSTAT_DATA_UINT64);
1251 tsp->itxs_hck_badl4.value.ui64 = 0;
1252 kstat_named_init(&tsp->itxs_err_notcb, "tx_err_notcb",
1253 KSTAT_DATA_UINT64);
1254 tsp->itxs_err_notcb.value.ui64 = 0;
1255 kstat_named_init(&tsp->itxs_err_nodescs, "tx_err_nodescs",
1256 KSTAT_DATA_UINT64);
1257 tsp->itxs_err_nodescs.value.ui64 = 0;
1258 kstat_named_init(&tsp->itxs_err_context, "tx_err_context",
1259 KSTAT_DATA_UINT64);
1260 tsp->itxs_err_context.value.ui64 = 0;
1261 kstat_named_init(&tsp->itxs_num_unblocked, "tx_num_unblocked",
1262 KSTAT_DATA_UINT64);
1263 tsp->itxs_num_unblocked.value.ui64 = 0;
1264
1265
1266 kstat_named_init(&rsp->irxs_bytes, "rx_bytes",
1267 KSTAT_DATA_UINT64);
1268 rsp->irxs_bytes.value.ui64 = 0;
1269 kstat_named_init(&rsp->irxs_packets, "rx_packets",
1270 KSTAT_DATA_UINT64);
1271 rsp->irxs_packets.value.ui64 = 0;
|
1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
14 * Copyright 2019 Joyent, Inc.
15 */
16
17 #include "i40e_sw.h"
18
19 /*
20 * -------------------
21 * Statistics Overview
22 * -------------------
23 *
24 * As part of managing the driver and understanding what's going on, we keep
25 * track of statistics from two different sources:
26 *
27 * - Statistics from the device
28 * - Statistics maintained by the driver
29 *
30 * Generally, the hardware provides us traditional IETF and MIB Ethernet
31 * statistics, for example, the total packets in and out, various errors in
32 * packets, the negotiated status etc. The driver, on the other hand, primarily
33 * contains statistics around driver-specific issues, such as information about
34 * checksumming on receive and transmit and the data in and out of a specific
52 *
53 * The PF's kstat is called 'pfstats' so as not to collide with other system
54 * provided kstats. Thus, for instance 0, usually the first PF, the full kstat
55 * would be: i40e:0:pfstats:.
56 *
57 * The kstat for each VSI is called vsi_%instance. So for the first PF, which is
58 * instance zero and the first vsi, which has id 0, it will be named vsi_0 and
59 * the full kstat would be i40e:0:vsi_0:.
60 *
61 * The kstat for each queue is trqpair_tx_%queue and trqpair_rx_%queue. Note
62 * that these are labeled based on their local index, which may mean that
63 * different instances have overlapping sets of queues. This isn't a problem as
64 * the kstats will always use the instance number of the pf to distinguish it in
65 * the kstat tuple.
66 *
67 * ---------------------
68 * Hardware Arrangements
69 * ---------------------
70 *
71 * The hardware keeps statistics at each physical function/MAC (PF) and it keeps
72 * statistics on each virtual station interface (VSI).
73 *
74 * The hardware keeps these statistics as 32-bit and 48-bit counters. We are
75 * required to read them and then compute the differences between them. The
76 * 48-bit counters span more than one 32-bit register in the BAR. The hardware
77 * suggests that to read them, we perform 64-bit reads of the lower of the two
78 * registers that make up a 48-bit stat. The hardware guarantees that the reads
79 * of those two registers will be atomic and we'll get a consistent value, not a
80 * property it has for every read of two registers.
81 *
82 * For every kstat we have based on this, we have a corresponding uint64_t that
83 * we keep around as a base value in a separate structure. Whenever we read a
84 * value, we end up grabbing the current value, calculating a difference between
85 * the previously stored value and the current one, and updating the kstat with
86 * that difference. After which, we go through and update the base value that we
87 * stored. This is all encapsulated in i40e_stat_get_uint32() and
88 * i40e_stat_get_uint48().
89 *
90 * The only unfortunate thing here is that the hardware doesn't give us any kind
91 * of overflow counter. It just tries to make sure that the uint32_t and
92 * uint48_t counters are large enough to hopefully not overflow right away. This
93 * isn't the most reassuring statement and we should investigate ways of
94 * ensuring that if a system is active, but not actively measured, we don't lose
95 * data.
96 *
97 * The pf kstats data is stored in the i40e_t`i40e_pf_kstat. It is backed by the
98 * i40e_t`i40e_pf_stat structure. Similarly the VSI related kstats are in
99 * i40e_t`i40e_vsis[idx].iv_kstats and the data is backed in the
100 * i40e_t`i40e_vsis[idx].iv_stats. All of this data is protected by the
101 * i40e_stat_lock, which should be taken last, when acquiring locks.
102 */
103
104 static void
105 i40e_stat_get_uint48(i40e_t *i40e, uintptr_t reg, kstat_named_t *kstat,
106 uint64_t *base, boolean_t init)
107 {
108 i40e_hw_t *hw = &i40e->i40e_hw_space;
109 uint64_t raw, delta;
110
111 ASSERT(MUTEX_HELD(&i40e->i40e_stat_lock));
112
113 raw = ddi_get64(i40e->i40e_osdep_space.ios_reg_handle,
114 (uint64_t *)((uintptr_t)hw->hw_addr + reg));
115
116 if (init == B_TRUE) {
117 *base = raw;
118 return;
119 }
120
121 /*
147 if (init == B_TRUE) {
148 *base = raw;
149 return;
150 }
151
152 /*
153 * Watch out for wraparound as we only have a 32-bit counter.
154 */
155 if (raw >= *base) {
156 delta = raw - *base;
157 } else {
158 delta = 0x100000000ULL - *base + raw;
159 }
160
161 kstat->value.ui64 += delta;
162 *base = raw;
163
164 }
165
166 static void
167 i40e_stat_vsi_update(i40e_t *i40e, uint_t idx, boolean_t init)
168 {
169 i40e_vsi_stats_t *ivs;
170 i40e_vsi_kstats_t *ivk;
171 uint16_t id = i40e->i40e_vsis[idx].iv_stats_id;
172
173 ASSERT3P(i40e->i40e_vsis[idx].iv_kstats, !=, NULL);
174 ivs = &i40e->i40e_vsis[idx].iv_stats;
175 ivk = i40e->i40e_vsis[idx].iv_kstats->ks_data;
176
177 mutex_enter(&i40e->i40e_stat_lock);
178
179 i40e_stat_get_uint48(i40e, I40E_GLV_GORCL(id), &ivk->ivk_rx_bytes,
180 &ivs->ivs_rx_bytes, init);
181 i40e_stat_get_uint48(i40e, I40E_GLV_UPRCL(id), &ivk->ivk_rx_unicast,
182 &ivs->ivs_rx_unicast, init);
183 i40e_stat_get_uint48(i40e, I40E_GLV_MPRCL(id), &ivk->ivk_rx_multicast,
184 &ivs->ivs_rx_multicast, init);
185 i40e_stat_get_uint48(i40e, I40E_GLV_BPRCL(id), &ivk->ivk_rx_broadcast,
186 &ivs->ivs_rx_broadcast, init);
187
188 i40e_stat_get_uint32(i40e, I40E_GLV_RDPC(id), &ivk->ivk_rx_discards,
189 &ivs->ivs_rx_discards, init);
190 i40e_stat_get_uint32(i40e, I40E_GLV_RUPP(id),
191 &ivk->ivk_rx_unknown_protocol,
192 &ivs->ivs_rx_unknown_protocol,
193 init);
194
195 i40e_stat_get_uint48(i40e, I40E_GLV_GOTCL(id), &ivk->ivk_tx_bytes,
209 /*
210 * We follow ixgbe's lead here and that if a kstat update didn't work
211 * 100% then we mark service unaffected as opposed to when fetching
212 * things for MAC directly.
213 */
214 if (i40e_check_acc_handle(i40e->i40e_osdep_space.ios_reg_handle) !=
215 DDI_FM_OK) {
216 ddi_fm_service_impact(i40e->i40e_dip, DDI_SERVICE_UNAFFECTED);
217 }
218 }
219
220 static int
221 i40e_stat_vsi_kstat_update(kstat_t *ksp, int rw)
222 {
223 i40e_t *i40e;
224
225 if (rw == KSTAT_WRITE)
226 return (EACCES);
227
228 i40e = ksp->ks_private;
229 for (uint_t i = 0; i < i40e->i40e_num_rx_groups; i++)
230 i40e_stat_vsi_update(i40e, i, B_FALSE);
231
232 return (0);
233 }
234
235 void
236 i40e_stat_vsi_fini(i40e_t *i40e, uint_t idx)
237 {
238 if (i40e->i40e_vsis[idx].iv_kstats != NULL) {
239 kstat_delete(i40e->i40e_vsis[idx].iv_kstats);
240 i40e->i40e_vsis[idx].iv_kstats = NULL;
241 }
242 }
243
244 boolean_t
245 i40e_stat_vsi_init(i40e_t *i40e, uint_t idx)
246 {
247 kstat_t *ksp;
248 i40e_vsi_kstats_t *ivk;
249 char buf[64];
250 uint16_t vsi_id = i40e->i40e_vsis[idx].iv_seid;
251
252 (void) snprintf(buf, sizeof (buf), "vsi_%u", vsi_id);
253
254 ksp = kstat_create(I40E_MODULE_NAME, ddi_get_instance(i40e->i40e_dip),
255 buf, "net", KSTAT_TYPE_NAMED,
256 sizeof (i40e_vsi_kstats_t) / sizeof (kstat_named_t), 0);
257
258 if (ksp == NULL) {
259 i40e_error(i40e, "Failed to create kstats for VSI %u", vsi_id);
260 return (B_FALSE);
261 }
262
263 i40e->i40e_vsis[idx].iv_kstats = ksp;
264 ivk = ksp->ks_data;
265 ksp->ks_update = i40e_stat_vsi_kstat_update;
266 ksp->ks_private = i40e;
267
268 kstat_named_init(&ivk->ivk_rx_bytes, "rx_bytes",
269 KSTAT_DATA_UINT64);
270 kstat_named_init(&ivk->ivk_rx_unicast, "rx_unicast",
271 KSTAT_DATA_UINT64);
272 kstat_named_init(&ivk->ivk_rx_multicast, "rx_multicast",
273 KSTAT_DATA_UINT64);
274 kstat_named_init(&ivk->ivk_rx_broadcast, "rx_broadcast",
275 KSTAT_DATA_UINT64);
276 kstat_named_init(&ivk->ivk_rx_discards, "rx_discards",
277 KSTAT_DATA_UINT64);
278 kstat_named_init(&ivk->ivk_rx_unknown_protocol, "rx_unknown_protocol",
279 KSTAT_DATA_UINT64);
280 kstat_named_init(&ivk->ivk_tx_bytes, "tx_bytes",
281 KSTAT_DATA_UINT64);
282 kstat_named_init(&ivk->ivk_tx_unicast, "tx_unicast",
283 KSTAT_DATA_UINT64);
284 kstat_named_init(&ivk->ivk_tx_multicast, "tx_multicast",
285 KSTAT_DATA_UINT64);
286 kstat_named_init(&ivk->ivk_tx_broadcast, "tx_broadcast",
287 KSTAT_DATA_UINT64);
288 kstat_named_init(&ivk->ivk_tx_errors, "tx_errors",
289 KSTAT_DATA_UINT64);
290
291 bzero(&i40e->i40e_vsis[idx].iv_stats, sizeof (i40e_vsi_stats_t));
292 i40e_stat_vsi_update(i40e, idx, B_TRUE);
293 kstat_install(i40e->i40e_vsis[idx].iv_kstats);
294
295 return (B_TRUE);
296 }
297
298 static void
299 i40e_stat_pf_update(i40e_t *i40e, boolean_t init)
300 {
301 i40e_pf_stats_t *ips;
302 i40e_pf_kstats_t *ipk;
303 int port = i40e->i40e_hw_space.port;
304 int i;
305
306 ASSERT(i40e->i40e_pf_kstat != NULL);
307 ips = &i40e->i40e_pf_stat;
308 ipk = i40e->i40e_pf_kstat->ks_data;
309
310 mutex_enter(&i40e->i40e_stat_lock);
311
312 /* 64-bit PCIe regs */
313 i40e_stat_get_uint48(i40e, I40E_GLPRT_GORCL(port),
650 KSTAT_DATA_UINT64);
651 kstat_named_init(&ipk->ipk_rx_unknown_protocol, "rx_unknown_protocol",
652 KSTAT_DATA_UINT64);
653 kstat_named_init(&ipk->ipk_rx_err1, "rx_err1",
654 KSTAT_DATA_UINT64);
655 kstat_named_init(&ipk->ipk_rx_err2, "rx_err2",
656 KSTAT_DATA_UINT64);
657
658
659 bzero(&i40e->i40e_pf_stat, sizeof (i40e_pf_stats_t));
660 i40e_stat_pf_update(i40e, B_TRUE);
661
662 kstat_install(i40e->i40e_pf_kstat);
663
664 return (B_TRUE);
665 }
666
667 void
668 i40e_stats_fini(i40e_t *i40e)
669 {
670 #ifdef DEBUG
671 for (uint_t i = 0; i < i40e->i40e_num_rx_groups; i++) {
672 ASSERT3P(i40e->i40e_vsis[i].iv_kstats, ==, NULL);
673 }
674 #endif
675
676 if (i40e->i40e_pf_kstat != NULL) {
677 kstat_delete(i40e->i40e_pf_kstat);
678 i40e->i40e_pf_kstat = NULL;
679 }
680
681 mutex_destroy(&i40e->i40e_stat_lock);
682 }
683
684 boolean_t
685 i40e_stats_init(i40e_t *i40e)
686 {
687 mutex_init(&i40e->i40e_stat_lock, NULL, MUTEX_DRIVER, NULL);
688 if (i40e_stat_pf_init(i40e) == B_FALSE) {
689 mutex_destroy(&i40e->i40e_stat_lock);
690 return (B_FALSE);
691 }
692
693 return (B_TRUE);
694 }
695
1215 kstat_delete(itrq->itrq_txkstat);
1216 itrq->itrq_txkstat = NULL;
1217 return (B_FALSE);
1218 }
1219
1220 itrq->itrq_txkstat->ks_data = &itrq->itrq_txstat;
1221 itrq->itrq_rxkstat->ks_data = &itrq->itrq_rxstat;
1222
1223 kstat_named_init(&tsp->itxs_bytes, "tx_bytes",
1224 KSTAT_DATA_UINT64);
1225 tsp->itxs_bytes.value.ui64 = 0;
1226 kstat_named_init(&tsp->itxs_packets, "tx_packets",
1227 KSTAT_DATA_UINT64);
1228 tsp->itxs_packets.value.ui64 = 0;
1229 kstat_named_init(&tsp->itxs_descriptors, "tx_descriptors",
1230 KSTAT_DATA_UINT64);
1231 tsp->itxs_descriptors.value.ui64 = 0;
1232 kstat_named_init(&tsp->itxs_recycled, "tx_recycled",
1233 KSTAT_DATA_UINT64);
1234 tsp->itxs_recycled.value.ui64 = 0;
1235 kstat_named_init(&tsp->itxs_force_copy, "tx_force_copy",
1236 KSTAT_DATA_UINT64);
1237 tsp->itxs_force_copy.value.ui64 = 0;
1238 kstat_named_init(&tsp->itxs_tso_force_copy, "tx_tso_force_copy",
1239 KSTAT_DATA_UINT64);
1240 tsp->itxs_tso_force_copy.value.ui64 = 0;
1241
1242 kstat_named_init(&tsp->itxs_hck_meoifail, "tx_hck_meoifail",
1243 KSTAT_DATA_UINT64);
1244 tsp->itxs_hck_meoifail.value.ui64 = 0;
1245 kstat_named_init(&tsp->itxs_hck_nol2info, "tx_hck_nol2info",
1246 KSTAT_DATA_UINT64);
1247 tsp->itxs_hck_nol2info.value.ui64 = 0;
1248 kstat_named_init(&tsp->itxs_hck_nol3info, "tx_hck_nol3info",
1249 KSTAT_DATA_UINT64);
1250 tsp->itxs_hck_nol3info.value.ui64 = 0;
1251 kstat_named_init(&tsp->itxs_hck_nol4info, "tx_hck_nol4info",
1252 KSTAT_DATA_UINT64);
1253 tsp->itxs_hck_nol4info.value.ui64 = 0;
1254 kstat_named_init(&tsp->itxs_hck_badl3, "tx_hck_badl3",
1255 KSTAT_DATA_UINT64);
1256 tsp->itxs_hck_badl3.value.ui64 = 0;
1257 kstat_named_init(&tsp->itxs_hck_badl4, "tx_hck_badl4",
1258 KSTAT_DATA_UINT64);
1259 tsp->itxs_hck_badl4.value.ui64 = 0;
1260 kstat_named_init(&tsp->itxs_lso_nohck, "tx_lso_nohck",
1261 KSTAT_DATA_UINT64);
1262 tsp->itxs_lso_nohck.value.ui64 = 0;
1263 kstat_named_init(&tsp->itxs_bind_fails, "tx_bind_fails",
1264 KSTAT_DATA_UINT64);
1265 tsp->itxs_bind_fails.value.ui64 = 0;
1266 kstat_named_init(&tsp->itxs_err_notcb, "tx_err_notcb",
1267 KSTAT_DATA_UINT64);
1268 tsp->itxs_err_notcb.value.ui64 = 0;
1269 kstat_named_init(&tsp->itxs_err_nodescs, "tx_err_nodescs",
1270 KSTAT_DATA_UINT64);
1271 tsp->itxs_err_nodescs.value.ui64 = 0;
1272 kstat_named_init(&tsp->itxs_err_context, "tx_err_context",
1273 KSTAT_DATA_UINT64);
1274 tsp->itxs_err_context.value.ui64 = 0;
1275 kstat_named_init(&tsp->itxs_num_unblocked, "tx_num_unblocked",
1276 KSTAT_DATA_UINT64);
1277 tsp->itxs_num_unblocked.value.ui64 = 0;
1278
1279
1280 kstat_named_init(&rsp->irxs_bytes, "rx_bytes",
1281 KSTAT_DATA_UINT64);
1282 rsp->irxs_bytes.value.ui64 = 0;
1283 kstat_named_init(&rsp->irxs_packets, "rx_packets",
1284 KSTAT_DATA_UINT64);
1285 rsp->irxs_packets.value.ui64 = 0;
|