net/mlx5: Refactor mlx5_add_flow_rule
[cascardo/linux.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_fs.c
index b327400..2e1e863 100644 (file)
@@ -156,19 +156,18 @@ enum mlx5e_vlan_rule_type {
 
 static int __mlx5e_add_vlan_rule(struct mlx5e_priv *priv,
                                 enum mlx5e_vlan_rule_type rule_type,
-                                u16 vid, u32 *mc, u32 *mv)
+                                u16 vid, struct mlx5_flow_spec *spec)
 {
        struct mlx5_flow_table *ft = priv->fs.vlan.ft.t;
        struct mlx5_flow_destination dest;
-       u8 match_criteria_enable = 0;
        struct mlx5_flow_rule **rule_p;
        int err = 0;
 
        dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
        dest.ft = priv->fs.l2.ft.t;
 
-       match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
-       MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.vlan_tag);
+       spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
+       MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.vlan_tag);
 
        switch (rule_type) {
        case MLX5E_VLAN_RULE_TYPE_UNTAGGED:
@@ -176,17 +175,19 @@ static int __mlx5e_add_vlan_rule(struct mlx5e_priv *priv,
                break;
        case MLX5E_VLAN_RULE_TYPE_ANY_VID:
                rule_p = &priv->fs.vlan.any_vlan_rule;
-               MLX5_SET(fte_match_param, mv, outer_headers.vlan_tag, 1);
+               MLX5_SET(fte_match_param, spec->match_value, outer_headers.vlan_tag, 1);
                break;
        default: /* MLX5E_VLAN_RULE_TYPE_MATCH_VID */
                rule_p = &priv->fs.vlan.active_vlans_rule[vid];
-               MLX5_SET(fte_match_param, mv, outer_headers.vlan_tag, 1);
-               MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.first_vid);
-               MLX5_SET(fte_match_param, mv, outer_headers.first_vid, vid);
+               MLX5_SET(fte_match_param, spec->match_value, outer_headers.vlan_tag, 1);
+               MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
+                                outer_headers.first_vid);
+               MLX5_SET(fte_match_param, spec->match_value, outer_headers.first_vid,
+                        vid);
                break;
        }
 
