common/cnxk: fix null access in IPv6 flow parsing
[dpdk.git] / drivers / common / cnxk / roc_nix_bpf.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4
5 #include "roc_api.h"
6 #include "roc_priv.h"
7
8 #define NIX_MAX_BPF_COUNT_LEAF_LAYER 64
9 #define NIX_MAX_BPF_COUNT_MID_LAYER  8
10 #define NIX_MAX_BPF_COUNT_TOP_LAYER  1
11
12 #define NIX_BPF_PRECOLOR_GEN_TABLE_SIZE  16
13 #define NIX_BPF_PRECOLOR_VLAN_TABLE_SIZE 16
14 #define NIX_BPF_PRECOLOR_DSCP_TABLE_SIZE 64
15
16 #define NIX_BPF_LEVEL_F_MASK                                                   \
17         (ROC_NIX_BPF_LEVEL_F_LEAF | ROC_NIX_BPF_LEVEL_F_MID |                  \
18          ROC_NIX_BPF_LEVEL_F_TOP)
19
20 #define NIX_RD_STATS(val)  plt_read64(nix->base + NIX_LF_RX_STATX(val))
21 #define NIX_RST_STATS(val) plt_write64(0, nix->base + NIX_LF_RX_STATX(val))
22
23 static uint8_t sw_to_hw_lvl_map[] = {NIX_RX_BAND_PROF_LAYER_LEAF,
24                                      NIX_RX_BAND_PROF_LAYER_MIDDLE,
25                                      NIX_RX_BAND_PROF_LAYER_TOP};
26
27 static inline struct mbox *
28 get_mbox(struct roc_nix *roc_nix)
29 {
30         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
31         struct dev *dev = &nix->dev;
32
33         return dev->mbox;
34 }
35
36 static inline uint64_t
37 meter_rate_to_nix(uint64_t value, uint64_t *exponent_p, uint64_t *mantissa_p,
38                   uint64_t *div_exp_p, uint32_t timeunit_p)
39 {
40         uint64_t div_exp, exponent, mantissa;
41         uint32_t time_ns = timeunit_p;
42
43         /* Boundary checks */
44         if (value < NIX_BPF_RATE(time_ns, 0, 0, 0) ||
45             value > NIX_BPF_RATE(time_ns, NIX_BPF_MAX_RATE_EXPONENT,
46                                  NIX_BPF_MAX_RATE_MANTISSA, 0))
47                 return 0;
48
49         div_exp = 0;
50         exponent = NIX_BPF_MAX_RATE_EXPONENT;
51         mantissa = NIX_BPF_MAX_RATE_MANTISSA;
52
53         while (value < (NIX_BPF_RATE(time_ns, exponent, 0, 0)))
54                 exponent -= 1;
55
56         while (value < (NIX_BPF_RATE(time_ns, exponent, mantissa, 0)))
57                 mantissa -= 1;
58
59         if (div_exp > NIX_BPF_MAX_RATE_DIV_EXP ||
60             exponent > NIX_BPF_MAX_RATE_EXPONENT ||
61             mantissa > NIX_BPF_MAX_RATE_MANTISSA)
62                 return 0;
63
64         if (div_exp_p)
65                 *div_exp_p = div_exp;
66         if (exponent_p)
67                 *exponent_p = exponent;
68         if (mantissa_p)
69                 *mantissa_p = mantissa;
70
71         /* Calculate real rate value */
72         return NIX_BPF_RATE(time_ns, exponent, mantissa, div_exp);
73 }
74
75 static inline uint64_t
76 meter_burst_to_nix(uint64_t value, uint64_t *exponent_p, uint64_t *mantissa_p)
77 {
78         uint64_t exponent, mantissa;
79
80         if (value < NIX_BPF_BURST_MIN || value > NIX_BPF_BURST_MAX)
81                 return 0;
82
83         /* Calculate burst exponent and mantissa using
84          * the following formula:
85          *
86          * value = (((256 + mantissa) << (exponent + 1)
87          / 256)
88          *
89          */
90         exponent = NIX_BPF_MAX_BURST_EXPONENT;
91         mantissa = NIX_BPF_MAX_BURST_MANTISSA;
92
93         while (value < (1ull << (exponent + 1)))
94                 exponent -= 1;
95
96         while (value < ((256 + mantissa) << (exponent + 1)) / 256)
97                 mantissa -= 1;
98
99         if (exponent > NIX_BPF_MAX_BURST_EXPONENT ||
100             mantissa > NIX_BPF_MAX_BURST_MANTISSA)
101                 return 0;
102
103         if (exponent_p)
104                 *exponent_p = exponent;
105         if (mantissa_p)
106                 *mantissa_p = mantissa;
107
108         return NIX_BPF_BURST(exponent, mantissa);
109 }
110
111 static inline void
112 nix_lf_bpf_dump(__io struct nix_band_prof_s *bpf)
113 {
114         plt_dump("W0: cir_mantissa  \t\t\t%d\nW0: pebs_mantissa \t\t\t0x%03x",
115                  bpf->cir_mantissa, bpf->pebs_mantissa);
116         plt_dump("W0: peir_mantissa \t\t\t\t%d\nW0: cbs_exponent \t\t\t%d",
117                  bpf->peir_mantissa, bpf->cbs_exponent);
118         plt_dump("W0: cir_exponent \t\t\t%d\nW0: pebs_exponent \t\t\t%d",
119                  bpf->cir_exponent, bpf->pebs_exponent);
120         plt_dump("W0: peir_exponent \t\t\t%d\n", bpf->peir_exponent);
121         plt_dump("W0: tnl_ena \t\t\t%d\n", bpf->tnl_ena);
122         plt_dump("W0: icolor \t\t\t%d\n", bpf->icolor);
123         plt_dump("W0: pc_mode \t\t\t%d\n", bpf->pc_mode);
124         plt_dump("W1: hl_en \t\t%d\nW1: band_prof_id \t\t%d", bpf->hl_en,
125                  bpf->band_prof_id);
126         plt_dump("W1: meter_algo \t\t%d\nW1: rc_action \t\t%d", bpf->meter_algo,
127                  bpf->rc_action);
128         plt_dump("W1: yc_action \t\t\t%d\nW1: gc_action \t\t\t%d",
129                  bpf->yc_action, bpf->gc_action);
130         plt_dump("W1: adjust_mantissa\t\t\t%d\nW1: adjust_exponent \t\t\t%d",
131                  bpf->adjust_mantissa, bpf->adjust_exponent);
132         plt_dump("W1: rdiv \t\t\t%d\n", bpf->rdiv);
133         plt_dump("W1: l_select \t\t%d\nW2: lmode \t\t%d", bpf->l_sellect,
134                  bpf->lmode);
135         plt_dump("W1: cbs_mantissa \t\t\t%d\n", bpf->cbs_mantissa);
136         plt_dump("W2: tsa \t\t\t0x%" PRIx64 "\n", (uint64_t)bpf->ts);
137         plt_dump("W3: c_accum \t\t%d\nW3: pe_accum \t\t%d", bpf->c_accum,
138                  bpf->pe_accum);
139         plt_dump("W4: green_pkt_pass \t\t\t0x%" PRIx64 "",
140                  (uint64_t)bpf->green_pkt_pass);
141         plt_dump("W5: yellow_pkt_pass \t\t\t0x%" PRIx64 "",
142                  (uint64_t)bpf->yellow_pkt_pass);
143         plt_dump("W6: red_pkt_pass \t\t\t0x%" PRIx64 "",
144                  (uint64_t)bpf->red_pkt_pass);
145         plt_dump("W7: green_octs_pass \t\t\t0x%" PRIx64 "",
146                  (uint64_t)bpf->green_octs_pass);
147         plt_dump("W8: yellow_octs_pass \t\t\t0x%" PRIx64 "",
148                  (uint64_t)bpf->yellow_octs_pass);
149         plt_dump("W9: red_octs_pass \t\t\t0x%" PRIx64 "",
150                  (uint64_t)bpf->red_octs_pass);
151         plt_dump("W10: green_pkt_drop \t\t\t0x%" PRIx64 "",
152                  (uint64_t)bpf->green_pkt_drop);
153         plt_dump("W11: yellow_pkt_drop \t\t\t0x%" PRIx64 "",
154                  (uint64_t)bpf->yellow_pkt_drop);
155         plt_dump("W12: red_pkt_drop \t\t\t0x%" PRIx64 "",
156                  (uint64_t)bpf->red_pkt_drop);
157         plt_dump("W13: green_octs_drop \t\t\t0x%" PRIx64 "",
158                  (uint64_t)bpf->green_octs_drop);
159         plt_dump("W14: yellow_octs_drop \t\t\t0x%" PRIx64 "",
160                  (uint64_t)bpf->yellow_octs_drop);
161         plt_dump("W15: red_octs_drop \t\t\t0x%" PRIx64 "",
162                  (uint64_t)bpf->red_octs_drop);
163 }
164
165 static inline void
166 nix_precolor_conv_table_write(struct roc_nix *roc_nix, uint64_t val,
167                               uint32_t off)
168 {
169         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
170         int64_t *addr;
171
172         addr = PLT_PTR_ADD(nix->base, off);
173         plt_write64(val, addr);
174 }
175
176 static uint8_t
177 nix_precolor_vlan_table_update(struct roc_nix *roc_nix,
178                                struct roc_nix_bpf_precolor *tbl)
179 {
180         uint64_t val = 0, i;
181         uint8_t tn_ena;
182         uint32_t off;
183
184         for (i = 0; i < tbl->count; i++)
185                 val |= (((uint64_t)tbl->color[i]) << (2 * i));
186
187         if (tbl->mode == ROC_NIX_BPF_PC_MODE_VLAN_INNER) {
188                 off = NIX_LF_RX_VLAN1_COLOR_CONV;
189                 tn_ena = true;
190         } else {
191                 off = NIX_LF_RX_VLAN0_COLOR_CONV;
192                 tn_ena = false;
193         }
194
195         nix_precolor_conv_table_write(roc_nix, val, off);
196         return tn_ena;
197 }
198
199 static uint8_t
200 nix_precolor_inner_dscp_table_update(struct roc_nix *roc_nix,
201                                      struct roc_nix_bpf_precolor *tbl)
202 {
203         uint64_t val_lo = 0, val_hi = 0, i, j;
204
205         for (i = 0, j = 0; i < (tbl->count / 2); i++, j++)
206                 val_lo |= (((uint64_t)tbl->color[i]) << (2 * j));
207
208         for (j = 0; i < tbl->count; i++, j++)
209                 val_hi |= (((uint64_t)tbl->color[i]) << (2 * j));
210
211         nix_precolor_conv_table_write(roc_nix, val_lo,
212                                       NIX_LF_RX_IIP_COLOR_CONV_LO);
213         nix_precolor_conv_table_write(roc_nix, val_hi,
214                                       NIX_LF_RX_IIP_COLOR_CONV_HI);
215
216         return true;
217 }
218
219 static uint8_t
220 nix_precolor_outer_dscp_table_update(struct roc_nix *roc_nix,
221                                      struct roc_nix_bpf_precolor *tbl)
222 {
223         uint64_t val_lo = 0, val_hi = 0, i, j;
224
225         for (i = 0, j = 0; i < (tbl->count / 2); i++, j++)
226                 val_lo |= (((uint64_t)tbl->color[i]) << (2 * j));
227
228         for (j = 0; i < tbl->count; i++, j++)
229                 val_hi |= (((uint64_t)tbl->color[i]) << (2 * j));
230
231         nix_precolor_conv_table_write(roc_nix, val_lo,
232                                       NIX_LF_RX_OIP_COLOR_CONV_LO);
233         nix_precolor_conv_table_write(roc_nix, val_hi,
234                                       NIX_LF_RX_OIP_COLOR_CONV_HI);
235
236         return false;
237 }
238
239 static uint8_t
240 nix_precolor_gen_table_update(struct roc_nix *roc_nix,
241                               struct roc_nix_bpf_precolor *tbl)
242 {
243         uint64_t val = 0, i;
244         uint8_t tn_ena;
245         uint32_t off;
246
247         for (i = 0; i < tbl->count; i++)
248                 val |= (((uint64_t)tbl->color[i]) << (2 * i));
249
250         if (tbl->mode == ROC_NIX_BPF_PC_MODE_GEN_INNER) {
251                 off = NIX_LF_RX_GEN_COLOR_CONVX(1);
252                 tn_ena = true;
253         } else {
254                 off = NIX_LF_RX_GEN_COLOR_CONVX(0);
255                 tn_ena = false;
256         }
257
258         nix_precolor_conv_table_write(roc_nix, val, off);
259         return tn_ena;
260 }
261
262 uint8_t
263 roc_nix_bpf_level_to_idx(enum roc_nix_bpf_level_flag level_f)
264 {
265         uint8_t idx;
266
267         if (level_f & ROC_NIX_BPF_LEVEL_F_LEAF)
268                 idx = 0;
269         else if (level_f & ROC_NIX_BPF_LEVEL_F_MID)
270                 idx = 1;
271         else if (level_f & ROC_NIX_BPF_LEVEL_F_TOP)
272                 idx = 2;
273         else
274                 idx = ROC_NIX_BPF_LEVEL_IDX_INVALID;
275         return idx;
276 }
277
278 uint8_t
279 roc_nix_bpf_stats_to_idx(enum roc_nix_bpf_stats level_f)
280 {
281         uint8_t idx;
282
283         if (level_f & ROC_NIX_BPF_GREEN_PKT_F_PASS)
284                 idx = 0;
285         else if (level_f & ROC_NIX_BPF_GREEN_OCTS_F_PASS)
286                 idx = 1;
287         else if (level_f & ROC_NIX_BPF_GREEN_PKT_F_DROP)
288                 idx = 2;
289         else if (level_f & ROC_NIX_BPF_GREEN_OCTS_F_DROP)
290                 idx = 3;
291         else if (level_f & ROC_NIX_BPF_YELLOW_PKT_F_PASS)
292                 idx = 4;
293         else if (level_f & ROC_NIX_BPF_YELLOW_OCTS_F_PASS)
294                 idx = 5;
295         else if (level_f & ROC_NIX_BPF_YELLOW_PKT_F_DROP)
296                 idx = 6;
297         else if (level_f & ROC_NIX_BPF_YELLOW_OCTS_F_DROP)
298                 idx = 7;
299         else if (level_f & ROC_NIX_BPF_RED_PKT_F_PASS)
300                 idx = 8;
301         else if (level_f & ROC_NIX_BPF_RED_OCTS_F_PASS)
302                 idx = 9;
303         else if (level_f & ROC_NIX_BPF_RED_PKT_F_DROP)
304                 idx = 10;
305         else if (level_f & ROC_NIX_BPF_RED_OCTS_F_DROP)
306                 idx = 11;
307         else
308                 idx = ROC_NIX_BPF_STATS_MAX;
309         return idx;
310 }
311
312 int
313 roc_nix_bpf_timeunit_get(struct roc_nix *roc_nix, uint32_t *time_unit)
314 {
315         struct nix_bandprof_get_hwinfo_rsp *rsp;
316         struct mbox *mbox = get_mbox(roc_nix);
317         struct msg_req *req;
318         int rc = -ENOSPC;
319
320         if (roc_model_is_cn9k())
321                 return NIX_ERR_HW_NOTSUP;
322
323         req = mbox_alloc_msg_nix_bandprof_get_hwinfo(mbox);
324         if (req == NULL)
325                 goto exit;
326
327         rc = mbox_process_msg(mbox, (void *)&rsp);
328         if (rc)
329                 goto exit;
330
331         *time_unit = rsp->policer_timeunit;
332
333 exit:
334         return rc;
335 }
336
337 int
338 roc_nix_bpf_count_get(struct roc_nix *roc_nix, uint8_t lvl_mask,
339                       uint16_t count[ROC_NIX_BPF_LEVEL_MAX])
340 {
341         uint8_t mask = lvl_mask & NIX_BPF_LEVEL_F_MASK;
342         struct nix_bandprof_get_hwinfo_rsp *rsp;
343         struct mbox *mbox = get_mbox(roc_nix);
344         uint8_t leaf_idx, mid_idx, top_idx;
345         struct msg_req *req;
346         int rc = -ENOSPC;
347
348         if (roc_model_is_cn9k())
349                 return NIX_ERR_HW_NOTSUP;
350
351         if (!mask)
352                 return NIX_ERR_PARAM;
353
354         req = mbox_alloc_msg_nix_bandprof_get_hwinfo(mbox);
355         if (req == NULL)
356                 goto exit;
357
358         rc = mbox_process_msg(mbox, (void *)&rsp);
359         if (rc)
360                 goto exit;
361
362         leaf_idx = roc_nix_bpf_level_to_idx(mask & ROC_NIX_BPF_LEVEL_F_LEAF);
363         mid_idx = roc_nix_bpf_level_to_idx(mask & ROC_NIX_BPF_LEVEL_F_MID);
364         top_idx = roc_nix_bpf_level_to_idx(mask & ROC_NIX_BPF_LEVEL_F_TOP);
365
366         if (leaf_idx != ROC_NIX_BPF_LEVEL_IDX_INVALID)
367                 count[leaf_idx] = rsp->prof_count[sw_to_hw_lvl_map[leaf_idx]];
368
369         if (mid_idx != ROC_NIX_BPF_LEVEL_IDX_INVALID)
370                 count[mid_idx] = rsp->prof_count[sw_to_hw_lvl_map[mid_idx]];
371
372         if (top_idx != ROC_NIX_BPF_LEVEL_IDX_INVALID)
373                 count[top_idx] = rsp->prof_count[sw_to_hw_lvl_map[top_idx]];
374
375 exit:
376         return rc;
377 }
378
379 int
380 roc_nix_bpf_alloc(struct roc_nix *roc_nix, uint8_t lvl_mask,
381                   uint16_t per_lvl_cnt[ROC_NIX_BPF_LEVEL_MAX],
382                   struct roc_nix_bpf_objs *profs)
383 {
384         uint8_t mask = lvl_mask & NIX_BPF_LEVEL_F_MASK;
385         struct mbox *mbox = get_mbox(roc_nix);
386         struct nix_bandprof_alloc_req *req;
387         struct nix_bandprof_alloc_rsp *rsp;
388         uint8_t leaf_idx, mid_idx, top_idx;
389         int rc = -ENOSPC, i;
390
391         if (roc_model_is_cn9k())
392                 return NIX_ERR_HW_NOTSUP;
393
394         if (!mask)
395                 return NIX_ERR_PARAM;
396
397         leaf_idx = roc_nix_bpf_level_to_idx(mask & ROC_NIX_BPF_LEVEL_F_LEAF);
398         mid_idx = roc_nix_bpf_level_to_idx(mask & ROC_NIX_BPF_LEVEL_F_MID);
399         top_idx = roc_nix_bpf_level_to_idx(mask & ROC_NIX_BPF_LEVEL_F_TOP);
400
401         if ((leaf_idx != ROC_NIX_BPF_LEVEL_IDX_INVALID) &&
402             (per_lvl_cnt[leaf_idx] > NIX_MAX_BPF_COUNT_LEAF_LAYER))
403                 return NIX_ERR_INVALID_RANGE;
404
405         if ((mid_idx != ROC_NIX_BPF_LEVEL_IDX_INVALID) &&
406             (per_lvl_cnt[mid_idx] > NIX_MAX_BPF_COUNT_MID_LAYER))
407                 return NIX_ERR_INVALID_RANGE;
408
409         if ((top_idx != ROC_NIX_BPF_LEVEL_IDX_INVALID) &&
410             (per_lvl_cnt[top_idx] > NIX_MAX_BPF_COUNT_TOP_LAYER))
411                 return NIX_ERR_INVALID_RANGE;
412
413         req = mbox_alloc_msg_nix_bandprof_alloc(mbox);
414         if (req == NULL)
415                 goto exit;
416
417         if (leaf_idx != ROC_NIX_BPF_LEVEL_IDX_INVALID) {
418                 req->prof_count[sw_to_hw_lvl_map[leaf_idx]] =
419                         per_lvl_cnt[leaf_idx];
420         }
421
422         if (mid_idx != ROC_NIX_BPF_LEVEL_IDX_INVALID) {
423                 req->prof_count[sw_to_hw_lvl_map[mid_idx]] =
424                         per_lvl_cnt[mid_idx];
425         }
426
427         if (top_idx != ROC_NIX_BPF_LEVEL_IDX_INVALID) {
428                 req->prof_count[sw_to_hw_lvl_map[top_idx]] =
429                         per_lvl_cnt[top_idx];
430         }
431
432         rc = mbox_process_msg(mbox, (void *)&rsp);
433         if (rc)
434                 goto exit;
435
436         if (leaf_idx != ROC_NIX_BPF_LEVEL_IDX_INVALID) {
437                 profs[leaf_idx].level = leaf_idx;
438                 profs[leaf_idx].count =
439                         rsp->prof_count[sw_to_hw_lvl_map[leaf_idx]];
440                 for (i = 0; i < profs[leaf_idx].count; i++) {
441                         profs[leaf_idx].ids[i] =
442                                 rsp->prof_idx[sw_to_hw_lvl_map[leaf_idx]][i];
443                 }
444         }
445
446         if (mid_idx != ROC_NIX_BPF_LEVEL_IDX_INVALID) {
447                 profs[mid_idx].level = mid_idx;
448                 profs[mid_idx].count =
449                         rsp->prof_count[sw_to_hw_lvl_map[mid_idx]];
450                 for (i = 0; i < profs[mid_idx].count; i++) {
451                         profs[mid_idx].ids[i] =
452                                 rsp->prof_idx[sw_to_hw_lvl_map[mid_idx]][i];
453                 }
454         }
455
456         if (top_idx != ROC_NIX_BPF_LEVEL_IDX_INVALID) {
457                 profs[top_idx].level = top_idx;
458                 profs[top_idx].count =
459                         rsp->prof_count[sw_to_hw_lvl_map[top_idx]];
460                 for (i = 0; i < profs[top_idx].count; i++) {
461                         profs[top_idx].ids[i] =
462                                 rsp->prof_idx[sw_to_hw_lvl_map[top_idx]][i];
463                 }
464         }
465
466 exit:
467         return rc;
468 }
469
470 int
471 roc_nix_bpf_free(struct roc_nix *roc_nix, struct roc_nix_bpf_objs *profs,
472                  uint8_t num_prof)
473 {
474         struct mbox *mbox = get_mbox(roc_nix);
475         struct nix_bandprof_free_req *req;
476         uint8_t level;
477         int i, j;
478
479         if (num_prof >= NIX_RX_BAND_PROF_LAYER_MAX)
480                 return NIX_ERR_INVALID_RANGE;
481
482         req = mbox_alloc_msg_nix_bandprof_free(mbox);
483         if (req == NULL)
484                 return -ENOSPC;
485
486         for (i = 0; i < num_prof; i++) {
487                 level = sw_to_hw_lvl_map[profs[i].level];
488                 req->prof_count[level] = profs[i].count;
489                 for (j = 0; j < profs[i].count; j++)
490                         req->prof_idx[level][j] = profs[i].ids[j];
491         }
492
493         return mbox_process(mbox);
494 }
495
496 int
497 roc_nix_bpf_free_all(struct roc_nix *roc_nix)
498 {
499         struct mbox *mbox = get_mbox(roc_nix);
500         struct nix_bandprof_free_req *req;
501
502         req = mbox_alloc_msg_nix_bandprof_free(mbox);
503         if (req == NULL)
504                 return -ENOSPC;
505
506         req->free_all = true;
507         return mbox_process(mbox);
508 }
509
510 int
511 roc_nix_bpf_config(struct roc_nix *roc_nix, uint16_t id,
512                    enum roc_nix_bpf_level_flag lvl_flag,
513                    struct roc_nix_bpf_cfg *cfg)
514 {
515         uint64_t exponent_p = 0, mantissa_p = 0, div_exp_p = 0;
516         struct mbox *mbox = get_mbox(roc_nix);
517         struct nix_cn10k_aq_enq_req *aq;
518         uint32_t policer_timeunit;
519         uint8_t level_idx;
520         int rc;
521
522         if (roc_model_is_cn9k())
523                 return NIX_ERR_HW_NOTSUP;
524
525         if (!cfg)
526                 return NIX_ERR_PARAM;
527
528         rc = roc_nix_bpf_timeunit_get(roc_nix, &policer_timeunit);
529         if (rc)
530                 return rc;
531
532         level_idx = roc_nix_bpf_level_to_idx(lvl_flag);
533         if (level_idx == ROC_NIX_BPF_LEVEL_IDX_INVALID)
534                 return NIX_ERR_PARAM;
535
536         aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
537         if (aq == NULL)
538                 return -ENOSPC;
539         aq->qidx = (sw_to_hw_lvl_map[level_idx] << 14) | id;
540         aq->ctype = NIX_AQ_CTYPE_BAND_PROF;
541         aq->op = NIX_AQ_INSTOP_WRITE;
542
543         aq->prof.adjust_exponent = NIX_BPF_DEFAULT_ADJUST_EXPONENT;
544         aq->prof.adjust_mantissa = NIX_BPF_DEFAULT_ADJUST_MANTISSA;
545         if (cfg->lmode == ROC_NIX_BPF_LMODE_BYTE)
546                 aq->prof.adjust_mantissa = NIX_BPF_DEFAULT_ADJUST_MANTISSA / 2;
547
548         aq->prof_mask.adjust_exponent = ~(aq->prof_mask.adjust_exponent);
549         aq->prof_mask.adjust_mantissa = ~(aq->prof_mask.adjust_mantissa);
550
551         switch (cfg->alg) {
552         case ROC_NIX_BPF_ALGO_2697:
553                 meter_rate_to_nix(cfg->algo2697.cir, &exponent_p, &mantissa_p,
554                                   &div_exp_p, policer_timeunit);
555                 aq->prof.cir_mantissa = mantissa_p;
556                 aq->prof.cir_exponent = exponent_p;
557
558                 meter_burst_to_nix(cfg->algo2697.cbs, &exponent_p, &mantissa_p);
559                 aq->prof.cbs_mantissa = mantissa_p;
560                 aq->prof.cbs_exponent = exponent_p;
561
562                 meter_burst_to_nix(cfg->algo2697.ebs, &exponent_p, &mantissa_p);
563                 aq->prof.pebs_mantissa = mantissa_p;
564                 aq->prof.pebs_exponent = exponent_p;
565
566                 aq->prof_mask.cir_mantissa = ~(aq->prof_mask.cir_mantissa);
567                 aq->prof_mask.cbs_mantissa = ~(aq->prof_mask.cbs_mantissa);
568                 aq->prof_mask.pebs_mantissa = ~(aq->prof_mask.pebs_mantissa);
569                 aq->prof_mask.cir_exponent = ~(aq->prof_mask.cir_exponent);
570                 aq->prof_mask.cbs_exponent = ~(aq->prof_mask.cbs_exponent);
571                 aq->prof_mask.pebs_exponent = ~(aq->prof_mask.pebs_exponent);
572                 break;
573
574         case ROC_NIX_BPF_ALGO_2698:
575                 meter_rate_to_nix(cfg->algo2698.cir, &exponent_p, &mantissa_p,
576                                   &div_exp_p, policer_timeunit);
577                 aq->prof.cir_mantissa = mantissa_p;
578                 aq->prof.cir_exponent = exponent_p;
579
580                 meter_rate_to_nix(cfg->algo2698.pir, &exponent_p, &mantissa_p,
581                                   &div_exp_p, policer_timeunit);
582                 aq->prof.peir_mantissa = mantissa_p;
583                 aq->prof.peir_exponent = exponent_p;
584
585                 meter_burst_to_nix(cfg->algo2698.cbs, &exponent_p, &mantissa_p);
586                 aq->prof.cbs_mantissa = mantissa_p;
587                 aq->prof.cbs_exponent = exponent_p;
588
589                 meter_burst_to_nix(cfg->algo2698.pbs, &exponent_p, &mantissa_p);
590                 aq->prof.pebs_mantissa = mantissa_p;
591                 aq->prof.pebs_exponent = exponent_p;
592
593                 aq->prof_mask.cir_mantissa = ~(aq->prof_mask.cir_mantissa);
594                 aq->prof_mask.peir_mantissa = ~(aq->prof_mask.peir_mantissa);
595                 aq->prof_mask.cbs_mantissa = ~(aq->prof_mask.cbs_mantissa);
596                 aq->prof_mask.pebs_mantissa = ~(aq->prof_mask.pebs_mantissa);
597                 aq->prof_mask.cir_exponent = ~(aq->prof_mask.cir_exponent);
598                 aq->prof_mask.peir_exponent = ~(aq->prof_mask.peir_exponent);
599                 aq->prof_mask.cbs_exponent = ~(aq->prof_mask.cbs_exponent);
600                 aq->prof_mask.pebs_exponent = ~(aq->prof_mask.pebs_exponent);
601                 break;
602
603         case ROC_NIX_BPF_ALGO_4115:
604                 meter_rate_to_nix(cfg->algo4115.cir, &exponent_p, &mantissa_p,
605                                   &div_exp_p, policer_timeunit);
606                 aq->prof.cir_mantissa = mantissa_p;
607                 aq->prof.cir_exponent = exponent_p;
608
609                 meter_rate_to_nix(cfg->algo4115.eir, &exponent_p, &mantissa_p,
610                                   &div_exp_p, policer_timeunit);
611                 aq->prof.peir_mantissa = mantissa_p;
612                 aq->prof.peir_exponent = exponent_p;
613
614                 meter_burst_to_nix(cfg->algo4115.cbs, &exponent_p, &mantissa_p);
615                 aq->prof.cbs_mantissa = mantissa_p;
616                 aq->prof.cbs_exponent = exponent_p;
617
618                 meter_burst_to_nix(cfg->algo4115.ebs, &exponent_p, &mantissa_p);
619                 aq->prof.pebs_mantissa = mantissa_p;
620                 aq->prof.pebs_exponent = exponent_p;
621
622                 aq->prof_mask.cir_mantissa = ~(aq->prof_mask.cir_mantissa);
623                 aq->prof_mask.peir_mantissa = ~(aq->prof_mask.peir_mantissa);
624                 aq->prof_mask.cbs_mantissa = ~(aq->prof_mask.cbs_mantissa);
625                 aq->prof_mask.pebs_mantissa = ~(aq->prof_mask.pebs_mantissa);
626
627                 aq->prof_mask.cir_exponent = ~(aq->prof_mask.cir_exponent);
628                 aq->prof_mask.peir_exponent = ~(aq->prof_mask.peir_exponent);
629                 aq->prof_mask.cbs_exponent = ~(aq->prof_mask.cbs_exponent);
630                 aq->prof_mask.pebs_exponent = ~(aq->prof_mask.pebs_exponent);
631                 break;
632
633         default:
634                 return NIX_ERR_PARAM;
635         }
636
637         aq->prof.lmode = cfg->lmode;
638         aq->prof.icolor = cfg->icolor;
639         aq->prof.meter_algo = cfg->alg;
640         aq->prof.pc_mode = cfg->pc_mode;
641         aq->prof.tnl_ena = cfg->tnl_ena;
642         aq->prof.gc_action = cfg->action[ROC_NIX_BPF_COLOR_GREEN];
643         aq->prof.yc_action = cfg->action[ROC_NIX_BPF_COLOR_YELLOW];
644         aq->prof.rc_action = cfg->action[ROC_NIX_BPF_COLOR_RED];
645
646         aq->prof_mask.lmode = ~(aq->prof_mask.lmode);
647         aq->prof_mask.icolor = ~(aq->prof_mask.icolor);
648         aq->prof_mask.meter_algo = ~(aq->prof_mask.meter_algo);
649         aq->prof_mask.pc_mode = ~(aq->prof_mask.pc_mode);
650         aq->prof_mask.tnl_ena = ~(aq->prof_mask.tnl_ena);
651         aq->prof_mask.gc_action = ~(aq->prof_mask.gc_action);
652         aq->prof_mask.yc_action = ~(aq->prof_mask.yc_action);
653         aq->prof_mask.rc_action = ~(aq->prof_mask.rc_action);
654
655         return mbox_process(mbox);
656 }
657
658 int
659 roc_nix_bpf_ena_dis(struct roc_nix *roc_nix, uint16_t id, struct roc_nix_rq *rq,
660                     bool enable)
661 {
662         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
663         struct mbox *mbox = get_mbox(roc_nix);
664         struct nix_cn10k_aq_enq_req *aq;
665         int rc;
666
667         if (roc_model_is_cn9k())
668                 return NIX_ERR_HW_NOTSUP;
669
670         if (rq->qid >= nix->nb_rx_queues)
671                 return NIX_ERR_QUEUE_INVALID_RANGE;
672
673         aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
674         if (aq == NULL)
675                 return -ENOSPC;
676         aq->qidx = rq->qid;
677         aq->ctype = NIX_AQ_CTYPE_RQ;
678         aq->op = NIX_AQ_INSTOP_WRITE;
679
680         aq->rq.policer_ena = enable;
681         aq->rq_mask.policer_ena = ~(aq->rq_mask.policer_ena);
682         if (enable) {
683                 aq->rq.band_prof_id = id;
684                 aq->rq_mask.band_prof_id = ~(aq->rq_mask.band_prof_id);
685         }
686
687         rc = mbox_process(mbox);
688         if (rc)
689                 goto exit;
690
691         rq->bpf_id = id;
692
693 exit:
694         return rc;
695 }
696
697 int
698 roc_nix_bpf_dump(struct roc_nix *roc_nix, uint16_t id,
699                  enum roc_nix_bpf_level_flag lvl_flag)
700 {
701         struct mbox *mbox = get_mbox(roc_nix);
702         struct nix_cn10k_aq_enq_rsp *rsp;
703         struct nix_cn10k_aq_enq_req *aq;
704         uint8_t level_idx;
705         int rc;
706
707         if (roc_model_is_cn9k())
708                 return NIX_ERR_HW_NOTSUP;
709
710         level_idx = roc_nix_bpf_level_to_idx(lvl_flag);
711         if (level_idx == ROC_NIX_BPF_LEVEL_IDX_INVALID)
712                 return NIX_ERR_PARAM;
713
714         aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
715         if (aq == NULL)
716                 return -ENOSPC;
717         aq->qidx = (sw_to_hw_lvl_map[level_idx] << 14 | id);
718         aq->ctype = NIX_AQ_CTYPE_BAND_PROF;
719         aq->op = NIX_AQ_INSTOP_READ;
720         rc = mbox_process_msg(mbox, (void *)&rsp);
721         if (!rc) {
722                 plt_dump("============= band prof id =%d ===============", id);
723                 nix_lf_bpf_dump(&rsp->prof);
724         }
725
726         return rc;
727 }
728
729 int
730 roc_nix_bpf_pre_color_tbl_setup(struct roc_nix *roc_nix, uint16_t id,
731                                 enum roc_nix_bpf_level_flag lvl_flag,
732                                 struct roc_nix_bpf_precolor *tbl)
733 {
734         struct mbox *mbox = get_mbox(roc_nix);
735         struct nix_cn10k_aq_enq_req *aq;
736         uint8_t pc_mode, tn_ena;
737         uint8_t level_idx;
738         int rc;
739
740         if (!tbl || !tbl->count)
741                 return NIX_ERR_PARAM;
742
743         if (roc_model_is_cn9k())
744                 return NIX_ERR_HW_NOTSUP;
745
746         level_idx = roc_nix_bpf_level_to_idx(lvl_flag);
747         if (level_idx == ROC_NIX_BPF_LEVEL_IDX_INVALID)
748                 return NIX_ERR_PARAM;
749
750         switch (tbl->mode) {
751         case ROC_NIX_BPF_PC_MODE_VLAN_INNER:
752         case ROC_NIX_BPF_PC_MODE_VLAN_OUTER:
753                 if (tbl->count != NIX_BPF_PRECOLOR_VLAN_TABLE_SIZE) {
754                         plt_err("Table size must be %d",
755                                 NIX_BPF_PRECOLOR_VLAN_TABLE_SIZE);
756                         rc = NIX_ERR_PARAM;
757                         goto exit;
758                 }
759                 tn_ena = nix_precolor_vlan_table_update(roc_nix, tbl);
760                 pc_mode = NIX_RX_BAND_PROF_PC_MODE_VLAN;
761                 break;
762         case ROC_NIX_BPF_PC_MODE_DSCP_INNER:
763                 if (tbl->count != NIX_BPF_PRECOLOR_DSCP_TABLE_SIZE) {
764                         plt_err("Table size must be %d",
765                                 NIX_BPF_PRECOLOR_DSCP_TABLE_SIZE);
766                         rc = NIX_ERR_PARAM;
767                         goto exit;
768                 }
769                 tn_ena = nix_precolor_inner_dscp_table_update(roc_nix, tbl);
770                 pc_mode = NIX_RX_BAND_PROF_PC_MODE_DSCP;
771                 break;
772         case ROC_NIX_BPF_PC_MODE_DSCP_OUTER:
773                 if (tbl->count != NIX_BPF_PRECOLOR_DSCP_TABLE_SIZE) {
774                         plt_err("Table size must be %d",
775                                 NIX_BPF_PRECOLOR_DSCP_TABLE_SIZE);
776                         rc = NIX_ERR_PARAM;
777                         goto exit;
778                 }
779                 tn_ena = nix_precolor_outer_dscp_table_update(roc_nix, tbl);
780                 pc_mode = NIX_RX_BAND_PROF_PC_MODE_DSCP;
781                 break;
782         case ROC_NIX_BPF_PC_MODE_GEN_INNER:
783         case ROC_NIX_BPF_PC_MODE_GEN_OUTER:
784                 if (tbl->count != NIX_BPF_PRECOLOR_GEN_TABLE_SIZE) {
785                         plt_err("Table size must be %d",
786                                 NIX_BPF_PRECOLOR_GEN_TABLE_SIZE);
787                         rc = NIX_ERR_PARAM;
788                         goto exit;
789                 }
790
791                 tn_ena = nix_precolor_gen_table_update(roc_nix, tbl);
792                 pc_mode = NIX_RX_BAND_PROF_PC_MODE_GEN;
793                 break;
794         default:
795                 rc = NIX_ERR_PARAM;
796                 goto exit;
797         }
798
799         /* Update corresponding bandwidth profile too */
800         aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
801         if (aq == NULL)
802                 return -ENOSPC;
803         aq->qidx = (sw_to_hw_lvl_map[level_idx] << 14) | id;
804         aq->ctype = NIX_AQ_CTYPE_BAND_PROF;
805         aq->op = NIX_AQ_INSTOP_WRITE;
806         aq->prof.pc_mode = pc_mode;
807         aq->prof.tnl_ena = tn_ena;
808         aq->prof_mask.pc_mode = ~(aq->prof_mask.pc_mode);
809         aq->prof_mask.tnl_ena = ~(aq->prof_mask.tnl_ena);
810
811         return mbox_process(mbox);
812
813 exit:
814         return rc;
815 }
816
817 int
818 roc_nix_bpf_connect(struct roc_nix *roc_nix,
819                     enum roc_nix_bpf_level_flag lvl_flag, uint16_t src_id,
820                     uint16_t dst_id)
821 {
822         struct mbox *mbox = get_mbox(roc_nix);
823         struct nix_cn10k_aq_enq_req *aq;
824         uint8_t level_idx;
825
826         if (roc_model_is_cn9k())
827                 return NIX_ERR_HW_NOTSUP;
828
829         level_idx = roc_nix_bpf_level_to_idx(lvl_flag);
830         if (level_idx == ROC_NIX_BPF_LEVEL_IDX_INVALID)
831                 return NIX_ERR_PARAM;
832
833         aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
834         if (aq == NULL)
835                 return -ENOSPC;
836         aq->qidx = (sw_to_hw_lvl_map[level_idx] << 14) | src_id;
837         aq->ctype = NIX_AQ_CTYPE_BAND_PROF;
838         aq->op = NIX_AQ_INSTOP_WRITE;
839
840         if (dst_id == ROC_NIX_BPF_ID_INVALID) {
841                 aq->prof.hl_en = false;
842                 aq->prof_mask.hl_en = ~(aq->prof_mask.hl_en);
843         } else {
844                 aq->prof.hl_en = true;
845                 aq->prof.band_prof_id = dst_id;
846                 aq->prof_mask.hl_en = ~(aq->prof_mask.hl_en);
847                 aq->prof_mask.band_prof_id = ~(aq->prof_mask.band_prof_id);
848         }
849
850         return mbox_process(mbox);
851 }
852
853 int
854 roc_nix_bpf_stats_read(struct roc_nix *roc_nix, uint16_t id, uint64_t mask,
855                        enum roc_nix_bpf_level_flag lvl_flag,
856                        uint64_t stats[ROC_NIX_BPF_STATS_MAX])
857 {
858         uint8_t yellow_pkt_pass, yellow_octs_pass, yellow_pkt_drop;
859         uint8_t green_octs_drop, yellow_octs_drop, red_octs_drop;
860         uint8_t green_pkt_pass, green_octs_pass, green_pkt_drop;
861         uint8_t red_pkt_pass, red_octs_pass, red_pkt_drop;
862         struct mbox *mbox = get_mbox(roc_nix);
863         struct nix_cn10k_aq_enq_rsp *rsp;
864         struct nix_cn10k_aq_enq_req *aq;
865         uint8_t level_idx;
866         int rc;
867
868         if (roc_model_is_cn9k())
869                 return NIX_ERR_HW_NOTSUP;
870
871         level_idx = roc_nix_bpf_level_to_idx(lvl_flag);
872         if (level_idx == ROC_NIX_BPF_LEVEL_IDX_INVALID)
873                 return NIX_ERR_PARAM;
874
875         aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
876         if (aq == NULL)
877                 return -ENOSPC;
878         aq->qidx = (sw_to_hw_lvl_map[level_idx] << 14 | id);
879         aq->ctype = NIX_AQ_CTYPE_BAND_PROF;
880         aq->op = NIX_AQ_INSTOP_READ;
881         rc = mbox_process_msg(mbox, (void *)&rsp);
882         if (rc)
883                 return rc;
884
885         green_pkt_pass =
886                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_GREEN_PKT_F_PASS);
887         green_octs_pass =
888                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_GREEN_OCTS_F_PASS);
889         green_pkt_drop =
890                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_GREEN_PKT_F_DROP);
891         green_octs_drop =
892                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_GREEN_OCTS_F_DROP);
893         yellow_pkt_pass =
894                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_YELLOW_PKT_F_PASS);
895         yellow_octs_pass =
896                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_YELLOW_OCTS_F_PASS);
897         yellow_pkt_drop =
898                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_YELLOW_PKT_F_DROP);
899         yellow_octs_drop =
900                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_YELLOW_OCTS_F_DROP);
901         red_pkt_pass =
902                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_RED_PKT_F_PASS);
903         red_octs_pass =
904                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_RED_OCTS_F_PASS);
905         red_pkt_drop =
906                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_RED_PKT_F_DROP);
907         red_octs_drop =
908                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_RED_OCTS_F_DROP);
909
910         if (green_pkt_pass != ROC_NIX_BPF_STATS_MAX)
911                 stats[green_pkt_pass] = rsp->prof.green_pkt_pass;
912
913         if (green_octs_pass != ROC_NIX_BPF_STATS_MAX)
914                 stats[green_octs_pass] = rsp->prof.green_octs_pass;
915
916         if (green_pkt_drop != ROC_NIX_BPF_STATS_MAX)
917                 stats[green_pkt_drop] = rsp->prof.green_pkt_drop;
918
919         if (green_octs_drop != ROC_NIX_BPF_STATS_MAX)
920                 stats[green_octs_drop] = rsp->prof.green_octs_pass;
921
922         if (yellow_pkt_pass != ROC_NIX_BPF_STATS_MAX)
923                 stats[yellow_pkt_pass] = rsp->prof.yellow_pkt_pass;
924
925         if (yellow_octs_pass != ROC_NIX_BPF_STATS_MAX)
926                 stats[yellow_octs_pass] = rsp->prof.yellow_octs_pass;
927
928         if (yellow_pkt_drop != ROC_NIX_BPF_STATS_MAX)
929                 stats[yellow_pkt_drop] = rsp->prof.yellow_pkt_drop;
930
931         if (yellow_octs_drop != ROC_NIX_BPF_STATS_MAX)
932                 stats[yellow_octs_drop] = rsp->prof.yellow_octs_drop;
933
934         if (red_pkt_pass != ROC_NIX_BPF_STATS_MAX)
935                 stats[red_pkt_pass] = rsp->prof.red_pkt_pass;
936
937         if (red_octs_pass != ROC_NIX_BPF_STATS_MAX)
938                 stats[red_octs_pass] = rsp->prof.red_octs_pass;
939
940         if (red_pkt_drop != ROC_NIX_BPF_STATS_MAX)
941                 stats[red_pkt_drop] = rsp->prof.red_pkt_drop;
942
943         if (red_octs_drop != ROC_NIX_BPF_STATS_MAX)
944                 stats[red_octs_drop] = rsp->prof.red_octs_drop;
945
946         return 0;
947 }
948
949 int
950 roc_nix_bpf_stats_reset(struct roc_nix *roc_nix, uint16_t id, uint64_t mask,
951                         enum roc_nix_bpf_level_flag lvl_flag)
952 {
953         struct mbox *mbox = get_mbox(roc_nix);
954         struct nix_cn10k_aq_enq_req *aq;
955         uint8_t level_idx;
956
957         if (roc_model_is_cn9k())
958                 return NIX_ERR_HW_NOTSUP;
959
960         level_idx = roc_nix_bpf_level_to_idx(lvl_flag);
961         if (level_idx == ROC_NIX_BPF_LEVEL_IDX_INVALID)
962                 return NIX_ERR_PARAM;
963
964         aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
965         if (aq == NULL)
966                 return -ENOSPC;
967         aq->qidx = (sw_to_hw_lvl_map[level_idx] << 14 | id);
968         aq->ctype = NIX_AQ_CTYPE_BAND_PROF;
969         aq->op = NIX_AQ_INSTOP_WRITE;
970
971         if (mask & ROC_NIX_BPF_GREEN_PKT_F_PASS) {
972                 aq->prof.green_pkt_pass = 0;
973                 aq->prof_mask.green_pkt_pass = ~(aq->prof_mask.green_pkt_pass);
974         }
975         if (mask & ROC_NIX_BPF_GREEN_OCTS_F_PASS) {
976                 aq->prof.green_octs_pass = 0;
977                 aq->prof_mask.green_octs_pass =
978                         ~(aq->prof_mask.green_octs_pass);
979         }
980         if (mask & ROC_NIX_BPF_GREEN_PKT_F_DROP) {
981                 aq->prof.green_pkt_drop = 0;
982                 aq->prof_mask.green_pkt_drop = ~(aq->prof_mask.green_pkt_drop);
983         }
984         if (mask & ROC_NIX_BPF_GREEN_OCTS_F_DROP) {
985                 aq->prof.green_octs_drop = 0;
986                 aq->prof_mask.green_octs_drop =
987                         ~(aq->prof_mask.green_octs_drop);
988         }
989         if (mask & ROC_NIX_BPF_YELLOW_PKT_F_PASS) {
990                 aq->prof.yellow_pkt_pass = 0;
991                 aq->prof_mask.yellow_pkt_pass =
992                         ~(aq->prof_mask.yellow_pkt_pass);
993         }
994         if (mask & ROC_NIX_BPF_YELLOW_OCTS_F_PASS) {
995                 aq->prof.yellow_octs_pass = 0;
996                 aq->prof_mask.yellow_octs_pass =
997                         ~(aq->prof_mask.yellow_octs_pass);
998         }
999         if (mask & ROC_NIX_BPF_YELLOW_PKT_F_DROP) {
1000                 aq->prof.yellow_pkt_drop = 0;
1001                 aq->prof_mask.yellow_pkt_drop =
1002                         ~(aq->prof_mask.yellow_pkt_drop);
1003         }
1004         if (mask & ROC_NIX_BPF_YELLOW_OCTS_F_DROP) {
1005                 aq->prof.yellow_octs_drop = 0;
1006                 aq->prof_mask.yellow_octs_drop =
1007                         ~(aq->prof_mask.yellow_octs_drop);
1008         }
1009         if (mask & ROC_NIX_BPF_RED_PKT_F_PASS) {
1010                 aq->prof.red_pkt_pass = 0;
1011                 aq->prof_mask.red_pkt_pass = ~(aq->prof_mask.red_pkt_pass);
1012         }
1013         if (mask & ROC_NIX_BPF_RED_OCTS_F_PASS) {
1014                 aq->prof.red_octs_pass = 0;
1015                 aq->prof_mask.red_octs_pass = ~(aq->prof_mask.red_octs_pass);
1016         }
1017         if (mask & ROC_NIX_BPF_RED_PKT_F_DROP) {
1018                 aq->prof.red_pkt_drop = 0;
1019                 aq->prof_mask.red_pkt_drop = ~(aq->prof_mask.red_pkt_drop);
1020         }
1021         if (mask & ROC_NIX_BPF_RED_OCTS_F_DROP) {
1022                 aq->prof.red_octs_drop = 0;
1023                 aq->prof_mask.red_octs_drop = ~(aq->prof_mask.red_octs_drop);
1024         }
1025
1026         return mbox_process(mbox);
1027 }
1028
1029 int
1030 roc_nix_bpf_lf_stats_read(struct roc_nix *roc_nix, uint64_t mask,
1031                           uint64_t stats[ROC_NIX_BPF_STATS_MAX])
1032 {
1033         uint8_t yellow_pkt_pass, yellow_octs_pass, yellow_pkt_drop;
1034         uint8_t green_octs_drop, yellow_octs_drop, red_octs_drop;
1035         uint8_t green_pkt_pass, green_octs_pass, green_pkt_drop;
1036         uint8_t red_pkt_pass, red_octs_pass, red_pkt_drop;
1037         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
1038
1039         green_pkt_pass =
1040                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_GREEN_PKT_F_PASS);
1041         green_octs_pass =
1042                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_GREEN_OCTS_F_PASS);
1043         green_pkt_drop =
1044                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_GREEN_PKT_F_DROP);
1045         green_octs_drop =
1046                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_GREEN_OCTS_F_DROP);
1047         yellow_pkt_pass =
1048                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_YELLOW_PKT_F_PASS);
1049         yellow_octs_pass =
1050                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_YELLOW_OCTS_F_PASS);
1051         yellow_pkt_drop =
1052                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_YELLOW_PKT_F_DROP);
1053         yellow_octs_drop =
1054                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_YELLOW_OCTS_F_DROP);
1055         red_pkt_pass =
1056                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_RED_PKT_F_PASS);
1057         red_octs_pass =
1058                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_RED_OCTS_F_PASS);
1059         red_pkt_drop =
1060                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_RED_PKT_F_DROP);
1061         red_octs_drop =
1062                 roc_nix_bpf_stats_to_idx(mask & ROC_NIX_BPF_RED_OCTS_F_DROP);
1063
1064         if (green_pkt_pass != ROC_NIX_BPF_STATS_MAX) {
1065                 stats[green_pkt_pass] =
1066                         NIX_RD_STATS(NIX_STAT_LF_RX_RX_GC_OCTS_PASSED);
1067         }
1068
1069         if (green_octs_pass != ROC_NIX_BPF_STATS_MAX) {
1070                 stats[green_octs_pass] =
1071                         NIX_RD_STATS(NIX_STAT_LF_RX_RX_YC_PKTS_PASSED);
1072         }
1073
1074         if (green_pkt_drop != ROC_NIX_BPF_STATS_MAX) {
1075                 stats[green_pkt_drop] =
1076                         NIX_RD_STATS(NIX_STAT_LF_RX_RX_GC_OCTS_DROP);
1077         }
1078
1079         if (green_octs_drop != ROC_NIX_BPF_STATS_MAX) {
1080                 stats[green_octs_drop] =
1081                         NIX_RD_STATS(NIX_STAT_LF_RX_RX_YC_PKTS_DROP);
1082         }
1083
1084         if (yellow_pkt_pass != ROC_NIX_BPF_STATS_MAX) {
1085                 stats[yellow_pkt_pass] =
1086                         NIX_RD_STATS(NIX_STAT_LF_RX_RX_GC_PKTS_PASSED);
1087         }
1088
1089         if (yellow_octs_pass != ROC_NIX_BPF_STATS_MAX) {
1090                 stats[yellow_octs_pass] =
1091                         NIX_RD_STATS(NIX_STAT_LF_RX_RX_RC_OCTS_PASSED);
1092         }
1093
1094         if (yellow_pkt_drop != ROC_NIX_BPF_STATS_MAX) {
1095                 stats[yellow_pkt_drop] =
1096                         NIX_RD_STATS(NIX_STAT_LF_RX_RX_GC_PKTS_DROP);
1097         }
1098
1099         if (yellow_octs_drop != ROC_NIX_BPF_STATS_MAX) {
1100                 stats[yellow_octs_drop] =
1101                         NIX_RD_STATS(NIX_STAT_LF_RX_RX_RC_OCTS_DROP);
1102         }
1103
1104         if (red_pkt_pass != ROC_NIX_BPF_STATS_MAX) {
1105                 stats[red_pkt_pass] =
1106                         NIX_RD_STATS(NIX_STAT_LF_RX_RX_YC_OCTS_PASSED);
1107         }
1108
1109         if (red_octs_pass != ROC_NIX_BPF_STATS_MAX) {
1110                 stats[red_octs_pass] =
1111                         NIX_RD_STATS(NIX_STAT_LF_RX_RX_RC_PKTS_PASSED);
1112         }
1113
1114         if (red_pkt_drop != ROC_NIX_BPF_STATS_MAX) {
1115                 stats[red_pkt_drop] =
1116                         NIX_RD_STATS(NIX_STAT_LF_RX_RX_YC_OCTS_DROP);
1117         }
1118
1119         if (red_octs_drop != ROC_NIX_BPF_STATS_MAX) {
1120                 stats[red_octs_drop] =
1121                         NIX_RD_STATS(NIX_STAT_LF_RX_RX_RC_PKTS_DROP);
1122         }
1123
1124         return 0;
1125 }
1126
1127 int
1128 roc_nix_bpf_lf_stats_reset(struct roc_nix *roc_nix, uint64_t mask)
1129 {
1130         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
1131
1132         if (mask & ROC_NIX_BPF_GREEN_PKT_F_PASS)
1133                 NIX_RST_STATS(ROC_NIX_BPF_GREEN_PKT_F_PASS);
1134         if (mask & ROC_NIX_BPF_GREEN_OCTS_F_PASS)
1135                 NIX_RST_STATS(ROC_NIX_BPF_GREEN_OCTS_F_PASS);
1136         if (mask & ROC_NIX_BPF_GREEN_PKT_F_DROP)
1137                 NIX_RST_STATS(ROC_NIX_BPF_GREEN_PKT_F_DROP);
1138         if (mask & ROC_NIX_BPF_GREEN_OCTS_F_DROP)
1139                 NIX_RST_STATS(ROC_NIX_BPF_GREEN_OCTS_F_DROP);
1140         if (mask & ROC_NIX_BPF_YELLOW_PKT_F_PASS)
1141                 NIX_RST_STATS(ROC_NIX_BPF_YELLOW_PKT_F_PASS);
1142         if (mask & ROC_NIX_BPF_YELLOW_OCTS_F_PASS)
1143                 NIX_RST_STATS(ROC_NIX_BPF_YELLOW_OCTS_F_PASS);
1144         if (mask & ROC_NIX_BPF_YELLOW_PKT_F_DROP)
1145                 NIX_RST_STATS(ROC_NIX_BPF_YELLOW_PKT_F_DROP);
1146         if (mask & ROC_NIX_BPF_YELLOW_OCTS_F_DROP)
1147                 NIX_RST_STATS(ROC_NIX_BPF_YELLOW_OCTS_F_DROP);
1148         if (mask & ROC_NIX_BPF_RED_PKT_F_PASS)
1149                 NIX_RST_STATS(ROC_NIX_BPF_RED_PKT_F_PASS);
1150         if (mask & ROC_NIX_BPF_RED_OCTS_F_PASS)
1151                 NIX_RST_STATS(ROC_NIX_BPF_RED_OCTS_F_PASS);
1152         if (mask & ROC_NIX_BPF_RED_PKT_F_DROP)
1153                 NIX_RST_STATS(ROC_NIX_BPF_RED_PKT_F_DROP);
1154         if (mask & ROC_NIX_BPF_RED_OCTS_F_DROP)
1155                 NIX_RST_STATS(ROC_NIX_BPF_RED_OCTS_F_DROP);
1156
1157         return 0;
1158 }