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