drm/msm: fix memleak on release
[sfrench/cifs-2.6.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 "lib/mlx5.h"
34 #include "en.h"
35 #include "en_accel/ipsec.h"
36 #include "en_accel/tls.h"
37
38 static const struct counter_desc sw_stats_desc[] = {
39         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_packets) },
40         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_bytes) },
41         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_packets) },
42         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_bytes) },
43         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tso_packets) },
44         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tso_bytes) },
45         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tso_inner_packets) },
46         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tso_inner_bytes) },
47         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_added_vlan_packets) },
48         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_nop) },
49
50 #ifdef CONFIG_MLX5_EN_TLS
51         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_encrypted_packets) },
52         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_encrypted_bytes) },
53         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_ctx) },
54         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_ooo) },
55         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_resync_bytes) },
56         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_drop_no_sync_data) },
57         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_drop_bypass_req) },
58         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_dump_packets) },
59         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_tls_dump_bytes) },
60 #endif
61
62         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_lro_packets) },
63         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_lro_bytes) },
64         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_ecn_mark) },
65         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_removed_vlan_packets) },
66         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_csum_unnecessary) },
67         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_csum_none) },
68         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_csum_complete) },
69         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_csum_complete_tail) },
70         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_csum_complete_tail_slow) },
71         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_csum_unnecessary_inner) },
72         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_drop) },
73         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_redirect) },
74         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_tx_xmit) },
75         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_tx_mpwqe) },
76         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_tx_inlnw) },
77         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_tx_nops) },
78         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_tx_full) },
79         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_tx_err) },
80         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_tx_cqe) },
81         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_csum_none) },
82         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_csum_partial) },
83         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_csum_partial_inner) },
84         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_queue_stopped) },
85         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_queue_dropped) },
86         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xmit_more) },
87         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_recover) },
88         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_cqes) },
89         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_queue_wake) },
90         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_cqe_err) },
91         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xdp_xmit) },
92         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xdp_mpwqe) },
93         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xdp_inlnw) },
94         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xdp_nops) },
95         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xdp_full) },
96         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xdp_err) },
97         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xdp_cqes) },
98         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_wqe_err) },
99         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_mpwqe_filler_cqes) },
100         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_mpwqe_filler_strides) },
101         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_oversize_pkts_sw_drop) },
102         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_buff_alloc_err) },
103         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cqe_compress_blks) },
104         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cqe_compress_pkts) },
105         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cache_reuse) },
106         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cache_full) },
107         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cache_empty) },
108         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cache_busy) },
109         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_cache_waive) },
110         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_congst_umr) },
111         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_arfs_err) },
112         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_recover) },
113         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, ch_events) },
114         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, ch_poll) },
115         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, ch_arm) },
116         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, ch_aff_change) },
117         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, ch_force_irq) },
118         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, ch_eq_rearm) },
119         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xsk_packets) },
120         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xsk_bytes) },
121         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xsk_csum_complete) },
122         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xsk_csum_unnecessary) },
123         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xsk_csum_unnecessary_inner) },
124         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xsk_csum_none) },
125         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xsk_ecn_mark) },
126         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xsk_removed_vlan_packets) },
127         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xsk_xdp_drop) },
128         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xsk_xdp_redirect) },
129         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xsk_wqe_err) },
130         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xsk_mpwqe_filler_cqes) },
131         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xsk_mpwqe_filler_strides) },
132         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xsk_oversize_pkts_sw_drop) },
133         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xsk_buff_alloc_err) },
134         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xsk_cqe_compress_blks) },
135         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xsk_cqe_compress_pkts) },
136         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xsk_congst_umr) },
137         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xsk_arfs_err) },
138         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xsk_xmit) },
139         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xsk_mpwqe) },
140         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xsk_inlnw) },
141         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xsk_full) },
142         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xsk_err) },
143         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_xsk_cqes) },
144 };
145
146 #define NUM_SW_COUNTERS                 ARRAY_SIZE(sw_stats_desc)
147
148 static int mlx5e_grp_sw_get_num_stats(struct mlx5e_priv *priv)
149 {
150         return NUM_SW_COUNTERS;
151 }
152
153 static int mlx5e_grp_sw_fill_strings(struct mlx5e_priv *priv, u8 *data, int idx)
154 {
155         int i;
156
157         for (i = 0; i < NUM_SW_COUNTERS; i++)
158                 strcpy(data + (idx++) * ETH_GSTRING_LEN, sw_stats_desc[i].format);
159         return idx;
160 }
161
162 static int mlx5e_grp_sw_fill_stats(struct mlx5e_priv *priv, u64 *data, int idx)
163 {
164         int i;
165
166         for (i = 0; i < NUM_SW_COUNTERS; i++)
167                 data[idx++] = MLX5E_READ_CTR64_CPU(&priv->stats.sw, sw_stats_desc, i);
168         return idx;
169 }
170
171 static void mlx5e_grp_sw_update_stats(struct mlx5e_priv *priv)
172 {
173         struct mlx5e_sw_stats *s = &priv->stats.sw;
174         int i;
175
176         memset(s, 0, sizeof(*s));
177
178         for (i = 0; i < priv->max_nch; i++) {
179                 struct mlx5e_channel_stats *channel_stats =
180                         &priv->channel_stats[i];
181                 struct mlx5e_xdpsq_stats *xdpsq_red_stats = &channel_stats->xdpsq;
182                 struct mlx5e_xdpsq_stats *xdpsq_stats = &channel_stats->rq_xdpsq;
183                 struct mlx5e_xdpsq_stats *xsksq_stats = &channel_stats->xsksq;
184                 struct mlx5e_rq_stats *xskrq_stats = &channel_stats->xskrq;
185                 struct mlx5e_rq_stats *rq_stats = &channel_stats->rq;
186                 struct mlx5e_ch_stats *ch_stats = &channel_stats->ch;
187                 int j;
188
189                 s->rx_packets   += rq_stats->packets;
190                 s->rx_bytes     += rq_stats->bytes;
191                 s->rx_lro_packets += rq_stats->lro_packets;
192                 s->rx_lro_bytes += rq_stats->lro_bytes;
193                 s->rx_ecn_mark  += rq_stats->ecn_mark;
194                 s->rx_removed_vlan_packets += rq_stats->removed_vlan_packets;
195                 s->rx_csum_none += rq_stats->csum_none;
196                 s->rx_csum_complete += rq_stats->csum_complete;
197                 s->rx_csum_complete_tail += rq_stats->csum_complete_tail;
198                 s->rx_csum_complete_tail_slow += rq_stats->csum_complete_tail_slow;
199                 s->rx_csum_unnecessary += rq_stats->csum_unnecessary;
200                 s->rx_csum_unnecessary_inner += rq_stats->csum_unnecessary_inner;
201                 s->rx_xdp_drop     += rq_stats->xdp_drop;
202                 s->rx_xdp_redirect += rq_stats->xdp_redirect;
203                 s->rx_xdp_tx_xmit  += xdpsq_stats->xmit;
204                 s->rx_xdp_tx_mpwqe += xdpsq_stats->mpwqe;
205                 s->rx_xdp_tx_inlnw += xdpsq_stats->inlnw;
206                 s->rx_xdp_tx_nops  += xdpsq_stats->nops;
207                 s->rx_xdp_tx_full  += xdpsq_stats->full;
208                 s->rx_xdp_tx_err   += xdpsq_stats->err;
209                 s->rx_xdp_tx_cqe   += xdpsq_stats->cqes;
210                 s->rx_wqe_err   += rq_stats->wqe_err;
211                 s->rx_mpwqe_filler_cqes    += rq_stats->mpwqe_filler_cqes;
212                 s->rx_mpwqe_filler_strides += rq_stats->mpwqe_filler_strides;
213                 s->rx_oversize_pkts_sw_drop += rq_stats->oversize_pkts_sw_drop;
214                 s->rx_buff_alloc_err += rq_stats->buff_alloc_err;
215                 s->rx_cqe_compress_blks += rq_stats->cqe_compress_blks;
216                 s->rx_cqe_compress_pkts += rq_stats->cqe_compress_pkts;
217                 s->rx_cache_reuse += rq_stats->cache_reuse;
218                 s->rx_cache_full  += rq_stats->cache_full;
219                 s->rx_cache_empty += rq_stats->cache_empty;
220                 s->rx_cache_busy  += rq_stats->cache_busy;
221                 s->rx_cache_waive += rq_stats->cache_waive;
222                 s->rx_congst_umr  += rq_stats->congst_umr;
223                 s->rx_arfs_err    += rq_stats->arfs_err;
224                 s->rx_recover     += rq_stats->recover;
225                 s->ch_events      += ch_stats->events;
226                 s->ch_poll        += ch_stats->poll;
227                 s->ch_arm         += ch_stats->arm;
228                 s->ch_aff_change  += ch_stats->aff_change;
229                 s->ch_force_irq   += ch_stats->force_irq;
230                 s->ch_eq_rearm    += ch_stats->eq_rearm;
231                 /* xdp redirect */
232                 s->tx_xdp_xmit    += xdpsq_red_stats->xmit;
233                 s->tx_xdp_mpwqe   += xdpsq_red_stats->mpwqe;
234                 s->tx_xdp_inlnw   += xdpsq_red_stats->inlnw;
235                 s->tx_xdp_nops    += xdpsq_red_stats->nops;
236                 s->tx_xdp_full    += xdpsq_red_stats->full;
237                 s->tx_xdp_err     += xdpsq_red_stats->err;
238                 s->tx_xdp_cqes    += xdpsq_red_stats->cqes;
239                 /* AF_XDP zero-copy */
240                 s->rx_xsk_packets                += xskrq_stats->packets;
241                 s->rx_xsk_bytes                  += xskrq_stats->bytes;
242                 s->rx_xsk_csum_complete          += xskrq_stats->csum_complete;
243                 s->rx_xsk_csum_unnecessary       += xskrq_stats->csum_unnecessary;
244                 s->rx_xsk_csum_unnecessary_inner += xskrq_stats->csum_unnecessary_inner;
245                 s->rx_xsk_csum_none              += xskrq_stats->csum_none;
246                 s->rx_xsk_ecn_mark               += xskrq_stats->ecn_mark;
247                 s->rx_xsk_removed_vlan_packets   += xskrq_stats->removed_vlan_packets;
248                 s->rx_xsk_xdp_drop               += xskrq_stats->xdp_drop;
249                 s->rx_xsk_xdp_redirect           += xskrq_stats->xdp_redirect;
250                 s->rx_xsk_wqe_err                += xskrq_stats->wqe_err;
251                 s->rx_xsk_mpwqe_filler_cqes      += xskrq_stats->mpwqe_filler_cqes;
252                 s->rx_xsk_mpwqe_filler_strides   += xskrq_stats->mpwqe_filler_strides;
253                 s->rx_xsk_oversize_pkts_sw_drop  += xskrq_stats->oversize_pkts_sw_drop;
254                 s->rx_xsk_buff_alloc_err         += xskrq_stats->buff_alloc_err;
255                 s->rx_xsk_cqe_compress_blks      += xskrq_stats->cqe_compress_blks;
256                 s->rx_xsk_cqe_compress_pkts      += xskrq_stats->cqe_compress_pkts;
257                 s->rx_xsk_congst_umr             += xskrq_stats->congst_umr;
258                 s->rx_xsk_arfs_err               += xskrq_stats->arfs_err;
259                 s->tx_xsk_xmit                   += xsksq_stats->xmit;
260                 s->tx_xsk_mpwqe                  += xsksq_stats->mpwqe;
261                 s->tx_xsk_inlnw                  += xsksq_stats->inlnw;
262                 s->tx_xsk_full                   += xsksq_stats->full;
263                 s->tx_xsk_err                    += xsksq_stats->err;
264                 s->tx_xsk_cqes                   += xsksq_stats->cqes;
265
266                 for (j = 0; j < priv->max_opened_tc; j++) {
267                         struct mlx5e_sq_stats *sq_stats = &channel_stats->sq[j];
268
269                         s->tx_packets           += sq_stats->packets;
270                         s->tx_bytes             += sq_stats->bytes;
271                         s->tx_tso_packets       += sq_stats->tso_packets;
272                         s->tx_tso_bytes         += sq_stats->tso_bytes;
273                         s->tx_tso_inner_packets += sq_stats->tso_inner_packets;
274                         s->tx_tso_inner_bytes   += sq_stats->tso_inner_bytes;
275                         s->tx_added_vlan_packets += sq_stats->added_vlan_packets;
276                         s->tx_nop               += sq_stats->nop;
277                         s->tx_queue_stopped     += sq_stats->stopped;
278                         s->tx_queue_wake        += sq_stats->wake;
279                         s->tx_queue_dropped     += sq_stats->dropped;
280                         s->tx_cqe_err           += sq_stats->cqe_err;
281                         s->tx_recover           += sq_stats->recover;
282                         s->tx_xmit_more         += sq_stats->xmit_more;
283                         s->tx_csum_partial_inner += sq_stats->csum_partial_inner;
284                         s->tx_csum_none         += sq_stats->csum_none;
285                         s->tx_csum_partial      += sq_stats->csum_partial;
286 #ifdef CONFIG_MLX5_EN_TLS
287                         s->tx_tls_encrypted_packets += sq_stats->tls_encrypted_packets;
288                         s->tx_tls_encrypted_bytes   += sq_stats->tls_encrypted_bytes;
289                         s->tx_tls_ctx               += sq_stats->tls_ctx;
290                         s->tx_tls_ooo               += sq_stats->tls_ooo;
291                         s->tx_tls_resync_bytes      += sq_stats->tls_resync_bytes;
292                         s->tx_tls_drop_no_sync_data += sq_stats->tls_drop_no_sync_data;
293                         s->tx_tls_drop_bypass_req   += sq_stats->tls_drop_bypass_req;
294                         s->tx_tls_dump_bytes        += sq_stats->tls_dump_bytes;
295                         s->tx_tls_dump_packets      += sq_stats->tls_dump_packets;
296 #endif
297                         s->tx_cqes              += sq_stats->cqes;
298                 }
299         }
300 }
301
302 static const struct counter_desc q_stats_desc[] = {
303         { MLX5E_DECLARE_STAT(struct mlx5e_qcounter_stats, rx_out_of_buffer) },
304 };
305
306 static const struct counter_desc drop_rq_stats_desc[] = {
307         { MLX5E_DECLARE_STAT(struct mlx5e_qcounter_stats, rx_if_down_packets) },
308 };
309
310 #define NUM_Q_COUNTERS                  ARRAY_SIZE(q_stats_desc)
311 #define NUM_DROP_RQ_COUNTERS            ARRAY_SIZE(drop_rq_stats_desc)
312
313 static int mlx5e_grp_q_get_num_stats(struct mlx5e_priv *priv)
314 {
315         int num_stats = 0;
316
317         if (priv->q_counter)
318                 num_stats += NUM_Q_COUNTERS;
319
320         if (priv->drop_rq_q_counter)
321                 num_stats += NUM_DROP_RQ_COUNTERS;
322
323         return num_stats;
324 }
325
326 static int mlx5e_grp_q_fill_strings(struct mlx5e_priv *priv, u8 *data, int idx)
327 {
328         int i;
329
330         for (i = 0; i < NUM_Q_COUNTERS && priv->q_counter; i++)
331                 strcpy(data + (idx++) * ETH_GSTRING_LEN,
332                        q_stats_desc[i].format);
333
334         for (i = 0; i < NUM_DROP_RQ_COUNTERS && priv->drop_rq_q_counter; i++)
335                 strcpy(data + (idx++) * ETH_GSTRING_LEN,
336                        drop_rq_stats_desc[i].format);
337
338         return idx;
339 }
340
341 static int mlx5e_grp_q_fill_stats(struct mlx5e_priv *priv, u64 *data, int idx)
342 {
343         int i;
344
345         for (i = 0; i < NUM_Q_COUNTERS && priv->q_counter; i++)
346                 data[idx++] = MLX5E_READ_CTR32_CPU(&priv->stats.qcnt,
347                                                    q_stats_desc, i);
348         for (i = 0; i < NUM_DROP_RQ_COUNTERS && priv->drop_rq_q_counter; i++)
349                 data[idx++] = MLX5E_READ_CTR32_CPU(&priv->stats.qcnt,
350                                                    drop_rq_stats_desc, i);
351         return idx;
352 }
353
354 static void mlx5e_grp_q_update_stats(struct mlx5e_priv *priv)
355 {
356         struct mlx5e_qcounter_stats *qcnt = &priv->stats.qcnt;
357         u32 out[MLX5_ST_SZ_DW(query_q_counter_out)];
358
359         if (priv->q_counter &&
360             !mlx5_core_query_q_counter(priv->mdev, priv->q_counter, 0, out,
361                                        sizeof(out)))
362                 qcnt->rx_out_of_buffer = MLX5_GET(query_q_counter_out,
363                                                   out, out_of_buffer);
364         if (priv->drop_rq_q_counter &&
365             !mlx5_core_query_q_counter(priv->mdev, priv->drop_rq_q_counter, 0,
366                                        out, sizeof(out)))
367                 qcnt->rx_if_down_packets = MLX5_GET(query_q_counter_out, out,
368                                                     out_of_buffer);
369 }
370
371 #define VNIC_ENV_OFF(c) MLX5_BYTE_OFF(query_vnic_env_out, c)
372 static const struct counter_desc vnic_env_stats_steer_desc[] = {
373         { "rx_steer_missed_packets",
374                 VNIC_ENV_OFF(vport_env.nic_receive_steering_discard) },
375 };
376
377 static const struct counter_desc vnic_env_stats_dev_oob_desc[] = {
378         { "dev_internal_queue_oob",
379                 VNIC_ENV_OFF(vport_env.internal_rq_out_of_buffer) },
380 };
381
382 #define NUM_VNIC_ENV_STEER_COUNTERS(dev) \
383         (MLX5_CAP_GEN(dev, nic_receive_steering_discard) ? \
384          ARRAY_SIZE(vnic_env_stats_steer_desc) : 0)
385 #define NUM_VNIC_ENV_DEV_OOB_COUNTERS(dev) \
386         (MLX5_CAP_GEN(dev, vnic_env_int_rq_oob) ? \
387          ARRAY_SIZE(vnic_env_stats_dev_oob_desc) : 0)
388
389 static int mlx5e_grp_vnic_env_get_num_stats(struct mlx5e_priv *priv)
390 {
391         return NUM_VNIC_ENV_STEER_COUNTERS(priv->mdev) +
392                 NUM_VNIC_ENV_DEV_OOB_COUNTERS(priv->mdev);
393 }
394
395 static int mlx5e_grp_vnic_env_fill_strings(struct mlx5e_priv *priv, u8 *data,
396                                            int idx)
397 {
398         int i;
399
400         for (i = 0; i < NUM_VNIC_ENV_STEER_COUNTERS(priv->mdev); i++)
401                 strcpy(data + (idx++) * ETH_GSTRING_LEN,
402                        vnic_env_stats_steer_desc[i].format);
403
404         for (i = 0; i < NUM_VNIC_ENV_DEV_OOB_COUNTERS(priv->mdev); i++)
405                 strcpy(data + (idx++) * ETH_GSTRING_LEN,
406                        vnic_env_stats_dev_oob_desc[i].format);
407         return idx;
408 }
409
410 static int mlx5e_grp_vnic_env_fill_stats(struct mlx5e_priv *priv, u64 *data,
411                                          int idx)
412 {
413         int i;
414
415         for (i = 0; i < NUM_VNIC_ENV_STEER_COUNTERS(priv->mdev); i++)
416                 data[idx++] = MLX5E_READ_CTR64_BE(priv->stats.vnic.query_vnic_env_out,
417                                                   vnic_env_stats_steer_desc, i);
418
419         for (i = 0; i < NUM_VNIC_ENV_DEV_OOB_COUNTERS(priv->mdev); i++)
420                 data[idx++] = MLX5E_READ_CTR32_BE(priv->stats.vnic.query_vnic_env_out,
421                                                   vnic_env_stats_dev_oob_desc, i);
422         return idx;
423 }
424
425 static void mlx5e_grp_vnic_env_update_stats(struct mlx5e_priv *priv)
426 {
427         u32 *out = (u32 *)priv->stats.vnic.query_vnic_env_out;
428         int outlen = MLX5_ST_SZ_BYTES(query_vnic_env_out);
429         u32 in[MLX5_ST_SZ_DW(query_vnic_env_in)] = {0};
430         struct mlx5_core_dev *mdev = priv->mdev;
431
432         if (!MLX5_CAP_GEN(priv->mdev, nic_receive_steering_discard))
433                 return;
434
435         MLX5_SET(query_vnic_env_in, in, opcode,
436                  MLX5_CMD_OP_QUERY_VNIC_ENV);
437         MLX5_SET(query_vnic_env_in, in, op_mod, 0);
438         MLX5_SET(query_vnic_env_in, in, other_vport, 0);
439         mlx5_cmd_exec(mdev, in, sizeof(in), out, outlen);
440 }
441
442 #define VPORT_COUNTER_OFF(c) MLX5_BYTE_OFF(query_vport_counter_out, c)
443 static const struct counter_desc vport_stats_desc[] = {
444         { "rx_vport_unicast_packets",
445                 VPORT_COUNTER_OFF(received_eth_unicast.packets) },
446         { "rx_vport_unicast_bytes",
447                 VPORT_COUNTER_OFF(received_eth_unicast.octets) },
448         { "tx_vport_unicast_packets",
449                 VPORT_COUNTER_OFF(transmitted_eth_unicast.packets) },
450         { "tx_vport_unicast_bytes",
451                 VPORT_COUNTER_OFF(transmitted_eth_unicast.octets) },
452         { "rx_vport_multicast_packets",
453                 VPORT_COUNTER_OFF(received_eth_multicast.packets) },
454         { "rx_vport_multicast_bytes",
455                 VPORT_COUNTER_OFF(received_eth_multicast.octets) },
456         { "tx_vport_multicast_packets",
457                 VPORT_COUNTER_OFF(transmitted_eth_multicast.packets) },
458         { "tx_vport_multicast_bytes",
459                 VPORT_COUNTER_OFF(transmitted_eth_multicast.octets) },
460         { "rx_vport_broadcast_packets",
461                 VPORT_COUNTER_OFF(received_eth_broadcast.packets) },
462         { "rx_vport_broadcast_bytes",
463                 VPORT_COUNTER_OFF(received_eth_broadcast.octets) },
464         { "tx_vport_broadcast_packets",
465                 VPORT_COUNTER_OFF(transmitted_eth_broadcast.packets) },
466         { "tx_vport_broadcast_bytes",
467                 VPORT_COUNTER_OFF(transmitted_eth_broadcast.octets) },
468         { "rx_vport_rdma_unicast_packets",
469                 VPORT_COUNTER_OFF(received_ib_unicast.packets) },
470         { "rx_vport_rdma_unicast_bytes",
471                 VPORT_COUNTER_OFF(received_ib_unicast.octets) },
472         { "tx_vport_rdma_unicast_packets",
473                 VPORT_COUNTER_OFF(transmitted_ib_unicast.packets) },
474         { "tx_vport_rdma_unicast_bytes",
475                 VPORT_COUNTER_OFF(transmitted_ib_unicast.octets) },
476         { "rx_vport_rdma_multicast_packets",
477                 VPORT_COUNTER_OFF(received_ib_multicast.packets) },
478         { "rx_vport_rdma_multicast_bytes",
479                 VPORT_COUNTER_OFF(received_ib_multicast.octets) },
480         { "tx_vport_rdma_multicast_packets",
481                 VPORT_COUNTER_OFF(transmitted_ib_multicast.packets) },
482         { "tx_vport_rdma_multicast_bytes",
483                 VPORT_COUNTER_OFF(transmitted_ib_multicast.octets) },
484 };
485
486 #define NUM_VPORT_COUNTERS              ARRAY_SIZE(vport_stats_desc)
487
488 static int mlx5e_grp_vport_get_num_stats(struct mlx5e_priv *priv)
489 {
490         return NUM_VPORT_COUNTERS;
491 }
492
493 static int mlx5e_grp_vport_fill_strings(struct mlx5e_priv *priv, u8 *data,
494                                         int idx)
495 {
496         int i;
497
498         for (i = 0; i < NUM_VPORT_COUNTERS; i++)
499                 strcpy(data + (idx++) * ETH_GSTRING_LEN, vport_stats_desc[i].format);
500         return idx;
501 }
502
503 static int mlx5e_grp_vport_fill_stats(struct mlx5e_priv *priv, u64 *data,
504                                       int idx)
505 {
506         int i;
507
508         for (i = 0; i < NUM_VPORT_COUNTERS; i++)
509                 data[idx++] = MLX5E_READ_CTR64_BE(priv->stats.vport.query_vport_out,
510                                                   vport_stats_desc, i);
511         return idx;
512 }
513
514 static void mlx5e_grp_vport_update_stats(struct mlx5e_priv *priv)
515 {
516         int outlen = MLX5_ST_SZ_BYTES(query_vport_counter_out);
517         u32 *out = (u32 *)priv->stats.vport.query_vport_out;
518         u32 in[MLX5_ST_SZ_DW(query_vport_counter_in)] = {0};
519         struct mlx5_core_dev *mdev = priv->mdev;
520
521         MLX5_SET(query_vport_counter_in, in, opcode, MLX5_CMD_OP_QUERY_VPORT_COUNTER);
522         MLX5_SET(query_vport_counter_in, in, op_mod, 0);
523         MLX5_SET(query_vport_counter_in, in, other_vport, 0);
524         mlx5_cmd_exec(mdev, in, sizeof(in), out, outlen);
525 }
526
527 #define PPORT_802_3_OFF(c) \
528         MLX5_BYTE_OFF(ppcnt_reg, \
529                       counter_set.eth_802_3_cntrs_grp_data_layout.c##_high)
530 static const struct counter_desc pport_802_3_stats_desc[] = {
531         { "tx_packets_phy", PPORT_802_3_OFF(a_frames_transmitted_ok) },
532         { "rx_packets_phy", PPORT_802_3_OFF(a_frames_received_ok) },
533         { "rx_crc_errors_phy", PPORT_802_3_OFF(a_frame_check_sequence_errors) },
534         { "tx_bytes_phy", PPORT_802_3_OFF(a_octets_transmitted_ok) },
535         { "rx_bytes_phy", PPORT_802_3_OFF(a_octets_received_ok) },
536         { "tx_multicast_phy", PPORT_802_3_OFF(a_multicast_frames_xmitted_ok) },
537         { "tx_broadcast_phy", PPORT_802_3_OFF(a_broadcast_frames_xmitted_ok) },
538         { "rx_multicast_phy", PPORT_802_3_OFF(a_multicast_frames_received_ok) },
539         { "rx_broadcast_phy", PPORT_802_3_OFF(a_broadcast_frames_received_ok) },
540         { "rx_in_range_len_errors_phy", PPORT_802_3_OFF(a_in_range_length_errors) },
541         { "rx_out_of_range_len_phy", PPORT_802_3_OFF(a_out_of_range_length_field) },
542         { "rx_oversize_pkts_phy", PPORT_802_3_OFF(a_frame_too_long_errors) },
543         { "rx_symbol_err_phy", PPORT_802_3_OFF(a_symbol_error_during_carrier) },
544         { "tx_mac_control_phy", PPORT_802_3_OFF(a_mac_control_frames_transmitted) },
545         { "rx_mac_control_phy", PPORT_802_3_OFF(a_mac_control_frames_received) },
546         { "rx_unsupported_op_phy", PPORT_802_3_OFF(a_unsupported_opcodes_received) },
547         { "rx_pause_ctrl_phy", PPORT_802_3_OFF(a_pause_mac_ctrl_frames_received) },
548         { "tx_pause_ctrl_phy", PPORT_802_3_OFF(a_pause_mac_ctrl_frames_transmitted) },
549 };
550
551 #define NUM_PPORT_802_3_COUNTERS        ARRAY_SIZE(pport_802_3_stats_desc)
552
553 static int mlx5e_grp_802_3_get_num_stats(struct mlx5e_priv *priv)
554 {
555         return NUM_PPORT_802_3_COUNTERS;
556 }
557
558 static int mlx5e_grp_802_3_fill_strings(struct mlx5e_priv *priv, u8 *data,
559                                         int idx)
560 {
561         int i;
562
563         for (i = 0; i < NUM_PPORT_802_3_COUNTERS; i++)
564                 strcpy(data + (idx++) * ETH_GSTRING_LEN, pport_802_3_stats_desc[i].format);
565         return idx;
566 }
567
568 static int mlx5e_grp_802_3_fill_stats(struct mlx5e_priv *priv, u64 *data,
569                                       int idx)
570 {
571         int i;
572
573         for (i = 0; i < NUM_PPORT_802_3_COUNTERS; i++)
574                 data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.IEEE_802_3_counters,
575                                                   pport_802_3_stats_desc, i);
576         return idx;
577 }
578
579 #define MLX5_BASIC_PPCNT_SUPPORTED(mdev) \
580         (MLX5_CAP_GEN(mdev, pcam_reg) ? MLX5_CAP_PCAM_REG(mdev, ppcnt) : 1)
581
582 void mlx5e_grp_802_3_update_stats(struct mlx5e_priv *priv)
583 {
584         struct mlx5e_pport_stats *pstats = &priv->stats.pport;
585         struct mlx5_core_dev *mdev = priv->mdev;
586         u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {0};
587         int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
588         void *out;
589
590         if (!MLX5_BASIC_PPCNT_SUPPORTED(mdev))
591                 return;
592
593         MLX5_SET(ppcnt_reg, in, local_port, 1);
594         out = pstats->IEEE_802_3_counters;
595         MLX5_SET(ppcnt_reg, in, grp, MLX5_IEEE_802_3_COUNTERS_GROUP);
596         mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
597 }
598
599 #define PPORT_2863_OFF(c) \
600         MLX5_BYTE_OFF(ppcnt_reg, \
601                       counter_set.eth_2863_cntrs_grp_data_layout.c##_high)
602 static const struct counter_desc pport_2863_stats_desc[] = {
603         { "rx_discards_phy", PPORT_2863_OFF(if_in_discards) },
604         { "tx_discards_phy", PPORT_2863_OFF(if_out_discards) },
605         { "tx_errors_phy", PPORT_2863_OFF(if_out_errors) },
606 };
607
608 #define NUM_PPORT_2863_COUNTERS         ARRAY_SIZE(pport_2863_stats_desc)
609
610 static int mlx5e_grp_2863_get_num_stats(struct mlx5e_priv *priv)
611 {
612         return NUM_PPORT_2863_COUNTERS;
613 }
614
615 static int mlx5e_grp_2863_fill_strings(struct mlx5e_priv *priv, u8 *data,
616                                        int idx)
617 {
618         int i;
619
620         for (i = 0; i < NUM_PPORT_2863_COUNTERS; i++)
621                 strcpy(data + (idx++) * ETH_GSTRING_LEN, pport_2863_stats_desc[i].format);
622         return idx;
623 }
624
625 static int mlx5e_grp_2863_fill_stats(struct mlx5e_priv *priv, u64 *data,
626                                      int idx)
627 {
628         int i;
629
630         for (i = 0; i < NUM_PPORT_2863_COUNTERS; i++)
631                 data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.RFC_2863_counters,
632                                                   pport_2863_stats_desc, i);
633         return idx;
634 }
635
636 static void mlx5e_grp_2863_update_stats(struct mlx5e_priv *priv)
637 {
638         struct mlx5e_pport_stats *pstats = &priv->stats.pport;
639         struct mlx5_core_dev *mdev = priv->mdev;
640         u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {0};
641         int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
642         void *out;
643
644         MLX5_SET(ppcnt_reg, in, local_port, 1);
645         out = pstats->RFC_2863_counters;
646         MLX5_SET(ppcnt_reg, in, grp, MLX5_RFC_2863_COUNTERS_GROUP);
647         mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
648 }
649
650 #define PPORT_2819_OFF(c) \
651         MLX5_BYTE_OFF(ppcnt_reg, \
652                       counter_set.eth_2819_cntrs_grp_data_layout.c##_high)
653 static const struct counter_desc pport_2819_stats_desc[] = {
654         { "rx_undersize_pkts_phy", PPORT_2819_OFF(ether_stats_undersize_pkts) },
655         { "rx_fragments_phy", PPORT_2819_OFF(ether_stats_fragments) },
656         { "rx_jabbers_phy", PPORT_2819_OFF(ether_stats_jabbers) },
657         { "rx_64_bytes_phy", PPORT_2819_OFF(ether_stats_pkts64octets) },
658         { "rx_65_to_127_bytes_phy", PPORT_2819_OFF(ether_stats_pkts65to127octets) },
659         { "rx_128_to_255_bytes_phy", PPORT_2819_OFF(ether_stats_pkts128to255octets) },
660         { "rx_256_to_511_bytes_phy", PPORT_2819_OFF(ether_stats_pkts256to511octets) },
661         { "rx_512_to_1023_bytes_phy", PPORT_2819_OFF(ether_stats_pkts512to1023octets) },
662         { "rx_1024_to_1518_bytes_phy", PPORT_2819_OFF(ether_stats_pkts1024to1518octets) },
663         { "rx_1519_to_2047_bytes_phy", PPORT_2819_OFF(ether_stats_pkts1519to2047octets) },
664         { "rx_2048_to_4095_bytes_phy", PPORT_2819_OFF(ether_stats_pkts2048to4095octets) },
665         { "rx_4096_to_8191_bytes_phy", PPORT_2819_OFF(ether_stats_pkts4096to8191octets) },
666         { "rx_8192_to_10239_bytes_phy", PPORT_2819_OFF(ether_stats_pkts8192to10239octets) },
667 };
668
669 #define NUM_PPORT_2819_COUNTERS         ARRAY_SIZE(pport_2819_stats_desc)
670
671 static int mlx5e_grp_2819_get_num_stats(struct mlx5e_priv *priv)
672 {
673         return NUM_PPORT_2819_COUNTERS;
674 }
675
676 static int mlx5e_grp_2819_fill_strings(struct mlx5e_priv *priv, u8 *data,
677                                        int idx)
678 {
679         int i;
680
681         for (i = 0; i < NUM_PPORT_2819_COUNTERS; i++)
682                 strcpy(data + (idx++) * ETH_GSTRING_LEN, pport_2819_stats_desc[i].format);
683         return idx;
684 }
685
686 static int mlx5e_grp_2819_fill_stats(struct mlx5e_priv *priv, u64 *data,
687                                      int idx)
688 {
689         int i;
690
691         for (i = 0; i < NUM_PPORT_2819_COUNTERS; i++)
692                 data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.RFC_2819_counters,
693                                                   pport_2819_stats_desc, i);
694         return idx;
695 }
696
697 static void mlx5e_grp_2819_update_stats(struct mlx5e_priv *priv)
698 {
699         struct mlx5e_pport_stats *pstats = &priv->stats.pport;
700         struct mlx5_core_dev *mdev = priv->mdev;
701         u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {0};
702         int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
703         void *out;
704
705         if (!MLX5_BASIC_PPCNT_SUPPORTED(mdev))
706                 return;
707
708         MLX5_SET(ppcnt_reg, in, local_port, 1);
709         out = pstats->RFC_2819_counters;
710         MLX5_SET(ppcnt_reg, in, grp, MLX5_RFC_2819_COUNTERS_GROUP);
711         mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
712 }
713
714 #define PPORT_PHY_STATISTICAL_OFF(c) \
715         MLX5_BYTE_OFF(ppcnt_reg, \
716                       counter_set.phys_layer_statistical_cntrs.c##_high)
717 static const struct counter_desc pport_phy_statistical_stats_desc[] = {
718         { "rx_pcs_symbol_err_phy", PPORT_PHY_STATISTICAL_OFF(phy_symbol_errors) },
719         { "rx_corrected_bits_phy", PPORT_PHY_STATISTICAL_OFF(phy_corrected_bits) },
720 };
721
722 static const struct counter_desc
723 pport_phy_statistical_err_lanes_stats_desc[] = {
724         { "rx_err_lane_0_phy", PPORT_PHY_STATISTICAL_OFF(phy_corrected_bits_lane0) },
725         { "rx_err_lane_1_phy", PPORT_PHY_STATISTICAL_OFF(phy_corrected_bits_lane1) },
726         { "rx_err_lane_2_phy", PPORT_PHY_STATISTICAL_OFF(phy_corrected_bits_lane2) },
727         { "rx_err_lane_3_phy", PPORT_PHY_STATISTICAL_OFF(phy_corrected_bits_lane3) },
728 };
729
730 #define NUM_PPORT_PHY_STATISTICAL_COUNTERS \
731         ARRAY_SIZE(pport_phy_statistical_stats_desc)
732 #define NUM_PPORT_PHY_STATISTICAL_PER_LANE_COUNTERS \
733         ARRAY_SIZE(pport_phy_statistical_err_lanes_stats_desc)
734
735 static int mlx5e_grp_phy_get_num_stats(struct mlx5e_priv *priv)
736 {
737         struct mlx5_core_dev *mdev = priv->mdev;
738         int num_stats;
739
740         /* "1" for link_down_events special counter */
741         num_stats = 1;
742
743         num_stats += MLX5_CAP_PCAM_FEATURE(mdev, ppcnt_statistical_group) ?
744                      NUM_PPORT_PHY_STATISTICAL_COUNTERS : 0;
745
746         num_stats += MLX5_CAP_PCAM_FEATURE(mdev, per_lane_error_counters) ?
747                      NUM_PPORT_PHY_STATISTICAL_PER_LANE_COUNTERS : 0;
748
749         return num_stats;
750 }
751
752 static int mlx5e_grp_phy_fill_strings(struct mlx5e_priv *priv, u8 *data,
753                                       int idx)
754 {
755         struct mlx5_core_dev *mdev = priv->mdev;
756         int i;
757
758         strcpy(data + (idx++) * ETH_GSTRING_LEN, "link_down_events_phy");
759
760         if (!MLX5_CAP_PCAM_FEATURE(mdev, ppcnt_statistical_group))
761                 return idx;
762
763         for (i = 0; i < NUM_PPORT_PHY_STATISTICAL_COUNTERS; i++)
764                 strcpy(data + (idx++) * ETH_GSTRING_LEN,
765                        pport_phy_statistical_stats_desc[i].format);
766
767         if (MLX5_CAP_PCAM_FEATURE(mdev, per_lane_error_counters))
768                 for (i = 0; i < NUM_PPORT_PHY_STATISTICAL_PER_LANE_COUNTERS; i++)
769                         strcpy(data + (idx++) * ETH_GSTRING_LEN,
770                                pport_phy_statistical_err_lanes_stats_desc[i].format);
771
772         return idx;
773 }
774
775 static int mlx5e_grp_phy_fill_stats(struct mlx5e_priv *priv, u64 *data, int idx)
776 {
777         struct mlx5_core_dev *mdev = priv->mdev;
778         int i;
779
780         /* link_down_events_phy has special handling since it is not stored in __be64 format */
781         data[idx++] = MLX5_GET(ppcnt_reg, priv->stats.pport.phy_counters,
782                                counter_set.phys_layer_cntrs.link_down_events);
783
784         if (!MLX5_CAP_PCAM_FEATURE(mdev, ppcnt_statistical_group))
785                 return idx;
786
787         for (i = 0; i < NUM_PPORT_PHY_STATISTICAL_COUNTERS; i++)
788                 data[idx++] =
789                         MLX5E_READ_CTR64_BE(&priv->stats.pport.phy_statistical_counters,
790                                             pport_phy_statistical_stats_desc, i);
791
792         if (MLX5_CAP_PCAM_FEATURE(mdev, per_lane_error_counters))
793                 for (i = 0; i < NUM_PPORT_PHY_STATISTICAL_PER_LANE_COUNTERS; i++)
794                         data[idx++] =
795                                 MLX5E_READ_CTR64_BE(&priv->stats.pport.phy_statistical_counters,
796                                                     pport_phy_statistical_err_lanes_stats_desc,
797                                                     i);
798         return idx;
799 }
800
801 static void mlx5e_grp_phy_update_stats(struct mlx5e_priv *priv)
802 {
803         struct mlx5e_pport_stats *pstats = &priv->stats.pport;
804         struct mlx5_core_dev *mdev = priv->mdev;
805         u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {0};
806         int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
807         void *out;
808
809         MLX5_SET(ppcnt_reg, in, local_port, 1);
810         out = pstats->phy_counters;
811         MLX5_SET(ppcnt_reg, in, grp, MLX5_PHYSICAL_LAYER_COUNTERS_GROUP);
812         mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
813
814         if (!MLX5_CAP_PCAM_FEATURE(mdev, ppcnt_statistical_group))
815                 return;
816
817         out = pstats->phy_statistical_counters;
818         MLX5_SET(ppcnt_reg, in, grp, MLX5_PHYSICAL_LAYER_STATISTICAL_GROUP);
819         mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
820 }
821
822 #define PPORT_ETH_EXT_OFF(c) \
823         MLX5_BYTE_OFF(ppcnt_reg, \
824                       counter_set.eth_extended_cntrs_grp_data_layout.c##_high)
825 static const struct counter_desc pport_eth_ext_stats_desc[] = {
826         { "rx_buffer_passed_thres_phy", PPORT_ETH_EXT_OFF(rx_buffer_almost_full) },
827 };
828
829 #define NUM_PPORT_ETH_EXT_COUNTERS      ARRAY_SIZE(pport_eth_ext_stats_desc)
830
831 static int mlx5e_grp_eth_ext_get_num_stats(struct mlx5e_priv *priv)
832 {
833         if (MLX5_CAP_PCAM_FEATURE((priv)->mdev, rx_buffer_fullness_counters))
834                 return NUM_PPORT_ETH_EXT_COUNTERS;
835
836         return 0;
837 }
838
839 static int mlx5e_grp_eth_ext_fill_strings(struct mlx5e_priv *priv, u8 *data,
840                                           int idx)
841 {
842         int i;
843
844         if (MLX5_CAP_PCAM_FEATURE((priv)->mdev, rx_buffer_fullness_counters))
845                 for (i = 0; i < NUM_PPORT_ETH_EXT_COUNTERS; i++)
846                         strcpy(data + (idx++) * ETH_GSTRING_LEN,
847                                pport_eth_ext_stats_desc[i].format);
848         return idx;
849 }
850
851 static int mlx5e_grp_eth_ext_fill_stats(struct mlx5e_priv *priv, u64 *data,
852                                         int idx)
853 {
854         int i;
855
856         if (MLX5_CAP_PCAM_FEATURE((priv)->mdev, rx_buffer_fullness_counters))
857                 for (i = 0; i < NUM_PPORT_ETH_EXT_COUNTERS; i++)
858                         data[idx++] =
859                                 MLX5E_READ_CTR64_BE(&priv->stats.pport.eth_ext_counters,
860                                                     pport_eth_ext_stats_desc, i);
861         return idx;
862 }
863
864 static void mlx5e_grp_eth_ext_update_stats(struct mlx5e_priv *priv)
865 {
866         struct mlx5e_pport_stats *pstats = &priv->stats.pport;
867         struct mlx5_core_dev *mdev = priv->mdev;
868         u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {0};
869         int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
870         void *out;
871
872         if (!MLX5_CAP_PCAM_FEATURE(mdev, rx_buffer_fullness_counters))
873                 return;
874
875         MLX5_SET(ppcnt_reg, in, local_port, 1);
876         out = pstats->eth_ext_counters;
877         MLX5_SET(ppcnt_reg, in, grp, MLX5_ETHERNET_EXTENDED_COUNTERS_GROUP);
878         mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
879 }
880
881 #define PCIE_PERF_OFF(c) \
882         MLX5_BYTE_OFF(mpcnt_reg, counter_set.pcie_perf_cntrs_grp_data_layout.c)
883 static const struct counter_desc pcie_perf_stats_desc[] = {
884         { "rx_pci_signal_integrity", PCIE_PERF_OFF(rx_errors) },
885         { "tx_pci_signal_integrity", PCIE_PERF_OFF(tx_errors) },
886 };
887
888 #define PCIE_PERF_OFF64(c) \
889         MLX5_BYTE_OFF(mpcnt_reg, counter_set.pcie_perf_cntrs_grp_data_layout.c##_high)
890 static const struct counter_desc pcie_perf_stats_desc64[] = {
891         { "outbound_pci_buffer_overflow", PCIE_PERF_OFF64(tx_overflow_buffer_pkt) },
892 };
893
894 static const struct counter_desc pcie_perf_stall_stats_desc[] = {
895         { "outbound_pci_stalled_rd", PCIE_PERF_OFF(outbound_stalled_reads) },
896         { "outbound_pci_stalled_wr", PCIE_PERF_OFF(outbound_stalled_writes) },
897         { "outbound_pci_stalled_rd_events", PCIE_PERF_OFF(outbound_stalled_reads_events) },
898         { "outbound_pci_stalled_wr_events", PCIE_PERF_OFF(outbound_stalled_writes_events) },
899 };
900
901 #define NUM_PCIE_PERF_COUNTERS          ARRAY_SIZE(pcie_perf_stats_desc)
902 #define NUM_PCIE_PERF_COUNTERS64        ARRAY_SIZE(pcie_perf_stats_desc64)
903 #define NUM_PCIE_PERF_STALL_COUNTERS    ARRAY_SIZE(pcie_perf_stall_stats_desc)
904
905 static int mlx5e_grp_pcie_get_num_stats(struct mlx5e_priv *priv)
906 {
907         int num_stats = 0;
908
909         if (MLX5_CAP_MCAM_FEATURE((priv)->mdev, pcie_performance_group))
910                 num_stats += NUM_PCIE_PERF_COUNTERS;
911
912         if (MLX5_CAP_MCAM_FEATURE((priv)->mdev, tx_overflow_buffer_pkt))
913                 num_stats += NUM_PCIE_PERF_COUNTERS64;
914
915         if (MLX5_CAP_MCAM_FEATURE((priv)->mdev, pcie_outbound_stalled))
916                 num_stats += NUM_PCIE_PERF_STALL_COUNTERS;
917
918         return num_stats;
919 }
920
921 static int mlx5e_grp_pcie_fill_strings(struct mlx5e_priv *priv, u8 *data,
922                                        int idx)
923 {
924         int i;
925
926         if (MLX5_CAP_MCAM_FEATURE((priv)->mdev, pcie_performance_group))
927                 for (i = 0; i < NUM_PCIE_PERF_COUNTERS; i++)
928                         strcpy(data + (idx++) * ETH_GSTRING_LEN,
929                                pcie_perf_stats_desc[i].format);
930
931         if (MLX5_CAP_MCAM_FEATURE((priv)->mdev, tx_overflow_buffer_pkt))
932                 for (i = 0; i < NUM_PCIE_PERF_COUNTERS64; i++)
933                         strcpy(data + (idx++) * ETH_GSTRING_LEN,
934                                pcie_perf_stats_desc64[i].format);
935
936         if (MLX5_CAP_MCAM_FEATURE((priv)->mdev, pcie_outbound_stalled))
937                 for (i = 0; i < NUM_PCIE_PERF_STALL_COUNTERS; i++)
938                         strcpy(data + (idx++) * ETH_GSTRING_LEN,
939                                pcie_perf_stall_stats_desc[i].format);
940         return idx;
941 }
942
943 static int mlx5e_grp_pcie_fill_stats(struct mlx5e_priv *priv, u64 *data,
944                                      int idx)
945 {
946         int i;
947
948         if (MLX5_CAP_MCAM_FEATURE((priv)->mdev, pcie_performance_group))
949                 for (i = 0; i < NUM_PCIE_PERF_COUNTERS; i++)
950                         data[idx++] =
951                                 MLX5E_READ_CTR32_BE(&priv->stats.pcie.pcie_perf_counters,
952                                                     pcie_perf_stats_desc, i);
953
954         if (MLX5_CAP_MCAM_FEATURE((priv)->mdev, tx_overflow_buffer_pkt))
955                 for (i = 0; i < NUM_PCIE_PERF_COUNTERS64; i++)
956                         data[idx++] =
957                                 MLX5E_READ_CTR64_BE(&priv->stats.pcie.pcie_perf_counters,
958                                                     pcie_perf_stats_desc64, i);
959
960         if (MLX5_CAP_MCAM_FEATURE((priv)->mdev, pcie_outbound_stalled))
961                 for (i = 0; i < NUM_PCIE_PERF_STALL_COUNTERS; i++)
962                         data[idx++] =
963                                 MLX5E_READ_CTR32_BE(&priv->stats.pcie.pcie_perf_counters,
964                                                     pcie_perf_stall_stats_desc, i);
965         return idx;
966 }
967
968 static void mlx5e_grp_pcie_update_stats(struct mlx5e_priv *priv)
969 {
970         struct mlx5e_pcie_stats *pcie_stats = &priv->stats.pcie;
971         struct mlx5_core_dev *mdev = priv->mdev;
972         u32 in[MLX5_ST_SZ_DW(mpcnt_reg)] = {0};
973         int sz = MLX5_ST_SZ_BYTES(mpcnt_reg);
974         void *out;
975
976         if (!MLX5_CAP_MCAM_FEATURE(mdev, pcie_performance_group))
977                 return;
978
979         out = pcie_stats->pcie_perf_counters;
980         MLX5_SET(mpcnt_reg, in, grp, MLX5_PCIE_PERFORMANCE_COUNTERS_GROUP);
981         mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_MPCNT, 0, 0);
982 }
983
984 #define PPORT_PER_TC_PRIO_OFF(c) \
985         MLX5_BYTE_OFF(ppcnt_reg, \
986                       counter_set.eth_per_tc_prio_grp_data_layout.c##_high)
987
988 static const struct counter_desc pport_per_tc_prio_stats_desc[] = {
989         { "rx_prio%d_buf_discard", PPORT_PER_TC_PRIO_OFF(no_buffer_discard_uc) },
990 };
991
992 #define NUM_PPORT_PER_TC_PRIO_COUNTERS  ARRAY_SIZE(pport_per_tc_prio_stats_desc)
993
994 #define PPORT_PER_TC_CONGEST_PRIO_OFF(c) \
995         MLX5_BYTE_OFF(ppcnt_reg, \
996                       counter_set.eth_per_tc_congest_prio_grp_data_layout.c##_high)
997
998 static const struct counter_desc pport_per_tc_congest_prio_stats_desc[] = {
999         { "rx_prio%d_cong_discard", PPORT_PER_TC_CONGEST_PRIO_OFF(wred_discard) },
1000         { "rx_prio%d_marked", PPORT_PER_TC_CONGEST_PRIO_OFF(ecn_marked_tc) },
1001 };
1002
1003 #define NUM_PPORT_PER_TC_CONGEST_PRIO_COUNTERS \
1004         ARRAY_SIZE(pport_per_tc_congest_prio_stats_desc)
1005
1006 static int mlx5e_grp_per_tc_prio_get_num_stats(struct mlx5e_priv *priv)
1007 {
1008         struct mlx5_core_dev *mdev = priv->mdev;
1009
1010         if (!MLX5_CAP_GEN(mdev, sbcam_reg))
1011                 return 0;
1012
1013         return NUM_PPORT_PER_TC_PRIO_COUNTERS * NUM_PPORT_PRIO;
1014 }
1015
1016 static int mlx5e_grp_per_port_buffer_congest_fill_strings(struct mlx5e_priv *priv,
1017                                                           u8 *data, int idx)
1018 {
1019         struct mlx5_core_dev *mdev = priv->mdev;
1020         int i, prio;
1021
1022         if (!MLX5_CAP_GEN(mdev, sbcam_reg))
1023                 return idx;
1024
1025         for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
1026                 for (i = 0; i < NUM_PPORT_PER_TC_PRIO_COUNTERS; i++)
1027                         sprintf(data + (idx++) * ETH_GSTRING_LEN,
1028                                 pport_per_tc_prio_stats_desc[i].format, prio);
1029                 for (i = 0; i < NUM_PPORT_PER_TC_CONGEST_PRIO_COUNTERS; i++)
1030                         sprintf(data + (idx++) * ETH_GSTRING_LEN,
1031                                 pport_per_tc_congest_prio_stats_desc[i].format, prio);
1032         }
1033
1034         return idx;
1035 }
1036
1037 static int mlx5e_grp_per_port_buffer_congest_fill_stats(struct mlx5e_priv *priv,
1038                                                         u64 *data, int idx)
1039 {
1040         struct mlx5e_pport_stats *pport = &priv->stats.pport;
1041         struct mlx5_core_dev *mdev = priv->mdev;
1042         int i, prio;
1043
1044         if (!MLX5_CAP_GEN(mdev, sbcam_reg))
1045                 return idx;
1046
1047         for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
1048                 for (i = 0; i < NUM_PPORT_PER_TC_PRIO_COUNTERS; i++)
1049                         data[idx++] =
1050                                 MLX5E_READ_CTR64_BE(&pport->per_tc_prio_counters[prio],
1051                                                     pport_per_tc_prio_stats_desc, i);
1052                 for (i = 0; i < NUM_PPORT_PER_TC_CONGEST_PRIO_COUNTERS ; i++)
1053                         data[idx++] =
1054                                 MLX5E_READ_CTR64_BE(&pport->per_tc_congest_prio_counters[prio],
1055                                                     pport_per_tc_congest_prio_stats_desc, i);
1056         }
1057
1058         return idx;
1059 }
1060
1061 static void mlx5e_grp_per_tc_prio_update_stats(struct mlx5e_priv *priv)
1062 {
1063         struct mlx5e_pport_stats *pstats = &priv->stats.pport;
1064         struct mlx5_core_dev *mdev = priv->mdev;
1065         u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {};
1066         int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
1067         void *out;
1068         int prio;
1069
1070         if (!MLX5_CAP_GEN(mdev, sbcam_reg))
1071                 return;
1072
1073         MLX5_SET(ppcnt_reg, in, pnat, 2);
1074         MLX5_SET(ppcnt_reg, in, grp, MLX5_PER_TRAFFIC_CLASS_COUNTERS_GROUP);
1075         for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
1076                 out = pstats->per_tc_prio_counters[prio];
1077                 MLX5_SET(ppcnt_reg, in, prio_tc, prio);
1078                 mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
1079         }
1080 }
1081
1082 static int mlx5e_grp_per_tc_congest_prio_get_num_stats(struct mlx5e_priv *priv)
1083 {
1084         struct mlx5_core_dev *mdev = priv->mdev;
1085
1086         if (!MLX5_CAP_GEN(mdev, sbcam_reg))
1087                 return 0;
1088
1089         return NUM_PPORT_PER_TC_CONGEST_PRIO_COUNTERS * NUM_PPORT_PRIO;
1090 }
1091
1092 static void mlx5e_grp_per_tc_congest_prio_update_stats(struct mlx5e_priv *priv)
1093 {
1094         struct mlx5e_pport_stats *pstats = &priv->stats.pport;
1095         struct mlx5_core_dev *mdev = priv->mdev;
1096         u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {};
1097         int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
1098         void *out;
1099         int prio;
1100
1101         if (!MLX5_CAP_GEN(mdev, sbcam_reg))
1102                 return;
1103
1104         MLX5_SET(ppcnt_reg, in, pnat, 2);
1105         MLX5_SET(ppcnt_reg, in, grp, MLX5_PER_TRAFFIC_CLASS_CONGESTION_GROUP);
1106         for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
1107                 out = pstats->per_tc_congest_prio_counters[prio];
1108                 MLX5_SET(ppcnt_reg, in, prio_tc, prio);
1109                 mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
1110         }
1111 }
1112
1113 static int mlx5e_grp_per_port_buffer_congest_get_num_stats(struct mlx5e_priv *priv)
1114 {
1115         return mlx5e_grp_per_tc_prio_get_num_stats(priv) +
1116                 mlx5e_grp_per_tc_congest_prio_get_num_stats(priv);
1117 }
1118
1119 static void mlx5e_grp_per_port_buffer_congest_update_stats(struct mlx5e_priv *priv)
1120 {
1121         mlx5e_grp_per_tc_prio_update_stats(priv);
1122         mlx5e_grp_per_tc_congest_prio_update_stats(priv);
1123 }
1124
1125 #define PPORT_PER_PRIO_OFF(c) \
1126         MLX5_BYTE_OFF(ppcnt_reg, \
1127                       counter_set.eth_per_prio_grp_data_layout.c##_high)
1128 static const struct counter_desc pport_per_prio_traffic_stats_desc[] = {
1129         { "rx_prio%d_bytes", PPORT_PER_PRIO_OFF(rx_octets) },
1130         { "rx_prio%d_packets", PPORT_PER_PRIO_OFF(rx_frames) },
1131         { "tx_prio%d_bytes", PPORT_PER_PRIO_OFF(tx_octets) },
1132         { "tx_prio%d_packets", PPORT_PER_PRIO_OFF(tx_frames) },
1133 };
1134
1135 #define NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS     ARRAY_SIZE(pport_per_prio_traffic_stats_desc)
1136
1137 static int mlx5e_grp_per_prio_traffic_get_num_stats(void)
1138 {
1139         return NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS * NUM_PPORT_PRIO;
1140 }
1141
1142 static int mlx5e_grp_per_prio_traffic_fill_strings(struct mlx5e_priv *priv,
1143                                                    u8 *data,
1144                                                    int idx)
1145 {
1146         int i, prio;
1147
1148         for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
1149                 for (i = 0; i < NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS; i++)
1150                         sprintf(data + (idx++) * ETH_GSTRING_LEN,
1151                                 pport_per_prio_traffic_stats_desc[i].format, prio);
1152         }
1153
1154         return idx;
1155 }
1156
1157 static int mlx5e_grp_per_prio_traffic_fill_stats(struct mlx5e_priv *priv,
1158                                                  u64 *data,
1159                                                  int idx)
1160 {
1161         int i, prio;
1162
1163         for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
1164                 for (i = 0; i < NUM_PPORT_PER_PRIO_TRAFFIC_COUNTERS; i++)
1165                         data[idx++] =
1166                                 MLX5E_READ_CTR64_BE(&priv->stats.pport.per_prio_counters[prio],
1167                                                     pport_per_prio_traffic_stats_desc, i);
1168         }
1169
1170         return idx;
1171 }
1172
1173 static const struct counter_desc pport_per_prio_pfc_stats_desc[] = {
1174         /* %s is "global" or "prio{i}" */
1175         { "rx_%s_pause", PPORT_PER_PRIO_OFF(rx_pause) },
1176         { "rx_%s_pause_duration", PPORT_PER_PRIO_OFF(rx_pause_duration) },
1177         { "tx_%s_pause", PPORT_PER_PRIO_OFF(tx_pause) },
1178         { "tx_%s_pause_duration", PPORT_PER_PRIO_OFF(tx_pause_duration) },
1179         { "rx_%s_pause_transition", PPORT_PER_PRIO_OFF(rx_pause_transition) },
1180 };
1181
1182 static const struct counter_desc pport_pfc_stall_stats_desc[] = {
1183         { "tx_pause_storm_warning_events", PPORT_PER_PRIO_OFF(device_stall_minor_watermark_cnt) },
1184         { "tx_pause_storm_error_events", PPORT_PER_PRIO_OFF(device_stall_critical_watermark_cnt) },
1185 };
1186
1187 #define NUM_PPORT_PER_PRIO_PFC_COUNTERS         ARRAY_SIZE(pport_per_prio_pfc_stats_desc)
1188 #define NUM_PPORT_PFC_STALL_COUNTERS(priv)      (ARRAY_SIZE(pport_pfc_stall_stats_desc) * \
1189                                                  MLX5_CAP_PCAM_FEATURE((priv)->mdev, pfcc_mask) * \
1190                                                  MLX5_CAP_DEBUG((priv)->mdev, stall_detect))
1191
1192 static unsigned long mlx5e_query_pfc_combined(struct mlx5e_priv *priv)
1193 {
1194         struct mlx5_core_dev *mdev = priv->mdev;
1195         u8 pfc_en_tx;
1196         u8 pfc_en_rx;
1197         int err;
1198
1199         if (MLX5_CAP_GEN(mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
1200                 return 0;
1201
1202         err = mlx5_query_port_pfc(mdev, &pfc_en_tx, &pfc_en_rx);
1203
1204         return err ? 0 : pfc_en_tx | pfc_en_rx;
1205 }
1206
1207 static bool mlx5e_query_global_pause_combined(struct mlx5e_priv *priv)
1208 {
1209         struct mlx5_core_dev *mdev = priv->mdev;
1210         u32 rx_pause;
1211         u32 tx_pause;
1212         int err;
1213
1214         if (MLX5_CAP_GEN(mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
1215                 return false;
1216
1217         err = mlx5_query_port_pause(mdev, &rx_pause, &tx_pause);
1218
1219         return err ? false : rx_pause | tx_pause;
1220 }
1221
1222 static int mlx5e_grp_per_prio_pfc_get_num_stats(struct mlx5e_priv *priv)
1223 {
1224         return (mlx5e_query_global_pause_combined(priv) +
1225                 hweight8(mlx5e_query_pfc_combined(priv))) *
1226                 NUM_PPORT_PER_PRIO_PFC_COUNTERS +
1227                 NUM_PPORT_PFC_STALL_COUNTERS(priv);
1228 }
1229
1230 static int mlx5e_grp_per_prio_pfc_fill_strings(struct mlx5e_priv *priv,
1231                                                u8 *data,
1232                                                int idx)
1233 {
1234         unsigned long pfc_combined;
1235         int i, prio;
1236
1237         pfc_combined = mlx5e_query_pfc_combined(priv);
1238         for_each_set_bit(prio, &pfc_combined, NUM_PPORT_PRIO) {
1239                 for (i = 0; i < NUM_PPORT_PER_PRIO_PFC_COUNTERS; i++) {
1240                         char pfc_string[ETH_GSTRING_LEN];
1241
1242                         snprintf(pfc_string, sizeof(pfc_string), "prio%d", prio);
1243                         sprintf(data + (idx++) * ETH_GSTRING_LEN,
1244                                 pport_per_prio_pfc_stats_desc[i].format, pfc_string);
1245                 }
1246         }
1247
1248         if (mlx5e_query_global_pause_combined(priv)) {
1249                 for (i = 0; i < NUM_PPORT_PER_PRIO_PFC_COUNTERS; i++) {
1250                         sprintf(data + (idx++) * ETH_GSTRING_LEN,
1251                                 pport_per_prio_pfc_stats_desc[i].format, "global");
1252                 }
1253         }
1254
1255         for (i = 0; i < NUM_PPORT_PFC_STALL_COUNTERS(priv); i++)
1256                 strcpy(data + (idx++) * ETH_GSTRING_LEN,
1257                        pport_pfc_stall_stats_desc[i].format);
1258
1259         return idx;
1260 }
1261
1262 static int mlx5e_grp_per_prio_pfc_fill_stats(struct mlx5e_priv *priv,
1263                                              u64 *data,
1264                                              int idx)
1265 {
1266         unsigned long pfc_combined;
1267         int i, prio;
1268
1269         pfc_combined = mlx5e_query_pfc_combined(priv);
1270         for_each_set_bit(prio, &pfc_combined, NUM_PPORT_PRIO) {
1271                 for (i = 0; i < NUM_PPORT_PER_PRIO_PFC_COUNTERS; i++) {
1272                         data[idx++] =
1273                                 MLX5E_READ_CTR64_BE(&priv->stats.pport.per_prio_counters[prio],
1274                                                     pport_per_prio_pfc_stats_desc, i);
1275                 }
1276         }
1277
1278         if (mlx5e_query_global_pause_combined(priv)) {
1279                 for (i = 0; i < NUM_PPORT_PER_PRIO_PFC_COUNTERS; i++) {
1280                         data[idx++] =
1281                                 MLX5E_READ_CTR64_BE(&priv->stats.pport.per_prio_counters[0],
1282                                                     pport_per_prio_pfc_stats_desc, i);
1283                 }
1284         }
1285
1286         for (i = 0; i < NUM_PPORT_PFC_STALL_COUNTERS(priv); i++)
1287                 data[idx++] = MLX5E_READ_CTR64_BE(&priv->stats.pport.per_prio_counters[0],
1288                                                   pport_pfc_stall_stats_desc, i);
1289
1290         return idx;
1291 }
1292
1293 static int mlx5e_grp_per_prio_get_num_stats(struct mlx5e_priv *priv)
1294 {
1295         return mlx5e_grp_per_prio_traffic_get_num_stats() +
1296                 mlx5e_grp_per_prio_pfc_get_num_stats(priv);
1297 }
1298
1299 static int mlx5e_grp_per_prio_fill_strings(struct mlx5e_priv *priv, u8 *data,
1300                                            int idx)
1301 {
1302         idx = mlx5e_grp_per_prio_traffic_fill_strings(priv, data, idx);
1303         idx = mlx5e_grp_per_prio_pfc_fill_strings(priv, data, idx);
1304         return idx;
1305 }
1306
1307 static int mlx5e_grp_per_prio_fill_stats(struct mlx5e_priv *priv, u64 *data,
1308                                          int idx)
1309 {
1310         idx = mlx5e_grp_per_prio_traffic_fill_stats(priv, data, idx);
1311         idx = mlx5e_grp_per_prio_pfc_fill_stats(priv, data, idx);
1312         return idx;
1313 }
1314
1315 static void mlx5e_grp_per_prio_update_stats(struct mlx5e_priv *priv)
1316 {
1317         struct mlx5e_pport_stats *pstats = &priv->stats.pport;
1318         struct mlx5_core_dev *mdev = priv->mdev;
1319         u32 in[MLX5_ST_SZ_DW(ppcnt_reg)] = {0};
1320         int sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
1321         int prio;
1322         void *out;
1323
1324         if (!MLX5_BASIC_PPCNT_SUPPORTED(mdev))
1325                 return;
1326
1327         MLX5_SET(ppcnt_reg, in, local_port, 1);
1328         MLX5_SET(ppcnt_reg, in, grp, MLX5_PER_PRIORITY_COUNTERS_GROUP);
1329         for (prio = 0; prio < NUM_PPORT_PRIO; prio++) {
1330                 out = pstats->per_prio_counters[prio];
1331                 MLX5_SET(ppcnt_reg, in, prio_tc, prio);
1332                 mlx5_core_access_reg(mdev, in, sz, out, sz,
1333                                      MLX5_REG_PPCNT, 0, 0);
1334         }
1335 }
1336
1337 static const struct counter_desc mlx5e_pme_status_desc[] = {
1338         { "module_unplug",       sizeof(u64) * MLX5_MODULE_STATUS_UNPLUGGED },
1339 };
1340
1341 static const struct counter_desc mlx5e_pme_error_desc[] = {
1342         { "module_bus_stuck",    sizeof(u64) * MLX5_MODULE_EVENT_ERROR_BUS_STUCK },
1343         { "module_high_temp",    sizeof(u64) * MLX5_MODULE_EVENT_ERROR_HIGH_TEMPERATURE },
1344         { "module_bad_shorted",  sizeof(u64) * MLX5_MODULE_EVENT_ERROR_BAD_CABLE },
1345 };
1346
1347 #define NUM_PME_STATUS_STATS            ARRAY_SIZE(mlx5e_pme_status_desc)
1348 #define NUM_PME_ERR_STATS               ARRAY_SIZE(mlx5e_pme_error_desc)
1349
1350 static int mlx5e_grp_pme_get_num_stats(struct mlx5e_priv *priv)
1351 {
1352         return NUM_PME_STATUS_STATS + NUM_PME_ERR_STATS;
1353 }
1354
1355 static int mlx5e_grp_pme_fill_strings(struct mlx5e_priv *priv, u8 *data,
1356                                       int idx)
1357 {
1358         int i;
1359
1360         for (i = 0; i < NUM_PME_STATUS_STATS; i++)
1361                 strcpy(data + (idx++) * ETH_GSTRING_LEN, mlx5e_pme_status_desc[i].format);
1362
1363         for (i = 0; i < NUM_PME_ERR_STATS; i++)
1364                 strcpy(data + (idx++) * ETH_GSTRING_LEN, mlx5e_pme_error_desc[i].format);
1365
1366         return idx;
1367 }
1368
1369 static int mlx5e_grp_pme_fill_stats(struct mlx5e_priv *priv, u64 *data,
1370                                     int idx)
1371 {
1372         struct mlx5_pme_stats pme_stats;
1373         int i;
1374
1375         mlx5_get_pme_stats(priv->mdev, &pme_stats);
1376
1377         for (i = 0; i < NUM_PME_STATUS_STATS; i++)
1378                 data[idx++] = MLX5E_READ_CTR64_CPU(pme_stats.status_counters,
1379                                                    mlx5e_pme_status_desc, i);
1380
1381         for (i = 0; i < NUM_PME_ERR_STATS; i++)
1382                 data[idx++] = MLX5E_READ_CTR64_CPU(pme_stats.error_counters,
1383                                                    mlx5e_pme_error_desc, i);
1384
1385         return idx;
1386 }
1387
1388 static int mlx5e_grp_ipsec_get_num_stats(struct mlx5e_priv *priv)
1389 {
1390         return mlx5e_ipsec_get_count(priv);
1391 }
1392
1393 static int mlx5e_grp_ipsec_fill_strings(struct mlx5e_priv *priv, u8 *data,
1394                                         int idx)
1395 {
1396         return idx + mlx5e_ipsec_get_strings(priv,
1397                                              data + idx * ETH_GSTRING_LEN);
1398 }
1399
1400 static int mlx5e_grp_ipsec_fill_stats(struct mlx5e_priv *priv, u64 *data,
1401                                       int idx)
1402 {
1403         return idx + mlx5e_ipsec_get_stats(priv, data + idx);
1404 }
1405
1406 static void mlx5e_grp_ipsec_update_stats(struct mlx5e_priv *priv)
1407 {
1408         mlx5e_ipsec_update_stats(priv);
1409 }
1410
1411 static int mlx5e_grp_tls_get_num_stats(struct mlx5e_priv *priv)
1412 {
1413         return mlx5e_tls_get_count(priv);
1414 }
1415
1416 static int mlx5e_grp_tls_fill_strings(struct mlx5e_priv *priv, u8 *data,
1417                                       int idx)
1418 {
1419         return idx + mlx5e_tls_get_strings(priv, data + idx * ETH_GSTRING_LEN);
1420 }
1421
1422 static int mlx5e_grp_tls_fill_stats(struct mlx5e_priv *priv, u64 *data, int idx)
1423 {
1424         return idx + mlx5e_tls_get_stats(priv, data + idx);
1425 }
1426
1427 static const struct counter_desc rq_stats_desc[] = {
1428         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, packets) },
1429         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, bytes) },
1430         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_complete) },
1431         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_complete_tail) },
1432         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_complete_tail_slow) },
1433         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_unnecessary) },
1434         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_unnecessary_inner) },
1435         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_none) },
1436         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, xdp_drop) },
1437         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, xdp_redirect) },
1438         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, lro_packets) },
1439         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, lro_bytes) },
1440         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, ecn_mark) },
1441         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, removed_vlan_packets) },
1442         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, wqe_err) },
1443         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, mpwqe_filler_cqes) },
1444         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, mpwqe_filler_strides) },
1445         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, oversize_pkts_sw_drop) },
1446         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, buff_alloc_err) },
1447         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cqe_compress_blks) },
1448         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cqe_compress_pkts) },
1449         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cache_reuse) },
1450         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cache_full) },
1451         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cache_empty) },
1452         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cache_busy) },
1453         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, cache_waive) },
1454         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, congst_umr) },
1455         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, arfs_err) },
1456         { MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, recover) },
1457 };
1458
1459 static const struct counter_desc sq_stats_desc[] = {
1460         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, packets) },
1461         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, bytes) },
1462         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tso_packets) },
1463         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tso_bytes) },
1464         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tso_inner_packets) },
1465         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tso_inner_bytes) },
1466         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, csum_partial) },
1467         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, csum_partial_inner) },
1468         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, added_vlan_packets) },
1469         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, nop) },
1470 #ifdef CONFIG_MLX5_EN_TLS
1471         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_encrypted_packets) },
1472         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_encrypted_bytes) },
1473         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_ctx) },
1474         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_ooo) },
1475         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_drop_no_sync_data) },
1476         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_drop_bypass_req) },
1477         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_dump_packets) },
1478         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, tls_dump_bytes) },
1479 #endif
1480         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, csum_none) },
1481         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, stopped) },
1482         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, dropped) },
1483         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, xmit_more) },
1484         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, recover) },
1485         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, cqes) },
1486         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, wake) },
1487         { MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, cqe_err) },
1488 };
1489
1490 static const struct counter_desc rq_xdpsq_stats_desc[] = {
1491         { MLX5E_DECLARE_RQ_XDPSQ_STAT(struct mlx5e_xdpsq_stats, xmit) },
1492         { MLX5E_DECLARE_RQ_XDPSQ_STAT(struct mlx5e_xdpsq_stats, mpwqe) },
1493         { MLX5E_DECLARE_RQ_XDPSQ_STAT(struct mlx5e_xdpsq_stats, inlnw) },
1494         { MLX5E_DECLARE_RQ_XDPSQ_STAT(struct mlx5e_xdpsq_stats, nops) },
1495         { MLX5E_DECLARE_RQ_XDPSQ_STAT(struct mlx5e_xdpsq_stats, full) },
1496         { MLX5E_DECLARE_RQ_XDPSQ_STAT(struct mlx5e_xdpsq_stats, err) },
1497         { MLX5E_DECLARE_RQ_XDPSQ_STAT(struct mlx5e_xdpsq_stats, cqes) },
1498 };
1499
1500 static const struct counter_desc xdpsq_stats_desc[] = {
1501         { MLX5E_DECLARE_XDPSQ_STAT(struct mlx5e_xdpsq_stats, xmit) },
1502         { MLX5E_DECLARE_XDPSQ_STAT(struct mlx5e_xdpsq_stats, mpwqe) },
1503         { MLX5E_DECLARE_XDPSQ_STAT(struct mlx5e_xdpsq_stats, inlnw) },
1504         { MLX5E_DECLARE_XDPSQ_STAT(struct mlx5e_xdpsq_stats, nops) },
1505         { MLX5E_DECLARE_XDPSQ_STAT(struct mlx5e_xdpsq_stats, full) },
1506         { MLX5E_DECLARE_XDPSQ_STAT(struct mlx5e_xdpsq_stats, err) },
1507         { MLX5E_DECLARE_XDPSQ_STAT(struct mlx5e_xdpsq_stats, cqes) },
1508 };
1509
1510 static const struct counter_desc xskrq_stats_desc[] = {
1511         { MLX5E_DECLARE_XSKRQ_STAT(struct mlx5e_rq_stats, packets) },
1512         { MLX5E_DECLARE_XSKRQ_STAT(struct mlx5e_rq_stats, bytes) },
1513         { MLX5E_DECLARE_XSKRQ_STAT(struct mlx5e_rq_stats, csum_complete) },
1514         { MLX5E_DECLARE_XSKRQ_STAT(struct mlx5e_rq_stats, csum_unnecessary) },
1515         { MLX5E_DECLARE_XSKRQ_STAT(struct mlx5e_rq_stats, csum_unnecessary_inner) },
1516         { MLX5E_DECLARE_XSKRQ_STAT(struct mlx5e_rq_stats, csum_none) },
1517         { MLX5E_DECLARE_XSKRQ_STAT(struct mlx5e_rq_stats, ecn_mark) },
1518         { MLX5E_DECLARE_XSKRQ_STAT(struct mlx5e_rq_stats, removed_vlan_packets) },
1519         { MLX5E_DECLARE_XSKRQ_STAT(struct mlx5e_rq_stats, xdp_drop) },
1520         { MLX5E_DECLARE_XSKRQ_STAT(struct mlx5e_rq_stats, xdp_redirect) },
1521         { MLX5E_DECLARE_XSKRQ_STAT(struct mlx5e_rq_stats, wqe_err) },
1522         { MLX5E_DECLARE_XSKRQ_STAT(struct mlx5e_rq_stats, mpwqe_filler_cqes) },
1523         { MLX5E_DECLARE_XSKRQ_STAT(struct mlx5e_rq_stats, mpwqe_filler_strides) },
1524         { MLX5E_DECLARE_XSKRQ_STAT(struct mlx5e_rq_stats, oversize_pkts_sw_drop) },
1525         { MLX5E_DECLARE_XSKRQ_STAT(struct mlx5e_rq_stats, buff_alloc_err) },
1526         { MLX5E_DECLARE_XSKRQ_STAT(struct mlx5e_rq_stats, cqe_compress_blks) },
1527         { MLX5E_DECLARE_XSKRQ_STAT(struct mlx5e_rq_stats, cqe_compress_pkts) },
1528         { MLX5E_DECLARE_XSKRQ_STAT(struct mlx5e_rq_stats, congst_umr) },
1529         { MLX5E_DECLARE_XSKRQ_STAT(struct mlx5e_rq_stats, arfs_err) },
1530 };
1531
1532 static const struct counter_desc xsksq_stats_desc[] = {
1533         { MLX5E_DECLARE_XSKSQ_STAT(struct mlx5e_xdpsq_stats, xmit) },
1534         { MLX5E_DECLARE_XSKSQ_STAT(struct mlx5e_xdpsq_stats, mpwqe) },
1535         { MLX5E_DECLARE_XSKSQ_STAT(struct mlx5e_xdpsq_stats, inlnw) },
1536         { MLX5E_DECLARE_XSKSQ_STAT(struct mlx5e_xdpsq_stats, full) },
1537         { MLX5E_DECLARE_XSKSQ_STAT(struct mlx5e_xdpsq_stats, err) },
1538         { MLX5E_DECLARE_XSKSQ_STAT(struct mlx5e_xdpsq_stats, cqes) },
1539 };
1540
1541 static const struct counter_desc ch_stats_desc[] = {
1542         { MLX5E_DECLARE_CH_STAT(struct mlx5e_ch_stats, events) },
1543         { MLX5E_DECLARE_CH_STAT(struct mlx5e_ch_stats, poll) },
1544         { MLX5E_DECLARE_CH_STAT(struct mlx5e_ch_stats, arm) },
1545         { MLX5E_DECLARE_CH_STAT(struct mlx5e_ch_stats, aff_change) },
1546         { MLX5E_DECLARE_CH_STAT(struct mlx5e_ch_stats, force_irq) },
1547         { MLX5E_DECLARE_CH_STAT(struct mlx5e_ch_stats, eq_rearm) },
1548 };
1549
1550 #define NUM_RQ_STATS                    ARRAY_SIZE(rq_stats_desc)
1551 #define NUM_SQ_STATS                    ARRAY_SIZE(sq_stats_desc)
1552 #define NUM_XDPSQ_STATS                 ARRAY_SIZE(xdpsq_stats_desc)
1553 #define NUM_RQ_XDPSQ_STATS              ARRAY_SIZE(rq_xdpsq_stats_desc)
1554 #define NUM_XSKRQ_STATS                 ARRAY_SIZE(xskrq_stats_desc)
1555 #define NUM_XSKSQ_STATS                 ARRAY_SIZE(xsksq_stats_desc)
1556 #define NUM_CH_STATS                    ARRAY_SIZE(ch_stats_desc)
1557
1558 static int mlx5e_grp_channels_get_num_stats(struct mlx5e_priv *priv)
1559 {
1560         int max_nch = priv->max_nch;
1561
1562         return (NUM_RQ_STATS * max_nch) +
1563                (NUM_CH_STATS * max_nch) +
1564                (NUM_SQ_STATS * max_nch * priv->max_opened_tc) +
1565                (NUM_RQ_XDPSQ_STATS * max_nch) +
1566                (NUM_XDPSQ_STATS * max_nch) +
1567                (NUM_XSKRQ_STATS * max_nch * priv->xsk.ever_used) +
1568                (NUM_XSKSQ_STATS * max_nch * priv->xsk.ever_used);
1569 }
1570
1571 static int mlx5e_grp_channels_fill_strings(struct mlx5e_priv *priv, u8 *data,
1572                                            int idx)
1573 {
1574         bool is_xsk = priv->xsk.ever_used;
1575         int max_nch = priv->max_nch;
1576         int i, j, tc;
1577
1578         for (i = 0; i < max_nch; i++)
1579                 for (j = 0; j < NUM_CH_STATS; j++)
1580                         sprintf(data + (idx++) * ETH_GSTRING_LEN,
1581                                 ch_stats_desc[j].format, i);
1582
1583         for (i = 0; i < max_nch; i++) {
1584                 for (j = 0; j < NUM_RQ_STATS; j++)
1585                         sprintf(data + (idx++) * ETH_GSTRING_LEN,
1586                                 rq_stats_desc[j].format, i);
1587                 for (j = 0; j < NUM_XSKRQ_STATS * is_xsk; j++)
1588                         sprintf(data + (idx++) * ETH_GSTRING_LEN,
1589                                 xskrq_stats_desc[j].format, i);
1590                 for (j = 0; j < NUM_RQ_XDPSQ_STATS; j++)
1591                         sprintf(data + (idx++) * ETH_GSTRING_LEN,
1592                                 rq_xdpsq_stats_desc[j].format, i);
1593         }
1594
1595         for (tc = 0; tc < priv->max_opened_tc; tc++)
1596                 for (i = 0; i < max_nch; i++)
1597                         for (j = 0; j < NUM_SQ_STATS; j++)
1598                                 sprintf(data + (idx++) * ETH_GSTRING_LEN,
1599                                         sq_stats_desc[j].format,
1600                                         priv->channel_tc2txq[i][tc]);
1601
1602         for (i = 0; i < max_nch; i++) {
1603                 for (j = 0; j < NUM_XSKSQ_STATS * is_xsk; j++)
1604                         sprintf(data + (idx++) * ETH_GSTRING_LEN,
1605                                 xsksq_stats_desc[j].format, i);
1606                 for (j = 0; j < NUM_XDPSQ_STATS; j++)
1607                         sprintf(data + (idx++) * ETH_GSTRING_LEN,
1608                                 xdpsq_stats_desc[j].format, i);
1609         }
1610
1611         return idx;
1612 }
1613
1614 static int mlx5e_grp_channels_fill_stats(struct mlx5e_priv *priv, u64 *data,
1615                                          int idx)
1616 {
1617         bool is_xsk = priv->xsk.ever_used;
1618         int max_nch = priv->max_nch;
1619         int i, j, tc;
1620
1621         for (i = 0; i < max_nch; i++)
1622                 for (j = 0; j < NUM_CH_STATS; j++)
1623                         data[idx++] =
1624                                 MLX5E_READ_CTR64_CPU(&priv->channel_stats[i].ch,
1625                                                      ch_stats_desc, j);
1626
1627         for (i = 0; i < max_nch; i++) {
1628                 for (j = 0; j < NUM_RQ_STATS; j++)
1629                         data[idx++] =
1630                                 MLX5E_READ_CTR64_CPU(&priv->channel_stats[i].rq,
1631                                                      rq_stats_desc, j);
1632                 for (j = 0; j < NUM_XSKRQ_STATS * is_xsk; j++)
1633                         data[idx++] =
1634                                 MLX5E_READ_CTR64_CPU(&priv->channel_stats[i].xskrq,
1635                                                      xskrq_stats_desc, j);
1636                 for (j = 0; j < NUM_RQ_XDPSQ_STATS; j++)
1637                         data[idx++] =
1638                                 MLX5E_READ_CTR64_CPU(&priv->channel_stats[i].rq_xdpsq,
1639                                                      rq_xdpsq_stats_desc, j);
1640         }
1641
1642         for (tc = 0; tc < priv->max_opened_tc; tc++)
1643                 for (i = 0; i < max_nch; i++)
1644                         for (j = 0; j < NUM_SQ_STATS; j++)
1645                                 data[idx++] =
1646                                         MLX5E_READ_CTR64_CPU(&priv->channel_stats[i].sq[tc],
1647                                                              sq_stats_desc, j);
1648
1649         for (i = 0; i < max_nch; i++) {
1650                 for (j = 0; j < NUM_XSKSQ_STATS * is_xsk; j++)
1651                         data[idx++] =
1652                                 MLX5E_READ_CTR64_CPU(&priv->channel_stats[i].xsksq,
1653                                                      xsksq_stats_desc, j);
1654                 for (j = 0; j < NUM_XDPSQ_STATS; j++)
1655                         data[idx++] =
1656                                 MLX5E_READ_CTR64_CPU(&priv->channel_stats[i].xdpsq,
1657                                                      xdpsq_stats_desc, j);
1658         }
1659
1660         return idx;
1661 }
1662
1663 /* The stats groups order is opposite to the update_stats() order calls */
1664 const struct mlx5e_stats_grp mlx5e_stats_grps[] = {
1665         {
1666                 .get_num_stats = mlx5e_grp_sw_get_num_stats,
1667                 .fill_strings = mlx5e_grp_sw_fill_strings,
1668                 .fill_stats = mlx5e_grp_sw_fill_stats,
1669                 .update_stats = mlx5e_grp_sw_update_stats,
1670         },
1671         {
1672                 .get_num_stats = mlx5e_grp_q_get_num_stats,
1673                 .fill_strings = mlx5e_grp_q_fill_strings,
1674                 .fill_stats = mlx5e_grp_q_fill_stats,
1675                 .update_stats_mask = MLX5E_NDO_UPDATE_STATS,
1676                 .update_stats = mlx5e_grp_q_update_stats,
1677         },
1678         {
1679                 .get_num_stats = mlx5e_grp_vnic_env_get_num_stats,
1680                 .fill_strings = mlx5e_grp_vnic_env_fill_strings,
1681                 .fill_stats = mlx5e_grp_vnic_env_fill_stats,
1682                 .update_stats = mlx5e_grp_vnic_env_update_stats,
1683         },
1684         {
1685                 .get_num_stats = mlx5e_grp_vport_get_num_stats,
1686                 .fill_strings = mlx5e_grp_vport_fill_strings,
1687                 .fill_stats = mlx5e_grp_vport_fill_stats,
1688                 .update_stats_mask = MLX5E_NDO_UPDATE_STATS,
1689                 .update_stats = mlx5e_grp_vport_update_stats,
1690         },
1691         {
1692                 .get_num_stats = mlx5e_grp_802_3_get_num_stats,
1693                 .fill_strings = mlx5e_grp_802_3_fill_strings,
1694                 .fill_stats = mlx5e_grp_802_3_fill_stats,
1695                 .update_stats_mask = MLX5E_NDO_UPDATE_STATS,
1696                 .update_stats = mlx5e_grp_802_3_update_stats,
1697         },
1698         {
1699                 .get_num_stats = mlx5e_grp_2863_get_num_stats,
1700                 .fill_strings = mlx5e_grp_2863_fill_strings,
1701                 .fill_stats = mlx5e_grp_2863_fill_stats,
1702                 .update_stats = mlx5e_grp_2863_update_stats,
1703         },
1704         {
1705                 .get_num_stats = mlx5e_grp_2819_get_num_stats,
1706                 .fill_strings = mlx5e_grp_2819_fill_strings,
1707                 .fill_stats = mlx5e_grp_2819_fill_stats,
1708                 .update_stats = mlx5e_grp_2819_update_stats,
1709         },
1710         {
1711                 .get_num_stats = mlx5e_grp_phy_get_num_stats,
1712                 .fill_strings = mlx5e_grp_phy_fill_strings,
1713                 .fill_stats = mlx5e_grp_phy_fill_stats,
1714                 .update_stats = mlx5e_grp_phy_update_stats,
1715         },
1716         {
1717                 .get_num_stats = mlx5e_grp_eth_ext_get_num_stats,
1718                 .fill_strings = mlx5e_grp_eth_ext_fill_strings,
1719                 .fill_stats = mlx5e_grp_eth_ext_fill_stats,
1720                 .update_stats = mlx5e_grp_eth_ext_update_stats,
1721         },
1722         {
1723                 .get_num_stats = mlx5e_grp_pcie_get_num_stats,
1724                 .fill_strings = mlx5e_grp_pcie_fill_strings,
1725                 .fill_stats = mlx5e_grp_pcie_fill_stats,
1726                 .update_stats = mlx5e_grp_pcie_update_stats,
1727         },
1728         {
1729                 .get_num_stats = mlx5e_grp_per_prio_get_num_stats,
1730                 .fill_strings = mlx5e_grp_per_prio_fill_strings,
1731                 .fill_stats = mlx5e_grp_per_prio_fill_stats,
1732                 .update_stats = mlx5e_grp_per_prio_update_stats,
1733         },
1734         {
1735                 .get_num_stats = mlx5e_grp_pme_get_num_stats,
1736                 .fill_strings = mlx5e_grp_pme_fill_strings,
1737                 .fill_stats = mlx5e_grp_pme_fill_stats,
1738         },
1739         {
1740                 .get_num_stats = mlx5e_grp_ipsec_get_num_stats,
1741                 .fill_strings = mlx5e_grp_ipsec_fill_strings,
1742                 .fill_stats = mlx5e_grp_ipsec_fill_stats,
1743                 .update_stats = mlx5e_grp_ipsec_update_stats,
1744         },
1745         {
1746                 .get_num_stats = mlx5e_grp_tls_get_num_stats,
1747                 .fill_strings = mlx5e_grp_tls_fill_strings,
1748                 .fill_stats = mlx5e_grp_tls_fill_stats,
1749         },
1750         {
1751                 .get_num_stats = mlx5e_grp_channels_get_num_stats,
1752                 .fill_strings = mlx5e_grp_channels_fill_strings,
1753                 .fill_stats = mlx5e_grp_channels_fill_stats,
1754         },
1755         {
1756                 .get_num_stats = mlx5e_grp_per_port_buffer_congest_get_num_stats,
1757                 .fill_strings = mlx5e_grp_per_port_buffer_congest_fill_strings,
1758                 .fill_stats = mlx5e_grp_per_port_buffer_congest_fill_stats,
1759                 .update_stats = mlx5e_grp_per_port_buffer_congest_update_stats,
1760         },
1761 };
1762
1763 const int mlx5e_num_stats_grps = ARRAY_SIZE(mlx5e_stats_grps);