xref: /dpdk/drivers/common/cnxk/roc_nix_bpf.c (revision 947904d0)
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 *
get_mbox(struct roc_nix * roc_nix)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
meter_rate_to_nix(uint64_t value,uint64_t * exponent_p,uint64_t * mantissa_p,uint64_t * div_exp_p,uint32_t timeunit_p)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
meter_burst_to_nix(uint64_t value,uint64_t * exponent_p,uint64_t * mantissa_p)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
nix_lf_bpf_dump(__io struct nix_band_prof_s * bpf)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
nix_precolor_conv_table_write(struct roc_nix * roc_nix,uint64_t val,uint32_t off)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
nix_precolor_vlan_table_update(struct roc_nix * roc_nix,struct roc_nix_bpf_precolor * tbl)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
nix_precolor_inner_dscp_table_update(struct roc_nix * roc_nix,struct roc_nix_bpf_precolor * tbl)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
nix_precolor_outer_dscp_table_update(struct roc_nix * roc_nix,struct roc_nix_bpf_precolor * tbl)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
nix_precolor_gen_table_update(struct roc_nix * roc_nix,struct roc_nix_bpf_precolor * tbl)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
roc_nix_bpf_level_to_idx(enum roc_nix_bpf_level_flag level_f)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
roc_nix_bpf_stats_to_idx(enum roc_nix_bpf_stats level_f)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
roc_nix_bpf_timeunit_get(struct roc_nix * roc_nix,uint32_t * time_unit)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
roc_nix_bpf_count_get(struct roc_nix * roc_nix,uint8_t lvl_mask,uint16_t count[ROC_NIX_BPF_LEVEL_MAX])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
roc_nix_bpf_alloc(struct roc_nix * roc_nix,uint8_t lvl_mask,uint16_t per_lvl_cnt[ROC_NIX_BPF_LEVEL_MAX],struct roc_nix_bpf_objs * profs)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
roc_nix_bpf_free(struct roc_nix * roc_nix,struct roc_nix_bpf_objs * profs,uint8_t num_prof)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
roc_nix_bpf_free_all(struct roc_nix * roc_nix)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
roc_nix_bpf_config(struct roc_nix * roc_nix,uint16_t id,enum roc_nix_bpf_level_flag lvl_flag,struct roc_nix_bpf_cfg * cfg)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
roc_nix_bpf_ena_dis(struct roc_nix * roc_nix,uint16_t id,struct roc_nix_rq * rq,bool enable)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
roc_nix_bpf_dump(struct roc_nix * roc_nix,uint16_t id,enum roc_nix_bpf_level_flag lvl_flag)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
roc_nix_bpf_pre_color_tbl_setup(struct roc_nix * roc_nix,uint16_t id,enum roc_nix_bpf_level_flag lvl_flag,struct roc_nix_bpf_precolor * tbl)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
roc_nix_bpf_connect(struct roc_nix * roc_nix,enum roc_nix_bpf_level_flag lvl_flag,uint16_t src_id,uint16_t dst_id)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
roc_nix_bpf_stats_read(struct roc_nix * roc_nix,uint16_t id,uint64_t mask,enum roc_nix_bpf_level_flag lvl_flag,uint64_t stats[ROC_NIX_BPF_STATS_MAX])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
roc_nix_bpf_stats_reset(struct roc_nix * roc_nix,uint16_t id,uint64_t mask,enum roc_nix_bpf_level_flag lvl_flag)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
roc_nix_bpf_lf_stats_read(struct roc_nix * roc_nix,uint64_t mask,uint64_t stats[ROC_NIX_BPF_STATS_MAX])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
roc_nix_bpf_lf_stats_reset(struct roc_nix * roc_nix,uint64_t mask)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 }
1159