xref: /dpdk/drivers/net/bnxt/tf_ulp/ulp_def_rules.c (revision 68a03efeed657e6e05f281479b33b51102797e15)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2021 Broadcom
3  * All rights reserved.
4  */
5 
6 #include "bnxt_tf_common.h"
7 #include "ulp_template_struct.h"
8 #include "ulp_template_db_enum.h"
9 #include "ulp_template_db_field.h"
10 #include "ulp_utils.h"
11 #include "ulp_port_db.h"
12 #include "ulp_flow_db.h"
13 #include "ulp_mapper.h"
14 
15 struct bnxt_ulp_def_param_handler {
16 	int32_t (*vfr_func)(struct bnxt_ulp_context *ulp_ctx,
17 			    struct ulp_tlv_param *param,
18 			    struct bnxt_ulp_mapper_create_parms *mapper_params);
19 };
20 
21 static int32_t
22 ulp_set_svif_in_comp_fld(struct bnxt_ulp_context *ulp_ctx,
23 			 uint32_t  ifindex, uint8_t svif_type,
24 			 struct bnxt_ulp_mapper_create_parms *mapper_params)
25 {
26 	uint16_t svif;
27 	uint8_t idx;
28 	int rc;
29 
30 	rc = ulp_port_db_svif_get(ulp_ctx, ifindex, svif_type, &svif);
31 	if (rc)
32 		return rc;
33 
34 	if (svif_type == BNXT_ULP_PHY_PORT_SVIF)
35 		idx = BNXT_ULP_CF_IDX_PHY_PORT_SVIF;
36 	else if (svif_type == BNXT_ULP_DRV_FUNC_SVIF)
37 		idx = BNXT_ULP_CF_IDX_DRV_FUNC_SVIF;
38 	else
39 		idx = BNXT_ULP_CF_IDX_VF_FUNC_SVIF;
40 
41 	ULP_COMP_FLD_IDX_WR(mapper_params, idx, svif);
42 
43 	return 0;
44 }
45 
46 static int32_t
47 ulp_set_spif_in_comp_fld(struct bnxt_ulp_context *ulp_ctx,
48 			 uint32_t  ifindex, uint8_t spif_type,
49 			 struct bnxt_ulp_mapper_create_parms *mapper_params)
50 {
51 	uint16_t spif;
52 	uint8_t idx;
53 	int rc;
54 
55 	rc = ulp_port_db_spif_get(ulp_ctx, ifindex, spif_type, &spif);
56 	if (rc)
57 		return rc;
58 
59 	if (spif_type == BNXT_ULP_PHY_PORT_SPIF)
60 		idx = BNXT_ULP_CF_IDX_PHY_PORT_SPIF;
61 	else if (spif_type == BNXT_ULP_DRV_FUNC_SPIF)
62 		idx = BNXT_ULP_CF_IDX_DRV_FUNC_SPIF;
63 	else
64 		idx = BNXT_ULP_CF_IDX_VF_FUNC_SPIF;
65 
66 	ULP_COMP_FLD_IDX_WR(mapper_params, idx, spif);
67 
68 	return 0;
69 }
70 
71 static int32_t
72 ulp_set_parif_in_comp_fld(struct bnxt_ulp_context *ulp_ctx,
73 			  uint32_t  ifindex, uint8_t parif_type,
74 			  struct bnxt_ulp_mapper_create_parms *mapper_params)
75 {
76 	uint16_t parif;
77 	uint8_t idx;
78 	int rc;
79 
80 	rc = ulp_port_db_parif_get(ulp_ctx, ifindex, parif_type, &parif);
81 	if (rc)
82 		return rc;
83 
84 	if (parif_type == BNXT_ULP_PHY_PORT_PARIF)
85 		idx = BNXT_ULP_CF_IDX_PHY_PORT_PARIF;
86 	else if (parif_type == BNXT_ULP_DRV_FUNC_PARIF)
87 		idx = BNXT_ULP_CF_IDX_DRV_FUNC_PARIF;
88 	else
89 		idx = BNXT_ULP_CF_IDX_VF_FUNC_PARIF;
90 
91 	ULP_COMP_FLD_IDX_WR(mapper_params, idx, parif);
92 
93 	return 0;
94 }
95 
96 static int32_t
97 ulp_set_vport_in_comp_fld(struct bnxt_ulp_context *ulp_ctx, uint32_t ifindex,
98 			  struct bnxt_ulp_mapper_create_parms *mapper_params)
99 {
100 	uint16_t vport;
101 	int rc;
102 
103 	rc = ulp_port_db_vport_get(ulp_ctx, ifindex, &vport);
104 	if (rc)
105 		return rc;
106 
107 	ULP_COMP_FLD_IDX_WR(mapper_params, BNXT_ULP_CF_IDX_PHY_PORT_VPORT,
108 			    vport);
109 	return 0;
110 }
111 
112 static int32_t
113 ulp_set_vnic_in_comp_fld(struct bnxt_ulp_context *ulp_ctx,
114 			 uint32_t  ifindex, uint8_t vnic_type,
115 			 struct bnxt_ulp_mapper_create_parms *mapper_params)
116 {
117 	uint16_t vnic;
118 	uint8_t idx;
119 	int rc;
120 
121 	rc = ulp_port_db_default_vnic_get(ulp_ctx, ifindex, vnic_type, &vnic);
122 	if (rc)
123 		return rc;
124 
125 	if (vnic_type == BNXT_ULP_DRV_FUNC_VNIC)
126 		idx = BNXT_ULP_CF_IDX_DRV_FUNC_VNIC;
127 	else
128 		idx = BNXT_ULP_CF_IDX_VF_FUNC_VNIC;
129 
130 	ULP_COMP_FLD_IDX_WR(mapper_params, idx, vnic);
131 
132 	return 0;
133 }
134 
135 static int32_t
136 ulp_set_vlan_in_act_prop(uint16_t port_id,
137 			 struct bnxt_ulp_mapper_create_parms *mapper_params)
138 {
139 	struct ulp_rte_act_prop *act_prop = mapper_params->act_prop;
140 
141 	if (ULP_BITMAP_ISSET(mapper_params->act->bits,
142 			     BNXT_ULP_ACTION_BIT_SET_VLAN_VID)) {
143 		BNXT_TF_DBG(ERR,
144 			    "VLAN already set, multiple VLANs unsupported\n");
145 		return BNXT_TF_RC_ERROR;
146 	}
147 
148 	port_id = rte_cpu_to_be_16(port_id);
149 
150 	ULP_BITMAP_SET(mapper_params->act->bits,
151 		       BNXT_ULP_ACTION_BIT_SET_VLAN_VID);
152 
153 	memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_VTAG],
154 	       &port_id, sizeof(port_id));
155 
156 	return 0;
157 }
158 
159 static int32_t
160 ulp_set_mark_in_act_prop(uint16_t port_id,
161 			 struct bnxt_ulp_mapper_create_parms *mapper_params)
162 {
163 	if (ULP_BITMAP_ISSET(mapper_params->act->bits,
164 			     BNXT_ULP_ACTION_BIT_MARK)) {
165 		BNXT_TF_DBG(ERR,
166 			    "MARK already set, multiple MARKs unsupported\n");
167 		return BNXT_TF_RC_ERROR;
168 	}
169 
170 	ULP_COMP_FLD_IDX_WR(mapper_params, BNXT_ULP_CF_IDX_DEV_PORT_ID,
171 			    port_id);
172 
173 	return 0;
174 }
175 
176 static int32_t
177 ulp_df_dev_port_handler(struct bnxt_ulp_context *ulp_ctx,
178 			struct ulp_tlv_param *param,
179 			struct bnxt_ulp_mapper_create_parms *mapper_params)
180 {
181 	uint16_t port_id;
182 	uint32_t ifindex;
183 	int rc;
184 
185 	port_id = param->value[0] | param->value[1];
186 
187 	rc = ulp_port_db_dev_port_to_ulp_index(ulp_ctx, port_id, &ifindex);
188 	if (rc) {
189 		BNXT_TF_DBG(ERR,
190 				"Invalid port id\n");
191 		return BNXT_TF_RC_ERROR;
192 	}
193 
194 	/* Set port SVIF */
195 	rc = ulp_set_svif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_PHY_PORT_SVIF,
196 				      mapper_params);
197 	if (rc)
198 		return rc;
199 
200 	/* Set DRV Func SVIF */
201 	rc = ulp_set_svif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_DRV_FUNC_SVIF,
202 				      mapper_params);
203 	if (rc)
204 		return rc;
205 
206 	/* Set VF Func SVIF */
207 	rc = ulp_set_svif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_VF_FUNC_SVIF,
208 				      mapper_params);
209 	if (rc)
210 		return rc;
211 
212 	/* Set port SPIF */
213 	rc = ulp_set_spif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_PHY_PORT_SPIF,
214 				      mapper_params);
215 	if (rc)
216 		return rc;
217 
218 	/* Set DRV Func SPIF */
219 	rc = ulp_set_spif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_DRV_FUNC_SPIF,
220 				      mapper_params);
221 	if (rc)
222 		return rc;
223 
224 	/* Set VF Func SPIF */
225 	rc = ulp_set_spif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_DRV_FUNC_SPIF,
226 				      mapper_params);
227 	if (rc)
228 		return rc;
229 
230 	/* Set port PARIF */
231 	rc = ulp_set_parif_in_comp_fld(ulp_ctx, ifindex,
232 				       BNXT_ULP_PHY_PORT_PARIF, mapper_params);
233 	if (rc)
234 		return rc;
235 
236 	/* Set DRV Func PARIF */
237 	rc = ulp_set_parif_in_comp_fld(ulp_ctx, ifindex,
238 				       BNXT_ULP_DRV_FUNC_PARIF, mapper_params);
239 	if (rc)
240 		return rc;
241 
242 	/* Set VF Func PARIF */
243 	rc = ulp_set_parif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_VF_FUNC_PARIF,
244 				       mapper_params);
245 	if (rc)
246 		return rc;
247 
248 	/* Set uplink VNIC */
249 	rc = ulp_set_vnic_in_comp_fld(ulp_ctx, ifindex, true, mapper_params);
250 	if (rc)
251 		return rc;
252 
253 	/* Set VF VNIC */
254 	rc = ulp_set_vnic_in_comp_fld(ulp_ctx, ifindex, false, mapper_params);
255 	if (rc)
256 		return rc;
257 
258 	/* Set VPORT */
259 	rc = ulp_set_vport_in_comp_fld(ulp_ctx, ifindex, mapper_params);
260 	if (rc)
261 		return rc;
262 
263 	/* Set VLAN */
264 	rc = ulp_set_vlan_in_act_prop(port_id, mapper_params);
265 	if (rc)
266 		return rc;
267 
268 	/* Set MARK */
269 	rc = ulp_set_mark_in_act_prop(port_id, mapper_params);
270 	if (rc)
271 		return rc;
272 
273 	return 0;
274 }
275 
276 struct bnxt_ulp_def_param_handler ulp_def_handler_tbl[] = {
277 	[BNXT_ULP_DF_PARAM_TYPE_DEV_PORT_ID] = {
278 			.vfr_func = ulp_df_dev_port_handler }
279 };
280 
281 /*
282  * Function to create default rules for the following paths
283  * 1) Device PORT to DPDK App
284  * 2) DPDK App to Device PORT
285  * 3) VF Representor to VF
286  * 4) VF to VF Representor
287  *
288  * eth_dev [in] Ptr to rte eth device.
289  * param_list [in] Ptr to a list of parameters (Currently, only DPDK port_id).
290  * ulp_class_tid [in] Class template ID number.
291  * flow_id [out] Ptr to flow identifier.
292  *
293  * Returns 0 on success or negative number on failure.
294  */
295 int32_t
296 ulp_default_flow_create(struct rte_eth_dev *eth_dev,
297 			struct ulp_tlv_param *param_list,
298 			uint32_t ulp_class_tid,
299 			uint32_t *flow_id)
300 {
301 	struct ulp_rte_hdr_field	hdr_field[BNXT_ULP_PROTO_HDR_MAX];
302 	uint32_t			comp_fld[BNXT_ULP_CF_IDX_LAST];
303 	struct bnxt_ulp_mapper_create_parms mapper_params = { 0 };
304 	struct ulp_rte_act_prop		act_prop;
305 	struct ulp_rte_act_bitmap	act = { 0 };
306 	struct bnxt_ulp_context		*ulp_ctx;
307 	uint32_t type, ulp_flags = 0, fid;
308 	int rc = 0;
309 
310 	memset(&mapper_params, 0, sizeof(mapper_params));
311 	memset(hdr_field, 0, sizeof(hdr_field));
312 	memset(comp_fld, 0, sizeof(comp_fld));
313 	memset(&act_prop, 0, sizeof(act_prop));
314 
315 	mapper_params.hdr_field = hdr_field;
316 	mapper_params.act = &act;
317 	mapper_params.act_prop = &act_prop;
318 	mapper_params.comp_fld = comp_fld;
319 	mapper_params.class_tid = ulp_class_tid;
320 	mapper_params.flow_type = BNXT_ULP_FDB_TYPE_DEFAULT;
321 
322 	ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
323 	if (!ulp_ctx) {
324 		BNXT_TF_DBG(ERR, "ULP context is not initialized. "
325 				 "Failed to create default flow.\n");
326 		return -EINVAL;
327 	}
328 
329 	/* update the vf rep flag */
330 	if (bnxt_ulp_cntxt_ptr2_ulp_flags_get(ulp_ctx, &ulp_flags)) {
331 		BNXT_TF_DBG(ERR, "Error in getting ULP context flags\n");
332 		return -EINVAL;
333 	}
334 	if (ULP_VF_REP_IS_ENABLED(ulp_flags))
335 		ULP_COMP_FLD_IDX_WR(&mapper_params,
336 				    BNXT_ULP_CF_IDX_VFR_MODE, 1);
337 
338 	type = param_list->type;
339 	while (type != BNXT_ULP_DF_PARAM_TYPE_LAST) {
340 		if (ulp_def_handler_tbl[type].vfr_func) {
341 			rc = ulp_def_handler_tbl[type].vfr_func(ulp_ctx,
342 								param_list,
343 								&mapper_params);
344 			if (rc) {
345 				BNXT_TF_DBG(ERR,
346 					    "Failed to create default flow.\n");
347 				return rc;
348 			}
349 		}
350 
351 		param_list++;
352 		type = param_list->type;
353 	}
354 
355 	/* Get the function id */
356 	if (ulp_port_db_port_func_id_get(ulp_ctx,
357 					 eth_dev->data->port_id,
358 					 &mapper_params.func_id)) {
359 		BNXT_TF_DBG(ERR, "conversion of port to func id failed\n");
360 		goto err1;
361 	}
362 
363 	/* Protect flow creation */
364 	if (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {
365 		BNXT_TF_DBG(ERR, "Flow db lock acquire failed\n");
366 		goto err1;
367 	}
368 
369 	rc = ulp_flow_db_fid_alloc(ulp_ctx, BNXT_ULP_FDB_TYPE_DEFAULT,
370 				   mapper_params.func_id, &fid);
371 	if (rc) {
372 		BNXT_TF_DBG(ERR, "Unable to allocate flow table entry\n");
373 		goto err2;
374 	}
375 
376 	mapper_params.flow_id = fid;
377 	rc = ulp_mapper_flow_create(ulp_ctx, &mapper_params);
378 	if (rc)
379 		goto err3;
380 
381 	bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
382 	*flow_id = fid;
383 	return 0;
384 
385 err3:
386 	ulp_flow_db_fid_free(ulp_ctx, BNXT_ULP_FDB_TYPE_DEFAULT, fid);
387 err2:
388 	bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
389 err1:
390 	BNXT_TF_DBG(ERR, "Failed to create default flow.\n");
391 	return rc;
392 }
393 
394 /*
395  * Function to destroy default rules for the following paths
396  * 1) Device PORT to DPDK App
397  * 2) DPDK App to Device PORT
398  * 3) VF Representor to VF
399  * 4) VF to VF Representor
400  *
401  * eth_dev [in] Ptr to rte eth device.
402  * flow_id [in] Flow identifier.
403  *
404  * Returns 0 on success or negative number on failure.
405  */
406 int32_t
407 ulp_default_flow_destroy(struct rte_eth_dev *eth_dev, uint32_t flow_id)
408 {
409 	struct bnxt_ulp_context *ulp_ctx;
410 	int rc = 0;
411 
412 	ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
413 	if (!ulp_ctx) {
414 		BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
415 		return -EINVAL;
416 	}
417 
418 	if (!flow_id) {
419 		BNXT_TF_DBG(DEBUG, "invalid flow id zero\n");
420 		return rc;
421 	}
422 
423 	if (bnxt_ulp_cntxt_acquire_fdb_lock(ulp_ctx)) {
424 		BNXT_TF_DBG(ERR, "Flow db lock acquire failed\n");
425 		return -EINVAL;
426 	}
427 	rc = ulp_mapper_flow_destroy(ulp_ctx, BNXT_ULP_FDB_TYPE_DEFAULT,
428 				     flow_id);
429 	if (rc)
430 		BNXT_TF_DBG(ERR, "Failed to destroy flow.\n");
431 	bnxt_ulp_cntxt_release_fdb_lock(ulp_ctx);
432 
433 	return rc;
434 }
435 
436 void
437 bnxt_ulp_destroy_df_rules(struct bnxt *bp, bool global)
438 {
439 	struct bnxt_ulp_df_rule_info *info;
440 	uint16_t port_id;
441 
442 	if (!BNXT_TRUFLOW_EN(bp) ||
443 	    BNXT_ETH_DEV_IS_REPRESENTOR(bp->eth_dev))
444 		return;
445 
446 	if (!bp->ulp_ctx || !bp->ulp_ctx->cfg_data)
447 		return;
448 
449 	/* Delete default rules per port */
450 	if (!global) {
451 		port_id = bp->eth_dev->data->port_id;
452 		info = &bp->ulp_ctx->cfg_data->df_rule_info[port_id];
453 		if (!info->valid)
454 			return;
455 
456 		ulp_default_flow_destroy(bp->eth_dev,
457 					 info->port_to_app_flow_id);
458 		ulp_default_flow_destroy(bp->eth_dev,
459 					 info->app_to_port_flow_id);
460 		memset(info, 0, sizeof(struct bnxt_ulp_df_rule_info));
461 		return;
462 	}
463 
464 	/* Delete default rules for all ports */
465 	for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) {
466 		info = &bp->ulp_ctx->cfg_data->df_rule_info[port_id];
467 		if (!info->valid)
468 			continue;
469 
470 		ulp_default_flow_destroy(bp->eth_dev,
471 					 info->port_to_app_flow_id);
472 		ulp_default_flow_destroy(bp->eth_dev,
473 					 info->app_to_port_flow_id);
474 		memset(info, 0, sizeof(struct bnxt_ulp_df_rule_info));
475 	}
476 }
477 
478 static int32_t
479 bnxt_create_port_app_df_rule(struct bnxt *bp, uint8_t flow_type,
480 			     uint32_t *flow_id)
481 {
482 	uint16_t port_id = bp->eth_dev->data->port_id;
483 	struct ulp_tlv_param param_list[] = {
484 		{
485 			.type = BNXT_ULP_DF_PARAM_TYPE_DEV_PORT_ID,
486 			.length = 2,
487 			.value = {(port_id >> 8) & 0xff, port_id & 0xff}
488 		},
489 		{
490 			.type = BNXT_ULP_DF_PARAM_TYPE_LAST,
491 			.length = 0,
492 			.value = {0}
493 		}
494 	};
495 
496 	return ulp_default_flow_create(bp->eth_dev, param_list, flow_type,
497 				       flow_id);
498 }
499 
500 int32_t
501 bnxt_ulp_create_df_rules(struct bnxt *bp)
502 {
503 	struct bnxt_ulp_df_rule_info *info;
504 	uint16_t port_id;
505 	int rc;
506 
507 	if (!BNXT_TRUFLOW_EN(bp) ||
508 	    BNXT_ETH_DEV_IS_REPRESENTOR(bp->eth_dev) || !bp->ulp_ctx)
509 		return 0;
510 
511 	port_id = bp->eth_dev->data->port_id;
512 	info = &bp->ulp_ctx->cfg_data->df_rule_info[port_id];
513 	rc = bnxt_create_port_app_df_rule(bp, BNXT_ULP_DF_TPL_PORT_TO_VS,
514 					  &info->port_to_app_flow_id);
515 	if (rc) {
516 		BNXT_TF_DBG(ERR,
517 			    "Failed to create port to app default rule\n");
518 		return rc;
519 	}
520 
521 	bp->tx_cfa_action = 0;
522 	rc = bnxt_create_port_app_df_rule(bp, BNXT_ULP_DF_TPL_VS_TO_PORT,
523 					  &info->app_to_port_flow_id);
524 	if (rc) {
525 		BNXT_TF_DBG(ERR,
526 			    "Failed to create app to port default rule\n");
527 		goto port_to_app_free;
528 	}
529 
530 	rc = ulp_default_flow_db_cfa_action_get(bp->ulp_ctx,
531 						info->app_to_port_flow_id,
532 						&bp->tx_cfa_action);
533 	if (rc)
534 		goto app_to_port_free;
535 
536 	info->valid = true;
537 	return 0;
538 
539 app_to_port_free:
540 	ulp_default_flow_destroy(bp->eth_dev, info->app_to_port_flow_id);
541 port_to_app_free:
542 	ulp_default_flow_destroy(bp->eth_dev, info->port_to_app_flow_id);
543 	info->valid = false;
544 
545 	return rc;
546 }
547 
548 static int32_t
549 bnxt_create_port_vfr_default_rule(struct bnxt *bp,
550 				  uint8_t flow_type,
551 				  uint16_t vfr_port_id,
552 				  uint32_t *flow_id)
553 {
554 	struct ulp_tlv_param param_list[] = {
555 		{
556 			.type = BNXT_ULP_DF_PARAM_TYPE_DEV_PORT_ID,
557 			.length = 2,
558 			.value = {(vfr_port_id >> 8) & 0xff, vfr_port_id & 0xff}
559 		},
560 		{
561 			.type = BNXT_ULP_DF_PARAM_TYPE_LAST,
562 			.length = 0,
563 			.value = {0}
564 		}
565 	};
566 	return ulp_default_flow_create(bp->eth_dev, param_list, flow_type,
567 				       flow_id);
568 }
569 
570 int32_t
571 bnxt_ulp_create_vfr_default_rules(struct rte_eth_dev *vfr_ethdev)
572 {
573 	struct bnxt_ulp_vfr_rule_info *info;
574 	struct bnxt_representor *vfr = vfr_ethdev->data->dev_private;
575 	struct rte_eth_dev *parent_dev = vfr->parent_dev;
576 	struct bnxt *bp = parent_dev->data->dev_private;
577 	uint16_t vfr_port_id = vfr_ethdev->data->port_id;
578 	uint16_t port_id;
579 	int rc;
580 
581 	if (!bp || !BNXT_TRUFLOW_EN(bp))
582 		return 0;
583 
584 	port_id = vfr_ethdev->data->port_id;
585 	info = bnxt_ulp_cntxt_ptr2_ulp_vfr_info_get(bp->ulp_ctx, port_id);
586 
587 	if (!info) {
588 		BNXT_TF_DBG(ERR, "Failed to get vfr ulp context\n");
589 		return -EINVAL;
590 	}
591 
592 	if (info->valid) {
593 		BNXT_TF_DBG(ERR, "VFR already allocated\n");
594 		return -EINVAL;
595 	}
596 
597 	memset(info, 0, sizeof(struct bnxt_ulp_vfr_rule_info));
598 	rc = bnxt_create_port_vfr_default_rule(bp, BNXT_ULP_DF_TPL_VFREP_TO_VF,
599 					       vfr_port_id,
600 					       &info->rep2vf_flow_id);
601 	if (rc) {
602 		BNXT_TF_DBG(ERR, "Failed to create VFREP to VF default rule\n");
603 		goto error;
604 	}
605 	rc = bnxt_create_port_vfr_default_rule(bp, BNXT_ULP_DF_TPL_VF_TO_VFREP,
606 					       vfr_port_id,
607 					       &info->vf2rep_flow_id);
608 	if (rc) {
609 		BNXT_TF_DBG(ERR, "Failed to create VF to VFREP default rule\n");
610 		goto error;
611 	}
612 	rc = ulp_default_flow_db_cfa_action_get(bp->ulp_ctx,
613 						info->rep2vf_flow_id,
614 						&vfr->vfr_tx_cfa_action);
615 	if (rc) {
616 		BNXT_TF_DBG(ERR, "Failed to get the tx cfa action\n");
617 		goto error;
618 	}
619 
620 	/* Update the other details */
621 	info->valid = true;
622 	info->parent_port_id =  bp->eth_dev->data->port_id;
623 	return 0;
624 
625 error:
626 	if (info->rep2vf_flow_id)
627 		ulp_default_flow_destroy(bp->eth_dev, info->rep2vf_flow_id);
628 	if (info->vf2rep_flow_id)
629 		ulp_default_flow_destroy(bp->eth_dev, info->vf2rep_flow_id);
630 	return rc;
631 }
632 
633 int32_t
634 bnxt_ulp_delete_vfr_default_rules(struct bnxt_representor *vfr)
635 {
636 	struct bnxt_ulp_vfr_rule_info *info;
637 	struct rte_eth_dev *parent_dev = vfr->parent_dev;
638 	struct bnxt *bp = parent_dev->data->dev_private;
639 
640 	if (!bp || !BNXT_TRUFLOW_EN(bp))
641 		return 0;
642 	info = bnxt_ulp_cntxt_ptr2_ulp_vfr_info_get(bp->ulp_ctx,
643 						    vfr->dpdk_port_id);
644 	if (!info) {
645 		BNXT_TF_DBG(ERR, "Failed to get vfr ulp context\n");
646 		return -EINVAL;
647 	}
648 
649 	if (!info->valid) {
650 		BNXT_TF_DBG(ERR, "VFR already freed\n");
651 		return -EINVAL;
652 	}
653 	ulp_default_flow_destroy(bp->eth_dev, info->rep2vf_flow_id);
654 	ulp_default_flow_destroy(bp->eth_dev, info->vf2rep_flow_id);
655 	vfr->vfr_tx_cfa_action = 0;
656 	memset(info, 0, sizeof(struct bnxt_ulp_vfr_rule_info));
657 	return 0;
658 }
659