99LOG_MODULE_DECLARE (net_shell );
1010
1111#include <zephyr/net/net_stats.h>
12+ #include <zephyr/net/ethernet.h>
1213
1314#include "net_shell_private.h"
1415
@@ -21,6 +22,12 @@ enum net_shell_stats_format {
2122 NET_SHELL_STATS_FORMAT_BOTH
2223};
2324
25+ /** Shell stats options passed via user_data */
26+ struct net_shell_stats_options {
27+ enum net_shell_stats_format format ;
28+ uint32_t type ; /* Bitmask of ethernet_stats_type */
29+ };
30+
2431#if defined(CONFIG_NET_STATISTICS )
2532
2633
@@ -55,74 +62,86 @@ static const char *priority2str(enum net_priority priority)
5562static void print_eth_stats (struct net_if * iface , struct net_stats_eth * data ,
5663 const struct shell * sh , struct net_shell_user_data * user_data )
5764{
58- PR ("Statistics for Ethernet interface %p [%d]\n" , iface ,
59- net_if_get_by_iface (iface ));
60-
61- PR ("Bytes received : %llu\n" , data -> bytes .received );
62- PR ("Bytes sent : %llu\n" , data -> bytes .sent );
63- PR ("Packets received : %u\n" , data -> pkts .rx );
64- PR ("Packets sent : %u\n" , data -> pkts .tx );
65- PR ("Bcast received : %u\n" , data -> broadcast .rx );
66- PR ("Bcast sent : %u\n" , data -> broadcast .tx );
67- PR ("Mcast received : %u\n" , data -> multicast .rx );
68- PR ("Mcast sent : %u\n" , data -> multicast .tx );
69-
70- PR ("Send errors : %u\n" , data -> errors .tx );
71- PR ("Receive errors : %u\n" , data -> errors .rx );
72- PR ("Collisions : %u\n" , data -> collisions );
73- PR ("Send Drops : %u\n" , data -> tx_dropped );
74- PR ("Send timeouts : %u\n" , data -> tx_timeout_count );
75- PR ("Send restarts : %u\n" , data -> tx_restart_queue );
76- PR ("Unknown protocol : %u\n" , data -> unknown_protocol );
77-
78- PR ("Checksum offload : RX good %u errors %u\n" ,
79- data -> csum .rx_csum_offload_good ,
80- data -> csum .rx_csum_offload_errors );
81- PR ("Flow control : RX xon %u xoff %u TX xon %u xoff %u\n" ,
82- data -> flow_control .rx_flow_control_xon ,
83- data -> flow_control .rx_flow_control_xoff ,
84- data -> flow_control .tx_flow_control_xon ,
85- data -> flow_control .tx_flow_control_xoff );
86- PR ("ECC errors : uncorrected %u corrected %u\n" ,
87- data -> error_details .uncorr_ecc_errors ,
88- data -> error_details .corr_ecc_errors );
89- PR ("HW timestamp : RX cleared %u TX timeout %u skipped %u\n" ,
90- data -> hw_timestamp .rx_hwtstamp_cleared ,
91- data -> hw_timestamp .tx_hwtstamp_timeouts ,
92- data -> hw_timestamp .tx_hwtstamp_skipped );
93-
94- PR ("RX errors : %5s %5s %5s %5s %5s %5s %5s %5s %5s %5s %5s\n" ,
95- "Len" , "Over" , "CRC" , "Frame" , "NoBuf" , "Miss" , "Long" , "Short" ,
96- "Align" , "DMA" , "Alloc" );
97- PR (" %5u %5u %5u %5u %5u %5u %5u %5u %5u %5u %5u\n" ,
98- data -> error_details .rx_length_errors ,
99- data -> error_details .rx_over_errors ,
100- data -> error_details .rx_crc_errors ,
101- data -> error_details .rx_frame_errors ,
102- data -> error_details .rx_no_buffer_count ,
103- data -> error_details .rx_missed_errors ,
104- data -> error_details .rx_long_length_errors ,
105- data -> error_details .rx_short_length_errors ,
106- data -> error_details .rx_align_errors ,
107- data -> error_details .rx_dma_failed ,
108- data -> error_details .rx_buf_alloc_failed );
109- PR ("TX errors : %5s %8s %5s %10s %7s %5s\n" ,
110- "Abort" , "Carrier" , "Fifo" , "Heartbeat" , "Window" , "DMA" );
111- PR (" %5u %8u %5u %10u %7u %5u\n" ,
112- data -> error_details .tx_aborted_errors ,
113- data -> error_details .tx_carrier_errors ,
114- data -> error_details .tx_fifo_errors ,
115- data -> error_details .tx_heartbeat_errors ,
116- data -> error_details .tx_window_errors ,
117- data -> error_details .tx_dma_failed );
65+ struct net_shell_stats_options * opts = NULL ;
66+ uint32_t type = ETHERNET_STATS_TYPE_ALL ;
67+
68+ if (user_data != NULL && user_data -> user_data != NULL ) {
69+ opts = (struct net_shell_stats_options * )user_data -> user_data ;
70+ type = opts -> type ;
71+ }
72+
73+ /* Print common stats if requested */
74+ if (type & ETHERNET_STATS_TYPE_COMMON ) {
75+ PR ("Statistics for Ethernet interface %p [%d]\n" , iface ,
76+ net_if_get_by_iface (iface ));
77+
78+ PR ("Bytes received : %llu\n" , data -> bytes .received );
79+ PR ("Bytes sent : %llu\n" , data -> bytes .sent );
80+ PR ("Packets received : %u\n" , data -> pkts .rx );
81+ PR ("Packets sent : %u\n" , data -> pkts .tx );
82+ PR ("Bcast received : %u\n" , data -> broadcast .rx );
83+ PR ("Bcast sent : %u\n" , data -> broadcast .tx );
84+ PR ("Mcast received : %u\n" , data -> multicast .rx );
85+ PR ("Mcast sent : %u\n" , data -> multicast .tx );
86+
87+ PR ("Send errors : %u\n" , data -> errors .tx );
88+ PR ("Receive errors : %u\n" , data -> errors .rx );
89+ PR ("Collisions : %u\n" , data -> collisions );
90+ PR ("Send Drops : %u\n" , data -> tx_dropped );
91+ PR ("Send timeouts : %u\n" , data -> tx_timeout_count );
92+ PR ("Send restarts : %u\n" , data -> tx_restart_queue );
93+ PR ("Unknown protocol : %u\n" , data -> unknown_protocol );
94+
95+ PR ("Checksum offload : RX good %u errors %u\n" ,
96+ data -> csum .rx_csum_offload_good ,
97+ data -> csum .rx_csum_offload_errors );
98+ PR ("Flow control : RX xon %u xoff %u TX xon %u xoff %u\n" ,
99+ data -> flow_control .rx_flow_control_xon ,
100+ data -> flow_control .rx_flow_control_xoff ,
101+ data -> flow_control .tx_flow_control_xon ,
102+ data -> flow_control .tx_flow_control_xoff );
103+ PR ("ECC errors : uncorrected %u corrected %u\n" ,
104+ data -> error_details .uncorr_ecc_errors ,
105+ data -> error_details .corr_ecc_errors );
106+ PR ("HW timestamp : RX cleared %u TX timeout %u skipped %u\n" ,
107+ data -> hw_timestamp .rx_hwtstamp_cleared ,
108+ data -> hw_timestamp .tx_hwtstamp_timeouts ,
109+ data -> hw_timestamp .tx_hwtstamp_skipped );
110+
111+ PR ("RX errors : %5s %5s %5s %5s %5s %5s %5s %5s %5s %5s %5s\n" ,
112+ "Len" , "Over" , "CRC" , "Frame" , "NoBuf" , "Miss" , "Long" , "Short" ,
113+ "Align" , "DMA" , "Alloc" );
114+ PR (" %5u %5u %5u %5u %5u %5u %5u %5u %5u %5u %5u\n" ,
115+ data -> error_details .rx_length_errors ,
116+ data -> error_details .rx_over_errors ,
117+ data -> error_details .rx_crc_errors ,
118+ data -> error_details .rx_frame_errors ,
119+ data -> error_details .rx_no_buffer_count ,
120+ data -> error_details .rx_missed_errors ,
121+ data -> error_details .rx_long_length_errors ,
122+ data -> error_details .rx_short_length_errors ,
123+ data -> error_details .rx_align_errors ,
124+ data -> error_details .rx_dma_failed ,
125+ data -> error_details .rx_buf_alloc_failed );
126+ PR ("TX errors : %5s %8s %5s %10s %7s %5s\n" ,
127+ "Abort" , "Carrier" , "Fifo" , "Heartbeat" , "Window" , "DMA" );
128+ PR (" %5u %8u %5u %10u %7u %5u\n" ,
129+ data -> error_details .tx_aborted_errors ,
130+ data -> error_details .tx_carrier_errors ,
131+ data -> error_details .tx_fifo_errors ,
132+ data -> error_details .tx_heartbeat_errors ,
133+ data -> error_details .tx_window_errors ,
134+ data -> error_details .tx_dma_failed );
135+ }
118136
119137#if defined(CONFIG_NET_STATISTICS_ETHERNET_VENDOR )
120- if ( data -> vendor ) {
121- size_t i = 0 ;
138+ /* Print vendor stats if requested - format options only apply here */
139+ if (( type & ETHERNET_STATS_TYPE_VENDOR ) && data -> vendor ) {
122140 enum net_shell_stats_format format = NET_SHELL_STATS_FORMAT_DEFAULT ;
141+ size_t i = 0 ;
123142
124- if (user_data != NULL ) {
125- format = * ( enum net_shell_stats_format * ) user_data -> user_data ;
143+ if (opts != NULL ) {
144+ format = opts -> format ;
126145 }
127146
128147 PR ("Vendor specific statistics for Ethernet interface %p [%d]:\n" ,
@@ -619,13 +638,30 @@ static void net_shell_print_statistics(struct net_if *iface, void *user_data)
619638#if defined(CONFIG_NET_STATISTICS_ETHERNET ) && \
620639 defined(CONFIG_NET_STATISTICS_USER_API )
621640 if (iface && net_if_l2 (iface ) == & NET_L2_GET_NAME (ETHERNET )) {
622- struct net_stats_eth eth_data ;
623- int ret ;
641+ const struct ethernet_api * eth_api ;
642+ struct net_stats_eth * eth_data = NULL ;
643+ uint32_t type = ETHERNET_STATS_TYPE_ALL ;
624644
625- ret = net_mgmt (NET_REQUEST_STATS_GET_ETHERNET , iface ,
626- & eth_data , sizeof (eth_data ));
627- if (!ret ) {
628- print_eth_stats (iface , & eth_data , sh , data );
645+ if (data != NULL && data -> user_data != NULL ) {
646+ struct net_shell_stats_options * opts = data -> user_data ;
647+
648+ type = opts -> type ;
649+ }
650+
651+ eth_api = net_if_get_device (iface )-> api ;
652+ if (eth_api != NULL ) {
653+ /* Use get_stats_type if available for type filtering */
654+ if (eth_api -> get_stats_type != NULL ) {
655+ eth_data = eth_api -> get_stats_type (
656+ net_if_get_device (iface ), type );
657+ } else if (eth_api -> get_stats != NULL ) {
658+ eth_data = eth_api -> get_stats (
659+ net_if_get_device (iface ));
660+ }
661+ }
662+
663+ if (eth_data != NULL ) {
664+ print_eth_stats (iface , eth_data , sh , data );
629665 }
630666 }
631667#endif /* CONFIG_NET_STATISTICS_ETHERNET && CONFIG_NET_STATISTICS_USER_API */
@@ -653,31 +689,45 @@ static void net_shell_print_statistics_all(struct net_shell_user_data *data)
653689 net_if_foreach (net_shell_print_statistics , data );
654690 }
655691}
692+
693+ static void parse_stats_options (size_t argc , char * argv [], int start_idx ,
694+ struct net_shell_stats_options * opts )
695+ {
696+ opts -> format = NET_SHELL_STATS_FORMAT_DEFAULT ;
697+ opts -> type = ETHERNET_STATS_TYPE_ALL ;
698+
699+ for (int i = start_idx ; i < argc && argv [i ] != NULL ; i ++ ) {
700+ /* Format options */
701+ if (strcmp (argv [i ], "key-value" ) == 0 ) {
702+ opts -> format = NET_SHELL_STATS_FORMAT_KEY_VALUE ;
703+ } else if (strcmp (argv [i ], "hex-blob" ) == 0 ) {
704+ opts -> format = NET_SHELL_STATS_FORMAT_HEX_BLOB ;
705+ } else if (strcmp (argv [i ], "both" ) == 0 ) {
706+ opts -> format = NET_SHELL_STATS_FORMAT_BOTH ;
707+ /* Type filter options */
708+ } else if (strcmp (argv [i ], "common" ) == 0 ) {
709+ opts -> type = ETHERNET_STATS_TYPE_COMMON ;
710+ } else if (strcmp (argv [i ], "vendor" ) == 0 ) {
711+ opts -> type = ETHERNET_STATS_TYPE_VENDOR ;
712+ } else if (strcmp (argv [i ], "all" ) == 0 ) {
713+ opts -> type = ETHERNET_STATS_TYPE_ALL ;
714+ }
715+ }
716+ }
656717#endif /* CONFIG_NET_STATISTICS */
657718
658719int cmd_net_stats_all (const struct shell * sh , size_t argc , char * argv [])
659720{
660721#if defined(CONFIG_NET_STATISTICS )
661722 struct net_shell_user_data user_data ;
662- #endif
663-
664- #if defined(CONFIG_NET_STATISTICS )
665- enum net_shell_stats_format format = NET_SHELL_STATS_FORMAT_DEFAULT ;
723+ struct net_shell_stats_options opts ;
666724
667725 user_data .sh = sh ;
668726
669- /* Parse format argument if provided */
670- if (argc > 1 ) {
671- if (strcmp (argv [1 ], "key-value" ) == 0 ) {
672- format = NET_SHELL_STATS_FORMAT_KEY_VALUE ;
673- } else if (strcmp (argv [1 ], "hex-blob" ) == 0 ) {
674- format = NET_SHELL_STATS_FORMAT_HEX_BLOB ;
675- } else if (strcmp (argv [1 ], "both" ) == 0 ) {
676- format = NET_SHELL_STATS_FORMAT_BOTH ;
677- }
678- }
727+ /* Parse options starting from argv[1] */
728+ parse_stats_options (argc , argv , 1 , & opts );
679729
680- user_data .user_data = & format ;
730+ user_data .user_data = & opts ;
681731
682732 /* Print global network statistics */
683733 net_shell_print_statistics_all (& user_data );
@@ -697,6 +747,7 @@ int cmd_net_stats_iface(const struct shell *sh, size_t argc, char *argv[])
697747#if defined(CONFIG_NET_STATISTICS )
698748#if defined(CONFIG_NET_STATISTICS_PER_INTERFACE )
699749 struct net_shell_user_data data ;
750+ struct net_shell_stats_options opts ;
700751 struct net_if * iface ;
701752 char * endptr ;
702753 int idx ;
@@ -722,22 +773,12 @@ int cmd_net_stats_iface(const struct shell *sh, size_t argc, char *argv[])
722773 return - ENOEXEC ;
723774 }
724775
725- enum net_shell_stats_format format = NET_SHELL_STATS_FORMAT_DEFAULT ;
726-
727776 data .sh = sh ;
728777
729- /* Parse format argument if provided */
730- if (argc > 2 ) {
731- if (strcmp (argv [2 ], "key-value" ) == 0 ) {
732- format = NET_SHELL_STATS_FORMAT_KEY_VALUE ;
733- } else if (strcmp (argv [2 ], "hex-blob" ) == 0 ) {
734- format = NET_SHELL_STATS_FORMAT_HEX_BLOB ;
735- } else if (strcmp (argv [2 ], "both" ) == 0 ) {
736- format = NET_SHELL_STATS_FORMAT_BOTH ;
737- }
738- }
778+ /* Parse options starting from argv[2] */
779+ parse_stats_options (argc , argv , 2 , & opts );
739780
740- data .user_data = & format ;
781+ data .user_data = & opts ;
741782
742783 net_shell_print_statistics (iface , & data );
743784#else
@@ -766,8 +807,8 @@ static int cmd_net_stats(const struct shell *sh, size_t argc, char *argv[])
766807 if (strcmp (argv [1 ], "reset" ) == 0 ) {
767808 net_stats_reset (NULL );
768809 } else {
769- /* Shift arguments for iface command */
770- cmd_net_stats_iface (sh , argc - 1 , & argv [ 1 ] );
810+ /* Pass arguments directly - cmd_net_stats_iface expects index in argv[1] */
811+ cmd_net_stats_iface (sh , argc , argv );
771812 }
772813#else
773814 ARG_UNUSED (argc );
@@ -789,19 +830,23 @@ static int cmd_net_stats(const struct shell *sh, size_t argc, char *argv[])
789830SHELL_STATIC_SUBCMD_SET_CREATE (net_cmd_stats ,
790831 SHELL_CMD (all , NULL ,
791832 "Show network statistics for all network interfaces.\n"
792- "Usage: net stats all [key-value|hex-blob|both]" ,
833+ "Usage: net stats all [common|vendor|all] [ key-value|hex-blob|both]" ,
793834 cmd_net_stats_all ),
794835 SHELL_CMD (iface , IFACE_DYN_CMD ,
795- "'net stats <index> [key-value|hex-blob|both ]' shows network statistics for "
836+ "'net stats <index> [options ]' shows network statistics for "
796837 "one specific network interface.\n"
797- "Format options:\n"
798- " key-value: Show vendor stats as key-value pairs (default)\n"
799- " hex-blob: Show vendor stats as hex blob for parsing\n"
800- " both: Show both key-value and hex blob formats" ,
838+ "Type filter:\n"
839+ " common: Only common stats (skips FW query)\n"
840+ " vendor: Only vendor-specific stats\n"
841+ " all: All stats (default)\n"
842+ "Vendor stats format (only applies when vendor stats shown):\n"
843+ " key-value: Key-value pairs (default)\n"
844+ " hex-blob: Hex blob for parsing\n"
845+ " both: Both formats" ,
801846 cmd_net_stats_iface ),
802847 SHELL_SUBCMD_SET_END
803848);
804849
805850SHELL_SUBCMD_ADD ((net ), stats , & net_cmd_stats ,
806851 "Show network statistics." ,
807- cmd_net_stats , 1 , 3 );
852+ cmd_net_stats , 1 , 4 );
0 commit comments