Previously if the port info did not have REG_C mask set, flow_hw_conv_port_id() returned NULL. In order to allow for support of legacy source vport match, this patch changes that logic.
Now flow port info will be returned for all ports, regardless of REG_C mask value. HWS layer, depending on REG_C mask value (zero or non-zero) will decide which matching mode should be used for REPRESENTED_PORT items. If REG_C mask is available, metadata matching will be used. Otherwise, legacy source vport match will be used. Definer handling for legacy source vport match will be added in the follow up commit. Signed-off-by: Dariusz Sosnowski <[email protected]> --- drivers/net/mlx5/hws/mlx5dr_cmd.c | 13 +++++++-- drivers/net/mlx5/hws/mlx5dr_cmd.h | 1 + drivers/net/mlx5/hws/mlx5dr_definer.c | 38 ++++++++++++++++----------- drivers/net/mlx5/linux/mlx5_os.c | 1 + drivers/net/mlx5/mlx5.h | 1 + drivers/net/mlx5/mlx5_flow.h | 3 ++- drivers/net/mlx5/mlx5_flow_hw.c | 1 + 7 files changed, 40 insertions(+), 18 deletions(-) diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.c b/drivers/net/mlx5/hws/mlx5dr_cmd.c index 47e6a1fd49..668e409988 100644 --- a/drivers/net/mlx5/hws/mlx5dr_cmd.c +++ b/drivers/net/mlx5/hws/mlx5dr_cmd.c @@ -1363,10 +1363,19 @@ int mlx5dr_cmd_query_caps(struct ibv_context *ctx, strlcpy(caps->fw_ver, attr_ex.orig_attr.fw_ver, sizeof(caps->fw_ver)); port_info = flow_hw_get_wire_port(ctx); - if (port_info) + if (port_info) { caps->wire_regc_mask = port_info->regc_mask; - else + /* + * If REG_C_0 vport mask is available, then we can assume that vport metadata is + * enabled on the switchdev. + */ + caps->vport_metadata_match = !!port_info->regc_mask; + DR_LOG(DEBUG, "ibdev %s vport metadata match is %sabled", + ctx->device->name, + caps->vport_metadata_match ? "en" : "dis"); + } else { DR_LOG(INFO, "Failed to query wire port regc value"); + } return ret; } diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.h b/drivers/net/mlx5/hws/mlx5dr_cmd.h index eb9643c555..3ed7c6ecb7 100644 --- a/drivers/net/mlx5/hws/mlx5dr_cmd.h +++ b/drivers/net/mlx5/hws/mlx5dr_cmd.h @@ -207,6 +207,7 @@ struct mlx5dr_cmd_generate_wqe_attr { struct mlx5dr_cmd_query_caps { uint32_t wire_regc_mask; + bool vport_metadata_match; uint32_t flex_protocols; uint8_t wqe_based_update; uint8_t rtc_reparse_mode; diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c index 6a016de78e..3ba69c1001 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.c +++ b/drivers/net/mlx5/hws/mlx5dr_definer.c @@ -777,12 +777,13 @@ mlx5dr_definer_vport_set(struct mlx5dr_definer_fc *fc, const struct flow_hw_port_info *port_info = NULL; uint32_t regc_value; - if (v) + if (v) { port_info = flow_hw_conv_port_id(fc->dr_ctx, v->port_id); - if (unlikely(!port_info)) - regc_value = BAD_PORT; - else + assert(port_info != NULL); regc_value = port_info->regc_value >> fc->bit_off; + } else { + regc_value = BAD_PORT; + } /* Bit offset is set to 0 to since regc value is 32bit */ DR_SET(tag, regc_value, fc->byte_off, fc->bit_off, fc->bit_mask); @@ -1593,20 +1594,27 @@ mlx5dr_definer_conv_item_port(struct mlx5dr_definer_conv_data *cd, struct mlx5dr_definer_fc *fc; if (port_id) { - if (!caps->wire_regc_mask) { - DR_LOG(ERR, "Port ID item not supported, missing wire REGC mask"); + if (caps->vport_metadata_match) { + if (!caps->wire_regc_mask) { + DR_LOG(ERR, "Port ID item not supported, missing wire REGC mask"); + rte_errno = ENOTSUP; + return rte_errno; + } + + fc = &cd->fc[MLX5DR_DEFINER_FNAME_VPORT_REG_C_0]; + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_vport_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + DR_CALC_SET_HDR(fc, registers, register_c_0); + fc->bit_off = rte_ctz32(caps->wire_regc_mask); + 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_VPORT_REG_C_0]; - fc->item_idx = item_idx; - fc->tag_set = &mlx5dr_definer_vport_set; - fc->tag_mask_set = &mlx5dr_definer_ones_set; - DR_CALC_SET_HDR(fc, registers, register_c_0); - fc->bit_off = rte_ctz32(caps->wire_regc_mask); - fc->bit_mask = caps->wire_regc_mask >> fc->bit_off; - fc->dr_ctx = cd->ctx; } return 0; diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c index 3a9b019601..75a2936023 100644 --- a/drivers/net/mlx5/linux/mlx5_os.c +++ b/drivers/net/mlx5/linux/mlx5_os.c @@ -387,6 +387,7 @@ mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared *sh) sh->dev_cap.esw_info.regc_value = 0; sh->dev_cap.esw_info.regc_mask = 0; #endif + sh->dev_cap.esw_info.is_set = 1; return 0; } diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 7ae9129e46..8cd6562633 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -153,6 +153,7 @@ struct flow_hw_port_info { uint32_t regc_mask; uint32_t regc_value; uint32_t vhca_id; + uint32_t is_set:1; uint32_t is_wire:1; uint32_t direction:2; }; diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 4c56e638ab..c9e72a33d6 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -2156,8 +2156,9 @@ flow_hw_conv_port_id(void *ctx, const uint16_t port_id) if (port_id >= RTE_MAX_ETHPORTS) return NULL; + port_info = &mlx5_flow_hw_port_infos[port_id]; - return !!port_info->regc_mask ? port_info : NULL; + return port_info->is_set ? port_info : NULL; } #ifdef HAVE_IBV_FLOW_DV_SUPPORT diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c index adbd4f33b0..4871594c35 100644 --- a/drivers/net/mlx5/mlx5_flow_hw.c +++ b/drivers/net/mlx5/mlx5_flow_hw.c @@ -12307,6 +12307,7 @@ mlx5_flow_hw_set_port_info(struct rte_eth_dev *dev) info->regc_value = priv->vport_meta_tag; info->vhca_id = priv->vport_vhca_id; info->is_wire = mlx5_is_port_on_mpesw_device(priv) ? priv->mpesw_uplink : priv->master; + info->is_set = 1; } /* Clears vport tag and mask used for HWS rules. */ -- 2.47.3

