1 /*
2  * Copyright (c) 2016 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef __NET_STATS_H__
8 #define __NET_STATS_H__
9 
10 #if defined(CONFIG_NET_STATISTICS) && defined(CONFIG_NET_NATIVE)
11 
12 #include <stdlib.h>
13 
14 #include <zephyr/net/net_ip.h>
15 #include <zephyr/net/net_stats.h>
16 #include <zephyr/net/net_if.h>
17 
18 extern struct net_stats net_stats;
19 
20 #if defined(CONFIG_NET_STATISTICS_PER_INTERFACE)
21 #define SET_STAT(cmd) (cmd)
22 #define GET_STAT(iface, s) (iface ? iface->stats.s : net_stats.s)
23 #define GET_STAT_ADDR(iface, s) (iface ? &iface->stats.s : &net_stats.s)
24 #else
25 #define SET_STAT(cmd)
26 #define GET_STAT(iface, s) (net_stats.s)
27 #define GET_STAT_ADDR(iface, s) (&GET_STAT(iface, s))
28 #endif
29 
30 #define UPDATE_STAT_GLOBAL(cmd) (net_##cmd)
31 #define UPDATE_STAT(_iface, _cmd) \
32 	{ NET_ASSERT(_iface); (UPDATE_STAT_GLOBAL(_cmd)); \
33 	  SET_STAT(_iface->_cmd); }
34 /* Core stats */
35 
net_stats_update_processing_error(struct net_if * iface)36 static inline void net_stats_update_processing_error(struct net_if *iface)
37 {
38 	UPDATE_STAT(iface, stats.processing_error++);
39 }
40 
net_stats_update_ip_errors_protoerr(struct net_if * iface)41 static inline void net_stats_update_ip_errors_protoerr(struct net_if *iface)
42 {
43 	UPDATE_STAT(iface, stats.ip_errors.protoerr++);
44 }
45 
net_stats_update_ip_errors_vhlerr(struct net_if * iface)46 static inline void net_stats_update_ip_errors_vhlerr(struct net_if *iface)
47 {
48 	UPDATE_STAT(iface, stats.ip_errors.vhlerr++);
49 }
50 
net_stats_update_bytes_recv(struct net_if * iface,uint32_t bytes)51 static inline void net_stats_update_bytes_recv(struct net_if *iface,
52 					       uint32_t bytes)
53 {
54 	UPDATE_STAT(iface, stats.bytes.received += bytes);
55 }
56 
net_stats_update_bytes_sent(struct net_if * iface,uint32_t bytes)57 static inline void net_stats_update_bytes_sent(struct net_if *iface,
58 					       uint32_t bytes)
59 {
60 	UPDATE_STAT(iface, stats.bytes.sent += bytes);
61 }
62 #else
63 #define net_stats_update_processing_error(iface)
64 #define net_stats_update_ip_errors_protoerr(iface)
65 #define net_stats_update_ip_errors_vhlerr(iface)
66 #define net_stats_update_bytes_recv(iface, bytes)
67 #define net_stats_update_bytes_sent(iface, bytes)
68 #endif /* CONFIG_NET_STATISTICS */
69 
70 #if defined(CONFIG_NET_STATISTICS_IPV6) && defined(CONFIG_NET_NATIVE_IPV6)
71 /* IPv6 stats */
72 
net_stats_update_ipv6_sent(struct net_if * iface)73 static inline void net_stats_update_ipv6_sent(struct net_if *iface)
74 {
75 	UPDATE_STAT(iface, stats.ipv6.sent++);
76 }
77 
net_stats_update_ipv6_recv(struct net_if * iface)78 static inline void net_stats_update_ipv6_recv(struct net_if *iface)
79 {
80 	UPDATE_STAT(iface, stats.ipv6.recv++);
81 }
82 
net_stats_update_ipv6_drop(struct net_if * iface)83 static inline void net_stats_update_ipv6_drop(struct net_if *iface)
84 {
85 	UPDATE_STAT(iface, stats.ipv6.drop++);
86 }
87 #else
88 #define net_stats_update_ipv6_drop(iface)
89 #define net_stats_update_ipv6_sent(iface)
90 #define net_stats_update_ipv6_recv(iface)
91 #endif /* CONFIG_NET_STATISTICS_IPV6 */
92 
93 #if defined(CONFIG_NET_STATISTICS_IPV6_ND) && defined(CONFIG_NET_NATIVE_IPV6)
94 /* IPv6 Neighbor Discovery stats*/
95 
net_stats_update_ipv6_nd_sent(struct net_if * iface)96 static inline void net_stats_update_ipv6_nd_sent(struct net_if *iface)
97 {
98 	UPDATE_STAT(iface, stats.ipv6_nd.sent++);
99 }
100 
net_stats_update_ipv6_nd_recv(struct net_if * iface)101 static inline void net_stats_update_ipv6_nd_recv(struct net_if *iface)
102 {
103 	UPDATE_STAT(iface, stats.ipv6_nd.recv++);
104 }
105 
net_stats_update_ipv6_nd_drop(struct net_if * iface)106 static inline void net_stats_update_ipv6_nd_drop(struct net_if *iface)
107 {
108 	UPDATE_STAT(iface, stats.ipv6_nd.drop++);
109 }
110 #else
111 #define net_stats_update_ipv6_nd_sent(iface)
112 #define net_stats_update_ipv6_nd_recv(iface)
113 #define net_stats_update_ipv6_nd_drop(iface)
114 #endif /* CONFIG_NET_STATISTICS_IPV6_ND */
115 
116 #if defined(CONFIG_NET_STATISTICS_IPV6_PMTU) && defined(CONFIG_NET_NATIVE_IPV6)
117 /* IPv6 Path MTU Discovery stats */
118 
net_stats_update_ipv6_pmtu_sent(struct net_if * iface)119 static inline void net_stats_update_ipv6_pmtu_sent(struct net_if *iface)
120 {
121 	UPDATE_STAT(iface, stats.ipv6_pmtu.sent++);
122 }
123 
net_stats_update_ipv6_pmtu_recv(struct net_if * iface)124 static inline void net_stats_update_ipv6_pmtu_recv(struct net_if *iface)
125 {
126 	UPDATE_STAT(iface, stats.ipv6_pmtu.recv++);
127 }
128 
net_stats_update_ipv6_pmtu_drop(struct net_if * iface)129 static inline void net_stats_update_ipv6_pmtu_drop(struct net_if *iface)
130 {
131 	UPDATE_STAT(iface, stats.ipv6_pmtu.drop++);
132 }
133 #else
134 #define net_stats_update_ipv6_pmtu_sent(iface)
135 #define net_stats_update_ipv6_pmtu_recv(iface)
136 #define net_stats_update_ipv6_pmtu_drop(iface)
137 #endif /* CONFIG_NET_STATISTICS_IPV6_PMTU */
138 
139 #if defined(CONFIG_NET_STATISTICS_IPV4_PMTU) && defined(CONFIG_NET_NATIVE_IPV4)
140 /* IPv4 Path MTU Discovery stats */
141 
net_stats_update_ipv4_pmtu_sent(struct net_if * iface)142 static inline void net_stats_update_ipv4_pmtu_sent(struct net_if *iface)
143 {
144 	UPDATE_STAT(iface, stats.ipv4_pmtu.sent++);
145 }
146 
net_stats_update_ipv4_pmtu_recv(struct net_if * iface)147 static inline void net_stats_update_ipv4_pmtu_recv(struct net_if *iface)
148 {
149 	UPDATE_STAT(iface, stats.ipv4_pmtu.recv++);
150 }
151 
net_stats_update_ipv4_pmtu_drop(struct net_if * iface)152 static inline void net_stats_update_ipv4_pmtu_drop(struct net_if *iface)
153 {
154 	UPDATE_STAT(iface, stats.ipv4_pmtu.drop++);
155 }
156 #else
157 #define net_stats_update_ipv4_pmtu_sent(iface)
158 #define net_stats_update_ipv4_pmtu_recv(iface)
159 #define net_stats_update_ipv4_pmtu_drop(iface)
160 #endif /* CONFIG_NET_STATISTICS_IPV4_PMTU */
161 
162 #if defined(CONFIG_NET_STATISTICS_IPV4) && defined(CONFIG_NET_NATIVE_IPV4)
163 /* IPv4 stats */
164 
net_stats_update_ipv4_drop(struct net_if * iface)165 static inline void net_stats_update_ipv4_drop(struct net_if *iface)
166 {
167 	UPDATE_STAT(iface, stats.ipv4.drop++);
168 }
169 
net_stats_update_ipv4_sent(struct net_if * iface)170 static inline void net_stats_update_ipv4_sent(struct net_if *iface)
171 {
172 	UPDATE_STAT(iface, stats.ipv4.sent++);
173 }
174 
net_stats_update_ipv4_recv(struct net_if * iface)175 static inline void net_stats_update_ipv4_recv(struct net_if *iface)
176 {
177 	UPDATE_STAT(iface, stats.ipv4.recv++);
178 }
179 #else
180 #define net_stats_update_ipv4_drop(iface)
181 #define net_stats_update_ipv4_sent(iface)
182 #define net_stats_update_ipv4_recv(iface)
183 #endif /* CONFIG_NET_STATISTICS_IPV4 */
184 
185 #if defined(CONFIG_NET_STATISTICS_ICMP) && defined(CONFIG_NET_NATIVE_IPV4)
186 /* Common ICMPv4/ICMPv6 stats */
net_stats_update_icmp_sent(struct net_if * iface)187 static inline void net_stats_update_icmp_sent(struct net_if *iface)
188 {
189 	UPDATE_STAT(iface, stats.icmp.sent++);
190 }
191 
net_stats_update_icmp_recv(struct net_if * iface)192 static inline void net_stats_update_icmp_recv(struct net_if *iface)
193 {
194 	UPDATE_STAT(iface, stats.icmp.recv++);
195 }
196 
net_stats_update_icmp_drop(struct net_if * iface)197 static inline void net_stats_update_icmp_drop(struct net_if *iface)
198 {
199 	UPDATE_STAT(iface, stats.icmp.drop++);
200 }
201 #else
202 #define net_stats_update_icmp_sent(iface)
203 #define net_stats_update_icmp_recv(iface)
204 #define net_stats_update_icmp_drop(iface)
205 #endif /* CONFIG_NET_STATISTICS_ICMP */
206 
207 #if defined(CONFIG_NET_STATISTICS_UDP) && defined(CONFIG_NET_NATIVE_UDP)
208 /* UDP stats */
net_stats_update_udp_sent(struct net_if * iface)209 static inline void net_stats_update_udp_sent(struct net_if *iface)
210 {
211 	UPDATE_STAT(iface, stats.udp.sent++);
212 }
213 
net_stats_update_udp_recv(struct net_if * iface)214 static inline void net_stats_update_udp_recv(struct net_if *iface)
215 {
216 	UPDATE_STAT(iface, stats.udp.recv++);
217 }
218 
net_stats_update_udp_drop(struct net_if * iface)219 static inline void net_stats_update_udp_drop(struct net_if *iface)
220 {
221 	UPDATE_STAT(iface, stats.udp.drop++);
222 }
223 
net_stats_update_udp_chkerr(struct net_if * iface)224 static inline void net_stats_update_udp_chkerr(struct net_if *iface)
225 {
226 	UPDATE_STAT(iface, stats.udp.chkerr++);
227 }
228 #else
229 #define net_stats_update_udp_sent(iface)
230 #define net_stats_update_udp_recv(iface)
231 #define net_stats_update_udp_drop(iface)
232 #define net_stats_update_udp_chkerr(iface)
233 #endif /* CONFIG_NET_STATISTICS_UDP */
234 
235 #if defined(CONFIG_NET_STATISTICS_TCP) && defined(CONFIG_NET_NATIVE_TCP)
236 /* TCP stats */
net_stats_update_tcp_sent(struct net_if * iface,uint32_t bytes)237 static inline void net_stats_update_tcp_sent(struct net_if *iface, uint32_t bytes)
238 {
239 	UPDATE_STAT(iface, stats.tcp.bytes.sent += bytes);
240 }
241 
net_stats_update_tcp_recv(struct net_if * iface,uint32_t bytes)242 static inline void net_stats_update_tcp_recv(struct net_if *iface, uint32_t bytes)
243 {
244 	UPDATE_STAT(iface, stats.tcp.bytes.received += bytes);
245 }
246 
net_stats_update_tcp_resent(struct net_if * iface,uint32_t bytes)247 static inline void net_stats_update_tcp_resent(struct net_if *iface,
248 					       uint32_t bytes)
249 {
250 	UPDATE_STAT(iface, stats.tcp.resent += bytes);
251 }
252 
net_stats_update_tcp_drop(struct net_if * iface)253 static inline void net_stats_update_tcp_drop(struct net_if *iface)
254 {
255 	UPDATE_STAT(iface, stats.tcp.drop++);
256 }
257 
net_stats_update_tcp_seg_sent(struct net_if * iface)258 static inline void net_stats_update_tcp_seg_sent(struct net_if *iface)
259 {
260 	UPDATE_STAT(iface, stats.tcp.sent++);
261 }
262 
net_stats_update_tcp_seg_recv(struct net_if * iface)263 static inline void net_stats_update_tcp_seg_recv(struct net_if *iface)
264 {
265 	UPDATE_STAT(iface, stats.tcp.recv++);
266 }
267 
net_stats_update_tcp_seg_drop(struct net_if * iface)268 static inline void net_stats_update_tcp_seg_drop(struct net_if *iface)
269 {
270 	UPDATE_STAT(iface, stats.tcp.seg_drop++);
271 }
272 
net_stats_update_tcp_seg_rst(struct net_if * iface)273 static inline void net_stats_update_tcp_seg_rst(struct net_if *iface)
274 {
275 	UPDATE_STAT(iface, stats.tcp.rst++);
276 }
277 
net_stats_update_tcp_seg_conndrop(struct net_if * iface)278 static inline void net_stats_update_tcp_seg_conndrop(struct net_if *iface)
279 {
280 	UPDATE_STAT(iface, stats.tcp.conndrop++);
281 }
282 
net_stats_update_tcp_seg_connrst(struct net_if * iface)283 static inline void net_stats_update_tcp_seg_connrst(struct net_if *iface)
284 {
285 	UPDATE_STAT(iface, stats.tcp.connrst++);
286 }
287 
net_stats_update_tcp_seg_chkerr(struct net_if * iface)288 static inline void net_stats_update_tcp_seg_chkerr(struct net_if *iface)
289 {
290 	UPDATE_STAT(iface, stats.tcp.chkerr++);
291 }
292 
net_stats_update_tcp_seg_ackerr(struct net_if * iface)293 static inline void net_stats_update_tcp_seg_ackerr(struct net_if *iface)
294 {
295 	UPDATE_STAT(iface, stats.tcp.ackerr++);
296 }
297 
net_stats_update_tcp_seg_rsterr(struct net_if * iface)298 static inline void net_stats_update_tcp_seg_rsterr(struct net_if *iface)
299 {
300 	UPDATE_STAT(iface, stats.tcp.rsterr++);
301 }
302 
net_stats_update_tcp_seg_rexmit(struct net_if * iface)303 static inline void net_stats_update_tcp_seg_rexmit(struct net_if *iface)
304 {
305 	UPDATE_STAT(iface, stats.tcp.rexmit++);
306 }
307 #else
308 #define net_stats_update_tcp_sent(iface, bytes)
309 #define net_stats_update_tcp_resent(iface, bytes)
310 #define net_stats_update_tcp_recv(iface, bytes)
311 #define net_stats_update_tcp_drop(iface)
312 #define net_stats_update_tcp_seg_sent(iface)
313 #define net_stats_update_tcp_seg_recv(iface)
314 #define net_stats_update_tcp_seg_drop(iface)
315 #define net_stats_update_tcp_seg_rst(iface)
316 #define net_stats_update_tcp_seg_conndrop(iface)
317 #define net_stats_update_tcp_seg_connrst(iface)
318 #define net_stats_update_tcp_seg_chkerr(iface)
319 #define net_stats_update_tcp_seg_ackerr(iface)
320 #define net_stats_update_tcp_seg_rsterr(iface)
321 #define net_stats_update_tcp_seg_rexmit(iface)
322 #endif /* CONFIG_NET_STATISTICS_TCP */
323 
net_stats_update_per_proto_recv(struct net_if * iface,enum net_ip_protocol proto)324 static inline void net_stats_update_per_proto_recv(struct net_if *iface,
325 						   enum net_ip_protocol proto)
326 {
327 	if (!IS_ENABLED(CONFIG_NET_NATIVE)) {
328 		return;
329 	}
330 
331 	if (IS_ENABLED(CONFIG_NET_UDP) && proto == IPPROTO_UDP) {
332 		net_stats_update_udp_recv(iface);
333 	} else if (IS_ENABLED(CONFIG_NET_TCP) && proto == IPPROTO_TCP) {
334 		net_stats_update_tcp_seg_recv(iface);
335 	}
336 }
337 
net_stats_update_per_proto_drop(struct net_if * iface,enum net_ip_protocol proto)338 static inline void net_stats_update_per_proto_drop(struct net_if *iface,
339 						   enum net_ip_protocol proto)
340 {
341 	if (!IS_ENABLED(CONFIG_NET_NATIVE)) {
342 		return;
343 	}
344 
345 	if (IS_ENABLED(CONFIG_NET_UDP) && proto == IPPROTO_UDP) {
346 		net_stats_update_udp_drop(iface);
347 	} else if (IS_ENABLED(CONFIG_NET_TCP) && proto == IPPROTO_TCP) {
348 		net_stats_update_tcp_drop(iface);
349 	}
350 }
351 
352 #if defined(CONFIG_NET_STATISTICS_MLD) && defined(CONFIG_NET_NATIVE)
net_stats_update_ipv6_mld_recv(struct net_if * iface)353 static inline void net_stats_update_ipv6_mld_recv(struct net_if *iface)
354 {
355 	UPDATE_STAT(iface, stats.ipv6_mld.recv++);
356 }
357 
net_stats_update_ipv6_mld_sent(struct net_if * iface)358 static inline void net_stats_update_ipv6_mld_sent(struct net_if *iface)
359 {
360 	UPDATE_STAT(iface, stats.ipv6_mld.sent++);
361 }
362 
net_stats_update_ipv6_mld_drop(struct net_if * iface)363 static inline void net_stats_update_ipv6_mld_drop(struct net_if *iface)
364 {
365 	UPDATE_STAT(iface, stats.ipv6_mld.drop++);
366 }
367 #else
368 #define net_stats_update_ipv6_mld_recv(iface)
369 #define net_stats_update_ipv6_mld_sent(iface)
370 #define net_stats_update_ipv6_mld_drop(iface)
371 #endif /* CONFIG_NET_STATISTICS_MLD */
372 
373 #if defined(CONFIG_NET_STATISTICS_IGMP) && defined(CONFIG_NET_NATIVE)
net_stats_update_ipv4_igmp_recv(struct net_if * iface)374 static inline void net_stats_update_ipv4_igmp_recv(struct net_if *iface)
375 {
376 	UPDATE_STAT(iface, stats.ipv4_igmp.recv++);
377 }
378 
net_stats_update_ipv4_igmp_sent(struct net_if * iface)379 static inline void net_stats_update_ipv4_igmp_sent(struct net_if *iface)
380 {
381 	UPDATE_STAT(iface, stats.ipv4_igmp.sent++);
382 }
383 
net_stats_update_ipv4_igmp_drop(struct net_if * iface)384 static inline void net_stats_update_ipv4_igmp_drop(struct net_if *iface)
385 {
386 	UPDATE_STAT(iface, stats.ipv4_igmp.drop++);
387 }
388 #else
389 #define net_stats_update_ipv4_igmp_recv(iface)
390 #define net_stats_update_ipv4_igmp_sent(iface)
391 #define net_stats_update_ipv4_igmp_drop(iface)
392 #endif /* CONFIG_NET_STATISTICS_IGMP */
393 
394 #if defined(CONFIG_NET_STATISTICS_DNS)
net_stats_update_dns_recv(struct net_if * iface)395 static inline void net_stats_update_dns_recv(struct net_if *iface)
396 {
397 	UPDATE_STAT(iface, stats.dns.recv++);
398 }
399 
net_stats_update_dns_sent(struct net_if * iface)400 static inline void net_stats_update_dns_sent(struct net_if *iface)
401 {
402 	UPDATE_STAT(iface, stats.dns.sent++);
403 }
404 
net_stats_update_dns_drop(struct net_if * iface)405 static inline void net_stats_update_dns_drop(struct net_if *iface)
406 {
407 	UPDATE_STAT(iface, stats.dns.drop++);
408 }
409 #else
410 #define net_stats_update_dns_recv(iface)
411 #define net_stats_update_dns_sent(iface)
412 #define net_stats_update_dns_drop(iface)
413 #endif /* CONFIG_NET_STATISTICS_DNS */
414 
415 #if defined(CONFIG_NET_PKT_TXTIME_STATS) && defined(CONFIG_NET_STATISTICS)
net_stats_update_tx_time(struct net_if * iface,uint32_t start_time,uint32_t end_time)416 static inline void net_stats_update_tx_time(struct net_if *iface,
417 					    uint32_t start_time,
418 					    uint32_t end_time)
419 {
420 	uint32_t diff = end_time - start_time;
421 
422 	UPDATE_STAT(iface, stats.tx_time.sum +=
423 		    k_cyc_to_ns_floor64(diff) / 1000);
424 	UPDATE_STAT(iface, stats.tx_time.count += 1);
425 }
426 #else
427 #define net_stats_update_tx_time(iface, start_time, end_time)
428 #endif /* NET_PKT_TXTIME_STATS && NET_STATISTICS */
429 
430 #if defined(CONFIG_NET_PKT_TXTIME_STATS_DETAIL)
net_stats_update_tx_time_detail(struct net_if * iface,uint32_t detail_stat[])431 static inline void net_stats_update_tx_time_detail(struct net_if *iface,
432 						   uint32_t detail_stat[])
433 {
434 	int i;
435 
436 	for (i = 0; i < NET_PKT_DETAIL_STATS_COUNT; i++) {
437 		UPDATE_STAT(iface,
438 			    stats.tx_time_detail[i].sum +=
439 			    k_cyc_to_ns_floor64(detail_stat[i]) / 1000);
440 		UPDATE_STAT(iface,
441 			    stats.tx_time_detail[i].count += 1);
442 	}
443 }
444 #else
445 #define net_stats_update_tx_time_detail(iface, detail_stat)
446 #endif /* NET_PKT_TXTIME_STATS_DETAIL */
447 
448 #if defined(CONFIG_NET_PKT_RXTIME_STATS) && defined(CONFIG_NET_STATISTICS)
net_stats_update_rx_time(struct net_if * iface,uint32_t start_time,uint32_t end_time)449 static inline void net_stats_update_rx_time(struct net_if *iface,
450 					    uint32_t start_time,
451 					    uint32_t end_time)
452 {
453 	uint32_t diff = end_time - start_time;
454 
455 	UPDATE_STAT(iface, stats.rx_time.sum +=
456 		    k_cyc_to_ns_floor64(diff) / 1000);
457 	UPDATE_STAT(iface, stats.rx_time.count += 1);
458 }
459 #else
460 #define net_stats_update_rx_time(iface, start_time, end_time)
461 #endif /* NET_PKT_RXTIME_STATS && STATISTICS */
462 
463 #if defined(CONFIG_NET_PKT_RXTIME_STATS_DETAIL)
net_stats_update_rx_time_detail(struct net_if * iface,uint32_t detail_stat[])464 static inline void net_stats_update_rx_time_detail(struct net_if *iface,
465 						   uint32_t detail_stat[])
466 {
467 	int i;
468 
469 	for (i = 0; i < NET_PKT_DETAIL_STATS_COUNT; i++) {
470 		UPDATE_STAT(iface,
471 			    stats.rx_time_detail[i].sum +=
472 			    k_cyc_to_ns_floor64(detail_stat[i]) / 1000);
473 		UPDATE_STAT(iface,
474 			    stats.rx_time_detail[i].count += 1);
475 	}
476 }
477 #else
478 #define net_stats_update_rx_time_detail(iface, detail_stat)
479 #endif /* NET_PKT_RXTIME_STATS_DETAIL */
480 
481 #if (NET_TC_COUNT > 1) && defined(CONFIG_NET_STATISTICS) \
482 	&& defined(CONFIG_NET_NATIVE)
net_stats_update_tc_sent_pkt(struct net_if * iface,uint8_t tc)483 static inline void net_stats_update_tc_sent_pkt(struct net_if *iface, uint8_t tc)
484 {
485 	UPDATE_STAT(iface, stats.tc.sent[tc].pkts++);
486 }
487 
net_stats_update_tc_sent_dropped(struct net_if * iface,uint8_t tc)488 static inline void net_stats_update_tc_sent_dropped(struct net_if *iface, uint8_t tc)
489 {
490 	UPDATE_STAT(iface, stats.tc.sent[tc].dropped++);
491 }
492 
net_stats_update_tc_sent_bytes(struct net_if * iface,uint8_t tc,size_t bytes)493 static inline void net_stats_update_tc_sent_bytes(struct net_if *iface,
494 						  uint8_t tc, size_t bytes)
495 {
496 	UPDATE_STAT(iface, stats.tc.sent[tc].bytes += bytes);
497 }
498 
net_stats_update_tc_sent_priority(struct net_if * iface,uint8_t tc,uint8_t priority)499 static inline void net_stats_update_tc_sent_priority(struct net_if *iface,
500 						     uint8_t tc, uint8_t priority)
501 {
502 	UPDATE_STAT(iface, stats.tc.sent[tc].priority = priority);
503 }
504 
505 #if defined(CONFIG_NET_PKT_TXTIME_STATS) && \
506 	defined(CONFIG_NET_STATISTICS) && defined(CONFIG_NET_NATIVE)
net_stats_update_tc_tx_time(struct net_if * iface,uint8_t priority,uint32_t start_time,uint32_t end_time)507 static inline void net_stats_update_tc_tx_time(struct net_if *iface,
508 					       uint8_t priority,
509 					       uint32_t start_time,
510 					       uint32_t end_time)
511 {
512 	uint32_t diff = end_time - start_time;
513 	int tc = net_tx_priority2tc(priority);
514 
515 	UPDATE_STAT(iface, stats.tc.sent[tc].tx_time.sum +=
516 		    k_cyc_to_ns_floor64(diff) / 1000);
517 	UPDATE_STAT(iface, stats.tc.sent[tc].tx_time.count += 1);
518 
519 	net_stats_update_tx_time(iface, start_time, end_time);
520 }
521 #else
522 #define net_stats_update_tc_tx_time(iface, tc, start_time, end_time)
523 #endif /* NET_PKT_TXTIME_STATS && NET_STATISTICS && NET_NATIVE */
524 
525 #if defined(CONFIG_NET_PKT_TXTIME_STATS_DETAIL)
net_stats_update_tc_tx_time_detail(struct net_if * iface,uint8_t priority,uint32_t detail_stat[])526 static inline void net_stats_update_tc_tx_time_detail(struct net_if *iface,
527 						      uint8_t priority,
528 						      uint32_t detail_stat[])
529 {
530 	int tc = net_tx_priority2tc(priority);
531 	int i;
532 
533 	for (i = 0; i < NET_PKT_DETAIL_STATS_COUNT; i++) {
534 		UPDATE_STAT(iface,
535 			    stats.tc.sent[tc].tx_time_detail[i].sum +=
536 			    k_cyc_to_ns_floor64(detail_stat[i]) / 1000);
537 		UPDATE_STAT(iface,
538 			    stats.tc.sent[tc].tx_time_detail[i].count += 1);
539 	}
540 
541 	net_stats_update_tx_time_detail(iface, detail_stat);
542 }
543 #else
544 #define net_stats_update_tc_tx_time_detail(iface, tc, detail_stat)
545 #endif /* CONFIG_NET_PKT_TXTIME_STATS_DETAIL */
546 
547 #if defined(CONFIG_NET_PKT_RXTIME_STATS) && defined(CONFIG_NET_STATISTICS) \
548 	&& defined(CONFIG_NET_NATIVE)
net_stats_update_tc_rx_time(struct net_if * iface,uint8_t priority,uint32_t start_time,uint32_t end_time)549 static inline void net_stats_update_tc_rx_time(struct net_if *iface,
550 					       uint8_t priority,
551 					       uint32_t start_time,
552 					       uint32_t end_time)
553 {
554 	uint32_t diff = end_time - start_time;
555 	int tc = net_rx_priority2tc(priority);
556 
557 	UPDATE_STAT(iface, stats.tc.recv[tc].rx_time.sum +=
558 		    k_cyc_to_ns_floor64(diff) / 1000);
559 	UPDATE_STAT(iface, stats.tc.recv[tc].rx_time.count += 1);
560 
561 	net_stats_update_rx_time(iface, start_time, end_time);
562 }
563 #else
564 #define net_stats_update_tc_rx_time(iface, tc, start_time, end_time)
565 #endif /* NET_PKT_RXTIME_STATS && NET_STATISTICS */
566 
567 #if defined(CONFIG_NET_PKT_RXTIME_STATS_DETAIL)
net_stats_update_tc_rx_time_detail(struct net_if * iface,uint8_t priority,uint32_t detail_stat[])568 static inline void net_stats_update_tc_rx_time_detail(struct net_if *iface,
569 						      uint8_t priority,
570 						      uint32_t detail_stat[])
571 {
572 	int tc = net_rx_priority2tc(priority);
573 	int i;
574 
575 	for (i = 0; i < NET_PKT_DETAIL_STATS_COUNT; i++) {
576 		UPDATE_STAT(iface,
577 			    stats.tc.recv[tc].rx_time_detail[i].sum +=
578 			    k_cyc_to_ns_floor64(detail_stat[i]) / 1000);
579 		UPDATE_STAT(iface,
580 			    stats.tc.recv[tc].rx_time_detail[i].count += 1);
581 	}
582 
583 	net_stats_update_rx_time_detail(iface, detail_stat);
584 }
585 #else
586 #define net_stats_update_tc_rx_time_detail(iface, tc, detail_stat)
587 #endif /* CONFIG_NET_PKT_RXTIME_STATS_DETAIL */
588 
net_stats_update_tc_recv_pkt(struct net_if * iface,uint8_t tc)589 static inline void net_stats_update_tc_recv_pkt(struct net_if *iface, uint8_t tc)
590 {
591 	UPDATE_STAT(iface, stats.tc.recv[tc].pkts++);
592 }
593 
net_stats_update_tc_recv_dropped(struct net_if * iface,uint8_t tc)594 static inline void net_stats_update_tc_recv_dropped(struct net_if *iface, uint8_t tc)
595 {
596 	UPDATE_STAT(iface, stats.tc.recv[tc].dropped++);
597 }
598 
net_stats_update_tc_recv_bytes(struct net_if * iface,uint8_t tc,size_t bytes)599 static inline void net_stats_update_tc_recv_bytes(struct net_if *iface,
600 						  uint8_t tc, size_t bytes)
601 {
602 	UPDATE_STAT(iface, stats.tc.recv[tc].bytes += bytes);
603 }
604 
net_stats_update_tc_recv_priority(struct net_if * iface,uint8_t tc,uint8_t priority)605 static inline void net_stats_update_tc_recv_priority(struct net_if *iface,
606 						     uint8_t tc, uint8_t priority)
607 {
608 	UPDATE_STAT(iface, stats.tc.recv[tc].priority = priority);
609 }
610 #else
net_stats_update_tc_sent_pkt(struct net_if * iface,uint8_t tc)611 static inline void net_stats_update_tc_sent_pkt(struct net_if *iface, uint8_t tc)
612 {
613 	ARG_UNUSED(iface);
614 	ARG_UNUSED(tc);
615 }
616 
net_stats_update_tc_sent_dropped(struct net_if * iface,uint8_t tc)617 static inline void net_stats_update_tc_sent_dropped(struct net_if *iface, uint8_t tc)
618 {
619 	ARG_UNUSED(iface);
620 	ARG_UNUSED(tc);
621 }
622 
net_stats_update_tc_sent_bytes(struct net_if * iface,uint8_t tc,size_t bytes)623 static inline void net_stats_update_tc_sent_bytes(struct net_if *iface,
624 						  uint8_t tc, size_t bytes)
625 {
626 	ARG_UNUSED(iface);
627 	ARG_UNUSED(tc);
628 	ARG_UNUSED(bytes);
629 }
630 
net_stats_update_tc_sent_priority(struct net_if * iface,uint8_t tc,uint8_t priority)631 static inline void net_stats_update_tc_sent_priority(struct net_if *iface,
632 						     uint8_t tc, uint8_t priority)
633 {
634 	ARG_UNUSED(iface);
635 	ARG_UNUSED(tc);
636 	ARG_UNUSED(priority);
637 }
638 
net_stats_update_tc_recv_pkt(struct net_if * iface,uint8_t tc)639 static inline void net_stats_update_tc_recv_pkt(struct net_if *iface, uint8_t tc)
640 {
641 	ARG_UNUSED(iface);
642 	ARG_UNUSED(tc);
643 }
644 
net_stats_update_tc_recv_dropped(struct net_if * iface,uint8_t tc)645 static inline void net_stats_update_tc_recv_dropped(struct net_if *iface, uint8_t tc)
646 {
647 	ARG_UNUSED(iface);
648 	ARG_UNUSED(tc);
649 }
650 
net_stats_update_tc_recv_bytes(struct net_if * iface,uint8_t tc,size_t bytes)651 static inline void net_stats_update_tc_recv_bytes(struct net_if *iface,
652 						  uint8_t tc, size_t bytes)
653 {
654 	ARG_UNUSED(iface);
655 	ARG_UNUSED(tc);
656 	ARG_UNUSED(bytes);
657 }
658 
net_stats_update_tc_recv_priority(struct net_if * iface,uint8_t tc,uint8_t priority)659 static inline void net_stats_update_tc_recv_priority(struct net_if *iface,
660 						     uint8_t tc, uint8_t priority)
661 {
662 	ARG_UNUSED(iface);
663 	ARG_UNUSED(tc);
664 	ARG_UNUSED(priority);
665 }
666 
667 #if defined(CONFIG_NET_PKT_TXTIME_STATS) && \
668 	defined(CONFIG_NET_STATISTICS) && defined(CONFIG_NET_NATIVE)
net_stats_update_tc_tx_time(struct net_if * iface,uint8_t pkt_priority,uint32_t start_time,uint32_t end_time)669 static inline void net_stats_update_tc_tx_time(struct net_if *iface,
670 					       uint8_t pkt_priority,
671 					       uint32_t start_time,
672 					       uint32_t end_time)
673 {
674 	ARG_UNUSED(pkt_priority);
675 
676 	net_stats_update_tx_time(iface, start_time, end_time);
677 }
678 #else
679 #define net_stats_update_tc_tx_time(iface, priority, start_time, end_time)
680 #endif /* NET_PKT_TXTIME_STATS && NET_STATISTICS && NET_NATIVE */
681 
682 #if defined(CONFIG_NET_PKT_TXTIME_STATS_DETAIL)
net_stats_update_tc_tx_time_detail(struct net_if * iface,uint8_t pkt_priority,uint32_t detail_stat[])683 static inline void net_stats_update_tc_tx_time_detail(struct net_if *iface,
684 						      uint8_t pkt_priority,
685 						      uint32_t detail_stat[])
686 {
687 	ARG_UNUSED(pkt_priority);
688 
689 	net_stats_update_tx_time_detail(iface, detail_stat);
690 }
691 #else
692 #define net_stats_update_tc_tx_time_detail(iface, pkt_priority, detail_stat)
693 #endif /* CONFIG_NET_PKT_TXTIME_STATS_DETAIL */
694 
695 #if defined(CONFIG_NET_PKT_RXTIME_STATS) && defined(CONFIG_NET_STATISTICS) \
696 	&& defined(CONFIG_NET_NATIVE)
net_stats_update_tc_rx_time(struct net_if * iface,uint8_t pkt_priority,uint32_t start_time,uint32_t end_time)697 static inline void net_stats_update_tc_rx_time(struct net_if *iface,
698 					       uint8_t pkt_priority,
699 					       uint32_t start_time,
700 					       uint32_t end_time)
701 {
702 	ARG_UNUSED(pkt_priority);
703 
704 	net_stats_update_rx_time(iface, start_time, end_time);
705 }
706 #else
707 #define net_stats_update_tc_rx_time(iface, priority, start_time, end_time)
708 #endif /* NET_PKT_RXTIME_STATS && NET_STATISTICS */
709 
710 #if defined(CONFIG_NET_PKT_RXTIME_STATS_DETAIL)
net_stats_update_tc_rx_time_detail(struct net_if * iface,uint8_t pkt_priority,uint32_t detail_stat[])711 static inline void net_stats_update_tc_rx_time_detail(struct net_if *iface,
712 						      uint8_t pkt_priority,
713 						      uint32_t detail_stat[])
714 {
715 	ARG_UNUSED(pkt_priority);
716 
717 	net_stats_update_rx_time_detail(iface, detail_stat);
718 }
719 #else
720 #define net_stats_update_tc_rx_time_detail(iface, pkt_priority, detail_stat)
721 #endif /* CONFIG_NET_PKT_RXTIME_STATS_DETAIL */
722 #endif /* NET_TC_COUNT > 1 */
723 
724 #if defined(CONFIG_NET_STATISTICS_POWER_MANAGEMENT)	\
725 	&& defined(CONFIG_NET_STATISTICS) && defined(CONFIG_NET_NATIVE)
net_stats_add_suspend_start_time(struct net_if * iface,uint32_t time)726 static inline void net_stats_add_suspend_start_time(struct net_if *iface,
727 						    uint32_t time)
728 {
729 	UPDATE_STAT(iface, stats.pm.start_time = time);
730 }
731 
net_stats_add_suspend_end_time(struct net_if * iface,uint32_t time)732 static inline void net_stats_add_suspend_end_time(struct net_if *iface,
733 						  uint32_t time)
734 {
735 	uint32_t diff_time =
736 		k_cyc_to_ms_floor32(time - GET_STAT(iface, pm.start_time));
737 
738 	UPDATE_STAT(iface, stats.pm.start_time = 0);
739 	UPDATE_STAT(iface, stats.pm.last_suspend_time = diff_time);
740 	UPDATE_STAT(iface, stats.pm.suspend_count++);
741 	UPDATE_STAT(iface, stats.pm.overall_suspend_time += diff_time);
742 }
743 #else
744 #define net_stats_add_suspend_start_time(iface, time)
745 #define net_stats_add_suspend_end_time(iface, time)
746 #endif
747 
748 #if defined(CONFIG_NET_STATISTICS_PERIODIC_OUTPUT) \
749 	&& defined(CONFIG_NET_NATIVE)
750 /* A simple periodic statistic printer, used only in net core */
751 void net_print_statistics_all(void);
752 void net_print_statistics_iface(struct net_if *iface);
753 void net_print_statistics(void);
754 #else
755 #define net_print_statistics_all()
756 #define net_print_statistics_iface(iface)
757 #define net_print_statistics()
758 #endif
759 
760 void net_stats_reset(struct net_if *iface);
761 #endif /* __NET_STATS_H__ */
762