From 96f85ec489dbf7e206cdf54906d1e1c1092bc38e Mon Sep 17 00:00:00 2001 From: Dong Zhou Date: Thu, 22 Jul 2021 10:48:39 +0300 Subject: [PATCH] net/mlx5: check VLAN push/pop support For ConnectX-6 in FDB domain, pop and push VLAN on both ingress and egress directions are supported. For ConnectX-6 in NIC domain, and ConnectX-5 in both FWD and NIC domain, pop VLAN is only supported on ingress direction, push VLAN is only supported on egress direction. Signed-off-by: Dong Zhou Acked-by: Matan Azrad --- drivers/common/mlx5/mlx5_devx_cmds.c | 2 ++ drivers/common/mlx5/mlx5_devx_cmds.h | 1 + drivers/common/mlx5/mlx5_prm.h | 7 ++++- drivers/net/mlx5/linux/mlx5_os.c | 2 ++ drivers/net/mlx5/mlx5.h | 2 ++ drivers/net/mlx5/mlx5_flow_dv.c | 38 ++++++++++++++++++++++++---- 6 files changed, 46 insertions(+), 6 deletions(-) diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c b/drivers/common/mlx5/mlx5_devx_cmds.c index 10a02d13ee..56407cc332 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.c +++ b/drivers/common/mlx5/mlx5_devx_cmds.c @@ -819,6 +819,8 @@ mlx5_devx_cmd_query_hca_attr(void *ctx, attr->roce = MLX5_GET(cmd_hca_cap, hcattr, roce); attr->rq_ts_format = MLX5_GET(cmd_hca_cap, hcattr, rq_ts_format); attr->sq_ts_format = MLX5_GET(cmd_hca_cap, hcattr, sq_ts_format); + attr->steering_format_version = + MLX5_GET(cmd_hca_cap, hcattr, steering_format_version); attr->regex = MLX5_GET(cmd_hca_cap, hcattr, regexp); attr->regexp_num_of_engines = MLX5_GET(cmd_hca_cap, hcattr, regexp_num_of_engines); diff --git a/drivers/common/mlx5/mlx5_devx_cmds.h b/drivers/common/mlx5/mlx5_devx_cmds.h index c11ca6586f..e576e30f24 100644 --- a/drivers/common/mlx5/mlx5_devx_cmds.h +++ b/drivers/common/mlx5/mlx5_devx_cmds.h @@ -141,6 +141,7 @@ struct mlx5_hca_attr { uint32_t roce:1; uint32_t rq_ts_format:2; uint32_t sq_ts_format:2; + uint32_t steering_format_version:4; uint32_t qp_ts_format:2; uint32_t regex:1; uint32_t reg_c_preserve:1; diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index 88705be9d6..5b73a193ee 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -1317,6 +1317,10 @@ enum { #define MLX5_HCA_FLEX_ICMP_ENABLED (1UL << 8) #define MLX5_HCA_FLEX_ICMPV6_ENABLED (1UL << 9) +/* The device steering logic format. */ +#define MLX5_STEERING_LOGIC_FORMAT_CONNECTX_5 0x0 +#define MLX5_STEERING_LOGIC_FORMAT_CONNECTX_6DX 0x1 + struct mlx5_ifc_cmd_hca_cap_bits { u8 reserved_at_0[0x30]; u8 vhca_id[0x10]; @@ -1585,7 +1589,8 @@ struct mlx5_ifc_cmd_hca_cap_bits { u8 general_obj_types[0x40]; u8 sq_ts_format[0x2]; u8 rq_ts_format[0x2]; - u8 reserved_at_444[0x1C]; + u8 steering_format_version[0x4]; + u8 reserved_at_448[0x18]; u8 reserved_at_460[0x8]; u8 aes_xts[0x1]; u8 crypto[0x1]; diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c index db44169b84..81fbed2872 100644 --- a/drivers/net/mlx5/linux/mlx5_os.c +++ b/drivers/net/mlx5/linux/mlx5_os.c @@ -1364,6 +1364,8 @@ err_secondary: } sh->rq_ts_format = config->hca_attr.rq_ts_format; sh->sq_ts_format = config->hca_attr.sq_ts_format; + sh->steering_format_version = + config->hca_attr.steering_format_version; sh->qp_ts_format = config->hca_attr.qp_ts_format; /* Check for LRO support. */ if (config->dest_tir && config->hca_attr.lro_cap && diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index be907dc95b..faafe3d3f1 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -1129,6 +1129,8 @@ struct mlx5_dev_ctx_shared { uint32_t flow_hit_aso_en:1; /* Flow Hit ASO is supported. */ uint32_t rq_ts_format:2; /* RQ timestamp formats supported. */ uint32_t sq_ts_format:2; /* SQ timestamp formats supported. */ + uint32_t steering_format_version:4; + /* Indicates the device steering logic format. */ uint32_t qp_ts_format:2; /* QP timestamp formats supported. */ uint32_t meter_aso_en:1; /* Flow Meter ASO is supported. */ uint32_t ct_aso_en:1; /* Connection Tracking ASO is supported. */ diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 3ae7c9cf66..034930d458 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -2790,20 +2790,30 @@ flow_dv_validate_action_pop_vlan(struct rte_eth_dev *dev, struct rte_flow_error *error) { const struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_dev_ctx_shared *sh = priv->sh; + bool direction_error = false; - (void)action; - (void)attr; if (!priv->sh->pop_vlan_action) return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "pop vlan action is not supported"); - if (attr->egress) + /* Pop VLAN is not supported in egress except for CX6 FDB mode. */ + if (attr->transfer) { + bool fdb_tx = priv->representor_id != UINT16_MAX; + bool is_cx5 = sh->steering_format_version == + MLX5_STEERING_LOGIC_FORMAT_CONNECTX_5; + + if (fdb_tx && is_cx5) + direction_error = true; + } else if (attr->egress) { + direction_error = true; + } + if (direction_error) return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL, - "pop vlan action not supported for " - "egress"); + "pop vlan action not supported for egress"); if (action_flags & MLX5_FLOW_VLAN_ACTIONS) return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, action, @@ -2927,6 +2937,8 @@ flow_dv_validate_action_push_vlan(struct rte_eth_dev *dev, { const struct rte_flow_action_of_push_vlan *push_vlan = action->conf; const struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_dev_ctx_shared *sh = priv->sh; + bool direction_error = false; if (push_vlan->ethertype != RTE_BE16(RTE_ETHER_TYPE_VLAN) && push_vlan->ethertype != RTE_BE16(RTE_ETHER_TYPE_QINQ)) @@ -2938,6 +2950,22 @@ flow_dv_validate_action_push_vlan(struct rte_eth_dev *dev, RTE_FLOW_ERROR_TYPE_ACTION, action, "wrong action order, port_id should " "be after push VLAN"); + /* Push VLAN is not supported in ingress except for CX6 FDB mode. */ + if (attr->transfer) { + bool fdb_tx = priv->representor_id != UINT16_MAX; + bool is_cx5 = sh->steering_format_version == + MLX5_STEERING_LOGIC_FORMAT_CONNECTX_5; + + if (!fdb_tx && is_cx5) + direction_error = true; + } else if (attr->ingress) { + direction_error = true; + } + if (direction_error) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, + NULL, + "push vlan action not supported for ingress"); if (!attr->transfer && priv->representor) return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, -- 2.20.1