net/ice: refine debug build option
[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                 aq->qidx = qid;
128                 aq->ctype = NIX_AQ_CTYPE_RQ;
129                 aq->op = NIX_AQ_INSTOP_WRITE;
130
131                 aq->rq.octs = 0;
132                 aq->rq.pkts = 0;
133                 aq->rq.drop_octs = 0;
134                 aq->rq.drop_pkts = 0;
135                 aq->rq.re_pkts = 0;
136
137                 aq->rq_mask.octs = ~(aq->rq_mask.octs);
138                 aq->rq_mask.pkts = ~(aq->rq_mask.pkts);
139                 aq->rq_mask.drop_octs = ~(aq->rq_mask.drop_octs);
140                 aq->rq_mask.drop_pkts = ~(aq->rq_mask.drop_pkts);
141                 aq->rq_mask.re_pkts = ~(aq->rq_mask.re_pkts);
142         } else {
143                 struct nix_cn10k_aq_enq_req *aq;
144
145                 aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
146                 aq->qidx = qid;
147                 aq->ctype = NIX_AQ_CTYPE_RQ;
148                 aq->op = NIX_AQ_INSTOP_WRITE;
149
150                 aq->rq.octs = 0;
151                 aq->rq.pkts = 0;
152                 aq->rq.drop_octs = 0;
153                 aq->rq.drop_pkts = 0;
154                 aq->rq.re_pkts = 0;
155
156                 aq->rq_mask.octs = ~(aq->rq_mask.octs);
157                 aq->rq_mask.pkts = ~(aq->rq_mask.pkts);
158                 aq->rq_mask.drop_octs = ~(aq->rq_mask.drop_octs);
159                 aq->rq_mask.drop_pkts = ~(aq->rq_mask.drop_pkts);
160                 aq->rq_mask.re_pkts = ~(aq->rq_mask.re_pkts);
161         }
162
163         rc = mbox_process(mbox);
164         return rc ? NIX_ERR_AQ_WRITE_FAILED : 0;
165 }
166
167 static int
168 nix_stat_tx_queue_reset(struct nix *nix, uint16_t qid)
169 {
170         struct mbox *mbox = (&nix->dev)->mbox;
171         int rc;
172
173         if (roc_model_is_cn9k()) {
174                 struct nix_aq_enq_req *aq;
175
176                 aq = mbox_alloc_msg_nix_aq_enq(mbox);
177                 aq->qidx = qid;
178                 aq->ctype = NIX_AQ_CTYPE_SQ;
179                 aq->op = NIX_AQ_INSTOP_WRITE;
180                 aq->sq.octs = 0;
181                 aq->sq.pkts = 0;
182                 aq->sq.drop_octs = 0;
183                 aq->sq.drop_pkts = 0;
184
185                 aq->sq_mask.octs = ~(aq->sq_mask.octs);
186                 aq->sq_mask.pkts = ~(aq->sq_mask.pkts);
187                 aq->sq_mask.drop_octs = ~(aq->sq_mask.drop_octs);
188                 aq->sq_mask.drop_pkts = ~(aq->sq_mask.drop_pkts);
189         } else {
190                 struct nix_cn10k_aq_enq_req *aq;
191
192                 aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
193                 aq->qidx = qid;
194                 aq->ctype = NIX_AQ_CTYPE_SQ;
195                 aq->op = NIX_AQ_INSTOP_WRITE;
196                 aq->sq.octs = 0;
197                 aq->sq.pkts = 0;
198                 aq->sq.drop_octs = 0;
199                 aq->sq.drop_pkts = 0;
200
201                 aq->sq_mask.octs = ~(aq->sq_mask.octs);
202                 aq->sq_mask.pkts = ~(aq->sq_mask.pkts);
203                 aq->sq_mask.drop_octs = ~(aq->sq_mask.drop_octs);
204                 aq->sq_mask.drop_pkts = ~(aq->sq_mask.drop_pkts);
205         }
206
207         rc = mbox_process(mbox);
208         return rc ? NIX_ERR_AQ_WRITE_FAILED : 0;
209 }
210
211 int
212 roc_nix_stats_queue_get(struct roc_nix *roc_nix, uint16_t qid, bool is_rx,
213                         struct roc_nix_stats_queue *qstats)
214 {
215         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
216         int rc;
217
218         if (qstats == NULL)
219                 return NIX_ERR_PARAM;
220
221         rc = queue_is_valid(nix, qid, is_rx);
222         if (rc)
223                 goto fail;
224
225         if (is_rx)
226                 nix_stat_rx_queue_get(nix, qid, qstats);
227         else
228                 nix_stat_tx_queue_get(nix, qid, qstats);
229
230 fail:
231         return rc;
232 }
233
234 int
235 roc_nix_stats_queue_reset(struct roc_nix *roc_nix, uint16_t qid, bool is_rx)
236 {
237         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
238         int rc;
239
240         rc = queue_is_valid(nix, qid, is_rx);
241         if (rc)
242                 goto fail;
243
244         if (is_rx)
245                 rc = nix_stat_rx_queue_reset(nix, qid);
246         else
247                 rc = nix_stat_tx_queue_reset(nix, qid);
248
249 fail:
250         return rc;
251 }
252
253 int
254 roc_nix_xstats_get(struct roc_nix *roc_nix, struct roc_nix_xstat *xstats,
255                    unsigned int n)
256 {
257         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
258         struct mbox *mbox = (&nix->dev)->mbox;
259         struct cgx_stats_rsp *cgx_resp;
260         struct rpm_stats_rsp *rpm_resp;
261         uint64_t i, count = 0;
262         struct msg_req *req;
263         uint32_t xstat_cnt;
264         int rc;
265
266         xstat_cnt = roc_nix_num_xstats_get(roc_nix);
267         if (n < xstat_cnt)
268                 return xstat_cnt;
269
270         if (xstats == NULL)
271                 return -EINVAL;
272
273         memset(xstats, 0, (xstat_cnt * sizeof(*xstats)));
274         for (i = 0; i < CNXK_NIX_NUM_TX_XSTATS; i++) {
275                 xstats[count].value = NIX_TX_STATS(nix_tx_xstats[i].offset);
276                 xstats[count].id = count;
277                 count++;
278         }
279
280         for (i = 0; i < CNXK_NIX_NUM_RX_XSTATS; i++) {
281                 xstats[count].value = NIX_RX_STATS(nix_rx_xstats[i].offset);
282                 xstats[count].id = count;
283                 count++;
284         }
285
286         for (i = 0; i < nix->nb_rx_queues; i++)
287                 xstats[count].value +=
288                         qstat_read(nix, i, nix_q_xstats[0].offset);
289
290         xstats[count].id = count;
291         count++;
292
293         if (roc_nix_is_vf_or_sdp(roc_nix))
294                 return count;
295
296         if (roc_model_is_cn9k()) {
297                 req = mbox_alloc_msg_cgx_stats(mbox);
298                 req->hdr.pcifunc = roc_nix_get_pf_func(roc_nix);
299
300                 rc = mbox_process_msg(mbox, (void *)&cgx_resp);
301                 if (rc)
302                         return rc;
303
304                 for (i = 0; i < roc_nix_num_rx_xstats(); i++) {
305                         xstats[count].value =
306                                 cgx_resp->rx_stats[nix_rx_xstats_cgx[i].offset];
307                         xstats[count].id = count;
308                         count++;
309                 }
310
311                 for (i = 0; i < roc_nix_num_tx_xstats(); i++) {
312                         xstats[count].value =
313                                 cgx_resp->tx_stats[nix_tx_xstats_cgx[i].offset];
314                         xstats[count].id = count;
315                         count++;
316                 }
317         } else {
318                 req = mbox_alloc_msg_rpm_stats(mbox);
319                 req->hdr.pcifunc = roc_nix_get_pf_func(roc_nix);
320
321                 rc = mbox_process_msg(mbox, (void *)&rpm_resp);
322                 if (rc)
323                         return rc;
324
325                 for (i = 0; i < roc_nix_num_rx_xstats(); i++) {
326                         xstats[count].value =
327                                 rpm_resp->rx_stats[nix_rx_xstats_rpm[i].offset];
328                         xstats[count].id = count;
329                         count++;
330                 }
331
332                 for (i = 0; i < roc_nix_num_tx_xstats(); i++) {
333                         xstats[count].value =
334                                 rpm_resp->tx_stats[nix_tx_xstats_rpm[i].offset];
335                         xstats[count].id = count;
336                         count++;
337                 }
338         }
339
340         return count;
341 }
342
343 int
344 roc_nix_xstats_names_get(struct roc_nix *roc_nix,
345                          struct roc_nix_xstat_name *xstats_names,
346                          unsigned int limit)
347 {
348         uint64_t i, count = 0;
349         uint32_t xstat_cnt;
350
351         xstat_cnt = roc_nix_num_xstats_get(roc_nix);
352         if (limit < xstat_cnt && xstats_names != NULL)
353                 return -ENOMEM;
354
355         if (xstats_names) {
356                 for (i = 0; i < CNXK_NIX_NUM_TX_XSTATS; i++) {
357                         snprintf(xstats_names[count].name,
358                                  sizeof(xstats_names[count].name), "%s",
359                                  nix_tx_xstats[i].name);
360                         count++;
361                 }
362
363                 for (i = 0; i < CNXK_NIX_NUM_RX_XSTATS; i++) {
364                         snprintf(xstats_names[count].name,
365                                  sizeof(xstats_names[count].name), "%s",
366                                  nix_rx_xstats[i].name);
367                         count++;
368                 }
369                 for (i = 0; i < CNXK_NIX_NUM_QUEUE_XSTATS; i++) {
370                         snprintf(xstats_names[count].name,
371                                  sizeof(xstats_names[count].name), "%s",
372                                  nix_q_xstats[i].name);
373                         count++;
374                 }
375
376                 if (roc_nix_is_vf_or_sdp(roc_nix))
377                         return count;
378
379                 if (roc_model_is_cn9k()) {
380                         for (i = 0; i < roc_nix_num_rx_xstats(); i++) {
381                                 snprintf(xstats_names[count].name,
382                                          sizeof(xstats_names[count].name), "%s",
383                                          nix_rx_xstats_cgx[i].name);
384                                 count++;
385                         }
386
387                         for (i = 0; i < roc_nix_num_tx_xstats(); i++) {
388                                 snprintf(xstats_names[count].name,
389                                          sizeof(xstats_names[count].name), "%s",
390                                          nix_tx_xstats_cgx[i].name);
391                                 count++;
392                         }
393                 } else {
394                         for (i = 0; i < roc_nix_num_rx_xstats(); i++) {
395                                 snprintf(xstats_names[count].name,
396                                          sizeof(xstats_names[count].name), "%s",
397                                          nix_rx_xstats_rpm[i].name);
398                                 count++;
399                         }
400
401                         for (i = 0; i < roc_nix_num_tx_xstats(); i++) {
402                                 snprintf(xstats_names[count].name,
403                                          sizeof(xstats_names[count].name), "%s",
404                                          nix_tx_xstats_rpm[i].name);
405                                 count++;
406                         }
407                 }
408         }
409
410         return xstat_cnt;
411 }