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