@@ -18,6 +18,7 @@ enum mlx5dr_table_type {
MLX5DR_TABLE_TYPE_NIC_TX,
MLX5DR_TABLE_TYPE_FDB,
MLX5DR_TABLE_TYPE_MAX,
+ MLX5DR_TABLE_TYPE_DONTCARE = MLX5DR_TABLE_TYPE_MAX,
};
enum mlx5dr_matcher_resource_mode {
@@ -1741,6 +1741,7 @@ mlx5dr_definer_conv_item_tag(struct mlx5dr_definer_conv_data *cd,
if (item->type == RTE_FLOW_ITEM_TYPE_TAG)
reg = flow_hw_get_reg_id_from_ctx(cd->ctx,
RTE_FLOW_ITEM_TYPE_TAG,
+ MLX5DR_TABLE_TYPE_DONTCARE,
v->index);
else
reg = (int)v->index;
@@ -1801,9 +1802,10 @@ mlx5dr_definer_conv_item_quota(struct mlx5dr_definer_conv_data *cd,
__rte_unused struct rte_flow_item *item,
int item_idx)
{
- int mtr_reg =
- flow_hw_get_reg_id_from_ctx(cd->ctx, RTE_FLOW_ITEM_TYPE_METER_COLOR,
- 0);
+ int mtr_reg = flow_hw_get_reg_id_from_ctx(cd->ctx,
+ RTE_FLOW_ITEM_TYPE_METER_COLOR,
+ MLX5DR_TABLE_TYPE_DONTCARE,
+ 0);
struct mlx5dr_definer_fc *fc;
if (mtr_reg < 0) {
@@ -1822,6 +1824,7 @@ mlx5dr_definer_conv_item_quota(struct mlx5dr_definer_conv_data *cd,
static int
mlx5dr_definer_conv_item_metadata(struct mlx5dr_definer_conv_data *cd,
+ enum mlx5dr_table_type table_domain_type,
struct rte_flow_item *item,
int item_idx)
{
@@ -1833,7 +1836,8 @@ mlx5dr_definer_conv_item_metadata(struct mlx5dr_definer_conv_data *cd,
if (!m)
return 0;
- reg = flow_hw_get_reg_id_from_ctx(cd->ctx, RTE_FLOW_ITEM_TYPE_META, -1);
+ reg = flow_hw_get_reg_id_from_ctx(cd->ctx, RTE_FLOW_ITEM_TYPE_META,
+ table_domain_type, -1);
if (reg <= 0) {
DR_LOG(ERR, "Invalid register for item metadata");
rte_errno = EINVAL;
@@ -2140,8 +2144,9 @@ mlx5dr_definer_conv_item_conntrack(struct mlx5dr_definer_conv_data *cd,
if (!m)
return 0;
- reg = flow_hw_get_reg_id_from_ctx(cd->ctx, RTE_FLOW_ITEM_TYPE_CONNTRACK,
- -1);
+ reg = flow_hw_get_reg_id_from_ctx(cd->ctx,
+ RTE_FLOW_ITEM_TYPE_CONNTRACK,
+ MLX5DR_TABLE_TYPE_DONTCARE, -1);
if (reg <= 0) {
DR_LOG(ERR, "Invalid register for item conntrack");
rte_errno = EINVAL;
@@ -2283,7 +2288,8 @@ mlx5dr_definer_conv_item_meter_color(struct mlx5dr_definer_conv_data *cd,
return 0;
reg = flow_hw_get_reg_id_from_ctx(cd->ctx,
- RTE_FLOW_ITEM_TYPE_METER_COLOR, 0);
+ RTE_FLOW_ITEM_TYPE_METER_COLOR,
+ MLX5DR_TABLE_TYPE_DONTCARE, 0);
MLX5_ASSERT(reg > 0);
fc = mlx5dr_definer_get_register_fc(cd, reg);
@@ -2878,6 +2884,7 @@ mlx5dr_definer_conv_item_compare_field(const struct rte_flow_field_data *f,
const struct rte_flow_field_data *other_f,
struct mlx5dr_definer_conv_data *cd,
int item_idx,
+ enum mlx5dr_table_type table_domain_type,
enum mlx5dr_definer_compare_dw_selectors dw_offset)
{
struct mlx5dr_definer_fc *fc = NULL;
@@ -2892,7 +2899,8 @@ mlx5dr_definer_conv_item_compare_field(const struct rte_flow_field_data *f,
switch (f->field) {
case RTE_FLOW_FIELD_META:
reg = flow_hw_get_reg_id_from_ctx(cd->ctx,
- RTE_FLOW_ITEM_TYPE_META, -1);
+ RTE_FLOW_ITEM_TYPE_META,
+ table_domain_type, -1);
if (reg <= 0) {
DR_LOG(ERR, "Invalid register for compare metadata field");
rte_errno = EINVAL;
@@ -2911,6 +2919,7 @@ mlx5dr_definer_conv_item_compare_field(const struct rte_flow_field_data *f,
case RTE_FLOW_FIELD_TAG:
reg = flow_hw_get_reg_id_from_ctx(cd->ctx,
RTE_FLOW_ITEM_TYPE_TAG,
+ MLX5DR_TABLE_TYPE_DONTCARE,
f->tag_index);
if (reg <= 0) {
DR_LOG(ERR, "Invalid register for compare tag field");
@@ -2966,6 +2975,7 @@ mlx5dr_definer_conv_item_compare_field(const struct rte_flow_field_data *f,
static int
mlx5dr_definer_conv_item_compare(struct mlx5dr_definer_conv_data *cd,
+ enum mlx5dr_table_type table_domain_type,
struct rte_flow_item *item,
int item_idx)
{
@@ -2982,11 +2992,13 @@ mlx5dr_definer_conv_item_compare(struct mlx5dr_definer_conv_data *cd,
}
ret = mlx5dr_definer_conv_item_compare_field(a, b, cd, item_idx,
+ table_domain_type,
MLX5DR_DEFINER_COMPARE_ARGUMENT_0);
if (ret)
return ret;
ret = mlx5dr_definer_conv_item_compare_field(b, NULL, cd, item_idx,
+ table_domain_type,
MLX5DR_DEFINER_COMPARE_BASE_0);
if (ret)
return ret;
@@ -3082,7 +3094,7 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx,
item_flags |= MLX5_FLOW_ITEM_TAG;
break;
case RTE_FLOW_ITEM_TYPE_META:
- ret = mlx5dr_definer_conv_item_metadata(&cd, items, i);
+ ret = mlx5dr_definer_conv_item_metadata(&cd, matcher->tbl->type, items, i);
item_flags |= MLX5_FLOW_ITEM_METADATA;
break;
case RTE_FLOW_ITEM_TYPE_GRE:
@@ -3173,7 +3185,7 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx,
DR_LOG(ERR, "Compare matcher not supported for more than one item");
goto not_supp;
}
- ret = mlx5dr_definer_conv_item_compare(&cd, items, i);
+ ret = mlx5dr_definer_conv_item_compare(&cd, matcher->tbl->type, items, i);
item_flags |= MLX5_FLOW_ITEM_COMPARE;
matcher->flags |= MLX5DR_MATCHER_FLAGS_COMPARE;
break;
@@ -1722,12 +1722,12 @@ flow_hw_get_wire_port(struct ibv_context *ibctx)
/*
* Convert metadata or tag to the actual register.
- * META: Can only be used to match in the FDB in this stage, fixed C_1.
+ * META: Fixed C_1 for FDB mode, REG_A for NIC TX and REG_B for NIC RX.
* TAG: C_x expect meter color reg and the reserved ones.
*/
static __rte_always_inline int
-flow_hw_get_reg_id(struct rte_eth_dev *dev,
- enum rte_flow_item_type type, uint32_t id)
+flow_hw_get_reg_id(struct rte_eth_dev *dev, enum rte_flow_item_type type,
+ enum mlx5dr_table_type domain_type, uint32_t id)
{
struct mlx5_dev_ctx_shared *sh = MLX5_SH(dev);
struct mlx5_dev_registers *reg = &sh->registers;
@@ -1747,8 +1747,10 @@ flow_hw_get_reg_id(struct rte_eth_dev *dev,
* On non-root tables - REG_A corresponds to general_purpose_lookup_field,
* which translates to REG_A in NIC TX and to REG_B in NIC RX.
* However, current FW does not implement REG_B case right now, so
- * REG_B case should be rejected on pattern template validation.
+ * REG_B case is return explicitly by this function for NIC RX.
*/
+ if (domain_type == MLX5DR_TABLE_TYPE_NIC_RX)
+ return REG_B;
return REG_A;
case RTE_FLOW_ITEM_TYPE_CONNTRACK:
case RTE_FLOW_ITEM_TYPE_METER_COLOR:
@@ -1764,8 +1766,8 @@ flow_hw_get_reg_id(struct rte_eth_dev *dev,
}
static __rte_always_inline int
-flow_hw_get_reg_id_from_ctx(void *dr_ctx,
- enum rte_flow_item_type type, uint32_t id)
+flow_hw_get_reg_id_from_ctx(void *dr_ctx, enum rte_flow_item_type type,
+ enum mlx5dr_table_type domain_type, uint32_t id)
{
#ifdef HAVE_IBV_FLOW_DV_SUPPORT
uint16_t port;
@@ -1776,7 +1778,7 @@ flow_hw_get_reg_id_from_ctx(void *dr_ctx,
priv = rte_eth_devices[port].data->dev_private;
if (priv->dr_ctx == dr_ctx)
return flow_hw_get_reg_id(&rte_eth_devices[port],
- type, id);
+ type, domain_type, id);
}
#else
RTE_SET_USED(dr_ctx);
@@ -2089,6 +2089,7 @@ mlx5_flow_field_id_to_modify_info
if (priv->sh->config.dv_flow_en == 2)
reg = flow_hw_get_reg_id(dev,
RTE_FLOW_ITEM_TYPE_TAG,
+ MLX5DR_TABLE_TYPE_DONTCARE,
tag_index);
else
reg = mlx5_flow_get_reg_id(dev, MLX5_APP_TAG,
@@ -2206,12 +2207,13 @@ mlx5_flow_field_id_to_modify_info
int reg;
if (priv->sh->config.dv_flow_en == 2)
- reg = flow_hw_get_reg_id
- (dev,
- RTE_FLOW_ITEM_TYPE_METER_COLOR, 0);
+ reg = flow_hw_get_reg_id(dev,
+ RTE_FLOW_ITEM_TYPE_METER_COLOR,
+ MLX5DR_TABLE_TYPE_DONTCARE,
+ 0);
else
reg = mlx5_flow_get_reg_id(dev, MLX5_MTR_COLOR,
- 0, error);
+ 0, error);
if (reg < 0)
return;
MLX5_ASSERT(reg != REG_NON);
@@ -10548,7 +10550,8 @@ flow_dv_translate_item_meta(struct rte_eth_dev *dev,
if (!!(key_type & MLX5_SET_MATCHER_SW))
reg = flow_dv_get_metadata_reg(dev, attr, NULL);
else
- reg = flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_META, 0);
+ reg = flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_META,
+ MLX5DR_TABLE_TYPE_DONTCARE, 0);
if (reg < 0)
return;
MLX5_ASSERT(reg != REG_NON);
@@ -10651,7 +10654,8 @@ flow_dv_translate_item_tag(struct rte_eth_dev *dev, void *key,
if (!!(key_type & MLX5_SET_MATCHER_SW))
reg = mlx5_flow_get_reg_id(dev, MLX5_APP_TAG, index, NULL);
else
- reg = flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_TAG, index);
+ reg = flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_TAG,
+ MLX5DR_TABLE_TYPE_DONTCARE, index);
MLX5_ASSERT(reg > 0);
flow_dv_match_meta_reg(key, (enum modify_reg)reg, tag_v->data, tag_m->data);
}
@@ -11350,7 +11354,8 @@ flow_dv_translate_item_meter_color(struct rte_eth_dev *dev, void *key,
reg = mlx5_flow_get_reg_id(dev, MLX5_MTR_COLOR, 0, NULL);
else
reg = flow_hw_get_reg_id(dev,
- RTE_FLOW_ITEM_TYPE_METER_COLOR, 0);
+ RTE_FLOW_ITEM_TYPE_METER_COLOR,
+ MLX5DR_TABLE_TYPE_DONTCARE, 0);
if (reg == REG_NON)
return;
flow_dv_match_meta_reg(key, (enum modify_reg)reg, value, mask);
@@ -5221,9 +5221,13 @@ flow_hw_validate_action_modify_field(struct rte_eth_dev *dev,
RTE_FLOW_ERROR_TYPE_ACTION, action,
"tag index is out of range");
if ((action_conf->dst.field == RTE_FLOW_FIELD_TAG &&
- flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_TAG, action_conf->dst.tag_index) == REG_NON) ||
+ flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_TAG,
+ MLX5DR_TABLE_TYPE_DONTCARE,
+ action_conf->dst.tag_index) == REG_NON) ||
(action_conf->src.field == RTE_FLOW_FIELD_TAG &&
- flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_TAG, action_conf->src.tag_index) == REG_NON))
+ flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_TAG,
+ MLX5DR_TABLE_TYPE_DONTCARE,
+ action_conf->src.tag_index) == REG_NON))
return rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_ACTION, action,
"tag index is out of range");
@@ -7012,7 +7016,9 @@ flow_hw_pattern_validate(struct rte_eth_dev *dev,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
NULL,
"Invalid tag index");
- tag_idx = flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_TAG, tag->index);
+ tag_idx = flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_TAG,
+ MLX5DR_TABLE_TYPE_DONTCARE,
+ tag->index);
if (tag_idx == REG_NON)
return rte_flow_error_set(error, EINVAL,
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
@@ -7058,20 +7064,13 @@ flow_hw_pattern_validate(struct rte_eth_dev *dev,
" when egress attribute is set");
break;
case RTE_FLOW_ITEM_TYPE_META:
- if (!priv->sh->config.dv_esw_en ||
- priv->sh->config.dv_xmeta_en != MLX5_XMETA_MODE_META32_HWS) {
- if (attr->ingress)
- return rte_flow_error_set(error, EINVAL,
- RTE_FLOW_ERROR_TYPE_ITEM, NULL,
- "META item is not supported"
- " on current FW with ingress"
- " attribute");
- }
+ /* ingress + group 0 is not supported */
break;
case RTE_FLOW_ITEM_TYPE_METER_COLOR:
{
int reg = flow_hw_get_reg_id(dev,
RTE_FLOW_ITEM_TYPE_METER_COLOR,
+ MLX5DR_TABLE_TYPE_DONTCARE,
0);
if (reg == REG_NON)
return rte_flow_error_set(error, EINVAL,