examples/pipeline: fix build
[dpdk.git] / drivers / common / cnxk / roc_nix_stats.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4
5 #include <inttypes.h>
6
7 #include "roc_api.h"
8 #include "roc_nix_xstats.h"
9 #include "roc_priv.h"
10
11 #define NIX_RX_STATS(val) plt_read64(nix->base + NIX_LF_RX_STATX(val))
12 #define NIX_TX_STATS(val) plt_read64(nix->base + NIX_LF_TX_STATX(val))
13
14 int
15 roc_nix_num_xstats_get(struct roc_nix *roc_nix)
16 {
17         if (roc_nix_is_vf_or_sdp(roc_nix))
18                 return CNXK_NIX_NUM_XSTATS_REG;
19         else if (roc_model_is_cn9k())
20                 return CNXK_NIX_NUM_XSTATS_CGX;
21
22         return CNXK_NIX_NUM_XSTATS_RPM;
23 }
24
25 int
26 roc_nix_stats_get(struct roc_nix *roc_nix, struct roc_nix_stats *stats)
27 {
28         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
29
30         if (stats == NULL)
31                 return NIX_ERR_PARAM;
32
33         stats->rx_octs = NIX_RX_STATS(NIX_STAT_LF_RX_RX_OCTS);
34         stats->rx_ucast = NIX_RX_STATS(NIX_STAT_LF_RX_RX_UCAST);
35         stats->rx_bcast = NIX_RX_STATS(NIX_STAT_LF_RX_RX_BCAST);
36         stats->rx_mcast = NIX_RX_STATS(NIX_STAT_LF_RX_RX_MCAST);
37         stats->rx_drop = NIX_RX_STATS(NIX_STAT_LF_RX_RX_DROP);
38         stats->rx_drop_octs = NIX_RX_STATS(NIX_STAT_LF_RX_RX_DROP_OCTS);
39         stats->rx_fcs = NIX_RX_STATS(NIX_STAT_LF_RX_RX_FCS);
40         stats->rx_err = NIX_RX_STATS(NIX_STAT_LF_RX_RX_ERR);
41         stats->rx_drop_bcast = NIX_RX_STATS(NIX_STAT_LF_RX_RX_DRP_BCAST);
42         stats->rx_drop_mcast = NIX_RX_STATS(NIX_STAT_LF_RX_RX_DRP_MCAST);
43         stats->rx_drop_l3_bcast = NIX_RX_STATS(NIX_STAT_LF_RX_RX_DRP_L3BCAST);
44         stats->rx_drop_l3_mcast = NIX_RX_STATS(NIX_STAT_LF_RX_RX_DRP_L3MCAST);
45
46         stats->tx_ucast = NIX_TX_STATS(NIX_STAT_LF_TX_TX_UCAST);
47         stats->tx_bcast = NIX_TX_STATS(NIX_STAT_LF_TX_TX_BCAST);
48         stats->tx_mcast = NIX_TX_STATS(NIX_STAT_LF_TX_TX_MCAST);
49         stats->tx_drop = NIX_TX_STATS(NIX_STAT_LF_TX_TX_DROP);
50         stats->tx_octs = NIX_TX_STATS(NIX_STAT_LF_TX_TX_OCTS);
51         return 0;
52 }
53
54 int
55 roc_nix_stats_reset(struct roc_nix *roc_nix)
56 {
57         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
58         struct mbox *mbox = (&nix->dev)->mbox;
59
60         if (mbox_alloc_msg_nix_stats_rst(mbox) == NULL)
61                 return -ENOMEM;
62
63         return mbox_process(mbox);
64 }
65
66 static int
67 queue_is_valid(struct nix *nix, uint16_t qid, bool is_rx)
68 {
69         uint16_t nb_queues;
70
71         if (is_rx)
72                 nb_queues = nix->nb_rx_queues;
73         else
74                 nb_queues = nix->nb_tx_queues;
75
76         if (qid >= nb_queues)
77                 return NIX_ERR_QUEUE_INVALID_RANGE;
78
79         return 0;
80 }
81
82 static uint64_t
83 qstat_read(struct nix *nix, uint16_t qid, uint32_t off)
84 {
85         uint64_t reg, val;
86         int64_t *addr;
87
88         addr = (int64_t *)(nix->base + off);
89         reg = (((uint64_t)qid) << 32);
90         val = roc_atomic64_add_nosync(reg, addr);
91         if (val & BIT_ULL(NIX_CQ_OP_STAT_OP_ERR))
92                 val = 0;
93         return val;
94 }
95
96 static void
97 nix_stat_rx_queue_get(struct nix *nix, uint16_t qid,
98                       struct roc_nix_stats_queue *qstats)
99 {
100         qstats->rx_pkts = qstat_read(nix, qid, NIX_LF_RQ_OP_PKTS);
101         qstats->rx_octs = qstat_read(nix, qid, NIX_LF_RQ_OP_OCTS);
102         qstats->rx_drop_pkts = qstat_read(nix, qid, NIX_LF_RQ_OP_DROP_PKTS);
103         qstats->rx_drop_octs = qstat_read(nix, qid, NIX_LF_RQ_OP_DROP_OCTS);
104         qstats->rx_error_pkts = qstat_read(nix, qid, NIX_LF_RQ_OP_RE_PKTS);
105 }
106
107 static void
108 nix_stat_tx_queue_get(struct nix *nix, uint16_t qid,
109                       struct roc_nix_stats_queue *qstats)
110 {
111         qstats->tx_pkts = qstat_read(nix, qid, NIX_LF_SQ_OP_PKTS);
112         qstats->tx_octs = qstat_read(nix, qid, NIX_LF_SQ_OP_OCTS);
113         qstats->tx_drop_pkts = qstat_read(nix, qid, NIX_LF_SQ_OP_DROP_PKTS);
114         qstats->tx_drop_octs = qstat_read(nix, qid, NIX_LF_SQ_OP_DROP_OCTS);
115 }
116
117 static int
118 nix_stat_rx_queue_reset(struct nix *nix, uint16_t qid)
119 {
120         struct mbox *mbox = (&nix->dev)->mbox;
121         int rc;
122
123         if (roc_model_is_cn9k()) {
124                 struct nix_aq_enq_req *aq;
125
126                 aq = mbox_alloc_msg_nix_aq_enq(mbox);
127                 if (!aq)
128                         return -ENOSPC;
129
130                 aq->qidx = qid;
131                 aq->ctype = NIX_AQ_CTYPE_RQ;
132                 aq->op = NIX_AQ_INSTOP_WRITE;
133
134                 aq->rq.octs = 0;
135                 aq->rq.pkts = 0;
136                 aq->rq.drop_octs = 0;
137                 aq->rq.drop_pkts = 0;
138                 aq->rq.re_pkts = 0;
139
140                 aq->rq_mask.octs = ~(aq->rq_mask.octs);
141                 aq->rq_mask.pkts = ~(aq->rq_mask.pkts);
142                 aq->rq_mask.drop_octs = ~(aq->rq_mask.drop_octs);
143                 aq->rq_mask.drop_pkts = ~(aq->rq_mask.drop_pkts);
144                 aq->rq_mask.re_pkts = ~(aq->rq_mask.re_pkts);
145         } else {
146                 struct nix_cn10k_aq_enq_req *aq;
147
148                 aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
149                 if (!aq)
150                         return -ENOSPC;
151
152                 aq->qidx = qid;
153                 aq->ctype = NIX_AQ_CTYPE_RQ;
154                 aq->op = NIX_AQ_INSTOP_WRITE;
155
156                 aq->rq.octs = 0;
157                 aq->rq.pkts = 0;
158                 aq->rq.drop_octs = 0;
159                 aq->rq.drop_pkts = 0;
160                 aq->rq.re_pkts = 0;
161
162                 aq->rq_mask.octs = ~(aq->rq_mask.octs);
163                 aq->rq_mask.pkts = ~(aq->rq_mask.pkts);
164                 aq->rq_mask.drop_octs = ~(aq->rq_mask.drop_octs);
165                 aq->rq_mask.drop_pkts = ~(aq->rq_mask.drop_pkts);
166                 aq->rq_mask.re_pkts = ~(aq->rq_mask.re_pkts);
167         }
168
169         rc = mbox_process(mbox);
170         return rc ? NIX_ERR_AQ_WRITE_FAILED : 0;
171 }
172
173 static int
174 nix_stat_tx_queue_reset(struct nix *nix, uint16_t qid)
175 {
176         struct mbox *mbox = (&nix->dev)->mbox;
177         int rc;
178
179         if (roc_model_is_cn9k()) {
180                 struct nix_aq_enq_req *aq;
181
182                 aq = mbox_alloc_msg_nix_aq_enq(mbox);
183                 if (!aq)
184                         return -ENOSPC;
185
186                 aq->qidx = qid;
187                 aq->ctype = NIX_AQ_CTYPE_SQ;
188                 aq->op = NIX_AQ_INSTOP_WRITE;
189                 aq->sq.octs = 0;
190                 aq->sq.pkts = 0;
191                 aq->sq.drop_octs = 0;
192                 aq->sq.drop_pkts = 0;
193
194                 aq->sq_mask.octs = ~(aq->sq_mask.octs);
195                 aq->sq_mask.pkts = ~(aq->sq_mask.pkts);
196                 aq->sq_mask.drop_octs = ~(aq->sq_mask.drop_octs);
197                 aq->sq_mask.drop_pkts = ~(aq->sq_mask.drop_pkts);
198         } else {
199                 struct nix_cn10k_aq_enq_req *aq;
200
201                 aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
202                 if (!aq)
203                         return -ENOSPC;
204
205                 aq->qidx = qid;
206                 aq->ctype = NIX_AQ_CTYPE_SQ;
207                 aq->op = NIX_AQ_INSTOP_WRITE;
208                 aq->sq.octs = 0;
209                 aq->sq.pkts = 0;
210                 aq->sq.drop_octs = 0;
211                 aq->sq.drop_pkts = 0;
212
213                 aq->sq_mask.octs = ~(aq->sq_mask.octs);
214                 aq->sq_mask.pkts = ~(aq->sq_mask.pkts);
215                 aq->sq_mask.drop_octs = ~(aq->sq_mask.drop_octs);
216                 aq->sq_mask.drop_pkts = ~(aq->sq_mask.drop_pkts);
217         }
218
219         rc = mbox_process(mbox);
220         return rc ? NIX_ERR_AQ_WRITE_FAILED : 0;
221 }
222
223 int
224 roc_nix_stats_queue_get(struct roc_nix *roc_nix, uint16_t qid, bool is_rx,
225                         struct roc_nix_stats_queue *qstats)
226 {
227         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
228         int rc;
229
230         if (qstats == NULL)
231                 return NIX_ERR_PARAM;
232
233         rc = queue_is_valid(nix, qid, is_rx);
234         if (rc)
235                 goto fail;
236
237         if (is_rx)
238                 nix_stat_rx_queue_get(nix, qid, qstats);
239         else
240                 nix_stat_tx_queue_get(nix, qid, qstats);
241
242 fail:
243         return rc;
244 }
245
246 int
247 roc_nix_stats_queue_reset(struct roc_nix *roc_nix, uint16_t qid, bool is_rx)
248 {
249         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
250         int rc;
251
252         rc = queue_is_valid(nix, qid, is_rx);
253         if (rc)
254                 goto fail;
255
256         if (is_rx)
257                 rc = nix_stat_rx_queue_reset(nix, qid);
258         else
259                 rc = nix_stat_tx_queue_reset(nix, qid);
260
261 fail:
262         return rc;
263 }
264
265 int
266 roc_nix_xstats_get(struct roc_nix *roc_nix, struct roc_nix_xstat *xstats,
267                    unsigned int n)
268 {
269         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
270         struct mbox *mbox = (&nix->dev)->mbox;
271         struct cgx_stats_rsp *cgx_resp;
272         struct rpm_stats_rsp *rpm_resp;
273         uint64_t i, count = 0;
274         struct msg_req *req;
275         uint32_t xstat_cnt;
276         int rc;
277
278         xstat_cnt = roc_nix_num_xstats_get(roc_nix);
279         if (n < xstat_cnt)
280                 return xstat_cnt;
281
282         if (xstats == NULL)
283                 return -EINVAL;
284
285         memset(xstats, 0, (xstat_cnt * sizeof(*xstats)));
286         for (i = 0; i < CNXK_NIX_NUM_TX_XSTATS; i++) {
287                 xstats[count].value = NIX_TX_STATS(nix_tx_xstats[i].offset);
288                 xstats[count].id = count;
289                 count++;
290         }
291
292         for (i = 0; i < CNXK_NIX_NUM_RX_XSTATS; i++) {
293                 xstats[count].value = NIX_RX_STATS(nix_rx_xstats[i].offset);
294                 xstats[count].id = count;
295                 count++;
296         }
297
298         for (i = 0; i < nix->nb_rx_queues; i++)
299                 xstats[count].value +=
300                         qstat_read(nix, i, nix_q_xstats[0].offset);
301
302         xstats[count].id = count;
303         count++;
304
305         if (roc_nix_is_vf_or_sdp(roc_nix))
306                 return count;
307
308         if (roc_model_is_cn9k()) {
309                 req = mbox_alloc_msg_cgx_stats(mbox);
310                 if (!req)
311                         return -ENOSPC;
312
313                 req->hdr.pcifunc = roc_nix_get_pf_func(roc_nix);
314
315                 rc = mbox_process_msg(mbox, (void *)&cgx_resp);
316                 if (rc)
317                         return rc;
318
319                 for (i = 0; i < roc_nix_num_rx_xstats(); i++) {
320                         xstats[count].value =
321                                 cgx_resp->rx_stats[nix_rx_xstats_cgx[i].offset];
322                         xstats[count].id = count;
323                         count++;
324                 }
325
326                 for (i = 0; i < roc_nix_num_tx_xstats(); i++) {
327                         xstats[count].value =
328                                 cgx_resp->tx_stats[nix_tx_xstats_cgx[i].offset];
329                         xstats[count].id = count;
330                         count++;
331                 }
332         } else {
333                 req = mbox_alloc_msg_rpm_stats(mbox);
334                 if (!req)
335                         return -ENOSPC;
336
337                 req->hdr.pcifunc = roc_nix_get_pf_func(roc_nix);
338
339                 rc = mbox_process_msg(mbox, (void *)&rpm_resp);
340                 if (rc)
341                         return rc;
342
343                 for (i = 0; i < roc_nix_num_rx_xstats(); i++) {
344                         xstats[count].value =
345                                 rpm_resp->rx_stats[nix_rx_xstats_rpm[i].offset];
346                         xstats[count].id = count;
347                         count++;
348                 }
349
350                 for (i = 0; i < roc_nix_num_tx_xstats(); i++) {
351                         xstats[count].value =
352                                 rpm_resp->tx_stats[nix_tx_xstats_rpm[i].offset];
353                         xstats[count].id = count;
354                         count++;
355                 }
356
357                 for (i = 0; i < CNXK_NIX_NUM_CN10K_RX_XSTATS; i++) {
358                         xstats[count].value =
359                                 NIX_RX_STATS(nix_cn10k_rx_xstats[i].offset);
360                         xstats[count].id = count;
361                         count++;
362                 }
363         }
364
365         return count;
366 }
367
368 int
369 roc_nix_xstats_names_get(struct roc_nix *roc_nix,
370                          struct roc_nix_xstat_name *xstats_names,
371                          unsigned int limit)
372 {
373         uint64_t i, count = 0;
374         uint32_t xstat_cnt;
375
376         xstat_cnt = roc_nix_num_xstats_get(roc_nix);
377         if (limit < xstat_cnt && xstats_names != NULL)
378                 return -ENOMEM;
379
380         if (xstats_names) {
381                 for (i = 0; i < CNXK_NIX_NUM_TX_XSTATS; i++) {
382                         snprintf(xstats_names[count].name,
383                                  sizeof(xstats_names[count].name), "%s",
384                                  nix_tx_xstats[i].name);
385                         count++;
386                 }
387
388                 for (i = 0; i < CNXK_NIX_NUM_RX_XSTATS; i++) {
389                         snprintf(xstats_names[count].name,
390                                  sizeof(xstats_names[count].name), "%s",
391                                  nix_rx_xstats[i].name);
392                         count++;
393                 }
394                 for (i = 0; i < CNXK_NIX_NUM_QUEUE_XSTATS; i++) {
395                         snprintf(xstats_names[count].name,
396                                  sizeof(xstats_names[count].name), "%s",
397                                  nix_q_xstats[i].name);
398                         count++;
399                 }
400
401                 if (roc_nix_is_vf_or_sdp(roc_nix))
402                         return count;
403
404                 if (roc_model_is_cn9k()) {
405                         for (i = 0; i < roc_nix_num_rx_xstats(); i++) {
406                                 snprintf(xstats_names[count].name,
407                                          sizeof(xstats_names[count].name), "%s",
408                                          nix_rx_xstats_cgx[i].name);
409                                 count++;
410                         }
411
412                         for (i = 0; i < roc_nix_num_tx_xstats(); i++) {
413                                 snprintf(xstats_names[count].name,
414                                          sizeof(xstats_names[count].name), "%s",
415                                          nix_tx_xstats_cgx[i].name);
416                                 count++;
417                         }
418                 } else {
419                         for (i = 0; i < roc_nix_num_rx_xstats(); i++) {
420                                 snprintf(xstats_names[count].name,
421                                          sizeof(xstats_names[count].name), "%s",
422                                          nix_rx_xstats_rpm[i].name);
423                                 count++;
424                         }
425
426                         for (i = 0; i < roc_nix_num_tx_xstats(); i++) {
427                                 snprintf(xstats_names[count].name,
428                                          sizeof(xstats_names[count].name), "%s",
429                                          nix_tx_xstats_rpm[i].name);
430                                 count++;
431                         }
432
433                         for (i = 0; i < CNXK_NIX_NUM_CN10K_RX_XSTATS; i++) {
434                                 snprintf(xstats_names[count].name,
435                                          sizeof(xstats_names[count].name), "%s",
436                                          nix_cn10k_rx_xstats[i].name);
437                                 count++;
438                         }
439                 }
440         }
441
442         return xstat_cnt;
443 }