]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
Merge branch 'opp/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm
[linux.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_stats.c
1 /*
2  * Copyright (c) 2017, Mellanox Technologies, Ltd.  All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32
33 #include "en.h"
34 #include "en_accel/ipsec.h"
35 #include "en_accel/tls.h"
36
37 static const struct counter_desc sw_stats_desc[] = {
38         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_packets) },
39         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_bytes) },
40         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_packets) },
41         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_bytes) },
42         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tso_packets) },
43         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tso_bytes) },
44         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tso_inner_packets) },
45         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tso_inner_bytes) },
46         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_added_vlan_packets) },
47         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_nop) },
48
49 #ifdef CONFIG_MLX5_EN_TLS
50         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_ooo) },
51         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_resync_bytes) },
52 #endif
53
54         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_lro_packets) },
55         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_lro_bytes) },
56         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_ecn_mark) },
57         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_removed_vlan_packets) },
58         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_csum_unnecessary) },
59         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_csum_none) },
60         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_csum_complete) },
61         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_csum_unnecessary_inner) },
62         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_drop) },
63         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_redirect) },
64         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_tx_xmit) },
65         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_tx_full) },
66         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_tx_err) },
67         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_tx_cqe) },
68         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_csum_none) },
69         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_csum_partial) },
70         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_csum_partial_inner) },
71         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_queue_stopped) },
72         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_queue_dropped) },
73         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xmit_more) },
74         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_recover) },
75         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_cqes) },
76         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_queue_wake) },
77         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_udp_seg_rem) },
78         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_cqe_err) },
79         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xdp_xmit) },
80         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xdp_full) },
81         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xdp_err) },
82         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xdp_cqes) },
83         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_wqe_err) },
84         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_mpwqe_filler_cqes) },
85         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_mpwqe_filler_strides) },
86         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_oversize_pkts_sw_drop) },
87         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_buff_alloc_err) },
88         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cqe_compress_blks) },
89         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cqe_compress_pkts) },
90         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_page_reuse) },
91         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cache_reuse) },
92         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cache_full) },
93         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cache_empty) },
94         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cache_busy) },
95         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cache_waive) },
96         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_congst_umr) },
97         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_arfs_err) },
98         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, ch_events) },
99         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, ch_poll) },
100         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, ch_arm) },
101         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, ch_aff_change) },
102         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, ch_eq_rearm) },
103 };
104
105 #define NUM_SW_COUNTERS                 ARRAY_SIZE(sw_stats_desc)
106
107 static int mlx5e_grp_sw_get_num_stats(struct mlx5e_priv *priv)
108 {
109         return NUM_SW_COUNTERS;
110 }
111
112 static int mlx5e_grp_sw_fill_strings(struct mlx5e_priv *priv, u8 *data, int idx)
113 {
114         int i;
115
116         for (i = 0; i < NUM_SW_COUNTERS; i++)
117                 strcpy(data + (idx++) * ETH_GSTRING_LEN, sw_stats_desc[i].format);
118         return idx;
119 }
120
121 static int mlx5e_grp_sw_fill_stats(struct mlx5e_priv *priv, u64 *data, int idx)
122 {
123         int i;
124
125         for (i = 0; i < NUM_SW_COUNTERS; i++)
126                 data[idx++] = MLX5E_READ_CTR64_CPU(&priv->stats.sw, sw_stats_desc, i);
127         return idx;
128 }
129
130 void mlx5e_grp_sw_update_stats(struct mlx5e_priv *priv)
131 {
132         struct mlx5e_sw_stats temp, *s = &temp;
133         int i;
134
135         memset(s, 0, sizeof(*s));
136
137         for (i = 0; i < mlx5e_get_netdev_max_channels(priv->netdev); i++) {
138                 struct mlx5e_channel_stats *channel_stats =
139                         &priv->channel_stats[i];
140                 struct mlx5e_xdpsq_stats *xdpsq_red_stats = &channel_stats->xdpsq;
141                 struct mlx5e_xdpsq_stats *xdpsq_stats = &channel_stats->rq_xdpsq;
142                 struct mlx5e_rq_stats *rq_stats = &channel_stats->rq;
143                 struct mlx5e_ch_stats *ch_stats = &channel_stats->ch;
144                 int j;
145
146                 s->rx_packets   += rq_stats->packets;
147                 s->rx_bytes     += rq_stats->bytes;
148                 s->rx_lro_packets += rq_stats->lro_packets;
149                 s->rx_lro_bytes += rq_stats->lro_bytes;
150                 s->rx_ecn_mark  += rq_stats->ecn_mark;
151                 s->rx_removed_vlan_packets += rq_stats->removed_vlan_packets;
152                 s->rx_csum_none += rq_stats->csum_none;
153                 s->rx_csum_complete += rq_stats->csum_complete;
154                 s->rx_csum_unnecessary += rq_stats->csum_unnecessary;
155                 s->rx_csum_unnecessary_inner += rq_stats->csum_unnecessary_inner;
156                 s->rx_xdp_drop     += rq_stats->xdp_drop;
157                 s->rx_xdp_redirect += rq_stats->xdp_redirect;
158                 s->rx_xdp_tx_xmit  += xdpsq_stats->xmit;
159                 s->rx_xdp_tx_full  += xdpsq_stats->full;
160                 s->rx_xdp_tx_err   += xdpsq_stats->err;
161                 s->rx_xdp_tx_cqe   += xdpsq_stats->cqes;
162                 s->rx_wqe_err   += rq_stats->wqe_err;
163                 s->rx_mpwqe_filler_cqes    += rq_stats->mpwqe_filler_cqes;
164                 s->rx_mpwqe_filler_strides += rq_stats->mpwqe_filler_strides;
165                 s->rx_oversize_pkts_sw_drop += rq_stats->oversize_pkts_sw_drop;
166                 s->rx_buff_alloc_err += rq_stats->buff_alloc_err;
167                 s->rx_cqe_compress_blks += rq_stats->cqe_compress_blks;
168                 s->rx_cqe_compress_pkts += rq_stats->cqe_compress_pkts;
169                 s->rx_page_reuse  += rq_stats->page_reuse;
170                 s->rx_cache_reuse += rq_stats->cache_reuse;
171                 s->rx_cache_full  += rq_stats->cache_full;
172                 s->rx_cache_empty += rq_stats->cache_empty;
173                 s->rx_cache_busy  += rq_stats->cache_busy;
174                 s->rx_cache_waive += rq_stats->cache_waive;
175                 s->rx_congst_umr  += rq_stats->congst_umr;
176                 s->rx_arfs_err    += rq_stats->arfs_err;
177                 s->ch_events      += ch_stats->events;
178                 s->ch_poll        += ch_stats->poll;
179                 s->ch_arm         += ch_stats->arm;
180                 s->ch_aff_change  += ch_stats->aff_change;
181                 s->ch_eq_rearm    += ch_stats->eq_rearm;
182                 /* xdp redirect */
183                 s->tx_xdp_xmit    += xdpsq_red_stats->xmit;
184                 s->tx_xdp_full    += xdpsq_red_stats->full;
185                 s->tx_xdp_err     += xdpsq_red_stats->err;
186                 s->tx_xdp_cqes    += xdpsq_red_stats->cqes;
187
188                 for (j = 0; j < priv->max_opened_tc; j++) {
189                         struct mlx5e_sq_stats *sq_stats = &channel_stats->sq[j];
190
191                         s->tx_packets           += sq_stats->packets;
192                         s->tx_bytes             += sq_stats->bytes;
193                         s->tx_tso_packets       += sq_stats->tso_packets;
194                         s->tx_tso_bytes         += sq_stats->tso_bytes;
195                         s->tx_tso_inner_packets += sq_stats->tso_inner_packets;
196                         s->tx_tso_inner_bytes   += sq_stats->tso_inner_bytes;
197                         s->tx_added_vlan_packets += sq_stats->added_vlan_packets;
198                         s->tx_nop               += sq_stats->nop;
199                         s->tx_queue_stopped     += sq_stats->stopped;
200                         s->tx_queue_wake        += sq_stats->wake;
201                         s->tx_udp_seg_rem       += sq_stats->udp_seg_rem;
202                         s->tx_queue_dropped     += sq_stats->dropped;
203                         s->tx_cqe_err           += sq_stats->cqe_err;
204                         s->tx_recover           += sq_stats->recover;
205                         s->tx_xmit_more         += sq_stats->xmit_more;
206                         s->tx_csum_partial_inner += sq_stats->csum_partial_inner;
207                         s->tx_csum_none         += sq_stats->csum_none;
208                         s->tx_csum_partial      += sq_stats->csum_partial;
209 #ifdef CONFIG_MLX5_EN_TLS
210                         s->tx_tls_ooo           += sq_stats->tls_ooo;
211                         s->tx_tls_resync_bytes  += sq_stats->tls_resync_bytes;
212 #endif
213                         s->tx_cqes              += sq_stats->cqes;
214                 }
215         }
216
217         memcpy(&priv->stats.sw, s, sizeof(*s));
218 }
219
220 static const struct counter_desc q_stats_desc[] = {
221         { MLX5E_DECLARE_STAT(struct mlx5e_qcounter_stats, rx_out_of_buffer) },
222 };
223
224 static const struct counter_desc drop_rq_stats_desc[] = {
225         { MLX5E_DECLARE_STAT(struct mlx5e_qcounter_stats, rx_if_down_packets) },
226 };
227
228 #define NUM_Q_COUNTERS                  ARRAY_SIZE(q_stats_desc)
229 #define NUM_DROP_RQ_COUNTERS            ARRAY_SIZE(drop_rq_stats_desc)
230
231 static int mlx5e_grp_q_get_num_stats(struct mlx5e_priv *priv)
232 {
233         int num_stats = 0;
234
235         if (priv->q_counter)
236                 num_stats += NUM_Q_COUNTERS;
237
238         if (priv->drop_rq_q_counter)
239                 num_stats += NUM_DROP_RQ_COUNTERS;
240
241         return num_stats;
242 }
243
244 static int mlx5e_grp_q_fill_strings(struct mlx5e_priv *priv, u8 *data, int idx)
245 {
246         int i;
247
248         for (i = 0; i < NUM_Q_COUNTERS && priv->q_counter; i++)
249                 strcpy(data + (idx++) * ETH_GSTRING_LEN,
250                        q_stats_desc[i].format);
251
252         for (i = 0; i < NUM_DROP_RQ_COUNTERS && priv->drop_rq_q_counter; i++)
253                 strcpy(data + (idx++) * ETH_GSTRING_LEN,
254                        drop_rq_stats_desc[i].format);
255
256         return idx;
257 }
258
259 static int mlx5e_grp_q_fill_stats(struct mlx5e_priv *priv, u64 *data, int idx)
260 {
261         int i;
262
263         for (i = 0; i < NUM_Q_COUNTERS && priv->q_counter; i++)
264                 data[idx++] = MLX5E_READ_CTR32_CPU(&priv->stats.qcnt,
265                                                    q_stats_desc, i);
266         for (i = 0; i < NUM_DROP_RQ_COUNTERS && priv->drop_rq_q_counter; i++)
267                 data[idx++] = MLX5E_READ_CTR32_CPU(&priv->stats.qcnt,
268                                                    drop_rq_stats_desc, i);
269         return idx;
270 }
271
272 static void mlx5e_grp_q_update_stats(struct mlx5e_priv *priv)
273 {
274         struct mlx5e_qcounter_stats *qcnt = &priv->stats.qcnt;
275         u32 out[MLX5_ST_SZ_DW(query_q_counter_out)];
276
277         if (priv->q_counter &&
278             !mlx5_core_query_q_counter(priv->mdev, priv->q_counter, 0, out,
279                                        sizeof(out)))
280                 qcnt->rx_out_of_buffer = MLX5_GET(query_q_counter_out,
281                                                   out, out_of_buffer);
282         if (priv->drop_rq_q_counter &&
283             !mlx5_core_query_q_counter(priv->mdev, priv->drop_rq_q_counter, 0,
284                                        out, sizeof(out)))
285                 qcnt->rx_if_down_packets = MLX5_GET(query_q_counter_out, out,
286                                                     out_of_buffer);
287 }
288
289 #define VNIC_ENV_OFF(c) MLX5_BYTE_OFF(query_vnic_env_out, c)
290 static const struct counter_desc vnic_env_stats_desc[] = {
291         { "rx_steer_missed_packets",
292                 VNIC_ENV_OFF(vport_env.nic_receive_steering_discard) },
293 };
294
295 #define NUM_VNIC_ENV_COUNTERS           ARRAY_SIZE(vnic_env_stats_desc)
296
297 static int mlx5e_grp_vnic_env_get_num_stats(struct mlx5e_priv *priv)
298 {
299         return MLX5_CAP_GEN(priv->mdev, nic_receive_steering_discard) ?
300                 NUM_VNIC_ENV_COUNTERS : 0;
301 }
302
303 static int mlx5e_grp_vnic_env_fill_strings(struct mlx5e_priv *priv, u8 *data,
304                                            int idx)
305 {
306         int i;
307
308         if (!MLX5_CAP_GEN(priv->mdev, nic_receive_steering_discard))
309                 return idx;
310
311         for (i = 0; i < NUM_VNIC_ENV_COUNTERS; i++)
312                 strcpy(data + (idx++) * ETH_GSTRING_LEN,
313                        vnic_env_stats_desc[i].format);
314         return idx;
315 }
316
317 static int mlx5e_grp_vnic_env_fill_stats(struct mlx5e_priv *priv, u64 *data,
318                                          int idx)
319 {
320         int i;
321
322         if (!MLX5_CAP_GEN(priv->mdev, nic_receive_steering_discard))
323                 return idx;
324
325         for (i = 0; i < NUM_VNIC_ENV_COUNTERS; i++)
326                 data[idx++] = MLX5E_READ_CTR64_BE(priv->stats.vnic.query_vnic_env_out,
327                                                   vnic_env_stats_desc, i);
328         return idx;
329 }
330
331 static void mlx5e_grp_vnic_env_update_stats(struct mlx5e_priv *priv)
332 {
333         u32 *out = (u32 *)priv->stats.vnic.query_vnic_env_out;
334         int outlen = MLX5_ST_SZ_BYTES(query_vnic_env_out);
335         u32 in[MLX5_ST_SZ_DW(query_vnic_env_in)] = {0};
336         struct mlx5_core_dev *mdev = priv->mdev;
337
338         if (!MLX5_CAP_GEN(priv->mdev, nic_receive_steering_discard))
339                 return;
340
341         MLX5_SET(query_vnic_env_in, in, opcode,
342                  MLX5_CMD_OP_QUERY_VNIC_ENV);
343         MLX5_SET(query_vnic_env_in, in, op_mod, 0);
344         MLX5_SET(query_vnic_env_in, in, other_vport, 0);
345         mlx5_cmd_exec(mdev, in, sizeof(in), out, outlen);
346 }
347
348 #define VPORT_COUNTER_OFF(c) MLX5_BYTE_OFF(query_vport_counter_out, c)
349 static const struct counter_desc vport_stats_desc[] = {
350         { "rx_vport_unicast_packets",
351                 VPORT_COUNTER_OFF(received_eth_unicast.packets) },
352         { "rx_vport_unicast_bytes",
353                 VPORT_COUNTER_OFF(received_eth_unicast.octets) },
354         { "tx_vport_unicast_packets",
355                 VPORT_COUNTER_OFF(transmitted_eth_unicast.packets) },
356         { "tx_vport_unicast_bytes",
357                 VPORT_COUNTER_OFF(transmitted_eth_unicast.octets) },
358         { "rx_vport_multicast_packets",
359                 VPORT_COUNTER_OFF(received_eth_multicast.packets) },
360         { "rx_vport_multicast_bytes",
361                 VPORT_COUNTER_OFF(received_eth_multicast.octets) },
362         { "tx_vport_multicast_packets",
363                 VPORT_COUNTER_OFF(transmitted_eth_multicast.packets) },
364         { "tx_vport_multicast_bytes",
365                 VPORT_COUNTER_OFF(transmitted_eth_multicast.octets) },
366         { "rx_vport_broadcast_packets",
367                 VPORT_COUNTER_OFF(received_eth_broadcast.packets) },
368         { "rx_vport_broadcast_bytes",
369                 VPORT_COUNTER_OFF(received_eth_broadcast.octets) },
370         { "tx_vport_broadcast_packets",
371                 VPORT_COUNTER_OFF(transmitted_eth_broadcast.packets) },
372         { "tx_vport_broadcast_bytes",
373                 VPORT_COUNTER_OFF(transmitted_eth_broadcast.octets) },
374         { "rx_vport_rdma_unicast_packets",
375                 VPORT_COUNTER_OFF(received_ib_unicast.packets) },
376         { "rx_vport_rdma_unicast_bytes",
377                 VPORT_COUNTER_OFF(received_ib_unicast.octets) },
378         { "tx_vport_rdma_unicast_packets",
379                 VPORT_COUNTER_OFF(transmitted_ib_unicast.packets) },
380         { "tx_vport_rdma_unicast_bytes",
381                 VPORT_COUNTER_OFF(transmitted_ib_unicast.octets) },
382         { "rx_vport_rdma_multicast_packets",
383                 VPORT_COUNTER_OFF(received_ib_multicast.packets) },
384         { "rx_vport_rdma_multicast_bytes",
385                 VPORT_COUNTER_OFF(received_ib_multicast.octets) },
386         { "tx_vport_rdma_multicast_packets",
387                 VPORT_COUNTER_OFF(transmitted_ib_multicast.packets) },
388         { "tx_vport_rdma_multicast_bytes",
389                 VPORT_COUNTER_OFF(transmitted_ib_multicast.octets) },
390 };
391
392 #define NUM_VPORT_COUNTERS              ARRAY_SIZE(vport_stats_desc)
393
394 static int mlx5e_grp_vport_get_num_stats(struct mlx5e_priv *priv)
395 {
396         return NUM_VPORT_COUNTERS;
397 }
398
399 static int mlx5e_grp_vport_fill_strings(struct mlx5e_priv *priv, u8 *data,
400                                         int idx)
401 {
402         int i;
403
404         for (i = 0; i < NUM_VPORT_COUNTERS; i++)
405                 strcpy(data + (idx++) * ETH_GSTRING_LEN, vport_stats_desc[i].format);
406         return idx;
407 }
408
409 static int mlx5e_grp_vport_fill_stats(struct mlx5e_priv *priv, u64 *data,
410                                       int idx)
411 {
412         int i;
413
414         for (i = 0; i < NUM_VPORT_COUNTERS; i++)
415                 data[idx++] = MLX5E_READ_CTR64_BE(priv->stats.vport.query_vport_out,
416                                                   vport_stats_desc, i);
417         return idx;
418 }
419
420 static void mlx5e_grp_vport_update_stats(struct mlx5e_priv *priv)
421 {
422         int outlen = MLX5_ST_SZ_BYTES(query_vport_counter_out);
423         u32 *out = (u32 *)priv->stats.vport.query_vport_out;
424         u32 in[MLX5_ST_SZ_DW(query_vport_counter_in)] = {0};
425         struct mlx5_core_dev *mdev = priv->mdev;
426
427         MLX5_SET(query_vport_counter_in, in, opcode, MLX5_CMD_OP_QUERY_VPORT_COUNTER);
428         MLX5_SET(query_vport_counter_in, in, op_mod, 0);
429         MLX5_SET(query_vport_counter_in, in, other_vport, 0);
430         mlx5_cmd_exec(mdev, in, sizeof(in), out, outlen);
431 }
432
433 #define PPORT_802_3_OFF(c) \
434         MLX5_BYTE_OFF(ppcnt_reg, \
435                       counter_set.eth_802_3_cntrs_grp_data_layout.c##_high)
436 static const struct counter_desc pport_802_3_stats_desc[] = {
437         { "tx_packets_phy", PPORT_802_3_OFF(a_frames_transmitted_ok) },
438         { "rx_packets_phy", PPORT_802_3_OFF(a_frames_received_ok) },
439         { "rx_crc_errors_phy", PPORT_802_3_OFF(a_frame_check_sequence_errors) },
440         { "tx_bytes_phy", PPORT_802_3_OFF(a_octets_transmitted_ok) },
441         { "rx_bytes_phy", PPORT_802_3_OFF(a_octets_received_ok) },
442         { "tx_multicast_phy", PPORT_802_3_OFF(a_multicast_frames_xmitted_ok) },
443         { "tx_broadcast_phy", PPORT_802_3_OFF(a_broadcast_frames_xmitted_ok) },
444         { "rx_multicast_phy", PPORT_802_3_OFF(a_multicast_frames_received_ok) },
445         { "rx_broadcast_phy", PPORT_802_3_OFF(a_broadcast_frames_received_ok) },
446         { "rx_in_range_len_errors_phy", PPORT_802_3_OFF(a_in_range_length_errors) },
447         { "rx_out_of_range_len_phy", PPORT_802_3_OFF(a_out_of_range_length_field) },
448         { "rx_oversize_pkts_phy", PPORT_802_3_OFF(a_frame_too_long_errors) },
449         { "rx_symbol_err_phy", PPORT_802_3_OFF(a_symbol_error_during_carrier) },
450         { "tx_mac_control_phy", PPORT_802_3_OFF(a_mac_control_frames_transmitted) },
451         { "rx_mac_control_phy", PPORT_802_3_OFF(a_mac_control_frames_received) },
452         { "rx_unsupported_op_phy", PPORT_802_3_OFF(a_unsupported_opcodes_received) },
453         { "rx_pause_ctrl_phy", PPORT_802_3_OFF(a_pause_mac_ctrl_frames_received) },
454         { "tx_pause_ctrl_phy", PPORT_802_3_OFF(a_pause_mac_ctrl_frames_transmitted) },
455 };
456
457 #define NUM_PPORT_802_3_COUNTERS        ARRAY_SIZE(pport_802_3_stats_desc)
458
459 static int mlx5e_grp_802_3_get_num_stats(struct mlx5e_priv *priv)
460 {
461         return NUM_PPORT_802_3_COUNTERS;
462 }
463
464 static int mlx5e_grp_802_3_fill_strings(struct mlx5e_priv *priv, u8 *data,
465                                         int idx)
466 {
467         int i;
468
469         for (i = 0; i < NUM_PPORT_802_3_COUNTERS; i++)
470                 strcpy(data + (idx++) * ETH_GSTRING_LEN, pport_802_3_stats_desc[i].format);
471         return idx;
472 }
473
474 static int mlx5e_grp_802_3_fill_stats(struct mlx5e_priv *priv, u64 *data,
475                                       int idx)
476 {
477         int i;
478
479         for (i = 0; i < NUM_PPORT_802_3_COUNTERS; i++)
480                 data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.IEEE_802_3_counters,
481                                                   pport_802_3_stats_desc, i);
482         return idx;
483 }
484
485 static void mlx5e_grp_802_3_update_stats(struct mlx5e_priv *priv)
486 {
487         struct mlx5e_pport_stats *pstats = &priv->stats.pport;
488         struct mlx5_core_dev *mdev = priv->mdev;
489         u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {0};
490         int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
491         void *out;
492
493         MLX5_SET(ppcnt_reg, in, local_port, 1);
494         out = pstats->IEEE_802_3_counters;
495         MLX5_SET(ppcnt_reg, in, grp, MLX5_IEEE_802_3_COUNTERS_GROUP);
496         mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
497 }
498
499 #define PPORT_2863_OFF(c) \
500         MLX5_BYTE_OFF(ppcnt_reg, \
501                       counter_set.eth_2863_cntrs_grp_data_layout.c##_high)
502 static const struct counter_desc pport_2863_stats_desc[] = {
503         { "rx_discards_phy", PPORT_2863_OFF(if_in_discards) },
504         { "tx_discards_phy", PPORT_2863_OFF(if_out_discards) },
505         { "tx_errors_phy", PPORT_2863_OFF(if_out_errors) },
506 };
507
508 #define NUM_PPORT_2863_COUNTERS         ARRAY_SIZE(pport_2863_stats_desc)
509
510 static int mlx5e_grp_2863_get_num_stats(struct mlx5e_priv *priv)
511 {
512         return NUM_PPORT_2863_COUNTERS;
513 }
514
515 static int mlx5e_grp_2863_fill_strings(struct mlx5e_priv *priv, u8 *data,
516                                        int idx)
517 {
518         int i;
519
520         for (i = 0; i < NUM_PPORT_2863_COUNTERS; i++)
521                 strcpy(data + (idx++) * ETH_GSTRING_LEN, pport_2863_stats_desc[i].format);
522         return idx;
523 }
524
525 static int mlx5e_grp_2863_fill_stats(struct mlx5e_priv *priv, u64 *data,
526                                      int idx)
527 {
528         int i;
529
530         for (i = 0; i < NUM_PPORT_2863_COUNTERS; i++)
531                 data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.RFC_2863_counters,
532                                                   pport_2863_stats_desc, i);
533         return idx;
534 }
535
536 static void mlx5e_grp_2863_update_stats(struct mlx5e_priv *priv)
537 {
538         struct mlx5e_pport_stats *pstats = &priv->stats.pport;
539         struct mlx5_core_dev *mdev = priv->mdev;
540         u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {0};
541         int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
542         void *out;
543
544         MLX5_SET(ppcnt_reg, in, local_port, 1);
545         out = pstats->RFC_2863_counters;
546         MLX5_SET(ppcnt_reg, in, grp, MLX5_RFC_2863_COUNTERS_GROUP);
547         mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
548 }
549
550 #define PPORT_2819_OFF(c) \
551         MLX5_BYTE_OFF(ppcnt_reg, \
552                       counter_set.eth_2819_cntrs_grp_data_layout.c##_high)
553 static const struct counter_desc pport_2819_stats_desc[] = {
554         { "rx_undersize_pkts_phy", PPORT_2819_OFF(ether_stats_undersize_pkts) },
555         { "rx_fragments_phy", PPORT_2819_OFF(ether_stats_fragments) },
556         { "rx_jabbers_phy", PPORT_2819_OFF(ether_stats_jabbers) },
557         { "rx_64_bytes_phy", PPORT_2819_OFF(ether_stats_pkts64octets) },
558         { "rx_65_to_127_bytes_phy", PPORT_2819_OFF(ether_stats_pkts65to127octets) },
559         { "rx_128_to_255_bytes_phy", PPORT_2819_OFF(ether_stats_pkts128to255octets) },
560         { "rx_256_to_511_bytes_phy", PPORT_2819_OFF(ether_stats_pkts256to511octets) },
561         { "rx_512_to_1023_bytes_phy", PPORT_2819_OFF(ether_stats_pkts512to1023octets) },
562         { "rx_1024_to_1518_bytes_phy", PPORT_2819_OFF(ether_stats_pkts1024to1518octets) },
563         { "rx_1519_to_2047_bytes_phy", PPORT_2819_OFF(ether_stats_pkts1519to2047octets) },
564         { "rx_2048_to_4095_bytes_phy", PPORT_2819_OFF(ether_stats_pkts2048to4095octets) },
565         { "rx_4096_to_8191_bytes_phy", PPORT_2819_OFF(ether_stats_pkts4096to8191octets) },
566         { "rx_8192_to_10239_bytes_phy", PPORT_2819_OFF(ether_stats_pkts8192to10239octets) },
567 };
568
569 #define NUM_PPORT_2819_COUNTERS         ARRAY_SIZE(pport_2819_stats_desc)
570
571 static int mlx5e_grp_2819_get_num_stats(struct mlx5e_priv *priv)
572 {
573         return NUM_PPORT_2819_COUNTERS;
574 }
575
576 static int mlx5e_grp_2819_fill_strings(struct mlx5e_priv *priv, u8 *data,
577                                        int idx)
578 {
579         int i;
580
581         for (i = 0; i < NUM_PPORT_2819_COUNTERS; i++)
582                 strcpy(data + (idx++) * ETH_GSTRING_LEN, pport_2819_stats_desc[i].format);
583         return idx;
584 }
585
586 static int mlx5e_grp_2819_fill_stats(struct mlx5e_priv *priv, u64 *data,
587                                      int idx)
588 {
589         int i;
590
591         for (i = 0; i < NUM_PPORT_2819_COUNTERS; i++)
592                 data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.RFC_2819_counters,
593                                                   pport_2819_stats_desc, i);
594         return idx;
595 }
596
597 static void mlx5e_grp_2819_update_stats(struct mlx5e_priv *priv)
598 {
599         struct mlx5e_pport_stats *pstats = &priv->stats.pport;
600         struct mlx5_core_dev *mdev = priv->mdev;
601         u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {0};
602         int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
603         void *out;
604
605         MLX5_SET(ppcnt_reg, in, local_port, 1);
606         out = pstats->RFC_2819_counters;
607         MLX5_SET(ppcnt_reg, in, grp, MLX5_RFC_2819_COUNTERS_GROUP);
608         mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
609 }
610
611 #define PPORT_PHY_STATISTICAL_OFF(c) \
612         MLX5_BYTE_OFF(ppcnt_reg, \
613                       counter_set.phys_layer_statistical_cntrs.c##_high)
614 static const struct counter_desc pport_phy_statistical_stats_desc[] = {
615         { "rx_pcs_symbol_err_phy", PPORT_PHY_STATISTICAL_OFF(phy_symbol_errors) },
616         { "rx_corrected_bits_phy", PPORT_PHY_STATISTICAL_OFF(phy_corrected_bits) },
617 };
618
619 static const struct counter_desc
620 pport_phy_statistical_err_lanes_stats_desc[] = {
621         { "rx_err_lane_0_phy", PPORT_PHY_STATISTICAL_OFF(phy_corrected_bits_lane0) },
622         { "rx_err_lane_1_phy", PPORT_PHY_STATISTICAL_OFF(phy_corrected_bits_lane1) },
623         { "rx_err_lane_2_phy", PPORT_PHY_STATISTICAL_OFF(phy_corrected_bits_lane2) },
624         { "rx_err_lane_3_phy", PPORT_PHY_STATISTICAL_OFF(phy_corrected_bits_lane3) },
625 };
626
627 #define NUM_PPORT_PHY_STATISTICAL_COUNTERS \
628         ARRAY_SIZE(pport_phy_statistical_stats_desc)
629 #define NUM_PPORT_PHY_STATISTICAL_PER_LANE_COUNTERS \
630         ARRAY_SIZE(pport_phy_statistical_err_lanes_stats_desc)
631
632 static int mlx5e_grp_phy_get_num_stats(struct mlx5e_priv *priv)
633 {
634         struct mlx5_core_dev *mdev = priv->mdev;
635         int num_stats;
636
637         /* "1" for link_down_events special counter */
638         num_stats = 1;
639
640         num_stats += MLX5_CAP_PCAM_FEATURE(mdev, ppcnt_statistical_group) ?
641                      NUM_PPORT_PHY_STATISTICAL_COUNTERS : 0;
642
643         num_stats += MLX5_CAP_PCAM_FEATURE(mdev, per_lane_error_counters) ?
644                      NUM_PPORT_PHY_STATISTICAL_PER_LANE_COUNTERS : 0;
645
646         return num_stats;
647 }
648
649 static int mlx5e_grp_phy_fill_strings(struct mlx5e_priv *priv, u8 *data,
650                                       int idx)
651 {
652         struct mlx5_core_dev *mdev = priv->mdev;
653         int i;
654
655         strcpy(data + (idx++) * ETH_GSTRING_LEN, "link_down_events_phy");
656
657         if (!MLX5_CAP_PCAM_FEATURE(mdev, ppcnt_statistical_group))
658                 return idx;
659
660         for (i = 0; i < NUM_PPORT_PHY_STATISTICAL_COUNTERS; i++)
661                 strcpy(data + (idx++) * ETH_GSTRING_LEN,
662                        pport_phy_statistical_stats_desc[i].format);
663
664         if (MLX5_CAP_PCAM_FEATURE(mdev, per_lane_error_counters))
665                 for (i = 0; i < NUM_PPORT_PHY_STATISTICAL_PER_LANE_COUNTERS; i++)
666                         strcpy(data + (idx++) * ETH_GSTRING_LEN,
667                                pport_phy_statistical_err_lanes_stats_desc[i].format);
668
669         return idx;
670 }
671
672 static int mlx5e_grp_phy_fill_stats(struct mlx5e_priv *priv, u64 *data, int idx)
673 {
674         struct mlx5_core_dev *mdev = priv->mdev;
675         int i;
676
677         /* link_down_events_phy has special handling since it is not stored in __be64 format */
678         data[idx++] = MLX5_GET(ppcnt_reg, priv->stats.pport.phy_counters,
679                                counter_set.phys_layer_cntrs.link_down_events);
680
681         if (!MLX5_CAP_PCAM_FEATURE(mdev, ppcnt_statistical_group))
682                 return idx;
683
684         for (i = 0; i < NUM_PPORT_PHY_STATISTICAL_COUNTERS; i++)
685                 data[idx++] =
686                         MLX5E_READ_CTR64_BE(&priv->stats.pport.phy_statistical_counters,
687                                             pport_phy_statistical_stats_desc, i);
688
689         if (MLX5_CAP_PCAM_FEATURE(mdev, per_lane_error_counters))
690                 for (i = 0; i < NUM_PPORT_PHY_STATISTICAL_PER_LANE_COUNTERS; i++)
691                         data[idx++] =
692                                 MLX5E_READ_CTR64_BE(&priv->stats.pport.phy_statistical_counters,
693                                                     pport_phy_statistical_err_lanes_stats_desc,
694                                                     i);
695         return idx;
696 }
697
698 static void mlx5e_grp_phy_update_stats(struct mlx5e_priv *priv)
699 {
700         struct mlx5e_pport_stats *pstats = &priv->stats.pport;
701         struct mlx5_core_dev *mdev = priv->mdev;
702         u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {0};
703         int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
704         void *out;
705
706         MLX5_SET(ppcnt_reg, in, local_port, 1);
707         out = pstats->phy_counters;
708         MLX5_SET(ppcnt_reg, in, grp, MLX5_PHYSICAL_LAYER_COUNTERS_GROUP);
709         mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
710
711         if (!MLX5_CAP_PCAM_FEATURE(mdev, ppcnt_statistical_group))
712                 return;
713
714         out = pstats->phy_statistical_counters;
715         MLX5_SET(ppcnt_reg, in, grp, MLX5_PHYSICAL_LAYER_STATISTICAL_GROUP);
716         mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
717 }
718
719 #define PPORT_ETH_EXT_OFF(c) \
720         MLX5_BYTE_OFF(ppcnt_reg, \
721                       counter_set.eth_extended_cntrs_grp_data_layout.c##_high)
722 static const struct counter_desc pport_eth_ext_stats_desc[] = {
723         { "rx_buffer_passed_thres_phy", PPORT_ETH_EXT_OFF(rx_buffer_almost_full) },
724 };
725
726 #define NUM_PPORT_ETH_EXT_COUNTERS      ARRAY_SIZE(pport_eth_ext_stats_desc)
727
728 static int mlx5e_grp_eth_ext_get_num_stats(struct mlx5e_priv *priv)
729 {
730         if (MLX5_CAP_PCAM_FEATURE((priv)->mdev, rx_buffer_fullness_counters))
731                 return NUM_PPORT_ETH_EXT_COUNTERS;
732
733         return 0;
734 }
735
736 static int mlx5e_grp_eth_ext_fill_strings(struct mlx5e_priv *priv, u8 *data,
737                                           int idx)
738 {
739         int i;
740
741         if (MLX5_CAP_PCAM_FEATURE((priv)->mdev, rx_buffer_fullness_counters))
742                 for (i = 0; i < NUM_PPORT_ETH_EXT_COUNTERS; i++)
743                         strcpy(data + (idx++) * ETH_GSTRING_LEN,
744                                pport_eth_ext_stats_desc[i].format);
745         return idx;
746 }
747
748 static int mlx5e_grp_eth_ext_fill_stats(struct mlx5e_priv *priv, u64 *data,
749                                         int idx)
750 {
751         int i;
752
753         if (MLX5_CAP_PCAM_FEATURE((priv)->mdev, rx_buffer_fullness_counters))
754                 for (i = 0; i < NUM_PPORT_ETH_EXT_COUNTERS; i++)
755                         data[idx++] =
756                                 MLX5E_READ_CTR64_BE(&priv->stats.pport.eth_ext_counters,
757                                                     pport_eth_ext_stats_desc, i);
758         return idx;
759 }
760
761 static void mlx5e_grp_eth_ext_update_stats(struct mlx5e_priv *priv)
762 {
763         struct mlx5e_pport_stats *pstats = &priv->stats.pport;
764         struct mlx5_core_dev *mdev = priv->mdev;
765         u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {0};
766         int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
767         void *out;
768
769         if (!MLX5_CAP_PCAM_FEATURE(mdev, rx_buffer_fullness_counters))
770                 return;
771
772         MLX5_SET(ppcnt_reg, in, local_port, 1);
773         out = pstats->eth_ext_counters;
774         MLX5_SET(ppcnt_reg, in, grp, MLX5_ETHERNET_EXTENDED_COUNTERS_GROUP);
775         mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
776 }
777
778 #define PCIE_PERF_OFF(c) \
779         MLX5_BYTE_OFF(mpcnt_reg, counter_set.pcie_perf_cntrs_grp_data_layout.c)
780 static const struct counter_desc pcie_perf_stats_desc[] = {
781         { "rx_pci_signal_integrity", PCIE_PERF_OFF(rx_errors) },
782         { "tx_pci_signal_integrity", PCIE_PERF_OFF(tx_errors) },
783 };
784
785 #define PCIE_PERF_OFF64(c) \
786         MLX5_BYTE_OFF(mpcnt_reg, counter_set.pcie_perf_cntrs_grp_data_layout.c##_high)
787 static const struct counter_desc pcie_perf_stats_desc64[] = {
788         { "outbound_pci_buffer_overflow", PCIE_PERF_OFF64(tx_overflow_buffer_pkt) },
789 };
790
791 static const struct counter_desc pcie_perf_stall_stats_desc[] = {
792         { "outbound_pci_stalled_rd", PCIE_PERF_OFF(outbound_stalled_reads) },
793         { "outbound_pci_stalled_wr", PCIE_PERF_OFF(outbound_stalled_writes) },
794         { "outbound_pci_stalled_rd_events", PCIE_PERF_OFF(outbound_stalled_reads_events) },
795         { "outbound_pci_stalled_wr_events", PCIE_PERF_OFF(outbound_stalled_writes_events) },
796 };
797
798 #define NUM_PCIE_PERF_COUNTERS          ARRAY_SIZE(pcie_perf_stats_desc)
799 #define NUM_PCIE_PERF_COUNTERS64        ARRAY_SIZE(pcie_perf_stats_desc64)
800 #define NUM_PCIE_PERF_STALL_COUNTERS    ARRAY_SIZE(pcie_perf_stall_stats_desc)
801
802 static int mlx5e_grp_pcie_get_num_stats(struct mlx5e_priv *priv)
803 {
804         int num_stats = 0;
805
806         if (MLX5_CAP_MCAM_FEATURE((priv)->mdev, pcie_performance_group))
807                 num_stats += NUM_PCIE_PERF_COUNTERS;
808
809         if (MLX5_CAP_MCAM_FEATURE((priv)->mdev, tx_overflow_buffer_pkt))
810                 num_stats += NUM_PCIE_PERF_COUNTERS64;
811
812         if (MLX5_CAP_MCAM_FEATURE((priv)->mdev, pcie_outbound_stalled))
813                 num_stats += NUM_PCIE_PERF_STALL_COUNTERS;
814
815         return num_stats;
816 }
817
818 static int mlx5e_grp_pcie_fill_strings(struct mlx5e_priv *priv, u8 *data,
819                                        int idx)
820 {
821         int i;
822
823         if (MLX5_CAP_MCAM_FEATURE((priv)->mdev, pcie_performance_group))
824                 for (i = 0; i < NUM_PCIE_PERF_COUNTERS; i++)
825                         strcpy(data + (idx++) * ETH_GSTRING_LEN,
826                                pcie_perf_stats_desc[i].format);
827
828         if (MLX5_CAP_MCAM_FEATURE((priv)->mdev, tx_overflow_buffer_pkt))
829                 for (i = 0; i < NUM_PCIE_PERF_COUNTERS64; i++)
830                         strcpy(data + (idx++) * ETH_GSTRING_LEN,
831                                pcie_perf_stats_desc64[i].format);
832
833         if (MLX5_CAP_MCAM_FEATURE((priv)->mdev, pcie_outbound_stalled))
834                 for (i = 0; i < NUM_PCIE_PERF_STALL_COUNTERS; i++)
835                         strcpy(data + (idx++) * ETH_GSTRING_LEN,
836                                pcie_perf_stall_stats_desc[i].format);
837         return idx;
838 }
839
840 static int mlx5e_grp_pcie_fill_stats(struct mlx5e_priv *priv, u64 *data,
841                                      int idx)
842 {
843         int i;
844
845         if (MLX5_CAP_MCAM_FEATURE((priv)->mdev, pcie_performance_group))
846                 for (i = 0; i < NUM_PCIE_PERF_COUNTERS; i++)
847                         data[idx++] =
848                                 MLX5E_READ_CTR32_BE(&priv->stats.pcie.pcie_perf_counters,
849                                                     pcie_perf_stats_desc, i);
850
851         if (MLX5_CAP_MCAM_FEATURE((priv)->mdev, tx_overflow_buffer_pkt))
852                 for (i = 0; i < NUM_PCIE_PERF_COUNTERS64; i++)
853                         data[idx++] =
854                                 MLX5E_READ_CTR64_BE(&priv->stats.pcie.pcie_perf_counters,
855                                                     pcie_perf_stats_desc64, i);
856
857         if (MLX5_CAP_MCAM_FEATURE((priv)->mdev, pcie_outbound_stalled))
858                 for (i = 0; i < NUM_PCIE_PERF_STALL_COUNTERS; i++)
859                         data[idx++] =
860                                 MLX5E_READ_CTR32_BE(&priv->stats.pcie.pcie_perf_counters,
861                                                     pcie_perf_stall_stats_desc, i);
862         return idx;
863 }
864
865 static void mlx5e_grp_pcie_update_stats(struct mlx5e_priv *priv)
866 {
867         struct mlx5e_pcie_stats *pcie_stats = &priv->stats.pcie;
868         struct mlx5_core_dev *mdev = priv->mdev;
869         u32 in[MLX5_ST_SZ_DW(mpcnt_reg)] = {0};
870         int sz = MLX5_ST_SZ_BYTES(mpcnt_reg);
871         void *out;
872
873         if (!MLX5_CAP_MCAM_FEATURE(mdev, pcie_performance_group))
874                 return;
875
876         out = pcie_stats->pcie_perf_counters;
877         MLX5_SET(mpcnt_reg, in, grp, MLX5_PCIE_PERFORMANCE_COUNTERS_GROUP);
878         mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_MPCNT, 0, 0);
879 }
880
881 #define PPORT_PER_PRIO_OFF(c) \
882         MLX5_BYTE_OFF(ppcnt_reg, \
883                       counter_set.eth_per_prio_grp_data_layout.c##_high)
884 static const struct counter_desc pport_per_prio_traffic_stats_desc[] = {
885         { "rx_prio%d_bytes", PPORT_PER_PRIO_OFF(rx_octets) },
886         { "rx_prio%d_packets", PPORT_PER_PRIO_OFF(rx_frames) },
887         { "tx_prio%d_bytes", PPORT_PER_PRIO_OFF(tx_octets) },
888         { "tx_prio%d_packets", PPORT_PER_PRIO_OFF(tx_frames) },
889 };
890
891 #define NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS     ARRAY_SIZE(pport_per_prio_traffic_stats_desc)
892
893 static int mlx5e_grp_per_prio_traffic_get_num_stats(void)
894 {
895         return NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS * NUM_PPORT_PRIO;
896 }
897
898 static int mlx5e_grp_per_prio_traffic_fill_strings(struct mlx5e_priv *priv,
899                                                    u8 *data,
900                                                    int idx)
901 {
902         int i, prio;
903
904         for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
905                 for (i = 0; i < NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS; i++)
906                         sprintf(data + (idx++) * ETH_GSTRING_LEN,
907                                 pport_per_prio_traffic_stats_desc[i].format, prio);
908         }
909
910         return idx;
911 }
912
913 static int mlx5e_grp_per_prio_traffic_fill_stats(struct mlx5e_priv *priv,
914                                                  u64 *data,
915                                                  int idx)
916 {
917         int i, prio;
918
919         for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
920                 for (i = 0; i < NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS; i++)
921                         data[idx++] =
922                                 MLX5E_READ_CTR64_BE(&priv->stats.pport.per_prio_counters[prio],
923                                                     pport_per_prio_traffic_stats_desc, i);
924         }
925
926         return idx;
927 }
928
929 static const struct counter_desc pport_per_prio_pfc_stats_desc[] = {
930         /* %s is "global" or "prio{i}" */
931         { "rx_%s_pause", PPORT_PER_PRIO_OFF(rx_pause) },
932         { "rx_%s_pause_duration", PPORT_PER_PRIO_OFF(rx_pause_duration) },
933         { "tx_%s_pause", PPORT_PER_PRIO_OFF(tx_pause) },
934         { "tx_%s_pause_duration", PPORT_PER_PRIO_OFF(tx_pause_duration) },
935         { "rx_%s_pause_transition", PPORT_PER_PRIO_OFF(rx_pause_transition) },
936 };
937
938 static const struct counter_desc pport_pfc_stall_stats_desc[] = {
939         { "tx_pause_storm_warning_events ", PPORT_PER_PRIO_OFF(device_stall_minor_watermark_cnt) },
940         { "tx_pause_storm_error_events", PPORT_PER_PRIO_OFF(device_stall_critical_watermark_cnt) },
941 };
942
943 #define NUM_PPORT_PER_PRIO_PFC_COUNTERS         ARRAY_SIZE(pport_per_prio_pfc_stats_desc)
944 #define NUM_PPORT_PFC_STALL_COUNTERS(priv)      (ARRAY_SIZE(pport_pfc_stall_stats_desc) * \
945                                                  MLX5_CAP_PCAM_FEATURE((priv)->mdev, pfcc_mask) * \
946                                                  MLX5_CAP_DEBUG((priv)->mdev, stall_detect))
947
948 static unsigned long mlx5e_query_pfc_combined(struct mlx5e_priv *priv)
949 {
950         struct mlx5_core_dev *mdev = priv->mdev;
951         u8 pfc_en_tx;
952         u8 pfc_en_rx;
953         int err;
954
955         if (MLX5_CAP_GEN(mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
956                 return 0;
957
958         err = mlx5_query_port_pfc(mdev, &pfc_en_tx, &pfc_en_rx);
959
960         return err ? 0 : pfc_en_tx | pfc_en_rx;
961 }
962
963 static bool mlx5e_query_global_pause_combined(struct mlx5e_priv *priv)
964 {
965         struct mlx5_core_dev *mdev = priv->mdev;
966         u32 rx_pause;
967         u32 tx_pause;
968         int err;
969
970         if (MLX5_CAP_GEN(mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
971                 return false;
972
973         err = mlx5_query_port_pause(mdev, &rx_pause, &tx_pause);
974
975         return err ? false : rx_pause | tx_pause;
976 }
977
978 static int mlx5e_grp_per_prio_pfc_get_num_stats(struct mlx5e_priv *priv)
979 {
980         return (mlx5e_query_global_pause_combined(priv) +
981                 hweight8(mlx5e_query_pfc_combined(priv))) *
982                 NUM_PPORT_PER_PRIO_PFC_COUNTERS +
983                 NUM_PPORT_PFC_STALL_COUNTERS(priv);
984 }
985
986 static int mlx5e_grp_per_prio_pfc_fill_strings(struct mlx5e_priv *priv,
987                                                u8 *data,
988                                                int idx)
989 {
990         unsigned long pfc_combined;
991         int i, prio;
992
993         pfc_combined = mlx5e_query_pfc_combined(priv);
994         for_each_set_bit(prio, &pfc_combined, NUM_PPORT_PRIO) {
995                 for (i = 0; i < NUM_PPORT_PER_PRIO_PFC_COUNTERS; i++) {
996                         char pfc_string[ETH_GSTRING_LEN];
997
998                         snprintf(pfc_string, sizeof(pfc_string), "prio%d", prio);
999                         sprintf(data + (idx++) * ETH_GSTRING_LEN,
1000                                 pport_per_prio_pfc_stats_desc[i].format, pfc_string);
1001                 }
1002         }
1003
1004         if (mlx5e_query_global_pause_combined(priv)) {
1005                 for (i = 0; i < NUM_PPORT_PER_PRIO_PFC_COUNTERS; i++) {
1006                         sprintf(data + (idx++) * ETH_GSTRING_LEN,
1007                                 pport_per_prio_pfc_stats_desc[i].format, "global");
1008                 }
1009         }
1010
1011         for (i = 0; i < NUM_PPORT_PFC_STALL_COUNTERS(priv); i++)
1012                 strcpy(data + (idx++) * ETH_GSTRING_LEN,
1013                        pport_pfc_stall_stats_desc[i].format);
1014
1015         return idx;
1016 }
1017
1018 static int mlx5e_grp_per_prio_pfc_fill_stats(struct mlx5e_priv *priv,
1019                                              u64 *data,
1020                                              int idx)
1021 {
1022         unsigned long pfc_combined;
1023         int i, prio;
1024
1025         pfc_combined = mlx5e_query_pfc_combined(priv);
1026         for_each_set_bit(prio, &pfc_combined, NUM_PPORT_PRIO) {
1027                 for (i = 0; i < NUM_PPORT_PER_PRIO_PFC_COUNTERS; i++) {
1028                         data[idx++] =
1029                                 MLX5E_READ_CTR64_BE(&priv->stats.pport.per_prio_counters[prio],
1030                                                     pport_per_prio_pfc_stats_desc, i);
1031                 }
1032         }
1033
1034         if (mlx5e_query_global_pause_combined(priv)) {
1035                 for (i = 0; i < NUM_PPORT_PER_PRIO_PFC_COUNTERS; i++) {
1036                         data[idx++] =
1037                                 MLX5E_READ_CTR64_BE(&priv->stats.pport.per_prio_counters[0],
1038                                                     pport_per_prio_pfc_stats_desc, i);
1039                 }
1040         }
1041
1042         for (i = 0; i < NUM_PPORT_PFC_STALL_COUNTERS(priv); i++)
1043                 data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.per_prio_counters[0],
1044                                                   pport_pfc_stall_stats_desc, i);
1045
1046         return idx;
1047 }
1048
1049 static int mlx5e_grp_per_prio_get_num_stats(struct mlx5e_priv *priv)
1050 {
1051         return mlx5e_grp_per_prio_traffic_get_num_stats() +
1052                 mlx5e_grp_per_prio_pfc_get_num_stats(priv);
1053 }
1054
1055 static int mlx5e_grp_per_prio_fill_strings(struct mlx5e_priv *priv, u8 *data,
1056                                            int idx)
1057 {
1058         idx = mlx5e_grp_per_prio_traffic_fill_strings(priv, data, idx);
1059         idx = mlx5e_grp_per_prio_pfc_fill_strings(priv, data, idx);
1060         return idx;
1061 }
1062
1063 static int mlx5e_grp_per_prio_fill_stats(struct mlx5e_priv *priv, u64 *data,
1064                                          int idx)
1065 {
1066         idx = mlx5e_grp_per_prio_traffic_fill_stats(priv, data, idx);
1067         idx = mlx5e_grp_per_prio_pfc_fill_stats(priv, data, idx);
1068         return idx;
1069 }
1070
1071 static void mlx5e_grp_per_prio_update_stats(struct mlx5e_priv *priv)
1072 {
1073         struct mlx5e_pport_stats *pstats = &priv->stats.pport;
1074         struct mlx5_core_dev *mdev = priv->mdev;
1075         u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {0};
1076         int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
1077         int prio;
1078         void *out;
1079
1080         MLX5_SET(ppcnt_reg, in, local_port, 1);
1081         MLX5_SET(ppcnt_reg, in, grp, MLX5_PER_PRIORITY_COUNTERS_GROUP);
1082         for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
1083                 out = pstats->per_prio_counters[prio];
1084                 MLX5_SET(ppcnt_reg, in, prio_tc, prio);
1085                 mlx5_core_access_reg(mdev, in, sz, out, sz,
1086                                      MLX5_REG_PPCNT, 0, 0);
1087         }
1088 }
1089
1090 static const struct counter_desc mlx5e_pme_status_desc[] = {
1091         { "module_unplug", 8 },
1092 };
1093
1094 static const struct counter_desc mlx5e_pme_error_desc[] = {
1095         { "module_bus_stuck", 16 },       /* bus stuck (I2C or data shorted) */
1096         { "module_high_temp", 48 },       /* high temperature */
1097         { "module_bad_shorted", 56 },    /* bad or shorted cable/module */
1098 };
1099
1100 #define NUM_PME_STATUS_STATS            ARRAY_SIZE(mlx5e_pme_status_desc)
1101 #define NUM_PME_ERR_STATS               ARRAY_SIZE(mlx5e_pme_error_desc)
1102
1103 static int mlx5e_grp_pme_get_num_stats(struct mlx5e_priv *priv)
1104 {
1105         return NUM_PME_STATUS_STATS + NUM_PME_ERR_STATS;
1106 }
1107
1108 static int mlx5e_grp_pme_fill_strings(struct mlx5e_priv *priv, u8 *data,
1109                                       int idx)
1110 {
1111         int i;
1112
1113         for (i = 0; i < NUM_PME_STATUS_STATS; i++)
1114                 strcpy(data + (idx++) * ETH_GSTRING_LEN, mlx5e_pme_status_desc[i].format);
1115
1116         for (i = 0; i < NUM_PME_ERR_STATS; i++)
1117                 strcpy(data + (idx++) * ETH_GSTRING_LEN, mlx5e_pme_error_desc[i].format);
1118
1119         return idx;
1120 }
1121
1122 static int mlx5e_grp_pme_fill_stats(struct mlx5e_priv *priv, u64 *data,
1123                                     int idx)
1124 {
1125         struct mlx5_priv *mlx5_priv = &priv->mdev->priv;
1126         int i;
1127
1128         for (i = 0; i < NUM_PME_STATUS_STATS; i++)
1129                 data[idx++] = MLX5E_READ_CTR64_CPU(mlx5_priv->pme_stats.status_counters,
1130                                                    mlx5e_pme_status_desc, i);
1131
1132         for (i = 0; i < NUM_PME_ERR_STATS; i++)
1133                 data[idx++] = MLX5E_READ_CTR64_CPU(mlx5_priv->pme_stats.error_counters,
1134                                                    mlx5e_pme_error_desc, i);
1135
1136         return idx;
1137 }
1138
1139 static int mlx5e_grp_ipsec_get_num_stats(struct mlx5e_priv *priv)
1140 {
1141         return mlx5e_ipsec_get_count(priv);
1142 }
1143
1144 static int mlx5e_grp_ipsec_fill_strings(struct mlx5e_priv *priv, u8 *data,
1145                                         int idx)
1146 {
1147         return idx + mlx5e_ipsec_get_strings(priv,
1148                                              data + idx * ETH_GSTRING_LEN);
1149 }
1150
1151 static int mlx5e_grp_ipsec_fill_stats(struct mlx5e_priv *priv, u64 *data,
1152                                       int idx)
1153 {
1154         return idx + mlx5e_ipsec_get_stats(priv, data + idx);
1155 }
1156
1157 static void mlx5e_grp_ipsec_update_stats(struct mlx5e_priv *priv)
1158 {
1159         mlx5e_ipsec_update_stats(priv);
1160 }
1161
1162 static int mlx5e_grp_tls_get_num_stats(struct mlx5e_priv *priv)
1163 {
1164         return mlx5e_tls_get_count(priv);
1165 }
1166
1167 static int mlx5e_grp_tls_fill_strings(struct mlx5e_priv *priv, u8 *data,
1168                                       int idx)
1169 {
1170         return idx + mlx5e_tls_get_strings(priv, data + idx * ETH_GSTRING_LEN);
1171 }
1172
1173 static int mlx5e_grp_tls_fill_stats(struct mlx5e_priv *priv, u64 *data, int idx)
1174 {
1175         return idx + mlx5e_tls_get_stats(priv, data + idx);
1176 }
1177
1178 static const struct counter_desc rq_stats_desc[] = {
1179         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, packets) },
1180         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, bytes) },
1181         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_complete) },
1182         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_unnecessary) },
1183         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_unnecessary_inner) },
1184         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_none) },
1185         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, xdp_drop) },
1186         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, xdp_redirect) },
1187         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, lro_packets) },
1188         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, lro_bytes) },
1189         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, ecn_mark) },
1190         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, removed_vlan_packets) },
1191         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, wqe_err) },
1192         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, mpwqe_filler_cqes) },
1193         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, mpwqe_filler_strides) },
1194         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, oversize_pkts_sw_drop) },
1195         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, buff_alloc_err) },
1196         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cqe_compress_blks) },
1197         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cqe_compress_pkts) },
1198         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, page_reuse) },
1199         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cache_reuse) },
1200         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cache_full) },
1201         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cache_empty) },
1202         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cache_busy) },
1203         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cache_waive) },
1204         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, congst_umr) },
1205         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, arfs_err) },
1206 };
1207
1208 static const struct counter_desc sq_stats_desc[] = {
1209         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, packets) },
1210         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, bytes) },
1211         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tso_packets) },
1212         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tso_bytes) },
1213         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tso_inner_packets) },
1214         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tso_inner_bytes) },
1215         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, csum_partial) },
1216         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, csum_partial_inner) },
1217         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, added_vlan_packets) },
1218         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, nop) },
1219         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, csum_none) },
1220         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, stopped) },
1221         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, dropped) },
1222         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, xmit_more) },
1223         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, recover) },
1224         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, cqes) },
1225         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, wake) },
1226         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, cqe_err) },
1227 };
1228
1229 static const struct counter_desc rq_xdpsq_stats_desc[] = {
1230         { MLX5E_DECLARE_RQ_XDPSQ_STAT(struct mlx5e_xdpsq_stats, xmit) },
1231         { MLX5E_DECLARE_RQ_XDPSQ_STAT(struct mlx5e_xdpsq_stats, full) },
1232         { MLX5E_DECLARE_RQ_XDPSQ_STAT(struct mlx5e_xdpsq_stats, err) },
1233         { MLX5E_DECLARE_RQ_XDPSQ_STAT(struct mlx5e_xdpsq_stats, cqes) },
1234 };
1235
1236 static const struct counter_desc xdpsq_stats_desc[] = {
1237         { MLX5E_DECLARE_XDPSQ_STAT(struct mlx5e_xdpsq_stats, xmit) },
1238         { MLX5E_DECLARE_XDPSQ_STAT(struct mlx5e_xdpsq_stats, full) },
1239         { MLX5E_DECLARE_XDPSQ_STAT(struct mlx5e_xdpsq_stats, err) },
1240         { MLX5E_DECLARE_XDPSQ_STAT(struct mlx5e_xdpsq_stats, cqes) },
1241 };
1242
1243 static const struct counter_desc ch_stats_desc[] = {
1244         { MLX5E_DECLARE_CH_STAT(struct mlx5e_ch_stats, events) },
1245         { MLX5E_DECLARE_CH_STAT(struct mlx5e_ch_stats, poll) },
1246         { MLX5E_DECLARE_CH_STAT(struct mlx5e_ch_stats, arm) },
1247         { MLX5E_DECLARE_CH_STAT(struct mlx5e_ch_stats, aff_change) },
1248         { MLX5E_DECLARE_CH_STAT(struct mlx5e_ch_stats, eq_rearm) },
1249 };
1250
1251 #define NUM_RQ_STATS                    ARRAY_SIZE(rq_stats_desc)
1252 #define NUM_SQ_STATS                    ARRAY_SIZE(sq_stats_desc)
1253 #define NUM_XDPSQ_STATS                 ARRAY_SIZE(xdpsq_stats_desc)
1254 #define NUM_RQ_XDPSQ_STATS              ARRAY_SIZE(rq_xdpsq_stats_desc)
1255 #define NUM_CH_STATS                    ARRAY_SIZE(ch_stats_desc)
1256
1257 static int mlx5e_grp_channels_get_num_stats(struct mlx5e_priv *priv)
1258 {
1259         int max_nch = mlx5e_get_netdev_max_channels(priv->netdev);
1260
1261         return (NUM_RQ_STATS * max_nch) +
1262                (NUM_CH_STATS * max_nch) +
1263                (NUM_SQ_STATS * max_nch * priv->max_opened_tc) +
1264                (NUM_RQ_XDPSQ_STATS * max_nch) +
1265                (NUM_XDPSQ_STATS * max_nch);
1266 }
1267
1268 static int mlx5e_grp_channels_fill_strings(struct mlx5e_priv *priv, u8 *data,
1269                                            int idx)
1270 {
1271         int max_nch = mlx5e_get_netdev_max_channels(priv->netdev);
1272         int i, j, tc;
1273
1274         for (i = 0; i < max_nch; i++)
1275                 for (j = 0; j < NUM_CH_STATS; j++)
1276                         sprintf(data + (idx++) * ETH_GSTRING_LEN,
1277                                 ch_stats_desc[j].format, i);
1278
1279         for (i = 0; i < max_nch; i++) {
1280                 for (j = 0; j < NUM_RQ_STATS; j++)
1281                         sprintf(data + (idx++) * ETH_GSTRING_LEN,
1282                                 rq_stats_desc[j].format, i);
1283                 for (j = 0; j < NUM_RQ_XDPSQ_STATS; j++)
1284                         sprintf(data + (idx++) * ETH_GSTRING_LEN,
1285                                 rq_xdpsq_stats_desc[j].format, i);
1286         }
1287
1288         for (tc = 0; tc < priv->max_opened_tc; tc++)
1289                 for (i = 0; i < max_nch; i++)
1290                         for (j = 0; j < NUM_SQ_STATS; j++)
1291                                 sprintf(data + (idx++) * ETH_GSTRING_LEN,
1292                                         sq_stats_desc[j].format,
1293                                         priv->channel_tc2txq[i][tc]);
1294
1295         for (i = 0; i < max_nch; i++)
1296                 for (j = 0; j < NUM_XDPSQ_STATS; j++)
1297                         sprintf(data + (idx++) * ETH_GSTRING_LEN,
1298                                 xdpsq_stats_desc[j].format, i);
1299
1300         return idx;
1301 }
1302
1303 static int mlx5e_grp_channels_fill_stats(struct mlx5e_priv *priv, u64 *data,
1304                                          int idx)
1305 {
1306         int max_nch = mlx5e_get_netdev_max_channels(priv->netdev);
1307         int i, j, tc;
1308
1309         for (i = 0; i < max_nch; i++)
1310                 for (j = 0; j < NUM_CH_STATS; j++)
1311                         data[idx++] =
1312                                 MLX5E_READ_CTR64_CPU(&priv->channel_stats[i].ch,
1313                                                      ch_stats_desc, j);
1314
1315         for (i = 0; i < max_nch; i++) {
1316                 for (j = 0; j < NUM_RQ_STATS; j++)
1317                         data[idx++] =
1318                                 MLX5E_READ_CTR64_CPU(&priv->channel_stats[i].rq,
1319                                                      rq_stats_desc, j);
1320                 for (j = 0; j < NUM_RQ_XDPSQ_STATS; j++)
1321                         data[idx++] =
1322                                 MLX5E_READ_CTR64_CPU(&priv->channel_stats[i].rq_xdpsq,
1323                                                      rq_xdpsq_stats_desc, j);
1324         }
1325
1326         for (tc = 0; tc < priv->max_opened_tc; tc++)
1327                 for (i = 0; i < max_nch; i++)
1328                         for (j = 0; j < NUM_SQ_STATS; j++)
1329                                 data[idx++] =
1330                                         MLX5E_READ_CTR64_CPU(&priv->channel_stats[i].sq[tc],
1331                                                              sq_stats_desc, j);
1332
1333         for (i = 0; i < max_nch; i++)
1334                 for (j = 0; j < NUM_XDPSQ_STATS; j++)
1335                         data[idx++] =
1336                                 MLX5E_READ_CTR64_CPU(&priv->channel_stats[i].xdpsq,
1337                                                      xdpsq_stats_desc, j);
1338
1339         return idx;
1340 }
1341
1342 /* The stats groups order is opposite to the update_stats() order calls */
1343 const struct mlx5e_stats_grp mlx5e_stats_grps[] = {
1344         {
1345                 .get_num_stats = mlx5e_grp_sw_get_num_stats,
1346                 .fill_strings = mlx5e_grp_sw_fill_strings,
1347                 .fill_stats = mlx5e_grp_sw_fill_stats,
1348                 .update_stats = mlx5e_grp_sw_update_stats,
1349         },
1350         {
1351                 .get_num_stats = mlx5e_grp_q_get_num_stats,
1352                 .fill_strings = mlx5e_grp_q_fill_strings,
1353                 .fill_stats = mlx5e_grp_q_fill_stats,
1354                 .update_stats_mask = MLX5E_NDO_UPDATE_STATS,
1355                 .update_stats = mlx5e_grp_q_update_stats,
1356         },
1357         {
1358                 .get_num_stats = mlx5e_grp_vnic_env_get_num_stats,
1359                 .fill_strings = mlx5e_grp_vnic_env_fill_strings,
1360                 .fill_stats = mlx5e_grp_vnic_env_fill_stats,
1361                 .update_stats = mlx5e_grp_vnic_env_update_stats,
1362         },
1363         {
1364                 .get_num_stats = mlx5e_grp_vport_get_num_stats,
1365                 .fill_strings = mlx5e_grp_vport_fill_strings,
1366                 .fill_stats = mlx5e_grp_vport_fill_stats,
1367                 .update_stats_mask = MLX5E_NDO_UPDATE_STATS,
1368                 .update_stats = mlx5e_grp_vport_update_stats,
1369         },
1370         {
1371                 .get_num_stats = mlx5e_grp_802_3_get_num_stats,
1372                 .fill_strings = mlx5e_grp_802_3_fill_strings,
1373                 .fill_stats = mlx5e_grp_802_3_fill_stats,
1374                 .update_stats_mask = MLX5E_NDO_UPDATE_STATS,
1375                 .update_stats = mlx5e_grp_802_3_update_stats,
1376         },
1377         {
1378                 .get_num_stats = mlx5e_grp_2863_get_num_stats,
1379                 .fill_strings = mlx5e_grp_2863_fill_strings,
1380                 .fill_stats = mlx5e_grp_2863_fill_stats,
1381                 .update_stats = mlx5e_grp_2863_update_stats,
1382         },
1383         {
1384                 .get_num_stats = mlx5e_grp_2819_get_num_stats,
1385                 .fill_strings = mlx5e_grp_2819_fill_strings,
1386                 .fill_stats = mlx5e_grp_2819_fill_stats,
1387                 .update_stats = mlx5e_grp_2819_update_stats,
1388         },
1389         {
1390                 .get_num_stats = mlx5e_grp_phy_get_num_stats,
1391                 .fill_strings = mlx5e_grp_phy_fill_strings,
1392                 .fill_stats = mlx5e_grp_phy_fill_stats,
1393                 .update_stats = mlx5e_grp_phy_update_stats,
1394         },
1395         {
1396                 .get_num_stats = mlx5e_grp_eth_ext_get_num_stats,
1397                 .fill_strings = mlx5e_grp_eth_ext_fill_strings,
1398                 .fill_stats = mlx5e_grp_eth_ext_fill_stats,
1399                 .update_stats = mlx5e_grp_eth_ext_update_stats,
1400         },
1401         {
1402                 .get_num_stats = mlx5e_grp_pcie_get_num_stats,
1403                 .fill_strings = mlx5e_grp_pcie_fill_strings,
1404                 .fill_stats = mlx5e_grp_pcie_fill_stats,
1405                 .update_stats = mlx5e_grp_pcie_update_stats,
1406         },
1407         {
1408                 .get_num_stats = mlx5e_grp_per_prio_get_num_stats,
1409                 .fill_strings = mlx5e_grp_per_prio_fill_strings,
1410                 .fill_stats = mlx5e_grp_per_prio_fill_stats,
1411                 .update_stats = mlx5e_grp_per_prio_update_stats,
1412         },
1413         {
1414                 .get_num_stats = mlx5e_grp_pme_get_num_stats,
1415                 .fill_strings = mlx5e_grp_pme_fill_strings,
1416                 .fill_stats = mlx5e_grp_pme_fill_stats,
1417         },
1418         {
1419                 .get_num_stats = mlx5e_grp_ipsec_get_num_stats,
1420                 .fill_strings = mlx5e_grp_ipsec_fill_strings,
1421                 .fill_stats = mlx5e_grp_ipsec_fill_stats,
1422                 .update_stats = mlx5e_grp_ipsec_update_stats,
1423         },
1424         {
1425                 .get_num_stats = mlx5e_grp_tls_get_num_stats,
1426                 .fill_strings = mlx5e_grp_tls_fill_strings,
1427                 .fill_stats = mlx5e_grp_tls_fill_stats,
1428         },
1429         {
1430                 .get_num_stats = mlx5e_grp_channels_get_num_stats,
1431                 .fill_strings = mlx5e_grp_channels_fill_strings,
1432                 .fill_stats = mlx5e_grp_channels_fill_stats,
1433         }
1434 };
1435
1436 const int mlx5e_num_stats_grps = ARRAY_SIZE(mlx5e_stats_grps);