net/mlx5: Add core support for double vlan push/pop steering action
[sfrench/cifs-2.6.git] / drivers / net / ethernet / mellanox / mlx5 / core / fs_core.c
index c39c1692e6744a6fe22c2b0742c5341d58c944e1..05e7a5112b74c99bbae73bdae65f044ce24900f9 100644 (file)
@@ -325,7 +325,8 @@ static bool check_valid_mask(u8 match_criteria_enable, const u32 *match_criteria
        if (match_criteria_enable & ~(
                (1 << MLX5_CREATE_FLOW_GROUP_IN_MATCH_CRITERIA_ENABLE_OUTER_HEADERS)   |
                (1 << MLX5_CREATE_FLOW_GROUP_IN_MATCH_CRITERIA_ENABLE_MISC_PARAMETERS) |
-               (1 << MLX5_CREATE_FLOW_GROUP_IN_MATCH_CRITERIA_ENABLE_INNER_HEADERS)))
+               (1 << MLX5_CREATE_FLOW_GROUP_IN_MATCH_CRITERIA_ENABLE_INNER_HEADERS) |
+               (1 << MLX5_CREATE_FLOW_GROUP_IN_MATCH_CRITERIA_ENABLE_MISC_PARAMETERS_2)))
                return false;
 
        if (!(match_criteria_enable &
@@ -361,6 +362,17 @@ static bool check_valid_mask(u8 match_criteria_enable, const u32 *match_criteria
                        return false;
        }
 
+       if (!(match_criteria_enable &
+             1 << MLX5_CREATE_FLOW_GROUP_IN_MATCH_CRITERIA_ENABLE_MISC_PARAMETERS_2)) {
+               char *fg_type_mask = MLX5_ADDR_OF(fte_match_param,
+                                                 match_criteria, misc_parameters_2);
+
+               if (fg_type_mask[0] ||
+                   memcmp(fg_type_mask, fg_type_mask + 1,
+                          MLX5_ST_SZ_BYTES(fte_match_set_misc2) - 1))
+                       return false;
+       }
+
        return check_last_reserved(match_criteria);
 }
 
@@ -1191,8 +1203,7 @@ static struct mlx5_flow_handle *alloc_handle(int num_rules)
 {
        struct mlx5_flow_handle *handle;
 
-       handle = kzalloc(sizeof(*handle) + sizeof(handle->rule[0]) *
-                         num_rules, GFP_KERNEL);
+       handle = kzalloc(struct_size(handle, rule, num_rules), GFP_KERNEL);
        if (!handle)
                return NULL;
 
@@ -1374,6 +1385,8 @@ static int create_auto_flow_group(struct mlx5_flow_table *ft,
        struct mlx5_core_dev *dev = get_dev(&ft->node);
        int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
        void *match_criteria_addr;
+       u8 src_esw_owner_mask_on;
+       void *misc;
        int err;
        u32 *in;
 
@@ -1386,6 +1399,14 @@ static int create_auto_flow_group(struct mlx5_flow_table *ft,
        MLX5_SET(create_flow_group_in, in, start_flow_index, fg->start_index);
        MLX5_SET(create_flow_group_in, in, end_flow_index,   fg->start_index +
                 fg->max_ftes - 1);
+
+       misc = MLX5_ADDR_OF(fte_match_param, fg->mask.match_criteria,
+                           misc_parameters);
+       src_esw_owner_mask_on = !!MLX5_GET(fte_match_set_misc, misc,
+                                        source_eswitch_owner_vhca_id);
+       MLX5_SET(create_flow_group_in, in,
+                source_eswitch_owner_vhca_id_valid, src_esw_owner_mask_on);
+
        match_criteria_addr = MLX5_ADDR_OF(create_flow_group_in,
                                           in, match_criteria);
        memcpy(match_criteria_addr, fg->mask.match_criteria,
@@ -1406,7 +1427,7 @@ static bool mlx5_flow_dests_cmp(struct mlx5_flow_destination *d1,
 {
        if (d1->type == d2->type) {
                if ((d1->type == MLX5_FLOW_DESTINATION_TYPE_VPORT &&
-                    d1->vport_num == d2->vport_num) ||
+                    d1->vport.num == d2->vport.num) ||
                    (d1->type == MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE &&
                     d1->ft == d2->ft) ||
                    (d1->type == MLX5_FLOW_DESTINATION_TYPE_TIR &&
@@ -1443,7 +1464,9 @@ static bool check_conflicting_actions(u32 action1, u32 action2)
                             MLX5_FLOW_CONTEXT_ACTION_DECAP |
                             MLX5_FLOW_CONTEXT_ACTION_MOD_HDR  |
                             MLX5_FLOW_CONTEXT_ACTION_VLAN_POP |
-                            MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH))
+                            MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH |
+                            MLX5_FLOW_CONTEXT_ACTION_VLAN_POP_2 |
+                            MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2))
                return true;
 
        return false;
@@ -2485,7 +2508,7 @@ static int init_fdb_root_ns(struct mlx5_flow_steering *steering)
        if (!steering->fdb_root_ns)
                return -ENOMEM;
 
-       prio = fs_create_prio(&steering->fdb_root_ns->ns, 0, 1);
+       prio = fs_create_prio(&steering->fdb_root_ns->ns, 0, 2);
        if (IS_ERR(prio))
                goto out_err;