diff options
author | Madalin Bucur <madalin.bucur@nxp.com> | 2016-11-15 03:41:04 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-11-15 22:34:25 -0500 |
commit | b0ce0d02e44d3bd92b4cb6544d8ff9c90d730d07 (patch) | |
tree | 3201cc674b211ab3c279f169783339eee851fe7e | |
parent | b0cdb1682b2112d259dcd90b35eeaec40590e62f (diff) |
dpaa_eth: add ethtool statistics
Add a series of counters to be exported through ethtool:
- add detailed counters for reception errors;
- add detailed counters for QMan enqueue reject events;
- count the number of fragmented skbs received from the stack;
- count all frames received on the Tx confirmation path;
- add congestion group statistics;
- count the number of interrupts for each CPU.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 54 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/dpaa/dpaa_eth.h | 33 | ||||
-rw-r--r-- | drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 199 |
3 files changed, 284 insertions, 2 deletions
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index 0e7f1c7ff37a..fcb9cac6257a 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | |||
@@ -700,10 +700,15 @@ static void dpaa_eth_cgscn(struct qman_portal *qm, struct qman_cgr *cgr, | |||
700 | struct dpaa_priv *priv = (struct dpaa_priv *)container_of(cgr, | 700 | struct dpaa_priv *priv = (struct dpaa_priv *)container_of(cgr, |
701 | struct dpaa_priv, cgr_data.cgr); | 701 | struct dpaa_priv, cgr_data.cgr); |
702 | 702 | ||
703 | if (congested) | 703 | if (congested) { |
704 | priv->cgr_data.congestion_start_jiffies = jiffies; | ||
704 | netif_tx_stop_all_queues(priv->net_dev); | 705 | netif_tx_stop_all_queues(priv->net_dev); |
705 | else | 706 | priv->cgr_data.cgr_congested_count++; |
707 | } else { | ||
708 | priv->cgr_data.congested_jiffies += | ||
709 | (jiffies - priv->cgr_data.congestion_start_jiffies); | ||
706 | netif_tx_wake_all_queues(priv->net_dev); | 710 | netif_tx_wake_all_queues(priv->net_dev); |
711 | } | ||
707 | } | 712 | } |
708 | 713 | ||
709 | static int dpaa_eth_cgr_init(struct dpaa_priv *priv) | 714 | static int dpaa_eth_cgr_init(struct dpaa_priv *priv) |
@@ -1217,6 +1222,37 @@ static void dpaa_fd_release(const struct net_device *net_dev, | |||
1217 | dpaa_bman_release(dpaa_bp, &bmb, 1); | 1222 | dpaa_bman_release(dpaa_bp, &bmb, 1); |
1218 | } | 1223 | } |
1219 | 1224 | ||
1225 | static void count_ern(struct dpaa_percpu_priv *percpu_priv, | ||
1226 | const union qm_mr_entry *msg) | ||
1227 | { | ||
1228 | switch (msg->ern.rc & QM_MR_RC_MASK) { | ||
1229 | case QM_MR_RC_CGR_TAILDROP: | ||
1230 | percpu_priv->ern_cnt.cg_tdrop++; | ||
1231 | break; | ||
1232 | case QM_MR_RC_WRED: | ||
1233 | percpu_priv->ern_cnt.wred++; | ||
1234 | break; | ||
1235 | case QM_MR_RC_ERROR: | ||
1236 | percpu_priv->ern_cnt.err_cond++; | ||
1237 | break; | ||
1238 | case QM_MR_RC_ORPWINDOW_EARLY: | ||
1239 | percpu_priv->ern_cnt.early_window++; | ||
1240 | break; | ||
1241 | case QM_MR_RC_ORPWINDOW_LATE: | ||
1242 | percpu_priv->ern_cnt.late_window++; | ||
1243 | break; | ||
1244 | case QM_MR_RC_FQ_TAILDROP: | ||
1245 | percpu_priv->ern_cnt.fq_tdrop++; | ||
1246 | break; | ||
1247 | case QM_MR_RC_ORPWINDOW_RETIRED: | ||
1248 | percpu_priv->ern_cnt.fq_retired++; | ||
1249 | break; | ||
1250 | case QM_MR_RC_ORP_ZERO: | ||
1251 | percpu_priv->ern_cnt.orp_zero++; | ||
1252 | break; | ||
1253 | } | ||
1254 | } | ||
1255 | |||
1220 | /* Turn on HW checksum computation for this outgoing frame. | 1256 | /* Turn on HW checksum computation for this outgoing frame. |
1221 | * If the current protocol is not something we support in this regard | 1257 | * If the current protocol is not something we support in this regard |
1222 | * (or if the stack has already computed the SW checksum), we do nothing. | 1258 | * (or if the stack has already computed the SW checksum), we do nothing. |
@@ -1882,6 +1918,7 @@ static int dpaa_start_xmit(struct sk_buff *skb, struct net_device *net_dev) | |||
1882 | likely(skb_shinfo(skb)->nr_frags < DPAA_SGT_MAX_ENTRIES)) { | 1918 | likely(skb_shinfo(skb)->nr_frags < DPAA_SGT_MAX_ENTRIES)) { |
1883 | /* Just create a S/G fd based on the skb */ | 1919 | /* Just create a S/G fd based on the skb */ |
1884 | err = skb_to_sg_fd(priv, skb, &fd); | 1920 | err = skb_to_sg_fd(priv, skb, &fd); |
1921 | percpu_priv->tx_frag_skbuffs++; | ||
1885 | } else { | 1922 | } else { |
1886 | /* If the egress skb contains more fragments than we support | 1923 | /* If the egress skb contains more fragments than we support |
1887 | * we have no choice but to linearize it ourselves. | 1924 | * we have no choice but to linearize it ourselves. |
@@ -1918,6 +1955,15 @@ static void dpaa_rx_error(struct net_device *net_dev, | |||
1918 | 1955 | ||
1919 | percpu_priv->stats.rx_errors++; | 1956 | percpu_priv->stats.rx_errors++; |
1920 | 1957 | ||
1958 | if (fd->status & FM_FD_ERR_DMA) | ||
1959 | percpu_priv->rx_errors.dme++; | ||
1960 | if (fd->status & FM_FD_ERR_PHYSICAL) | ||
1961 | percpu_priv->rx_errors.fpe++; | ||
1962 | if (fd->status & FM_FD_ERR_SIZE) | ||
1963 | percpu_priv->rx_errors.fse++; | ||
1964 | if (fd->status & FM_FD_ERR_PRS_HDR_ERR) | ||
1965 | percpu_priv->rx_errors.phe++; | ||
1966 | |||
1921 | dpaa_fd_release(net_dev, fd); | 1967 | dpaa_fd_release(net_dev, fd); |
1922 | } | 1968 | } |
1923 | 1969 | ||
@@ -1973,6 +2019,8 @@ static void dpaa_tx_conf(struct net_device *net_dev, | |||
1973 | percpu_priv->stats.tx_errors++; | 2019 | percpu_priv->stats.tx_errors++; |
1974 | } | 2020 | } |
1975 | 2021 | ||
2022 | percpu_priv->tx_confirm++; | ||
2023 | |||
1976 | skb = dpaa_cleanup_tx_fd(priv, fd); | 2024 | skb = dpaa_cleanup_tx_fd(priv, fd); |
1977 | 2025 | ||
1978 | consume_skb(skb); | 2026 | consume_skb(skb); |
@@ -1987,6 +2035,7 @@ static inline int dpaa_eth_napi_schedule(struct dpaa_percpu_priv *percpu_priv, | |||
1987 | 2035 | ||
1988 | percpu_priv->np.p = portal; | 2036 | percpu_priv->np.p = portal; |
1989 | napi_schedule(&percpu_priv->np.napi); | 2037 | napi_schedule(&percpu_priv->np.napi); |
2038 | percpu_priv->in_interrupt++; | ||
1990 | return 1; | 2039 | return 1; |
1991 | } | 2040 | } |
1992 | return 0; | 2041 | return 0; |
@@ -2171,6 +2220,7 @@ static void egress_ern(struct qman_portal *portal, | |||
2171 | 2220 | ||
2172 | percpu_priv->stats.tx_dropped++; | 2221 | percpu_priv->stats.tx_dropped++; |
2173 | percpu_priv->stats.tx_fifo_errors++; | 2222 | percpu_priv->stats.tx_fifo_errors++; |
2223 | count_ern(percpu_priv, msg); | ||
2174 | 2224 | ||
2175 | skb = dpaa_cleanup_tx_fd(priv, fd); | 2225 | skb = dpaa_cleanup_tx_fd(priv, fd); |
2176 | dev_kfree_skb_any(skb); | 2226 | dev_kfree_skb_any(skb); |
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h index d6ab3354df86..711fb06200b7 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h | |||
@@ -95,6 +95,25 @@ struct dpaa_bp { | |||
95 | atomic_t refs; | 95 | atomic_t refs; |
96 | }; | 96 | }; |
97 | 97 | ||
98 | struct dpaa_rx_errors { | ||
99 | u64 dme; /* DMA Error */ | ||
100 | u64 fpe; /* Frame Physical Error */ | ||
101 | u64 fse; /* Frame Size Error */ | ||
102 | u64 phe; /* Header Error */ | ||
103 | }; | ||
104 | |||
105 | /* Counters for QMan ERN frames - one counter per rejection code */ | ||
106 | struct dpaa_ern_cnt { | ||
107 | u64 cg_tdrop; /* Congestion group taildrop */ | ||
108 | u64 wred; /* WRED congestion */ | ||
109 | u64 err_cond; /* Error condition */ | ||
110 | u64 early_window; /* Order restoration, frame too early */ | ||
111 | u64 late_window; /* Order restoration, frame too late */ | ||
112 | u64 fq_tdrop; /* FQ taildrop */ | ||
113 | u64 fq_retired; /* FQ is retired */ | ||
114 | u64 orp_zero; /* ORP disabled */ | ||
115 | }; | ||
116 | |||
98 | struct dpaa_napi_portal { | 117 | struct dpaa_napi_portal { |
99 | struct napi_struct napi; | 118 | struct napi_struct napi; |
100 | struct qman_portal *p; | 119 | struct qman_portal *p; |
@@ -104,7 +123,13 @@ struct dpaa_napi_portal { | |||
104 | struct dpaa_percpu_priv { | 123 | struct dpaa_percpu_priv { |
105 | struct net_device *net_dev; | 124 | struct net_device *net_dev; |
106 | struct dpaa_napi_portal np; | 125 | struct dpaa_napi_portal np; |
126 | u64 in_interrupt; | ||
127 | u64 tx_confirm; | ||
128 | /* fragmented (non-linear) skbuffs received from the stack */ | ||
129 | u64 tx_frag_skbuffs; | ||
107 | struct rtnl_link_stats64 stats; | 130 | struct rtnl_link_stats64 stats; |
131 | struct dpaa_rx_errors rx_errors; | ||
132 | struct dpaa_ern_cnt ern_cnt; | ||
108 | }; | 133 | }; |
109 | 134 | ||
110 | struct dpaa_buffer_layout { | 135 | struct dpaa_buffer_layout { |
@@ -133,6 +158,14 @@ struct dpaa_priv { | |||
133 | * (and the same) congestion group. | 158 | * (and the same) congestion group. |
134 | */ | 159 | */ |
135 | struct qman_cgr cgr; | 160 | struct qman_cgr cgr; |
161 | /* If congested, when it began. Used for performance stats. */ | ||
162 | u32 congestion_start_jiffies; | ||
163 | /* Number of jiffies the Tx port was congested. */ | ||
164 | u32 congested_jiffies; | ||
165 | /* Counter for the number of times the CGR | ||
166 | * entered congestion state | ||
167 | */ | ||
168 | u32 cgr_congested_count; | ||
136 | } cgr_data; | 169 | } cgr_data; |
137 | /* Use a per-port CGR for ingress traffic. */ | 170 | /* Use a per-port CGR for ingress traffic. */ |
138 | bool use_ingress_cgr; | 171 | bool use_ingress_cgr; |
diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c index 3580a62af369..27e7044667d1 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | |||
@@ -36,6 +36,42 @@ | |||
36 | #include "dpaa_eth.h" | 36 | #include "dpaa_eth.h" |
37 | #include "mac.h" | 37 | #include "mac.h" |
38 | 38 | ||
39 | static const char dpaa_stats_percpu[][ETH_GSTRING_LEN] = { | ||
40 | "interrupts", | ||
41 | "rx packets", | ||
42 | "tx packets", | ||
43 | "tx confirm", | ||
44 | "tx S/G", | ||
45 | "tx error", | ||
46 | "rx error", | ||
47 | }; | ||
48 | |||
49 | static char dpaa_stats_global[][ETH_GSTRING_LEN] = { | ||
50 | /* dpa rx errors */ | ||
51 | "rx dma error", | ||
52 | "rx frame physical error", | ||
53 | "rx frame size error", | ||
54 | "rx header error", | ||
55 | |||
56 | /* demultiplexing errors */ | ||
57 | "qman cg_tdrop", | ||
58 | "qman wred", | ||
59 | "qman error cond", | ||
60 | "qman early window", | ||
61 | "qman late window", | ||
62 | "qman fq tdrop", | ||
63 | "qman fq retired", | ||
64 | "qman orp disabled", | ||
65 | |||
66 | /* congestion related stats */ | ||
67 | "congestion time (ms)", | ||
68 | "entered congestion", | ||
69 | "congested (0/1)" | ||
70 | }; | ||
71 | |||
72 | #define DPAA_STATS_PERCPU_LEN ARRAY_SIZE(dpaa_stats_percpu) | ||
73 | #define DPAA_STATS_GLOBAL_LEN ARRAY_SIZE(dpaa_stats_global) | ||
74 | |||
39 | static int dpaa_get_settings(struct net_device *net_dev, | 75 | static int dpaa_get_settings(struct net_device *net_dev, |
40 | struct ethtool_cmd *et_cmd) | 76 | struct ethtool_cmd *et_cmd) |
41 | { | 77 | { |
@@ -205,6 +241,166 @@ static int dpaa_set_pauseparam(struct net_device *net_dev, | |||
205 | return err; | 241 | return err; |
206 | } | 242 | } |
207 | 243 | ||
244 | static int dpaa_get_sset_count(struct net_device *net_dev, int type) | ||
245 | { | ||
246 | unsigned int total_stats, num_stats; | ||
247 | |||
248 | num_stats = num_online_cpus() + 1; | ||
249 | total_stats = num_stats * (DPAA_STATS_PERCPU_LEN + DPAA_BPS_NUM) + | ||
250 | DPAA_STATS_GLOBAL_LEN; | ||
251 | |||
252 | switch (type) { | ||
253 | case ETH_SS_STATS: | ||
254 | return total_stats; | ||
255 | default: | ||
256 | return -EOPNOTSUPP; | ||
257 | } | ||
258 | } | ||
259 | |||
260 | static void copy_stats(struct dpaa_percpu_priv *percpu_priv, int num_cpus, | ||
261 | int crr_cpu, u64 *bp_count, u64 *data) | ||
262 | { | ||
263 | int num_values = num_cpus + 1; | ||
264 | int crr = 0, j; | ||
265 | |||
266 | /* update current CPU's stats and also add them to the total values */ | ||
267 | data[crr * num_values + crr_cpu] = percpu_priv->in_interrupt; | ||
268 | data[crr++ * num_values + num_cpus] += percpu_priv->in_interrupt; | ||
269 | |||
270 | data[crr * num_values + crr_cpu] = percpu_priv->stats.rx_packets; | ||
271 | data[crr++ * num_values + num_cpus] += percpu_priv->stats.rx_packets; | ||
272 | |||
273 | data[crr * num_values + crr_cpu] = percpu_priv->stats.tx_packets; | ||
274 | data[crr++ * num_values + num_cpus] += percpu_priv->stats.tx_packets; | ||
275 | |||
276 | data[crr * num_values + crr_cpu] = percpu_priv->tx_confirm; | ||
277 | data[crr++ * num_values + num_cpus] += percpu_priv->tx_confirm; | ||
278 | |||
279 | data[crr * num_values + crr_cpu] = percpu_priv->tx_frag_skbuffs; | ||
280 | data[crr++ * num_values + num_cpus] += percpu_priv->tx_frag_skbuffs; | ||
281 | |||
282 | data[crr * num_values + crr_cpu] = percpu_priv->stats.tx_errors; | ||
283 | data[crr++ * num_values + num_cpus] += percpu_priv->stats.tx_errors; | ||
284 | |||
285 | data[crr * num_values + crr_cpu] = percpu_priv->stats.rx_errors; | ||
286 | data[crr++ * num_values + num_cpus] += percpu_priv->stats.rx_errors; | ||
287 | |||
288 | for (j = 0; j < DPAA_BPS_NUM; j++) { | ||
289 | data[crr * num_values + crr_cpu] = bp_count[j]; | ||
290 | data[crr++ * num_values + num_cpus] += bp_count[j]; | ||
291 | } | ||
292 | } | ||
293 | |||
294 | static void dpaa_get_ethtool_stats(struct net_device *net_dev, | ||
295 | struct ethtool_stats *stats, u64 *data) | ||
296 | { | ||
297 | u64 bp_count[DPAA_BPS_NUM], cg_time, cg_num; | ||
298 | struct dpaa_percpu_priv *percpu_priv; | ||
299 | struct dpaa_rx_errors rx_errors; | ||
300 | unsigned int num_cpus, offset; | ||
301 | struct dpaa_ern_cnt ern_cnt; | ||
302 | struct dpaa_bp *dpaa_bp; | ||
303 | struct dpaa_priv *priv; | ||
304 | int total_stats, i, j; | ||
305 | bool cg_status; | ||
306 | |||
307 | total_stats = dpaa_get_sset_count(net_dev, ETH_SS_STATS); | ||
308 | priv = netdev_priv(net_dev); | ||
309 | num_cpus = num_online_cpus(); | ||
310 | |||
311 | memset(&bp_count, 0, sizeof(bp_count)); | ||
312 | memset(&rx_errors, 0, sizeof(struct dpaa_rx_errors)); | ||
313 | memset(&ern_cnt, 0, sizeof(struct dpaa_ern_cnt)); | ||
314 | memset(data, 0, total_stats * sizeof(u64)); | ||
315 | |||
316 | for_each_online_cpu(i) { | ||
317 | percpu_priv = per_cpu_ptr(priv->percpu_priv, i); | ||
318 | for (j = 0; j < DPAA_BPS_NUM; j++) { | ||
319 | dpaa_bp = priv->dpaa_bps[j]; | ||
320 | if (!dpaa_bp->percpu_count) | ||
321 | continue; | ||
322 | bp_count[j] = *(per_cpu_ptr(dpaa_bp->percpu_count, i)); | ||
323 | } | ||
324 | rx_errors.dme += percpu_priv->rx_errors.dme; | ||
325 | rx_errors.fpe += percpu_priv->rx_errors.fpe; | ||
326 | rx_errors.fse += percpu_priv->rx_errors.fse; | ||
327 | rx_errors.phe += percpu_priv->rx_errors.phe; | ||
328 | |||
329 | ern_cnt.cg_tdrop += percpu_priv->ern_cnt.cg_tdrop; | ||
330 | ern_cnt.wred += percpu_priv->ern_cnt.wred; | ||
331 | ern_cnt.err_cond += percpu_priv->ern_cnt.err_cond; | ||
332 | ern_cnt.early_window += percpu_priv->ern_cnt.early_window; | ||
333 | ern_cnt.late_window += percpu_priv->ern_cnt.late_window; | ||
334 | ern_cnt.fq_tdrop += percpu_priv->ern_cnt.fq_tdrop; | ||
335 | ern_cnt.fq_retired += percpu_priv->ern_cnt.fq_retired; | ||
336 | ern_cnt.orp_zero += percpu_priv->ern_cnt.orp_zero; | ||
337 | |||
338 | copy_stats(percpu_priv, num_cpus, i, bp_count, data); | ||
339 | } | ||
340 | |||
341 | offset = (num_cpus + 1) * (DPAA_STATS_PERCPU_LEN + DPAA_BPS_NUM); | ||
342 | memcpy(data + offset, &rx_errors, sizeof(struct dpaa_rx_errors)); | ||
343 | |||
344 | offset += sizeof(struct dpaa_rx_errors) / sizeof(u64); | ||
345 | memcpy(data + offset, &ern_cnt, sizeof(struct dpaa_ern_cnt)); | ||
346 | |||
347 | /* gather congestion related counters */ | ||
348 | cg_num = 0; | ||
349 | cg_status = 0; | ||
350 | cg_time = jiffies_to_msecs(priv->cgr_data.congested_jiffies); | ||
351 | if (qman_query_cgr_congested(&priv->cgr_data.cgr, &cg_status) == 0) { | ||
352 | cg_num = priv->cgr_data.cgr_congested_count; | ||
353 | |||
354 | /* reset congestion stats (like QMan API does */ | ||
355 | priv->cgr_data.congested_jiffies = 0; | ||
356 | priv->cgr_data.cgr_congested_count = 0; | ||
357 | } | ||
358 | |||
359 | offset += sizeof(struct dpaa_ern_cnt) / sizeof(u64); | ||
360 | data[offset++] = cg_time; | ||
361 | data[offset++] = cg_num; | ||
362 | data[offset++] = cg_status; | ||
363 | } | ||
364 | |||
365 | static void dpaa_get_strings(struct net_device *net_dev, u32 stringset, | ||
366 | u8 *data) | ||
367 | { | ||
368 | unsigned int i, j, num_cpus, size; | ||
369 | char string_cpu[ETH_GSTRING_LEN]; | ||
370 | u8 *strings; | ||
371 | |||
372 | memset(string_cpu, 0, sizeof(string_cpu)); | ||
373 | strings = data; | ||
374 | num_cpus = num_online_cpus(); | ||
375 | size = DPAA_STATS_GLOBAL_LEN * ETH_GSTRING_LEN; | ||
376 | |||
377 | for (i = 0; i < DPAA_STATS_PERCPU_LEN; i++) { | ||
378 | for (j = 0; j < num_cpus; j++) { | ||
379 | snprintf(string_cpu, ETH_GSTRING_LEN, "%s [CPU %d]", | ||
380 | dpaa_stats_percpu[i], j); | ||
381 | memcpy(strings, string_cpu, ETH_GSTRING_LEN); | ||
382 | strings += ETH_GSTRING_LEN; | ||
383 | } | ||
384 | snprintf(string_cpu, ETH_GSTRING_LEN, "%s [TOTAL]", | ||
385 | dpaa_stats_percpu[i]); | ||
386 | memcpy(strings, string_cpu, ETH_GSTRING_LEN); | ||
387 | strings += ETH_GSTRING_LEN; | ||
388 | } | ||
389 | for (i = 0; i < DPAA_BPS_NUM; i++) { | ||
390 | for (j = 0; j < num_cpus; j++) { | ||
391 | snprintf(string_cpu, ETH_GSTRING_LEN, | ||
392 | "bpool %c [CPU %d]", 'a' + i, j); | ||
393 | memcpy(strings, string_cpu, ETH_GSTRING_LEN); | ||
394 | strings += ETH_GSTRING_LEN; | ||
395 | } | ||
396 | snprintf(string_cpu, ETH_GSTRING_LEN, "bpool %c [TOTAL]", | ||
397 | 'a' + i); | ||
398 | memcpy(strings, string_cpu, ETH_GSTRING_LEN); | ||
399 | strings += ETH_GSTRING_LEN; | ||
400 | } | ||
401 | memcpy(strings, dpaa_stats_global, size); | ||
402 | } | ||
403 | |||
208 | const struct ethtool_ops dpaa_ethtool_ops = { | 404 | const struct ethtool_ops dpaa_ethtool_ops = { |
209 | .get_settings = dpaa_get_settings, | 405 | .get_settings = dpaa_get_settings, |
210 | .set_settings = dpaa_set_settings, | 406 | .set_settings = dpaa_set_settings, |
@@ -215,4 +411,7 @@ const struct ethtool_ops dpaa_ethtool_ops = { | |||
215 | .get_pauseparam = dpaa_get_pauseparam, | 411 | .get_pauseparam = dpaa_get_pauseparam, |
216 | .set_pauseparam = dpaa_set_pauseparam, | 412 | .set_pauseparam = dpaa_set_pauseparam, |
217 | .get_link = ethtool_op_get_link, | 413 | .get_link = ethtool_op_get_link, |
414 | .get_sset_count = dpaa_get_sset_count, | ||
415 | .get_ethtool_stats = dpaa_get_ethtool_stats, | ||
416 | .get_strings = dpaa_get_strings, | ||
218 | }; | 417 | }; |