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