Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2014-2023 Broadcom
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "bnxt.h"
7 : : #include "bnxt_tf_common.h"
8 : : #include "ulp_rte_parser.h"
9 : : #include "ulp_matcher.h"
10 : : #include "ulp_flow_db.h"
11 : : #include "ulp_mapper.h"
12 : : #include "ulp_fc_mgr.h"
13 : : #include "ulp_port_db.h"
14 : : #include "ulp_ha_mgr.h"
15 : : #include "ulp_tun.h"
16 : : #include <rte_malloc.h>
17 : : #include "ulp_template_db_tbl.h"
18 : : #include "tfp.h"
19 : :
20 : : static int32_t
21 : 0 : bnxt_ulp_flow_validate_args(const struct rte_flow_attr *attr,
22 : : const struct rte_flow_item pattern[],
23 : : const struct rte_flow_action actions[],
24 : : struct rte_flow_error *error)
25 : : {
26 : : /* Perform the validation of the arguments for null */
27 [ # # ]: 0 : if (!error)
28 : : return BNXT_TF_RC_ERROR;
29 : :
30 [ # # ]: 0 : if (!pattern) {
31 : 0 : rte_flow_error_set(error,
32 : : EINVAL,
33 : : RTE_FLOW_ERROR_TYPE_ITEM_NUM,
34 : : NULL,
35 : : "NULL pattern.");
36 : 0 : return BNXT_TF_RC_ERROR;
37 : : }
38 : :
39 [ # # ]: 0 : if (!actions) {
40 : 0 : rte_flow_error_set(error,
41 : : EINVAL,
42 : : RTE_FLOW_ERROR_TYPE_ACTION_NUM,
43 : : NULL,
44 : : "NULL action.");
45 : 0 : return BNXT_TF_RC_ERROR;
46 : : }
47 : :
48 [ # # ]: 0 : if (!attr) {
49 : 0 : rte_flow_error_set(error,
50 : : EINVAL,
51 : : RTE_FLOW_ERROR_TYPE_ATTR,
52 : : NULL,
53 : : "NULL attribute.");
54 : 0 : return BNXT_TF_RC_ERROR;
55 : : }
56 : :
57 [ # # ]: 0 : if (attr->egress && attr->ingress) {
58 : 0 : rte_flow_error_set(error,
59 : : EINVAL,
60 : : RTE_FLOW_ERROR_TYPE_ATTR,
61 : : attr,
62 : : "EGRESS AND INGRESS UNSUPPORTED");
63 : 0 : return BNXT_TF_RC_ERROR;
64 : : }
65 : : return BNXT_TF_RC_SUCCESS;
66 : : }
67 : :
68 : : static inline void
69 : : bnxt_ulp_set_dir_attributes(struct ulp_rte_parser_params *params,
70 : : const struct rte_flow_attr *attr)
71 : : {
72 : : /* Set the flow attributes */
73 [ # # # # ]: 0 : if (attr->egress)
74 : 0 : params->dir_attr |= BNXT_ULP_FLOW_ATTR_EGRESS;
75 [ # # # # ]: 0 : if (attr->ingress)
76 : 0 : params->dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS;
77 : : #if RTE_VERSION_NUM(17, 11, 10, 16) < RTE_VERSION
78 [ # # # # ]: 0 : if (attr->transfer)
79 : 0 : params->dir_attr |= BNXT_ULP_FLOW_ATTR_TRANSFER;
80 : : #endif
81 : : }
82 : :
83 : : static inline void
84 : 0 : bnxt_ulp_init_parser_cf_defaults(struct ulp_rte_parser_params *params,
85 : : uint16_t port_id)
86 : : {
87 : : /* Set up defaults for Comp field */
88 [ # # ]: 0 : ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_INCOMING_IF, port_id);
89 [ # # ]: 0 : ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_DEV_PORT_ID, port_id);
90 : 0 : ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_SVIF_FLAG,
91 : : BNXT_ULP_INVALID_SVIF_VAL);
92 : 0 : }
93 : :
94 : : void
95 : 0 : bnxt_ulp_init_mapper_params(struct bnxt_ulp_mapper_create_parms *mapper_cparms,
96 : : struct ulp_rte_parser_params *params,
97 : : enum bnxt_ulp_fdb_type flow_type)
98 : : {
99 [ # # ]: 0 : uint32_t ulp_flags = 0;
100 : :
101 : : memset(mapper_cparms, 0, sizeof(*mapper_cparms));
102 : 0 : mapper_cparms->flow_type = flow_type;
103 : 0 : mapper_cparms->app_priority = params->priority;
104 : 0 : mapper_cparms->dir_attr = params->dir_attr;
105 : 0 : mapper_cparms->class_tid = params->class_id;
106 : 0 : mapper_cparms->act_tid = params->act_tmpl;
107 : 0 : mapper_cparms->func_id = params->func_id;
108 : 0 : mapper_cparms->hdr_bitmap = ¶ms->hdr_bitmap;
109 : 0 : mapper_cparms->enc_hdr_bitmap = ¶ms->enc_hdr_bitmap;
110 : 0 : mapper_cparms->hdr_field = params->hdr_field;
111 : 0 : mapper_cparms->enc_field = params->enc_field;
112 : 0 : mapper_cparms->comp_fld = params->comp_fld;
113 : 0 : mapper_cparms->act = ¶ms->act_bitmap;
114 : 0 : mapper_cparms->act_prop = ¶ms->act_prop;
115 : 0 : mapper_cparms->flow_id = params->fid;
116 : 0 : mapper_cparms->parent_flow = params->parent_flow;
117 : 0 : mapper_cparms->child_flow = params->child_flow;
118 : 0 : mapper_cparms->fld_bitmap = ¶ms->fld_bitmap;
119 : 0 : mapper_cparms->flow_pattern_id = params->flow_pattern_id;
120 : 0 : mapper_cparms->act_pattern_id = params->act_pattern_id;
121 : 0 : mapper_cparms->app_id = params->app_id;
122 : 0 : mapper_cparms->port_id = params->port_id;
123 : 0 : mapper_cparms->tun_idx = params->tun_idx;
124 : :
125 : : /* update the signature fields into the computed field list */
126 [ # # ]: 0 : ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_HDR_SIG_ID,
127 : : params->hdr_sig_id);
128 [ # # ]: 0 : ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_FLOW_SIG_ID,
129 : : params->flow_sig_id);
130 : :
131 [ # # ]: 0 : if (bnxt_ulp_cntxt_ptr2_ulp_flags_get(params->ulp_ctx, &ulp_flags))
132 : 0 : return;
133 : :
134 : : /* update the WC Priority flag */
135 [ # # ]: 0 : if (ULP_HIGH_AVAIL_IS_ENABLED(ulp_flags)) {
136 : 0 : enum ulp_ha_mgr_region region = ULP_HA_REGION_LOW;
137 : : int32_t rc;
138 : :
139 : 0 : rc = ulp_ha_mgr_region_get(params->ulp_ctx, ®ion);
140 [ # # ]: 0 : if (rc)
141 : 0 : BNXT_TF_DBG(ERR, "Unable to get WC region\n");
142 [ # # ]: 0 : if (region == ULP_HA_REGION_HI)
143 : 0 : ULP_COMP_FLD_IDX_WR(params,
144 : : BNXT_ULP_CF_IDX_WC_IS_HA_HIGH_REG,
145 : : 1);
146 : : } else {
147 : 0 : ULP_COMP_FLD_IDX_WR(params,
148 : : BNXT_ULP_CF_IDX_HA_SUPPORT_DISABLED,
149 : : 1);
150 : : }
151 : :
152 : : /* Update the socket direct flag */
153 [ # # ]: 0 : if (ULP_BITMAP_ISSET(params->hdr_bitmap.bits,
154 : : BNXT_ULP_HDR_BIT_SVIF_IGNORE)) {
155 : : uint32_t ifindex;
156 : : uint16_t vport;
157 : :
158 : : /* Get the port db ifindex */
159 [ # # ]: 0 : if (ulp_port_db_dev_port_to_ulp_index(params->ulp_ctx,
160 : 0 : params->port_id,
161 : : &ifindex)) {
162 : 0 : BNXT_TF_DBG(ERR, "Invalid port id %u\n",
163 : : params->port_id);
164 : 0 : return;
165 : : }
166 : : /* Update the phy port of the other interface */
167 [ # # ]: 0 : if (ulp_port_db_vport_get(params->ulp_ctx, ifindex, &vport)) {
168 : 0 : BNXT_TF_DBG(ERR, "Invalid port if index %u\n", ifindex);
169 : 0 : return;
170 : : }
171 [ # # # # ]: 0 : ULP_COMP_FLD_IDX_WR(params, BNXT_ULP_CF_IDX_SOCKET_DIRECT_VPORT,
172 : : (vport == 1) ? 2 : 1);
173 : : }
174 : : }
175 : :
176 : : /* Function to create the rte flow. */
177 : : static struct rte_flow *
178 : 0 : bnxt_ulp_flow_create(struct rte_eth_dev *dev,
179 : : const struct rte_flow_attr *attr,
180 : : const struct rte_flow_item pattern[],
181 : : const struct rte_flow_action actions[],
182 : : struct rte_flow_error *error)
183 : : {
184 : 0 : struct bnxt_ulp_mapper_create_parms mapper_cparms = { 0 };
185 : : struct ulp_rte_parser_params params;
186 : : struct bnxt_ulp_context *ulp_ctx;
187 : : int rc, ret = BNXT_TF_RC_ERROR;
188 : : struct rte_flow *flow_id;
189 : : uint16_t func_id;
190 : : uint32_t fid;
191 : :
192 [ # # ]: 0 : if (bnxt_ulp_flow_validate_args(attr,
193 : : pattern, actions,
194 : : error) == BNXT_TF_RC_ERROR) {
195 : 0 : BNXT_TF_DBG(ERR, "Invalid arguments being passed\n");
196 : 0 : goto flow_error;
197 : : }
198 : :
199 : 0 : ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev);
200 [ # # ]: 0 : if (!ulp_ctx) {
201 : 0 : BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
202 : 0 : goto flow_error;
203 : : }
204 : :
205 : : /* Initialize the parser params */
206 : : memset(¶ms, 0, sizeof(struct ulp_rte_parser_params));
207 : 0 : params.ulp_ctx = ulp_ctx;
208 : :
209 [ # # ]: 0 : if (bnxt_ulp_cntxt_app_id_get(params.ulp_ctx, ¶ms.app_id)) {
210 : 0 : BNXT_TF_DBG(ERR, "failed to get the app id\n");
211 : 0 : goto flow_error;
212 : : }
213 : :
214 : : /* Set the flow attributes */
215 : : bnxt_ulp_set_dir_attributes(¶ms, attr);
216 : :
217 : 0 : bnxt_ulp_init_parser_cf_defaults(¶ms, dev->data->port_id);
218 : :
219 : : /* Get the function id */
220 [ # # ]: 0 : if (ulp_port_db_port_func_id_get(ulp_ctx,
221 : : dev->data->port_id,
222 : : &func_id)) {
223 : 0 : BNXT_TF_DBG(ERR, "conversion of port to func id failed\n");
224 : 0 : goto flow_error;
225 : : }
226 : :
227 : : /* Protect flow creation */
228 [ # # ]: 0 : if (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {
229 : 0 : BNXT_TF_DBG(ERR, "Flow db lock acquire failed\n");
230 : 0 : goto flow_error;
231 : : }
232 : :
233 : : /* Allocate a Flow ID for attaching all resources for the flow to.
234 : : * Once allocated, all errors have to walk the list of resources and
235 : : * free each of them.
236 : : */
237 : 0 : rc = ulp_flow_db_fid_alloc(ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR,
238 : : func_id, &fid);
239 [ # # ]: 0 : if (rc) {
240 : 0 : BNXT_TF_DBG(ERR, "Unable to allocate flow table entry\n");
241 : 0 : goto release_lock;
242 : : }
243 : :
244 : : /* Parse the rte flow pattern */
245 : 0 : ret = bnxt_ulp_rte_parser_hdr_parse(pattern, ¶ms);
246 [ # # ]: 0 : if (ret != BNXT_TF_RC_SUCCESS)
247 : 0 : goto free_fid;
248 : :
249 : : /* Parse the rte flow action */
250 : 0 : ret = bnxt_ulp_rte_parser_act_parse(actions, ¶ms);
251 [ # # ]: 0 : if (ret != BNXT_TF_RC_SUCCESS)
252 : 0 : goto free_fid;
253 : :
254 : 0 : params.fid = fid;
255 : 0 : params.func_id = func_id;
256 : 0 : params.priority = attr->priority;
257 : 0 : params.port_id = dev->data->port_id;
258 : :
259 : : /* Perform the rte flow post process */
260 : 0 : bnxt_ulp_rte_parser_post_process(¶ms);
261 : :
262 : : /* do the tunnel offload process if any */
263 : 0 : ret = ulp_tunnel_offload_process(¶ms);
264 [ # # ]: 0 : if (ret == BNXT_TF_RC_ERROR)
265 : 0 : goto free_fid;
266 : :
267 : 0 : ret = ulp_matcher_pattern_match(¶ms, ¶ms.class_id);
268 [ # # ]: 0 : if (ret != BNXT_TF_RC_SUCCESS)
269 : 0 : goto free_fid;
270 : :
271 : 0 : ret = ulp_matcher_action_match(¶ms, ¶ms.act_tmpl);
272 [ # # ]: 0 : if (ret != BNXT_TF_RC_SUCCESS)
273 : 0 : goto free_fid;
274 : :
275 : 0 : bnxt_ulp_init_mapper_params(&mapper_cparms, ¶ms,
276 : : BNXT_ULP_FDB_TYPE_REGULAR);
277 : : /* Call the ulp mapper to create the flow in the hardware. */
278 : 0 : ret = ulp_mapper_flow_create(ulp_ctx, &mapper_cparms);
279 [ # # ]: 0 : if (ret)
280 : 0 : goto free_fid;
281 : :
282 : 0 : bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
283 : :
284 : 0 : flow_id = (struct rte_flow *)((uintptr_t)fid);
285 : 0 : return flow_id;
286 : :
287 : 0 : free_fid:
288 : 0 : ulp_flow_db_fid_free(ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR, fid);
289 : 0 : release_lock:
290 : 0 : bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
291 : 0 : flow_error:
292 : 0 : rte_flow_error_set(error, ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
293 : : "Failed to create flow.");
294 : 0 : return NULL;
295 : : }
296 : :
297 : : /* Function to validate the rte flow. */
298 : : static int
299 : 0 : bnxt_ulp_flow_validate(struct rte_eth_dev *dev,
300 : : const struct rte_flow_attr *attr,
301 : : const struct rte_flow_item pattern[],
302 : : const struct rte_flow_action actions[],
303 : : struct rte_flow_error *error)
304 : : {
305 : : struct ulp_rte_parser_params params;
306 : : struct bnxt_ulp_context *ulp_ctx;
307 : : uint32_t class_id, act_tmpl;
308 : : int ret = BNXT_TF_RC_ERROR;
309 : :
310 [ # # ]: 0 : if (bnxt_ulp_flow_validate_args(attr,
311 : : pattern, actions,
312 : : error) == BNXT_TF_RC_ERROR) {
313 : 0 : BNXT_TF_DBG(ERR, "Invalid arguments being passed\n");
314 : 0 : goto parse_error;
315 : : }
316 : :
317 : 0 : ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev);
318 [ # # ]: 0 : if (!ulp_ctx) {
319 : 0 : BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
320 : 0 : goto parse_error;
321 : : }
322 : :
323 : : /* Initialize the parser params */
324 : : memset(¶ms, 0, sizeof(struct ulp_rte_parser_params));
325 : 0 : params.ulp_ctx = ulp_ctx;
326 : :
327 [ # # ]: 0 : if (bnxt_ulp_cntxt_app_id_get(params.ulp_ctx, ¶ms.app_id)) {
328 : 0 : BNXT_TF_DBG(ERR, "failed to get the app id\n");
329 : 0 : goto parse_error;
330 : : }
331 : :
332 : : /* Set the flow attributes */
333 : : bnxt_ulp_set_dir_attributes(¶ms, attr);
334 : 0 : bnxt_ulp_init_parser_cf_defaults(¶ms, dev->data->port_id);
335 : :
336 : : /* Parse the rte flow pattern */
337 : 0 : ret = bnxt_ulp_rte_parser_hdr_parse(pattern, ¶ms);
338 [ # # ]: 0 : if (ret != BNXT_TF_RC_SUCCESS)
339 : 0 : goto parse_error;
340 : :
341 : : /* Parse the rte flow action */
342 : 0 : ret = bnxt_ulp_rte_parser_act_parse(actions, ¶ms);
343 [ # # ]: 0 : if (ret != BNXT_TF_RC_SUCCESS)
344 : 0 : goto parse_error;
345 : :
346 : : /* Perform the rte flow post process */
347 : 0 : bnxt_ulp_rte_parser_post_process(¶ms);
348 : :
349 : : /* do the tunnel offload process if any */
350 : 0 : ret = ulp_tunnel_offload_process(¶ms);
351 [ # # ]: 0 : if (ret == BNXT_TF_RC_ERROR)
352 : 0 : goto parse_error;
353 : :
354 : 0 : ret = ulp_matcher_pattern_match(¶ms, &class_id);
355 : :
356 [ # # ]: 0 : if (ret != BNXT_TF_RC_SUCCESS)
357 : 0 : goto parse_error;
358 : :
359 : 0 : ret = ulp_matcher_action_match(¶ms, &act_tmpl);
360 [ # # ]: 0 : if (ret != BNXT_TF_RC_SUCCESS)
361 : 0 : goto parse_error;
362 : :
363 : : /* all good return success */
364 : : return ret;
365 : :
366 : 0 : parse_error:
367 : 0 : rte_flow_error_set(error, ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
368 : : "Failed to validate flow.");
369 : 0 : return -EINVAL;
370 : : }
371 : :
372 : : /* Function to destroy the rte flow. */
373 : : int
374 : 0 : bnxt_ulp_flow_destroy(struct rte_eth_dev *dev,
375 : : struct rte_flow *flow,
376 : : struct rte_flow_error *error)
377 : : {
378 : : struct bnxt_ulp_context *ulp_ctx;
379 : : uint32_t flow_id;
380 : : uint16_t func_id;
381 : : int ret;
382 : :
383 : 0 : ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev);
384 [ # # ]: 0 : if (!ulp_ctx) {
385 : 0 : BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
386 [ # # ]: 0 : if (error)
387 : 0 : rte_flow_error_set(error, EINVAL,
388 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
389 : : "Failed to destroy flow.");
390 : 0 : return -EINVAL;
391 : : }
392 : :
393 : 0 : flow_id = (uint32_t)(uintptr_t)flow;
394 : :
395 [ # # ]: 0 : if (ulp_port_db_port_func_id_get(ulp_ctx,
396 : 0 : dev->data->port_id,
397 : : &func_id)) {
398 : 0 : BNXT_TF_DBG(ERR, "conversion of port to func id failed\n");
399 [ # # ]: 0 : if (error)
400 : 0 : rte_flow_error_set(error, EINVAL,
401 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
402 : : "Failed to destroy flow.");
403 : 0 : return -EINVAL;
404 : : }
405 : :
406 [ # # ]: 0 : if (ulp_flow_db_validate_flow_func(ulp_ctx, flow_id, func_id) ==
407 : : false) {
408 : 0 : BNXT_TF_DBG(ERR, "Incorrect device params\n");
409 [ # # ]: 0 : if (error)
410 : 0 : rte_flow_error_set(error, EINVAL,
411 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
412 : : "Failed to destroy flow.");
413 : 0 : return -EINVAL;
414 : : }
415 : :
416 [ # # ]: 0 : if (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {
417 : 0 : BNXT_TF_DBG(ERR, "Flow db lock acquire failed\n");
418 : 0 : return -EINVAL;
419 : : }
420 : 0 : ret = ulp_mapper_flow_destroy(ulp_ctx, BNXT_ULP_FDB_TYPE_REGULAR,
421 : : flow_id);
422 [ # # ]: 0 : if (ret) {
423 : 0 : BNXT_TF_DBG(ERR, "Failed to destroy flow.\n");
424 [ # # ]: 0 : if (error)
425 : 0 : rte_flow_error_set(error, -ret,
426 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
427 : : "Failed to destroy flow.");
428 : : }
429 : 0 : bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
430 : :
431 : 0 : return ret;
432 : : }
433 : :
434 : : /* Function to destroy the rte flows. */
435 : : static int32_t
436 : 0 : bnxt_ulp_flow_flush(struct rte_eth_dev *eth_dev,
437 : : struct rte_flow_error *error)
438 : : {
439 : : struct bnxt_ulp_context *ulp_ctx;
440 : : int32_t ret = 0;
441 : : uint16_t func_id;
442 : :
443 : 0 : ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
444 [ # # ]: 0 : if (!ulp_ctx) {
445 : : return ret;
446 : : }
447 : :
448 : : /* Free the resources for the last device */
449 [ # # ]: 0 : if (ulp_ctx_deinit_allowed(ulp_ctx)) {
450 : 0 : ret = ulp_flow_db_session_flow_flush(ulp_ctx);
451 [ # # ]: 0 : } else if (bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctx)) {
452 : 0 : ret = ulp_port_db_port_func_id_get(ulp_ctx,
453 : 0 : eth_dev->data->port_id,
454 : : &func_id);
455 [ # # ]: 0 : if (!ret)
456 : 0 : ret = ulp_flow_db_function_flow_flush(ulp_ctx, func_id);
457 : : else
458 : 0 : BNXT_TF_DBG(ERR, "convert port to func id failed\n");
459 : : }
460 [ # # ]: 0 : if (ret)
461 : 0 : rte_flow_error_set(error, ret,
462 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
463 : : "Failed to flush flow.");
464 : : return ret;
465 : : }
466 : :
467 : : /* Function to query the rte flows. */
468 : : static int32_t
469 : 0 : bnxt_ulp_flow_query(struct rte_eth_dev *eth_dev,
470 : : struct rte_flow *flow,
471 : : const struct rte_flow_action *action,
472 : : void *data,
473 : : struct rte_flow_error *error)
474 : : {
475 : : int rc = 0;
476 : : struct bnxt_ulp_context *ulp_ctx;
477 : : struct rte_flow_query_count *count;
478 : : uint32_t flow_id;
479 : :
480 : 0 : ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
481 [ # # ]: 0 : if (!ulp_ctx) {
482 : 0 : BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
483 : 0 : rte_flow_error_set(error, EINVAL,
484 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
485 : : "Failed to query flow.");
486 : 0 : return -EINVAL;
487 : : }
488 : :
489 : 0 : flow_id = (uint32_t)(uintptr_t)flow;
490 : :
491 [ # # ]: 0 : switch (action->type) {
492 : 0 : case RTE_FLOW_ACTION_TYPE_COUNT:
493 : : count = data;
494 : 0 : rc = ulp_fc_mgr_query_count_get(ulp_ctx, flow_id, count);
495 [ # # ]: 0 : if (rc) {
496 : 0 : rte_flow_error_set(error, EINVAL,
497 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
498 : : "Failed to query flow.");
499 : : }
500 : : break;
501 : 0 : default:
502 : 0 : rte_flow_error_set(error, -rc, RTE_FLOW_ERROR_TYPE_ACTION_NUM,
503 : : NULL, "Unsupported action item");
504 : : }
505 : :
506 : : return rc;
507 : : }
508 : :
509 : : static int32_t
510 : : bnxt_ulp_action_handle_chk_args(const struct rte_flow_action *action,
511 : : const struct rte_flow_indir_action_conf *conf)
512 : : {
513 : 0 : if (!action || !conf)
514 : : return BNXT_TF_RC_ERROR;
515 : : /* shared action only allowed to have one direction */
516 [ # # ]: 0 : if (conf->ingress == 1 && conf->egress == 1)
517 : : return BNXT_TF_RC_ERROR;
518 : : /* shared action must have at least one direction */
519 [ # # ]: 0 : if (conf->ingress == 0 && conf->egress == 0)
520 : : return BNXT_TF_RC_ERROR;
521 : : return BNXT_TF_RC_SUCCESS;
522 : : }
523 : :
524 : : static inline void
525 : : bnxt_ulp_set_action_handle_dir_attr(struct ulp_rte_parser_params *params,
526 : : const struct rte_flow_indir_action_conf *conf)
527 : : {
528 : 0 : if (conf->ingress == 1)
529 : 0 : params->dir_attr |= BNXT_ULP_FLOW_ATTR_INGRESS;
530 [ # # ]: 0 : else if (conf->egress == 1)
531 : 0 : params->dir_attr |= BNXT_ULP_FLOW_ATTR_EGRESS;
532 : : }
533 : :
534 : : static struct rte_flow_action_handle *
535 : 0 : bnxt_ulp_action_handle_create(struct rte_eth_dev *dev,
536 : : const struct rte_flow_indir_action_conf *conf,
537 : : const struct rte_flow_action *action,
538 : : struct rte_flow_error *error)
539 : : {
540 : : enum bnxt_ulp_intf_type port_type = BNXT_ULP_INTF_TYPE_INVALID;
541 : 0 : struct bnxt_ulp_mapper_create_parms mparms = { 0 };
542 : : struct ulp_rte_parser_params params;
543 : : struct bnxt_ulp_context *ulp_ctx;
544 : : uint32_t act_tid;
545 : : uint16_t func_id;
546 : : uint32_t ifindex;
547 : : int ret = BNXT_TF_RC_ERROR;
548 : 0 : const struct rte_flow_action actions[2] = {
549 : : {
550 : 0 : .type = action->type,
551 [ # # ]: 0 : .conf = action->conf
552 : : },
553 : : {
554 : : .type = RTE_FLOW_ACTION_TYPE_END
555 : : }
556 : : };
557 : :
558 : : if (bnxt_ulp_action_handle_chk_args(action, conf) != BNXT_TF_RC_SUCCESS)
559 : 0 : goto parse_error;
560 : :
561 : 0 : ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev);
562 [ # # ]: 0 : if (!ulp_ctx) {
563 : 0 : BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
564 : 0 : goto parse_error;
565 : : }
566 : :
567 : : /* Initialize the parser params */
568 : : memset(¶ms, 0, sizeof(struct ulp_rte_parser_params));
569 : 0 : params.ulp_ctx = ulp_ctx;
570 : :
571 [ # # ]: 0 : ULP_BITMAP_SET(params.act_bitmap.bits, BNXT_ULP_ACT_BIT_SHARED);
572 : :
573 : : /* Set the shared action direction attribute */
574 : : bnxt_ulp_set_action_handle_dir_attr(¶ms, conf);
575 : :
576 : : /* perform the conversion from dpdk port to bnxt ifindex */
577 [ # # ]: 0 : if (ulp_port_db_dev_port_to_ulp_index(ulp_ctx,
578 : 0 : dev->data->port_id,
579 : : &ifindex)) {
580 : 0 : BNXT_TF_DBG(ERR, "Port id is not valid\n");
581 : 0 : goto parse_error;
582 : : }
583 : 0 : port_type = ulp_port_db_port_type_get(ulp_ctx, ifindex);
584 [ # # ]: 0 : if (port_type == BNXT_ULP_INTF_TYPE_INVALID) {
585 : 0 : BNXT_TF_DBG(ERR, "Port type is not valid\n");
586 : 0 : goto parse_error;
587 : : }
588 : :
589 : 0 : bnxt_ulp_init_parser_cf_defaults(¶ms, dev->data->port_id);
590 : :
591 : : /* Emulating the match port for direction processing */
592 [ # # ]: 0 : ULP_COMP_FLD_IDX_WR(¶ms, BNXT_ULP_CF_IDX_MATCH_PORT_TYPE,
593 : : port_type);
594 : :
595 [ # # # # ]: 0 : if ((params.dir_attr & BNXT_ULP_FLOW_ATTR_INGRESS) &&
596 : : port_type == BNXT_ULP_INTF_TYPE_VF_REP) {
597 : 0 : ULP_COMP_FLD_IDX_WR(¶ms, BNXT_ULP_CF_IDX_DIRECTION,
598 : : BNXT_ULP_DIR_EGRESS);
599 : : } else {
600 : : /* Assign the input direction */
601 [ # # ]: 0 : if (params.dir_attr & BNXT_ULP_FLOW_ATTR_INGRESS)
602 : 0 : ULP_COMP_FLD_IDX_WR(¶ms, BNXT_ULP_CF_IDX_DIRECTION,
603 : : BNXT_ULP_DIR_INGRESS);
604 : : else
605 : 0 : ULP_COMP_FLD_IDX_WR(¶ms, BNXT_ULP_CF_IDX_DIRECTION,
606 : : BNXT_ULP_DIR_EGRESS);
607 : : }
608 : :
609 : : /* Parse the shared action */
610 : 0 : ret = bnxt_ulp_rte_parser_act_parse(actions, ¶ms);
611 [ # # ]: 0 : if (ret != BNXT_TF_RC_SUCCESS)
612 : 0 : goto parse_error;
613 : :
614 : : /* Perform the rte flow post process */
615 : 0 : bnxt_ulp_rte_parser_post_process(¶ms);
616 : :
617 : : /* do the tunnel offload process if any */
618 : 0 : ret = ulp_tunnel_offload_process(¶ms);
619 [ # # ]: 0 : if (ret == BNXT_TF_RC_ERROR)
620 : 0 : goto parse_error;
621 : :
622 : 0 : ret = ulp_matcher_action_match(¶ms, &act_tid);
623 [ # # ]: 0 : if (ret != BNXT_TF_RC_SUCCESS)
624 : 0 : goto parse_error;
625 : :
626 : 0 : bnxt_ulp_init_mapper_params(&mparms, ¶ms,
627 : : BNXT_ULP_FDB_TYPE_REGULAR);
628 : 0 : mparms.act_tid = act_tid;
629 : :
630 : : /* Get the function id */
631 [ # # ]: 0 : if (ulp_port_db_port_func_id_get(ulp_ctx,
632 : 0 : dev->data->port_id,
633 : : &func_id)) {
634 : 0 : BNXT_TF_DBG(ERR, "conversion of port to func id failed\n");
635 : 0 : goto parse_error;
636 : : }
637 : :
638 : : /* Protect flow creation */
639 [ # # ]: 0 : if (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {
640 : 0 : BNXT_TF_DBG(ERR, "Flow db lock acquire failed\n");
641 : 0 : goto parse_error;
642 : : }
643 : :
644 : 0 : ret = ulp_mapper_flow_create(params.ulp_ctx, &mparms);
645 : 0 : bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
646 : :
647 [ # # ]: 0 : if (ret)
648 : 0 : goto parse_error;
649 : :
650 : 0 : return (struct rte_flow_action_handle *)((uintptr_t)mparms.shared_hndl);
651 : :
652 : 0 : parse_error:
653 : 0 : rte_flow_error_set(error, ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
654 : : "Failed to create shared action.");
655 : 0 : return NULL;
656 : : }
657 : :
658 : : static int
659 : 0 : bnxt_ulp_action_handle_destroy(struct rte_eth_dev *dev,
660 : : struct rte_flow_action_handle *shared_hndl,
661 : : struct rte_flow_error *error)
662 : : {
663 : 0 : struct bnxt_ulp_mapper_create_parms mparms = { 0 };
664 : : struct bnxt_ulp_shared_act_info *act_info;
665 : : struct ulp_rte_parser_params params;
666 : : struct ulp_rte_act_prop *act_prop;
667 : : struct bnxt_ulp_context *ulp_ctx;
668 : : enum bnxt_ulp_direction_type dir;
669 : : uint32_t act_tid, act_info_entries;
670 : : int ret = BNXT_TF_RC_ERROR;
671 : : uint32_t shared_action_type;
672 : : uint64_t tmp64;
673 : :
674 : 0 : ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(dev);
675 [ # # ]: 0 : if (!ulp_ctx) {
676 : 0 : BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
677 : 0 : goto parse_error;
678 : : }
679 : :
680 [ # # ]: 0 : if (!shared_hndl) {
681 : 0 : BNXT_TF_DBG(ERR, "Invalid argument of shared handle\n");
682 : 0 : goto parse_error;
683 : : }
684 : :
685 : : act_prop = ¶ms.act_prop;
686 : : memset(¶ms, 0, sizeof(struct ulp_rte_parser_params));
687 : 0 : params.ulp_ctx = ulp_ctx;
688 : :
689 [ # # ]: 0 : if (bnxt_ulp_cntxt_app_id_get(ulp_ctx, ¶ms.app_id)) {
690 : 0 : BNXT_TF_DBG(ERR, "failed to get the app id\n");
691 : 0 : goto parse_error;
692 : : }
693 : : /* The template will delete the entry if there are no references */
694 [ # # ]: 0 : if (bnxt_get_action_handle_type(shared_hndl, &shared_action_type)) {
695 : 0 : BNXT_TF_DBG(ERR, "Invalid shared handle\n");
696 : 0 : goto parse_error;
697 : : }
698 : :
699 : 0 : act_info_entries = 0;
700 : 0 : act_info = bnxt_ulp_shared_act_info_get(&act_info_entries);
701 [ # # # # ]: 0 : if (shared_action_type >= act_info_entries || !act_info) {
702 : 0 : BNXT_TF_DBG(ERR, "Invalid shared handle\n");
703 : 0 : goto parse_error;
704 : : }
705 : :
706 : 0 : ULP_BITMAP_SET(params.act_bitmap.bits,
707 : : act_info[shared_action_type].act_bitmask);
708 : 0 : ULP_BITMAP_SET(params.act_bitmap.bits, BNXT_ULP_ACT_BIT_DELETE);
709 : :
710 : 0 : ret = bnxt_get_action_handle_direction(shared_hndl, &dir);
711 [ # # ]: 0 : if (ret) {
712 : 0 : BNXT_TF_DBG(ERR, "Invalid shared handle dir\n");
713 : 0 : goto parse_error;
714 : : }
715 : :
716 [ # # ]: 0 : if (dir == BNXT_ULP_DIR_EGRESS) {
717 : 0 : params.dir_attr = BNXT_ULP_FLOW_ATTR_EGRESS;
718 : 0 : ULP_BITMAP_SET(params.act_bitmap.bits,
719 : : BNXT_ULP_FLOW_DIR_BITMASK_EGR);
720 : : } else {
721 : 0 : params.dir_attr = BNXT_ULP_FLOW_ATTR_INGRESS;
722 : : ULP_BITMAP_SET(params.act_bitmap.bits,
723 : : BNXT_ULP_FLOW_DIR_BITMASK_ING);
724 : : }
725 : :
726 : 0 : tmp64 = tfp_cpu_to_be_64((uint64_t)
727 : : bnxt_get_action_handle_index(shared_hndl));
728 : :
729 : : memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_SHARED_HANDLE],
730 : : &tmp64, BNXT_ULP_ACT_PROP_SZ_SHARED_HANDLE);
731 : :
732 : 0 : ret = ulp_matcher_action_match(¶ms, &act_tid);
733 [ # # ]: 0 : if (ret != BNXT_TF_RC_SUCCESS)
734 : 0 : goto parse_error;
735 : :
736 : 0 : bnxt_ulp_init_mapper_params(&mparms, ¶ms,
737 : : BNXT_ULP_FDB_TYPE_REGULAR);
738 : 0 : mparms.act_tid = act_tid;
739 : :
740 [ # # ]: 0 : if (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {
741 : 0 : BNXT_TF_DBG(ERR, "Flow db lock acquire failed\n");
742 : 0 : goto parse_error;
743 : : }
744 : :
745 : 0 : ret = ulp_mapper_flow_create(ulp_ctx, &mparms);
746 : 0 : bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
747 [ # # ]: 0 : if (ret)
748 : 0 : goto parse_error;
749 : :
750 : : return 0;
751 : :
752 : 0 : parse_error:
753 : 0 : rte_flow_error_set(error, BNXT_TF_RC_ERROR,
754 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
755 : : "Failed to destroy shared action.");
756 : 0 : return -EINVAL;
757 : : }
758 : :
759 : : /* Tunnel offload Apis */
760 : : #define BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS 1
761 : :
762 : : static int
763 : 0 : bnxt_ulp_tunnel_decap_set(struct rte_eth_dev *eth_dev,
764 : : struct rte_flow_tunnel *tunnel,
765 : : struct rte_flow_action **pmd_actions,
766 : : uint32_t *num_of_actions,
767 : : struct rte_flow_error *error)
768 : : {
769 : : struct bnxt_ulp_context *ulp_ctx;
770 : : struct bnxt_flow_app_tun_ent *tun_entry;
771 : : int32_t rc = 0;
772 : :
773 : 0 : ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
774 [ # # ]: 0 : if (ulp_ctx == NULL) {
775 : 0 : BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
776 : 0 : rte_flow_error_set(error, EINVAL,
777 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
778 : : "ULP context uninitialized");
779 : 0 : return -EINVAL;
780 : : }
781 : :
782 [ # # ]: 0 : if (tunnel == NULL) {
783 : 0 : BNXT_TF_DBG(ERR, "No tunnel specified\n");
784 : 0 : rte_flow_error_set(error, EINVAL,
785 : : RTE_FLOW_ERROR_TYPE_ATTR, NULL,
786 : : "no tunnel specified");
787 : 0 : return -EINVAL;
788 : : }
789 : :
790 [ # # ]: 0 : if (tunnel->type != RTE_FLOW_ITEM_TYPE_VXLAN) {
791 : 0 : BNXT_TF_DBG(ERR, "Tunnel type unsupported\n");
792 : 0 : rte_flow_error_set(error, EINVAL,
793 : : RTE_FLOW_ERROR_TYPE_ATTR, NULL,
794 : : "tunnel type unsupported");
795 : 0 : return -EINVAL;
796 : : }
797 : :
798 : 0 : rc = ulp_app_tun_search_entry(ulp_ctx, tunnel, &tun_entry);
799 [ # # ]: 0 : if (rc < 0) {
800 : 0 : rte_flow_error_set(error, EINVAL,
801 : : RTE_FLOW_ERROR_TYPE_ATTR, NULL,
802 : : "tunnel decap set failed");
803 : 0 : return -EINVAL;
804 : : }
805 : :
806 : 0 : rc = ulp_app_tun_entry_set_decap_action(tun_entry);
807 [ # # ]: 0 : if (rc < 0) {
808 : 0 : rte_flow_error_set(error, EINVAL,
809 : : RTE_FLOW_ERROR_TYPE_ATTR, NULL,
810 : : "tunnel decap set failed");
811 : 0 : return -EINVAL;
812 : : }
813 : :
814 : 0 : *pmd_actions = &tun_entry->action;
815 : 0 : *num_of_actions = BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS;
816 : 0 : return 0;
817 : : }
818 : :
819 : : static int
820 : 0 : bnxt_ulp_tunnel_match(struct rte_eth_dev *eth_dev,
821 : : struct rte_flow_tunnel *tunnel,
822 : : struct rte_flow_item **pmd_items,
823 : : uint32_t *num_of_items,
824 : : struct rte_flow_error *error)
825 : : {
826 : : struct bnxt_ulp_context *ulp_ctx;
827 : : struct bnxt_flow_app_tun_ent *tun_entry;
828 : : int32_t rc = 0;
829 : :
830 : 0 : ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
831 [ # # ]: 0 : if (ulp_ctx == NULL) {
832 : 0 : BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
833 : 0 : rte_flow_error_set(error, EINVAL,
834 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
835 : : "ULP context uninitialized");
836 : 0 : return -EINVAL;
837 : : }
838 : :
839 [ # # ]: 0 : if (tunnel == NULL) {
840 : 0 : BNXT_TF_DBG(ERR, "No tunnel specified\n");
841 : 0 : rte_flow_error_set(error, EINVAL,
842 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
843 : : "no tunnel specified");
844 : 0 : return -EINVAL;
845 : : }
846 : :
847 [ # # ]: 0 : if (tunnel->type != RTE_FLOW_ITEM_TYPE_VXLAN) {
848 : 0 : BNXT_TF_DBG(ERR, "Tunnel type unsupported\n");
849 : 0 : rte_flow_error_set(error, EINVAL,
850 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
851 : : "tunnel type unsupported");
852 : 0 : return -EINVAL;
853 : : }
854 : :
855 : 0 : rc = ulp_app_tun_search_entry(ulp_ctx, tunnel, &tun_entry);
856 [ # # ]: 0 : if (rc < 0) {
857 : 0 : rte_flow_error_set(error, EINVAL,
858 : : RTE_FLOW_ERROR_TYPE_ATTR, NULL,
859 : : "tunnel match set failed");
860 : 0 : return -EINVAL;
861 : : }
862 : :
863 : 0 : rc = ulp_app_tun_entry_set_decap_item(tun_entry);
864 [ # # ]: 0 : if (rc < 0) {
865 : 0 : rte_flow_error_set(error, EINVAL,
866 : : RTE_FLOW_ERROR_TYPE_ATTR, NULL,
867 : : "tunnel match set failed");
868 : 0 : return -EINVAL;
869 : : }
870 : :
871 : 0 : *pmd_items = &tun_entry->item;
872 : 0 : *num_of_items = BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS;
873 : 0 : return 0;
874 : : }
875 : :
876 : : static int
877 : 0 : bnxt_ulp_tunnel_decap_release(struct rte_eth_dev *eth_dev,
878 : : struct rte_flow_action *pmd_actions,
879 : : uint32_t num_actions,
880 : : struct rte_flow_error *error)
881 : : {
882 : : struct bnxt_ulp_context *ulp_ctx;
883 : : struct bnxt_flow_app_tun_ent *tun_entry;
884 : : const struct rte_flow_action *action_item = pmd_actions;
885 : :
886 : 0 : ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
887 [ # # ]: 0 : if (ulp_ctx == NULL) {
888 : 0 : BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
889 : 0 : rte_flow_error_set(error, EINVAL,
890 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
891 : : "ULP context uninitialized");
892 : 0 : return -EINVAL;
893 : : }
894 [ # # ]: 0 : if (num_actions != BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS) {
895 : 0 : BNXT_TF_DBG(ERR, "num actions is invalid\n");
896 : 0 : rte_flow_error_set(error, EINVAL,
897 : : RTE_FLOW_ERROR_TYPE_ATTR, NULL,
898 : : "num actions is invalid");
899 : 0 : return -EINVAL;
900 : : }
901 [ # # # # ]: 0 : while (action_item && action_item->type != RTE_FLOW_ACTION_TYPE_END) {
902 [ # # ]: 0 : if (action_item->type == (typeof(tun_entry->action.type))
903 : : BNXT_RTE_FLOW_ACTION_TYPE_VXLAN_DECAP) {
904 : 0 : tun_entry = ulp_app_tun_match_entry(ulp_ctx,
905 : 0 : action_item->conf);
906 : 0 : ulp_app_tun_entry_delete(tun_entry);
907 : : }
908 : 0 : action_item++;
909 : : }
910 : : return 0;
911 : : }
912 : :
913 : : static int
914 : 0 : bnxt_ulp_tunnel_item_release(struct rte_eth_dev *eth_dev,
915 : : struct rte_flow_item *pmd_items,
916 : : uint32_t num_items,
917 : : struct rte_flow_error *error)
918 : : {
919 : : struct bnxt_ulp_context *ulp_ctx;
920 : : struct bnxt_flow_app_tun_ent *tun_entry;
921 : :
922 : 0 : ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
923 [ # # ]: 0 : if (ulp_ctx == NULL) {
924 : 0 : BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
925 : 0 : rte_flow_error_set(error, EINVAL,
926 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
927 : : "ULP context uninitialized");
928 : 0 : return -EINVAL;
929 : : }
930 [ # # ]: 0 : if (num_items != BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS) {
931 : 0 : BNXT_TF_DBG(ERR, "num items is invalid\n");
932 : 0 : rte_flow_error_set(error, EINVAL,
933 : : RTE_FLOW_ERROR_TYPE_ATTR, NULL,
934 : : "num items is invalid");
935 : 0 : return -EINVAL;
936 : : }
937 : :
938 : 0 : tun_entry = ulp_app_tun_match_entry(ulp_ctx, pmd_items->spec);
939 : 0 : ulp_app_tun_entry_delete(tun_entry);
940 : 0 : return 0;
941 : : }
942 : :
943 : : const struct rte_flow_ops bnxt_ulp_rte_flow_ops = {
944 : : .validate = bnxt_ulp_flow_validate,
945 : : .create = bnxt_ulp_flow_create,
946 : : .destroy = bnxt_ulp_flow_destroy,
947 : : .flush = bnxt_ulp_flow_flush,
948 : : .query = bnxt_ulp_flow_query,
949 : : .isolate = NULL,
950 : : .action_handle_create = bnxt_ulp_action_handle_create,
951 : : .action_handle_destroy = bnxt_ulp_action_handle_destroy,
952 : : /* Tunnel offload callbacks */
953 : : .tunnel_decap_set = bnxt_ulp_tunnel_decap_set,
954 : : .tunnel_match = bnxt_ulp_tunnel_match,
955 : : .tunnel_action_decap_release = bnxt_ulp_tunnel_decap_release,
956 : : .tunnel_item_release = bnxt_ulp_tunnel_item_release,
957 : : .get_restore_info = NULL
958 : : };
|