diff options
-rw-r--r-- | drivers/infiniband/hw/mlx5/main.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index fc02f5f05b38..2e85f73c3235 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c | |||
@@ -1669,6 +1669,7 @@ static void set_tos(void *outer_c, void *outer_v, u8 mask, u8 val) | |||
1669 | #define LAST_IPV6_FIELD traffic_class | 1669 | #define LAST_IPV6_FIELD traffic_class |
1670 | #define LAST_TCP_UDP_FIELD src_port | 1670 | #define LAST_TCP_UDP_FIELD src_port |
1671 | #define LAST_TUNNEL_FIELD tunnel_id | 1671 | #define LAST_TUNNEL_FIELD tunnel_id |
1672 | #define LAST_FLOW_TAG_FIELD tag_id | ||
1672 | 1673 | ||
1673 | /* Field is the last supported field */ | 1674 | /* Field is the last supported field */ |
1674 | #define FIELDS_NOT_SUPPORTED(filter, field)\ | 1675 | #define FIELDS_NOT_SUPPORTED(filter, field)\ |
@@ -1679,7 +1680,7 @@ static void set_tos(void *outer_c, void *outer_v, u8 mask, u8 val) | |||
1679 | sizeof(filter.field)) | 1680 | sizeof(filter.field)) |
1680 | 1681 | ||
1681 | static int parse_flow_attr(u32 *match_c, u32 *match_v, | 1682 | static int parse_flow_attr(u32 *match_c, u32 *match_v, |
1682 | const union ib_flow_spec *ib_spec) | 1683 | const union ib_flow_spec *ib_spec, u32 *tag_id) |
1683 | { | 1684 | { |
1684 | void *misc_params_c = MLX5_ADDR_OF(fte_match_param, match_c, | 1685 | void *misc_params_c = MLX5_ADDR_OF(fte_match_param, match_c, |
1685 | misc_parameters); | 1686 | misc_parameters); |
@@ -1871,6 +1872,15 @@ static int parse_flow_attr(u32 *match_c, u32 *match_v, | |||
1871 | MLX5_SET(fte_match_set_misc, misc_params_v, vxlan_vni, | 1872 | MLX5_SET(fte_match_set_misc, misc_params_v, vxlan_vni, |
1872 | ntohl(ib_spec->tunnel.val.tunnel_id)); | 1873 | ntohl(ib_spec->tunnel.val.tunnel_id)); |
1873 | break; | 1874 | break; |
1875 | case IB_FLOW_SPEC_ACTION_TAG: | ||
1876 | if (FIELDS_NOT_SUPPORTED(ib_spec->flow_tag, | ||
1877 | LAST_FLOW_TAG_FIELD)) | ||
1878 | return -EOPNOTSUPP; | ||
1879 | if (ib_spec->flow_tag.tag_id >= BIT(24)) | ||
1880 | return -EINVAL; | ||
1881 | |||
1882 | *tag_id = ib_spec->flow_tag.tag_id; | ||
1883 | break; | ||
1874 | default: | 1884 | default: |
1875 | return -EINVAL; | 1885 | return -EINVAL; |
1876 | } | 1886 | } |
@@ -2054,6 +2064,7 @@ static struct mlx5_ib_flow_handler *create_flow_rule(struct mlx5_ib_dev *dev, | |||
2054 | struct mlx5_flow_spec *spec; | 2064 | struct mlx5_flow_spec *spec; |
2055 | const void *ib_flow = (const void *)flow_attr + sizeof(*flow_attr); | 2065 | const void *ib_flow = (const void *)flow_attr + sizeof(*flow_attr); |
2056 | unsigned int spec_index; | 2066 | unsigned int spec_index; |
2067 | u32 flow_tag = MLX5_FS_DEFAULT_FLOW_TAG; | ||
2057 | int err = 0; | 2068 | int err = 0; |
2058 | 2069 | ||
2059 | if (!is_valid_attr(flow_attr)) | 2070 | if (!is_valid_attr(flow_attr)) |
@@ -2070,7 +2081,7 @@ static struct mlx5_ib_flow_handler *create_flow_rule(struct mlx5_ib_dev *dev, | |||
2070 | 2081 | ||
2071 | for (spec_index = 0; spec_index < flow_attr->num_of_specs; spec_index++) { | 2082 | for (spec_index = 0; spec_index < flow_attr->num_of_specs; spec_index++) { |
2072 | err = parse_flow_attr(spec->match_criteria, | 2083 | err = parse_flow_attr(spec->match_criteria, |
2073 | spec->match_value, ib_flow); | 2084 | spec->match_value, ib_flow, &flow_tag); |
2074 | if (err < 0) | 2085 | if (err < 0) |
2075 | goto free; | 2086 | goto free; |
2076 | 2087 | ||
@@ -2080,7 +2091,16 @@ static struct mlx5_ib_flow_handler *create_flow_rule(struct mlx5_ib_dev *dev, | |||
2080 | spec->match_criteria_enable = get_match_criteria_enable(spec->match_criteria); | 2091 | spec->match_criteria_enable = get_match_criteria_enable(spec->match_criteria); |
2081 | flow_act.action = dst ? MLX5_FLOW_CONTEXT_ACTION_FWD_DEST : | 2092 | flow_act.action = dst ? MLX5_FLOW_CONTEXT_ACTION_FWD_DEST : |
2082 | MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO; | 2093 | MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO; |
2083 | flow_act.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG; | 2094 | |
2095 | if (flow_tag != MLX5_FS_DEFAULT_FLOW_TAG && | ||
2096 | (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT || | ||
2097 | flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT)) { | ||
2098 | mlx5_ib_warn(dev, "Flow tag %u and attribute type %x isn't allowed in leftovers\n", | ||
2099 | flow_tag, flow_attr->type); | ||
2100 | err = -EINVAL; | ||
2101 | goto free; | ||
2102 | } | ||
2103 | flow_act.flow_tag = flow_tag; | ||
2084 | handler->rule = mlx5_add_flow_rules(ft, spec, | 2104 | handler->rule = mlx5_add_flow_rules(ft, spec, |
2085 | &flow_act, | 2105 | &flow_act, |
2086 | dst, 1); | 2106 | dst, 1); |