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_bytes(struct net_if * iface,uint8_t tc,size_t bytes)488 static inline void net_stats_update_tc_sent_bytes(struct net_if *iface,
489 						  uint8_t tc, size_t bytes)
490 {
491 	UPDATE_STAT(iface, stats.tc.sent[tc].bytes += bytes);
492 }
493 
net_stats_update_tc_sent_priority(struct net_if * iface,uint8_t tc,uint8_t priority)494 static inline void net_stats_update_tc_sent_priority(struct net_if *iface,
495 						     uint8_t tc, uint8_t priority)
496 {
497 	UPDATE_STAT(iface, stats.tc.sent[tc].priority = priority);
498 }
499 
500 #if defined(CONFIG_NET_PKT_TXTIME_STATS) && \
501 	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)502 static inline void net_stats_update_tc_tx_time(struct net_if *iface,
503 					       uint8_t priority,
504 					       uint32_t start_time,
505 					       uint32_t end_time)
506 {
507 	uint32_t diff = end_time - start_time;
508 	int tc = net_tx_priority2tc(priority);
509 
510 	UPDATE_STAT(iface, stats.tc.sent[tc].tx_time.sum +=
511 		    k_cyc_to_ns_floor64(diff) / 1000);
512 	UPDATE_STAT(iface, stats.tc.sent[tc].tx_time.count += 1);
513 
514 	net_stats_update_tx_time(iface, start_time, end_time);
515 }
516 #else
517 #define net_stats_update_tc_tx_time(iface, tc, start_time, end_time)
518 #endif /* NET_PKT_TXTIME_STATS && NET_STATISTICS && NET_NATIVE */
519 
520 #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[])521 static inline void net_stats_update_tc_tx_time_detail(struct net_if *iface,
522 						      uint8_t priority,
523 						      uint32_t detail_stat[])
524 {
525 	int tc = net_tx_priority2tc(priority);
526 	int i;
527 
528 	for (i = 0; i < NET_PKT_DETAIL_STATS_COUNT; i++) {
529 		UPDATE_STAT(iface,
530 			    stats.tc.sent[tc].tx_time_detail[i].sum +=
531 			    k_cyc_to_ns_floor64(detail_stat[i]) / 1000);
532 		UPDATE_STAT(iface,
533 			    stats.tc.sent[tc].tx_time_detail[i].count += 1);
534 	}
535 
536 	net_stats_update_tx_time_detail(iface, detail_stat);
537 }
538 #else
539 #define net_stats_update_tc_tx_time_detail(iface, tc, detail_stat)
540 #endif /* CONFIG_NET_PKT_TXTIME_STATS_DETAIL */
541 
542 #if defined(CONFIG_NET_PKT_RXTIME_STATS) && defined(CONFIG_NET_STATISTICS) \
543 	&& 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)544 static inline void net_stats_update_tc_rx_time(struct net_if *iface,
545 					       uint8_t priority,
546 					       uint32_t start_time,
547 					       uint32_t end_time)
548 {
549 	uint32_t diff = end_time - start_time;
550 	int tc = net_rx_priority2tc(priority);
551 
552 	UPDATE_STAT(iface, stats.tc.recv[tc].rx_time.sum +=
553 		    k_cyc_to_ns_floor64(diff) / 1000);
554 	UPDATE_STAT(iface, stats.tc.recv[tc].rx_time.count += 1);
555 
556 	net_stats_update_rx_time(iface, start_time, end_time);
557 }
558 #else
559 #define net_stats_update_tc_rx_time(iface, tc, start_time, end_time)
560 #endif /* NET_PKT_RXTIME_STATS && NET_STATISTICS */
561 
562 #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[])563 static inline void net_stats_update_tc_rx_time_detail(struct net_if *iface,
564 						      uint8_t priority,
565 						      uint32_t detail_stat[])
566 {
567 	int tc = net_rx_priority2tc(priority);
568 	int i;
569 
570 	for (i = 0; i < NET_PKT_DETAIL_STATS_COUNT; i++) {
571 		UPDATE_STAT(iface,
572 			    stats.tc.recv[tc].rx_time_detail[i].sum +=
573 			    k_cyc_to_ns_floor64(detail_stat[i]) / 1000);
574 		UPDATE_STAT(iface,
575 			    stats.tc.recv[tc].rx_time_detail[i].count += 1);
576 	}
577 
578 	net_stats_update_rx_time_detail(iface, detail_stat);
579 }
580 #else
581 #define net_stats_update_tc_rx_time_detail(iface, tc, detail_stat)
582 #endif /* CONFIG_NET_PKT_RXTIME_STATS_DETAIL */
583 
net_stats_update_tc_recv_pkt(struct net_if * iface,uint8_t tc)584 static inline void net_stats_update_tc_recv_pkt(struct net_if *iface, uint8_t tc)
585 {
586 	UPDATE_STAT(iface, stats.tc.recv[tc].pkts++);
587 }
588 
net_stats_update_tc_recv_bytes(struct net_if * iface,uint8_t tc,size_t bytes)589 static inline void net_stats_update_tc_recv_bytes(struct net_if *iface,
590 						  uint8_t tc, size_t bytes)
591 {
592 	UPDATE_STAT(iface, stats.tc.recv[tc].bytes += bytes);
593 }
594 
net_stats_update_tc_recv_priority(struct net_if * iface,uint8_t tc,uint8_t priority)595 static inline void net_stats_update_tc_recv_priority(struct net_if *iface,
596 						     uint8_t tc, uint8_t priority)
597 {
598 	UPDATE_STAT(iface, stats.tc.recv[tc].priority = priority);
599 }
600 #else
601 #define net_stats_update_tc_sent_pkt(iface, tc)
602 #define net_stats_update_tc_sent_bytes(iface, tc, bytes)
603 #define net_stats_update_tc_sent_priority(iface, tc, priority)
604 #define net_stats_update_tc_recv_pkt(iface, tc)
605 #define net_stats_update_tc_recv_bytes(iface, tc, bytes)
606 #define net_stats_update_tc_recv_priority(iface, tc, priority)
607 
608 #if defined(CONFIG_NET_PKT_TXTIME_STATS) && \
609 	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)610 static inline void net_stats_update_tc_tx_time(struct net_if *iface,
611 					       uint8_t pkt_priority,
612 					       uint32_t start_time,
613 					       uint32_t end_time)
614 {
615 	ARG_UNUSED(pkt_priority);
616 
617 	net_stats_update_tx_time(iface, start_time, end_time);
618 }
619 #else
620 #define net_stats_update_tc_tx_time(iface, priority, start_time, end_time)
621 #endif /* NET_PKT_TXTIME_STATS && NET_STATISTICS && NET_NATIVE */
622 
623 #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[])624 static inline void net_stats_update_tc_tx_time_detail(struct net_if *iface,
625 						      uint8_t pkt_priority,
626 						      uint32_t detail_stat[])
627 {
628 	ARG_UNUSED(pkt_priority);
629 
630 	net_stats_update_tx_time_detail(iface, detail_stat);
631 }
632 #else
633 #define net_stats_update_tc_tx_time_detail(iface, pkt_priority, detail_stat)
634 #endif /* CONFIG_NET_PKT_TXTIME_STATS_DETAIL */
635 
636 #if defined(CONFIG_NET_PKT_RXTIME_STATS) && defined(CONFIG_NET_STATISTICS) \
637 	&& 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)638 static inline void net_stats_update_tc_rx_time(struct net_if *iface,
639 					       uint8_t pkt_priority,
640 					       uint32_t start_time,
641 					       uint32_t end_time)
642 {
643 	ARG_UNUSED(pkt_priority);
644 
645 	net_stats_update_rx_time(iface, start_time, end_time);
646 }
647 #else
648 #define net_stats_update_tc_rx_time(iface, priority, start_time, end_time)
649 #endif /* NET_PKT_RXTIME_STATS && NET_STATISTICS */
650 
651 #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[])652 static inline void net_stats_update_tc_rx_time_detail(struct net_if *iface,
653 						      uint8_t pkt_priority,
654 						      uint32_t detail_stat[])
655 {
656 	ARG_UNUSED(pkt_priority);
657 
658 	net_stats_update_rx_time_detail(iface, detail_stat);
659 }
660 #else
661 #define net_stats_update_tc_rx_time_detail(iface, pkt_priority, detail_stat)
662 #endif /* CONFIG_NET_PKT_RXTIME_STATS_DETAIL */
663 #endif /* NET_TC_COUNT > 1 */
664 
665 #if defined(CONFIG_NET_STATISTICS_POWER_MANAGEMENT)	\
666 	&& defined(CONFIG_NET_STATISTICS) && defined(CONFIG_NET_NATIVE)
net_stats_add_suspend_start_time(struct net_if * iface,uint32_t time)667 static inline void net_stats_add_suspend_start_time(struct net_if *iface,
668 						    uint32_t time)
669 {
670 	UPDATE_STAT(iface, stats.pm.start_time = time);
671 }
672 
net_stats_add_suspend_end_time(struct net_if * iface,uint32_t time)673 static inline void net_stats_add_suspend_end_time(struct net_if *iface,
674 						  uint32_t time)
675 {
676 	uint32_t diff_time =
677 		k_cyc_to_ms_floor32(time - GET_STAT(iface, pm.start_time));
678 
679 	UPDATE_STAT(iface, stats.pm.start_time = 0);
680 	UPDATE_STAT(iface, stats.pm.last_suspend_time = diff_time);
681 	UPDATE_STAT(iface, stats.pm.suspend_count++);
682 	UPDATE_STAT(iface, stats.pm.overall_suspend_time += diff_time);
683 }
684 #else
685 #define net_stats_add_suspend_start_time(iface, time)
686 #define net_stats_add_suspend_end_time(iface, time)
687 #endif
688 
689 #if defined(CONFIG_NET_STATISTICS_PERIODIC_OUTPUT) \
690 	&& defined(CONFIG_NET_NATIVE)
691 /* A simple periodic statistic printer, used only in net core */
692 void net_print_statistics_all(void);
693 void net_print_statistics_iface(struct net_if *iface);
694 void net_print_statistics(void);
695 #else
696 #define net_print_statistics_all()
697 #define net_print_statistics_iface(iface)
698 #define net_print_statistics()
699 #endif
700 
701 void net_stats_reset(struct net_if *iface);
702 #endif /* __NET_STATS_H__ */
703