-       *rule_p = mlx5_add_flow_rule(ft, match_criteria_enable, mc, mv,
+       *rule_p = mlx5_add_flow_rule(ft, spec,
                                     MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
                                     MLX5_FS_DEFAULT_FLOW_TAG,
                                     &dest);
@@ -203,27 +204,21 @@ static int __mlx5e_add_vlan_rule(struct mlx5e_priv *priv,
 static int mlx5e_add_vlan_rule(struct mlx5e_priv *priv,
                               enum mlx5e_vlan_rule_type rule_type, u16 vid)
 {
-       u32 *match_criteria;
-       u32 *match_value;
+       struct mlx5_flow_spec *spec;
        int err = 0;
 
-       match_value     = mlx5_vzalloc(MLX5_ST_SZ_BYTES(fte_match_param));
-       match_criteria  = mlx5_vzalloc(MLX5_ST_SZ_BYTES(fte_match_param));
-       if (!match_value || !match_criteria) {
+       spec = mlx5_vzalloc(sizeof(*spec));
+       if (!spec) {
                netdev_err(priv->netdev, "%s: alloc failed\n", __func__);
-               err = -ENOMEM;
-               goto add_vlan_rule_out;
+               return -ENOMEM;
        }
 
        if (rule_type == MLX5E_VLAN_RULE_TYPE_MATCH_VID)
                mlx5e_vport_context_update_vlans(priv);
 
-       err = __mlx5e_add_vlan_rule(priv, rule_type, vid, match_criteria,
-                                   match_value);
+       err = __mlx5e_add_vlan_rule(priv, rule_type, vid, spec);
 
-add_vlan_rule_out:
-       kvfree(match_criteria);
-       kvfree(match_value);
+       kvfree(spec);
 
        return err;
 }
@@ -598,32 +593,27 @@ static struct mlx5_flow_rule *mlx5e_generate_ttc_rule(struct mlx5e_priv *priv,
                                                      u8 proto)
 {
        struct mlx5_flow_rule *rule;
-       u8 match_criteria_enable = 0;
-       u32 *match_criteria;
-       u32 *match_value;
+       struct mlx5_flow_spec *spec;
        int err = 0;
 
-       match_value     = mlx5_vzalloc(MLX5_ST_SZ_BYTES(fte_match_param));
-       match_criteria  = mlx5_vzalloc(MLX5_ST_SZ_BYTES(fte_match_param));
-       if (!match_value || !match_criteria) {
+       spec = mlx5_vzalloc(sizeof(*spec));
+       if (!spec) {
                netdev_err(priv->netdev, "%s: alloc failed\n", __func__);
-               err = -ENOMEM;
-               goto out;
+               return ERR_PTR(-ENOMEM);
        }
 
        if (proto) {
-               match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
-               MLX5_SET_TO_ONES(fte_match_param, match_criteria, outer_headers.ip_protocol);
-               MLX5_SET(fte_match_param, match_value, outer_headers.ip_protocol, proto);
+               spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
+               MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_protocol);
+               MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_protocol, proto);
        }
        if (etype) {
-               match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
-               MLX5_SET_TO_ONES(fte_match_param, match_criteria, outer_headers.ethertype);
-               MLX5_SET(fte_match_param, match_value, outer_headers.ethertype, etype);
+               spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
+               MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ethertype);
+               MLX5_SET(fte_match_param, spec->match_value, outer_headers.ethertype, etype);
        }
 
-       rule = mlx5_add_flow_rule(ft, match_criteria_enable,
-                                 match_criteria, match_value,
+       rule = mlx5_add_flow_rule(ft, spec,
                                  MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
                                  MLX5_FS_DEFAULT_FLOW_TAG,
                                  dest);
@@ -631,9 +621,8 @@ static struct mlx5_flow_rule *mlx5e_generate_ttc_rule(struct mlx5e_priv *priv,
                err = PTR_ERR(rule);
                netdev_err(priv->netdev, "%s: add rule failed\n", __func__);
        }
-out:
-       kvfree(match_criteria);
-       kvfree(match_value);
+
+       kvfree(spec);
        return err ? ERR_PTR(err) : rule;
 }
 
@@ -655,7 +644,7 @@ static int mlx5e_generate_ttc_table_rules(struct mlx5e_priv *priv)
                if (tt == MLX5E_TT_ANY)
                        dest.tir_num = priv->direct_tir[0].tirn;
                else
-                       dest.tir_num = priv->indir_tirn[tt];
+                       dest.tir_num = priv->indir_tir[tt].tirn;
                rules[tt] = mlx5e_generate_ttc_rule(priv, ft, &dest,
                                                    ttc_rules[tt].etype,
                                                    ttc_rules[tt].proto);
@@ -792,24 +781,20 @@ static int mlx5e_add_l2_flow_rule(struct mlx5e_priv *priv,
 {
        struct mlx5_flow_table *ft = priv->fs.l2.ft.t;
        struct mlx5_flow_destination dest;
-       u8 match_criteria_enable = 0;
-       u32 *match_criteria;
-       u32 *match_value;
+       struct mlx5_flow_spec *spec;
        int err = 0;
        u8 *mc_dmac;
        u8 *mv_dmac;
 
-       match_value    = mlx5_vzalloc(MLX5_ST_SZ_BYTES(fte_match_param));
-       match_criteria = mlx5_vzalloc(MLX5_ST_SZ_BYTES(fte_match_param));
-       if (!match_value || !match_criteria) {
+       spec = mlx5_vzalloc(sizeof(*spec));
+       if (!spec) {
                netdev_err(priv->netdev, "%s: alloc failed\n", __func__);
-               err = -ENOMEM;
-               goto add_l2_rule_out;
+               return -ENOMEM;
        }
 
-       mc_dmac = MLX5_ADDR_OF(fte_match_param, match_criteria,
+       mc_dmac = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
                               outer_headers.dmac_47_16);
-       mv_dmac = MLX5_ADDR_OF(fte_match_param, match_value,
+       mv_dmac = MLX5_ADDR_OF(fte_match_param, spec->match_value,
                               outer_headers.dmac_47_16);
 
        dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
@@ -817,13 +802,13 @@ static int mlx5e_add_l2_flow_rule(struct mlx5e_priv *priv,
 
        switch (type) {
        case MLX5E_FULLMATCH:
-               match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
+               spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
                eth_broadcast_addr(mc_dmac);
                ether_addr_copy(mv_dmac, ai->addr);
                break;
 
        case MLX5E_ALLMULTI:
-               match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
+               spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
                mc_dmac[0] = 0x01;
                mv_dmac[0] = 0x01;
                break;
@@ -832,8 +817,7 @@ static int mlx5e_add_l2_flow_rule(struct mlx5e_priv *priv,
                break;
        }
 
-       ai->rule = mlx5_add_flow_rule(ft, match_criteria_enable, match_criteria,
-                                     match_value,
+       ai->rule = mlx5_add_flow_rule(ft, spec,
                                      MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
                                      MLX5_FS_DEFAULT_FLOW_TAG, &dest);
        if (IS_ERR(ai->rule)) {
@@ -843,9 +827,7 @@ static int mlx5e_add_l2_flow_rule(struct mlx5e_priv *priv,
                ai->rule = NULL;
        }
 
-add_l2_rule_out:
-       kvfree(match_criteria);
-       kvfree(match_value);
+       kvfree(spec);
 
        return err;
 }