Matching source vport without having vport metadata available requires matching on 2 fields:
- source_gvmi - equal to VHCA ID property of the port, - functional_lb There are following cases: - If packet comes from PF/VF/SF, then it originated on some Tx queue on the host. In this case, source_gvmi will be populated with the ID of the originating function. - If packet comes from the wire, then source_gvmi will be set to 0. There is one edge case - discriminating packets coming from PF0 and from wire. In this case, both packets will have source_gvmi set to 0. Distinguishing them requires additional match on functional_lb. If packet comes from PF, functional_lb will be set to 1. This only happens when packet was sent from PF to FDB, and then moved to PF again. Because of all of the above: - Unified FDB must be disabled when vport metadata is disabled, because packet from PF0 and from wire will not have correct functional_lb set yet when flow rules in FDB are processed. - Without unified FDB, when separate FDB_RX and FDB_TX tables are used internally, match on functional_lb is not needed. Table type already defines the direction. - NIC_TX tables belong to a single GVMI and as a result vport matching is not needed there. As a result, functional_lb match is only required on NIC_RX. This patch adds support for source_gvmi and functional_lb matching in HWS layer. Signed-off-by: Dariusz Sosnowski <[email protected]> --- drivers/net/mlx5/hws/mlx5dr_definer.c | 65 +++++++++++++++++++++++++-- drivers/net/mlx5/hws/mlx5dr_definer.h | 2 + drivers/net/mlx5/hws/mlx5dr_table.c | 6 +++ 3 files changed, 69 insertions(+), 4 deletions(-) diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c index 3ba69c1001..7400b8f252 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.c +++ b/drivers/net/mlx5/hws/mlx5dr_definer.c @@ -6,6 +6,8 @@ #include "mlx5dr_internal.h" +#define WIRE_GVMI 0 +#define BAD_GVMI 0xFFFF #define GTP_PDU_SC 0x85 #define BAD_PORT 0xBAD #define BAD_SQN 0xBAD @@ -789,6 +791,49 @@ mlx5dr_definer_vport_set(struct mlx5dr_definer_fc *fc, DR_SET(tag, regc_value, fc->byte_off, fc->bit_off, fc->bit_mask); } +static void +mlx5dr_definer_source_gvmi_set(struct mlx5dr_definer_fc *fc, + const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_ethdev *v = item_spec; + const struct flow_hw_port_info *port_info; + uint32_t source_gvmi; + + if (v) { + port_info = flow_hw_conv_port_id(fc->dr_ctx, v->port_id); + assert(port_info != NULL); + if (port_info->is_wire) + source_gvmi = WIRE_GVMI; + else + source_gvmi = port_info->vhca_id; + } else { + source_gvmi = BAD_GVMI; + } + + DR_SET(tag, source_gvmi, fc->byte_off, fc->bit_off, fc->bit_mask); +} + +static void +mlx5dr_definer_functional_lb_set(struct mlx5dr_definer_fc *fc, + const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_ethdev *v = item_spec; + const struct flow_hw_port_info *port_info; + uint32_t functional_lb; + + if (v) { + port_info = flow_hw_conv_port_id(fc->dr_ctx, v->port_id); + assert(port_info != NULL); + functional_lb = !port_info->is_wire; + } else { + functional_lb = 0; + } + + DR_SET(tag, functional_lb, fc->byte_off, fc->bit_off, fc->bit_mask); +} + static struct mlx5dr_definer_fc * mlx5dr_definer_get_mpls_fc(struct mlx5dr_definer_conv_data *cd, bool inner) { @@ -1610,10 +1655,22 @@ mlx5dr_definer_conv_item_port(struct mlx5dr_definer_conv_data *cd, fc->bit_mask = caps->wire_regc_mask >> fc->bit_off; fc->dr_ctx = cd->ctx; } else { - /* TODO */ - DR_LOG(ERR, "Port ID item with legacy vport match is not implemented"); - rte_errno = ENOTSUP; - return rte_errno; + fc = &cd->fc[MLX5DR_DEFINER_FNAME_SOURCE_GVMI]; + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_source_gvmi_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + DR_CALC_SET_HDR(fc, source_qp_gvmi, source_gvmi); + fc->dr_ctx = cd->ctx; + + if (cd->table_type != MLX5DR_TABLE_TYPE_NIC_RX) + return 0; + + fc = &cd->fc[MLX5DR_DEFINER_FNAME_FUNCTIONAL_LB]; + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_functional_lb_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + DR_CALC_SET_HDR(fc, source_qp_gvmi, functional_lb); + fc->dr_ctx = cd->ctx; } } diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.h b/drivers/net/mlx5/hws/mlx5dr_definer.h index d0c99399ae..f5d6cce887 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.h +++ b/drivers/net/mlx5/hws/mlx5dr_definer.h @@ -214,6 +214,8 @@ enum mlx5dr_definer_fname { MLX5DR_DEFINER_FNAME_PTYPE_FRAG_O, MLX5DR_DEFINER_FNAME_PTYPE_FRAG_I, MLX5DR_DEFINER_FNAME_RANDOM_NUM, + MLX5DR_DEFINER_FNAME_SOURCE_GVMI, + MLX5DR_DEFINER_FNAME_FUNCTIONAL_LB, MLX5DR_DEFINER_FNAME_MAX, }; diff --git a/drivers/net/mlx5/hws/mlx5dr_table.c b/drivers/net/mlx5/hws/mlx5dr_table.c index 41ffaa19e3..14e983a363 100644 --- a/drivers/net/mlx5/hws/mlx5dr_table.c +++ b/drivers/net/mlx5/hws/mlx5dr_table.c @@ -468,6 +468,12 @@ struct mlx5dr_table *mlx5dr_table_create(struct mlx5dr_context *ctx, return NULL; } + if (attr->type == MLX5DR_TABLE_TYPE_FDB_UNIFIED && !ctx->caps->vport_metadata_match) { + DR_LOG(ERR, "Table type %d requires vport metadata to be enabled", attr->type); + rte_errno = ENOTSUP; + return NULL; + } + if ((mlx5dr_table_is_fdb_any(attr->type) && attr->type != MLX5DR_TABLE_TYPE_FDB) && !attr->level) { DR_LOG(ERR, "Table type %d not supported by root table", attr->type); -- 2.47.3

