3
3
4
4
#include <linux/pci.h>
5
5
#include <linux/phy.h>
6
+ #include <linux/ethtool.h>
6
7
7
8
#include "wx_type.h"
8
9
#include "wx_ethtool.h"
10
+ #include "wx_hw.h"
11
+
12
+ struct wx_stats {
13
+ char stat_string [ETH_GSTRING_LEN ];
14
+ size_t sizeof_stat ;
15
+ off_t stat_offset ;
16
+ };
17
+
18
+ #define WX_STAT (str , m ) { \
19
+ .stat_string = str, \
20
+ .sizeof_stat = sizeof(((struct wx *)0)->m), \
21
+ .stat_offset = offsetof(struct wx, m) }
22
+
23
+ static const struct wx_stats wx_gstrings_stats [] = {
24
+ WX_STAT ("rx_dma_pkts" , stats .gprc ),
25
+ WX_STAT ("tx_dma_pkts" , stats .gptc ),
26
+ WX_STAT ("rx_dma_bytes" , stats .gorc ),
27
+ WX_STAT ("tx_dma_bytes" , stats .gotc ),
28
+ WX_STAT ("rx_total_pkts" , stats .tpr ),
29
+ WX_STAT ("tx_total_pkts" , stats .tpt ),
30
+ WX_STAT ("rx_long_length_count" , stats .roc ),
31
+ WX_STAT ("rx_short_length_count" , stats .ruc ),
32
+ WX_STAT ("os2bmc_rx_by_bmc" , stats .o2bgptc ),
33
+ WX_STAT ("os2bmc_tx_by_bmc" , stats .b2ospc ),
34
+ WX_STAT ("os2bmc_tx_by_host" , stats .o2bspc ),
35
+ WX_STAT ("os2bmc_rx_by_host" , stats .b2ogprc ),
36
+ WX_STAT ("rx_no_dma_resources" , stats .rdmdrop ),
37
+ WX_STAT ("tx_busy" , tx_busy ),
38
+ WX_STAT ("non_eop_descs" , non_eop_descs ),
39
+ WX_STAT ("tx_restart_queue" , restart_queue ),
40
+ WX_STAT ("rx_csum_offload_good_count" , hw_csum_rx_good ),
41
+ WX_STAT ("rx_csum_offload_errors" , hw_csum_rx_error ),
42
+ WX_STAT ("alloc_rx_buff_failed" , alloc_rx_buff_failed ),
43
+ };
44
+
45
+ /* drivers allocates num_tx_queues and num_rx_queues symmetrically so
46
+ * we set the num_rx_queues to evaluate to num_tx_queues. This is
47
+ * used because we do not have a good way to get the max number of
48
+ * rx queues with CONFIG_RPS disabled.
49
+ */
50
+ #define WX_NUM_RX_QUEUES netdev->num_tx_queues
51
+ #define WX_NUM_TX_QUEUES netdev->num_tx_queues
52
+
53
+ #define WX_QUEUE_STATS_LEN ( \
54
+ (WX_NUM_TX_QUEUES + WX_NUM_RX_QUEUES) * \
55
+ (sizeof(struct wx_queue_stats) / sizeof(u64)))
56
+ #define WX_GLOBAL_STATS_LEN ARRAY_SIZE(wx_gstrings_stats)
57
+ #define WX_STATS_LEN (WX_GLOBAL_STATS_LEN + WX_QUEUE_STATS_LEN)
58
+
59
+ int wx_get_sset_count (struct net_device * netdev , int sset )
60
+ {
61
+ switch (sset ) {
62
+ case ETH_SS_STATS :
63
+ return WX_STATS_LEN ;
64
+ default :
65
+ return - EOPNOTSUPP ;
66
+ }
67
+ }
68
+ EXPORT_SYMBOL (wx_get_sset_count );
69
+
70
+ void wx_get_strings (struct net_device * netdev , u32 stringset , u8 * data )
71
+ {
72
+ u8 * p = data ;
73
+ int i ;
74
+
75
+ switch (stringset ) {
76
+ case ETH_SS_STATS :
77
+ for (i = 0 ; i < WX_GLOBAL_STATS_LEN ; i ++ )
78
+ ethtool_sprintf (& p , wx_gstrings_stats [i ].stat_string );
79
+ for (i = 0 ; i < netdev -> num_tx_queues ; i ++ ) {
80
+ ethtool_sprintf (& p , "tx_queue_%u_packets" , i );
81
+ ethtool_sprintf (& p , "tx_queue_%u_bytes" , i );
82
+ }
83
+ for (i = 0 ; i < WX_NUM_RX_QUEUES ; i ++ ) {
84
+ ethtool_sprintf (& p , "rx_queue_%u_packets" , i );
85
+ ethtool_sprintf (& p , "rx_queue_%u_bytes" , i );
86
+ }
87
+ break ;
88
+ }
89
+ }
90
+ EXPORT_SYMBOL (wx_get_strings );
91
+
92
+ void wx_get_ethtool_stats (struct net_device * netdev ,
93
+ struct ethtool_stats * stats , u64 * data )
94
+ {
95
+ struct wx * wx = netdev_priv (netdev );
96
+ struct wx_ring * ring ;
97
+ unsigned int start ;
98
+ int i , j ;
99
+ char * p ;
100
+
101
+ wx_update_stats (wx );
102
+
103
+ for (i = 0 ; i < WX_GLOBAL_STATS_LEN ; i ++ ) {
104
+ p = (char * )wx + wx_gstrings_stats [i ].stat_offset ;
105
+ data [i ] = (wx_gstrings_stats [i ].sizeof_stat ==
106
+ sizeof (u64 )) ? * (u64 * )p : * (u32 * )p ;
107
+ }
108
+
109
+ for (j = 0 ; j < netdev -> num_tx_queues ; j ++ ) {
110
+ ring = wx -> tx_ring [j ];
111
+ if (!ring ) {
112
+ data [i ++ ] = 0 ;
113
+ data [i ++ ] = 0 ;
114
+ continue ;
115
+ }
116
+
117
+ do {
118
+ start = u64_stats_fetch_begin (& ring -> syncp );
119
+ data [i ] = ring -> stats .packets ;
120
+ data [i + 1 ] = ring -> stats .bytes ;
121
+ } while (u64_stats_fetch_retry (& ring -> syncp , start ));
122
+ i += 2 ;
123
+ }
124
+ for (j = 0 ; j < WX_NUM_RX_QUEUES ; j ++ ) {
125
+ ring = wx -> rx_ring [j ];
126
+ if (!ring ) {
127
+ data [i ++ ] = 0 ;
128
+ data [i ++ ] = 0 ;
129
+ continue ;
130
+ }
131
+
132
+ do {
133
+ start = u64_stats_fetch_begin (& ring -> syncp );
134
+ data [i ] = ring -> stats .packets ;
135
+ data [i + 1 ] = ring -> stats .bytes ;
136
+ } while (u64_stats_fetch_retry (& ring -> syncp , start ));
137
+ i += 2 ;
138
+ }
139
+ }
140
+ EXPORT_SYMBOL (wx_get_ethtool_stats );
141
+
142
+ void wx_get_mac_stats (struct net_device * netdev ,
143
+ struct ethtool_eth_mac_stats * mac_stats )
144
+ {
145
+ struct wx * wx = netdev_priv (netdev );
146
+ struct wx_hw_stats * hwstats ;
147
+
148
+ wx_update_stats (wx );
149
+
150
+ hwstats = & wx -> stats ;
151
+ mac_stats -> MulticastFramesXmittedOK = hwstats -> mptc ;
152
+ mac_stats -> BroadcastFramesXmittedOK = hwstats -> bptc ;
153
+ mac_stats -> MulticastFramesReceivedOK = hwstats -> mprc ;
154
+ mac_stats -> BroadcastFramesReceivedOK = hwstats -> bprc ;
155
+ }
156
+ EXPORT_SYMBOL (wx_get_mac_stats );
157
+
158
+ void wx_get_pause_stats (struct net_device * netdev ,
159
+ struct ethtool_pause_stats * stats )
160
+ {
161
+ struct wx * wx = netdev_priv (netdev );
162
+ struct wx_hw_stats * hwstats ;
163
+
164
+ wx_update_stats (wx );
165
+
166
+ hwstats = & wx -> stats ;
167
+ stats -> tx_pause_frames = hwstats -> lxontxc + hwstats -> lxofftxc ;
168
+ stats -> rx_pause_frames = hwstats -> lxonoffrxc ;
169
+ }
170
+ EXPORT_SYMBOL (wx_get_pause_stats );
9
171
10
172
void wx_get_drvinfo (struct net_device * netdev , struct ethtool_drvinfo * info )
11
173
{
@@ -14,5 +176,12 @@ void wx_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *info)
14
176
strscpy (info -> driver , wx -> driver_name , sizeof (info -> driver ));
15
177
strscpy (info -> fw_version , wx -> eeprom_id , sizeof (info -> fw_version ));
16
178
strscpy (info -> bus_info , pci_name (wx -> pdev ), sizeof (info -> bus_info ));
179
+ if (wx -> num_tx_queues <= WX_NUM_TX_QUEUES ) {
180
+ info -> n_stats = WX_STATS_LEN -
181
+ (WX_NUM_TX_QUEUES - wx -> num_tx_queues ) *
182
+ (sizeof (struct wx_queue_stats ) / sizeof (u64 )) * 2 ;
183
+ } else {
184
+ info -> n_stats = WX_STATS_LEN ;
185
+ }
17
186
}
18
187
EXPORT_SYMBOL (wx_get_drvinfo );
0 commit comments