1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019-2020 Broadcom
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"
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);
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)
30 rc = ulp_port_db_svif_get(ulp_ctx, ifindex, svif_type, &svif);
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;
39 idx = BNXT_ULP_CF_IDX_VF_FUNC_SVIF;
41 ULP_COMP_FLD_IDX_WR(mapper_params, idx, svif);
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)
55 rc = ulp_port_db_spif_get(ulp_ctx, ifindex, spif_type, &spif);
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;
64 idx = BNXT_ULP_CF_IDX_VF_FUNC_SPIF;
66 ULP_COMP_FLD_IDX_WR(mapper_params, idx, spif);
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)
80 rc = ulp_port_db_parif_get(ulp_ctx, ifindex, parif_type, &parif);
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;
89 idx = BNXT_ULP_CF_IDX_VF_FUNC_PARIF;
91 ULP_COMP_FLD_IDX_WR(mapper_params, idx, parif);
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)
103 rc = ulp_port_db_vport_get(ulp_ctx, ifindex, &vport);
107 ULP_COMP_FLD_IDX_WR(mapper_params, BNXT_ULP_CF_IDX_PHY_PORT_VPORT,
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)
121 rc = ulp_port_db_default_vnic_get(ulp_ctx, ifindex, vnic_type, &vnic);
125 if (vnic_type == BNXT_ULP_DRV_FUNC_VNIC)
126 idx = BNXT_ULP_CF_IDX_DRV_FUNC_VNIC;
128 idx = BNXT_ULP_CF_IDX_VF_FUNC_VNIC;
130 ULP_COMP_FLD_IDX_WR(mapper_params, idx, vnic);
136 ulp_set_vlan_in_act_prop(uint16_t port_id,
137 struct bnxt_ulp_mapper_create_parms *mapper_params)
139 struct ulp_rte_act_prop *act_prop = mapper_params->act_prop;
141 if (ULP_BITMAP_ISSET(mapper_params->act->bits,
142 BNXT_ULP_ACTION_BIT_SET_VLAN_VID)) {
144 "VLAN already set, multiple VLANs unsupported\n");
145 return BNXT_TF_RC_ERROR;
148 port_id = rte_cpu_to_be_16(port_id);
150 ULP_BITMAP_SET(mapper_params->act->bits,
151 BNXT_ULP_ACTION_BIT_SET_VLAN_VID);
153 memcpy(&act_prop->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_VTAG],
154 &port_id, sizeof(port_id));
160 ulp_set_mark_in_act_prop(uint16_t port_id,
161 struct bnxt_ulp_mapper_create_parms *mapper_params)
163 if (ULP_BITMAP_ISSET(mapper_params->act->bits,
164 BNXT_ULP_ACTION_BIT_MARK)) {
166 "MARK already set, multiple MARKs unsupported\n");
167 return BNXT_TF_RC_ERROR;
170 ULP_COMP_FLD_IDX_WR(mapper_params, BNXT_ULP_CF_IDX_DEV_PORT_ID,
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)
185 port_id = param->value[0] | param->value[1];
187 rc = ulp_port_db_dev_port_to_ulp_index(ulp_ctx, port_id, &ifindex);
190 "Invalid port id\n");
191 return BNXT_TF_RC_ERROR;
195 rc = ulp_set_svif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_PHY_PORT_SVIF,
200 /* Set DRV Func SVIF */
201 rc = ulp_set_svif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_DRV_FUNC_SVIF,
206 /* Set VF Func SVIF */
207 rc = ulp_set_svif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_VF_FUNC_SVIF,
213 rc = ulp_set_spif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_PHY_PORT_SPIF,
218 /* Set DRV Func SPIF */
219 rc = ulp_set_spif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_DRV_FUNC_SPIF,
224 /* Set VF Func SPIF */
225 rc = ulp_set_spif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_DRV_FUNC_SPIF,
231 rc = ulp_set_parif_in_comp_fld(ulp_ctx, ifindex,
232 BNXT_ULP_PHY_PORT_PARIF, mapper_params);
236 /* Set DRV Func PARIF */
237 rc = ulp_set_parif_in_comp_fld(ulp_ctx, ifindex,
238 BNXT_ULP_DRV_FUNC_PARIF, mapper_params);
242 /* Set VF Func PARIF */
243 rc = ulp_set_parif_in_comp_fld(ulp_ctx, ifindex, BNXT_ULP_VF_FUNC_PARIF,
248 /* Set uplink VNIC */
249 rc = ulp_set_vnic_in_comp_fld(ulp_ctx, ifindex, true, mapper_params);
254 rc = ulp_set_vnic_in_comp_fld(ulp_ctx, ifindex, false, mapper_params);
259 rc = ulp_set_vport_in_comp_fld(ulp_ctx, ifindex, mapper_params);
264 rc = ulp_set_vlan_in_act_prop(port_id, mapper_params);
269 rc = ulp_set_mark_in_act_prop(port_id, mapper_params);
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 }
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
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.
293 * Returns 0 on success or negative number on failure.
296 ulp_default_flow_create(struct rte_eth_dev *eth_dev,
297 struct ulp_tlv_param *param_list,
298 uint32_t ulp_class_tid,
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;
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));
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;
320 ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
322 BNXT_TF_DBG(ERR, "ULP context is not initialized. "
323 "Failed to create default flow.\n");
327 /* update the vf rep flag */
328 if (bnxt_ulp_cntxt_ptr2_ulp_flags_get(ulp_ctx, &ulp_flags)) {
329 BNXT_TF_DBG(ERR, "Error in getting ULP context flags\n");
332 if (ULP_VF_REP_IS_ENABLED(ulp_flags))
333 ULP_COMP_FLD_IDX_WR(&mapper_params,
334 BNXT_ULP_CF_IDX_VFR_MODE, 1);
336 type = param_list->type;
337 while (type != BNXT_ULP_DF_PARAM_TYPE_LAST) {
338 if (ulp_def_handler_tbl[type].vfr_func) {
339 rc = ulp_def_handler_tbl[type].vfr_func(ulp_ctx,
344 "Failed to create default flow.\n");
350 type = param_list->type;
353 mapper_params.class_tid = ulp_class_tid;
354 mapper_params.flow_type = BNXT_ULP_FDB_TYPE_DEFAULT;
356 rc = ulp_mapper_flow_create(ulp_ctx, &mapper_params, flow_id);
358 BNXT_TF_DBG(ERR, "Failed to create default flow.\n");
366 * Function to destroy default rules for the following paths
367 * 1) Device PORT to DPDK App
368 * 2) DPDK App to Device PORT
369 * 3) VF Representor to VF
370 * 4) VF to VF Representor
372 * eth_dev [in] Ptr to rte eth device.
373 * flow_id [in] Flow identifier.
375 * Returns 0 on success or negative number on failure.
378 ulp_default_flow_destroy(struct rte_eth_dev *eth_dev, uint32_t flow_id)
380 struct bnxt_ulp_context *ulp_ctx;
383 ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
385 BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
390 BNXT_TF_DBG(DEBUG, "invalid flow id zero\n");
394 rc = ulp_mapper_flow_destroy(ulp_ctx, BNXT_ULP_FDB_TYPE_DEFAULT,
397 BNXT_TF_DBG(ERR, "Failed to destroy flow.\n");
403 bnxt_ulp_destroy_df_rules(struct bnxt *bp, bool global)
405 struct bnxt_ulp_df_rule_info *info;
408 if (!BNXT_TRUFLOW_EN(bp) ||
409 BNXT_ETH_DEV_IS_REPRESENTOR(bp->eth_dev))
412 if (!bp->ulp_ctx || !bp->ulp_ctx->cfg_data)
415 /* Delete default rules per port */
417 port_id = bp->eth_dev->data->port_id;
418 info = &bp->ulp_ctx->cfg_data->df_rule_info[port_id];
422 ulp_default_flow_destroy(bp->eth_dev,
423 info->port_to_app_flow_id);
424 ulp_default_flow_destroy(bp->eth_dev,
425 info->app_to_port_flow_id);
426 memset(info, 0, sizeof(struct bnxt_ulp_df_rule_info));
430 /* Delete default rules for all ports */
431 for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++) {
432 info = &bp->ulp_ctx->cfg_data->df_rule_info[port_id];
436 ulp_default_flow_destroy(bp->eth_dev,
437 info->port_to_app_flow_id);
438 ulp_default_flow_destroy(bp->eth_dev,
439 info->app_to_port_flow_id);
440 memset(info, 0, sizeof(struct bnxt_ulp_df_rule_info));
445 bnxt_create_port_app_df_rule(struct bnxt *bp, uint8_t flow_type,
448 uint16_t port_id = bp->eth_dev->data->port_id;
449 struct ulp_tlv_param param_list[] = {
451 .type = BNXT_ULP_DF_PARAM_TYPE_DEV_PORT_ID,
453 .value = {(port_id >> 8) & 0xff, port_id & 0xff}
456 .type = BNXT_ULP_DF_PARAM_TYPE_LAST,
462 return ulp_default_flow_create(bp->eth_dev, param_list, flow_type,
467 bnxt_ulp_create_df_rules(struct bnxt *bp)
469 struct bnxt_ulp_df_rule_info *info;
473 if (!BNXT_TRUFLOW_EN(bp) ||
474 BNXT_ETH_DEV_IS_REPRESENTOR(bp->eth_dev) || !bp->ulp_ctx)
477 port_id = bp->eth_dev->data->port_id;
478 info = &bp->ulp_ctx->cfg_data->df_rule_info[port_id];
479 rc = bnxt_create_port_app_df_rule(bp, BNXT_ULP_DF_TPL_PORT_TO_VS,
480 &info->port_to_app_flow_id);
483 "Failed to create port to app default rule\n");
487 bp->tx_cfa_action = 0;
488 rc = bnxt_create_port_app_df_rule(bp, BNXT_ULP_DF_TPL_VS_TO_PORT,
489 &info->app_to_port_flow_id);
492 "Failed to create app to port default rule\n");
493 goto port_to_app_free;
496 rc = ulp_default_flow_db_cfa_action_get(bp->ulp_ctx,
497 info->app_to_port_flow_id,
500 goto app_to_port_free;
506 ulp_default_flow_destroy(bp->eth_dev, info->app_to_port_flow_id);
508 ulp_default_flow_destroy(bp->eth_dev, info->port_to_app_flow_id);
515 bnxt_create_port_vfr_default_rule(struct bnxt *bp,
517 uint16_t vfr_port_id,
520 struct ulp_tlv_param param_list[] = {
522 .type = BNXT_ULP_DF_PARAM_TYPE_DEV_PORT_ID,
524 .value = {(vfr_port_id >> 8) & 0xff, vfr_port_id & 0xff}
527 .type = BNXT_ULP_DF_PARAM_TYPE_LAST,
532 return ulp_default_flow_create(bp->eth_dev, param_list, flow_type,
537 bnxt_ulp_create_vfr_default_rules(struct rte_eth_dev *vfr_ethdev)
539 struct bnxt_ulp_vfr_rule_info *info;
540 struct bnxt_representor *vfr = vfr_ethdev->data->dev_private;
541 struct rte_eth_dev *parent_dev = vfr->parent_dev;
542 struct bnxt *bp = parent_dev->data->dev_private;
543 uint16_t vfr_port_id = vfr_ethdev->data->port_id;
547 if (!bp || !BNXT_TRUFLOW_EN(bp))
550 port_id = vfr_ethdev->data->port_id;
551 info = bnxt_ulp_cntxt_ptr2_ulp_vfr_info_get(bp->ulp_ctx, port_id);
554 BNXT_TF_DBG(ERR, "Failed to get vfr ulp context\n");
559 BNXT_TF_DBG(ERR, "VFR already allocated\n");
563 memset(info, 0, sizeof(struct bnxt_ulp_vfr_rule_info));
564 rc = bnxt_create_port_vfr_default_rule(bp, BNXT_ULP_DF_TPL_VFREP_TO_VF,
566 &info->rep2vf_flow_id);
568 BNXT_TF_DBG(ERR, "Failed to create VFREP to VF default rule\n");
571 rc = bnxt_create_port_vfr_default_rule(bp, BNXT_ULP_DF_TPL_VF_TO_VFREP,
573 &info->vf2rep_flow_id);
575 BNXT_TF_DBG(ERR, "Failed to create VF to VFREP default rule\n");
578 rc = ulp_default_flow_db_cfa_action_get(bp->ulp_ctx,
579 info->rep2vf_flow_id,
580 &vfr->vfr_tx_cfa_action);
582 BNXT_TF_DBG(ERR, "Failed to get the tx cfa action\n");
586 /* Update the other details */
588 info->parent_port_id = bp->eth_dev->data->port_id;
592 if (info->rep2vf_flow_id)
593 ulp_default_flow_destroy(bp->eth_dev, info->rep2vf_flow_id);
594 if (info->vf2rep_flow_id)
595 ulp_default_flow_destroy(bp->eth_dev, info->vf2rep_flow_id);
600 bnxt_ulp_delete_vfr_default_rules(struct bnxt_representor *vfr)
602 struct bnxt_ulp_vfr_rule_info *info;
603 struct rte_eth_dev *parent_dev = vfr->parent_dev;
604 struct bnxt *bp = parent_dev->data->dev_private;
606 if (!bp || !BNXT_TRUFLOW_EN(bp))
608 info = bnxt_ulp_cntxt_ptr2_ulp_vfr_info_get(bp->ulp_ctx,
611 BNXT_TF_DBG(ERR, "Failed to get vfr ulp context\n");
616 BNXT_TF_DBG(ERR, "VFR already freed\n");
619 ulp_default_flow_destroy(bp->eth_dev, info->rep2vf_flow_id);
620 ulp_default_flow_destroy(bp->eth_dev, info->vf2rep_flow_id);
621 vfr->vfr_tx_cfa_action = 0;
622 memset(info, 0, sizeof(struct bnxt_ulp_vfr_rule_info));