Merge branch 'mlx5-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mellanox...
[sfrench/cifs-2.6.git] / drivers / net / ethernet / mellanox / mlx5 / core / fs_core.c
index 37d114c668b7ba70ca968f76c88c42af84967f25..8d340e5181f8dadea456133ff9eb2279861e8521 100644 (file)
                                           FS_CAP(flow_table_properties_nic_receive.identified_miss_table_mode), \
                                           FS_CAP(flow_table_properties_nic_receive.flow_table_modify))
 
+#define FS_CHAINING_CAPS_EGRESS                                                \
+       FS_REQUIRED_CAPS(                                                      \
+               FS_CAP(flow_table_properties_nic_transmit.flow_modify_en),     \
+               FS_CAP(flow_table_properties_nic_transmit.modify_root),        \
+               FS_CAP(flow_table_properties_nic_transmit                      \
+                              .identified_miss_table_mode),                   \
+               FS_CAP(flow_table_properties_nic_transmit.flow_table_modify))
+
 #define LEFTOVERS_NUM_LEVELS 1
 #define LEFTOVERS_NUM_PRIOS 1
 
@@ -151,6 +159,17 @@ static struct init_tree_node {
        }
 };
 
+static struct init_tree_node egress_root_fs = {
+       .type = FS_TYPE_NAMESPACE,
+       .ar_size = 1,
+       .children = (struct init_tree_node[]) {
+               ADD_PRIO(0, MLX5_BY_PASS_NUM_PRIOS, 0,
+                        FS_CHAINING_CAPS_EGRESS,
+                        ADD_NS(ADD_MULTIPLE_PRIO(MLX5_BY_PASS_NUM_PRIOS,
+                                                 BY_PASS_PRIO_NUM_LEVELS))),
+       }
+};
+
 enum fs_i_lock_class {
        FS_LOCK_GRANDPARENT,
        FS_LOCK_PARENT,
@@ -1388,7 +1407,7 @@ static bool check_conflicting_actions(u32 action1, u32 action2)
                return false;
 
        if (xored_actions & (MLX5_FLOW_CONTEXT_ACTION_DROP  |
-                            MLX5_FLOW_CONTEXT_ACTION_ENCAP |
+                            MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT |
                             MLX5_FLOW_CONTEXT_ACTION_DECAP |
                             MLX5_FLOW_CONTEXT_ACTION_MOD_HDR  |
                             MLX5_FLOW_CONTEXT_ACTION_VLAN_POP |
@@ -1980,7 +1999,7 @@ struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev,
 {
        struct mlx5_flow_steering *steering = dev->priv.steering;
        struct mlx5_flow_root_namespace *root_ns;
-       int prio;
+       int prio = 0;
        struct fs_prio *fs_prio;
        struct mlx5_flow_namespace *ns;
 
@@ -1988,40 +2007,29 @@ struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev,
                return NULL;
 
        switch (type) {
-       case MLX5_FLOW_NAMESPACE_BYPASS:
-       case MLX5_FLOW_NAMESPACE_LAG:
-       case MLX5_FLOW_NAMESPACE_OFFLOADS:
-       case MLX5_FLOW_NAMESPACE_ETHTOOL:
-       case MLX5_FLOW_NAMESPACE_KERNEL:
-       case MLX5_FLOW_NAMESPACE_LEFTOVERS:
-       case MLX5_FLOW_NAMESPACE_ANCHOR:
-               prio = type;
-               break;
        case MLX5_FLOW_NAMESPACE_FDB:
                if (steering->fdb_root_ns)
                        return &steering->fdb_root_ns->ns;
-               else
-                       return NULL;
+               return NULL;
        case MLX5_FLOW_NAMESPACE_SNIFFER_RX:
                if (steering->sniffer_rx_root_ns)
                        return &steering->sniffer_rx_root_ns->ns;
-               else
-                       return NULL;
+               return NULL;
        case MLX5_FLOW_NAMESPACE_SNIFFER_TX:
                if (steering->sniffer_tx_root_ns)
                        return &steering->sniffer_tx_root_ns->ns;
-               else
-                       return NULL;
-       case MLX5_FLOW_NAMESPACE_EGRESS:
-               if (steering->egress_root_ns)
-                       return &steering->egress_root_ns->ns;
-               else
-                       return NULL;
-       default:
                return NULL;
+       default:
+               break;
+       }
+
+       if (type == MLX5_FLOW_NAMESPACE_EGRESS) {
+               root_ns = steering->egress_root_ns;
+       } else { /* Must be NIC RX */
+               root_ns = steering->root_ns;
+               prio = type;
        }
 
-       root_ns = steering->root_ns;
        if (!root_ns)
                return NULL;
 
@@ -2537,16 +2545,23 @@ cleanup_root_ns:
 
 static int init_egress_root_ns(struct mlx5_flow_steering *steering)
 {
-       struct fs_prio *prio;
+       int err;
 
        steering->egress_root_ns = create_root_ns(steering,
                                                  FS_FT_NIC_TX);
        if (!steering->egress_root_ns)
                return -ENOMEM;
 
-       /* create 1 prio*/
-       prio = fs_create_prio(&steering->egress_root_ns->ns, 0, 1);
-       return PTR_ERR_OR_ZERO(prio);
+       err = init_root_tree(steering, &egress_root_fs,
+                            &steering->egress_root_ns->ns.node);
+       if (err)
+               goto cleanup;
+       set_prio_attrs(steering->egress_root_ns);
+       return 0;
+cleanup:
+       cleanup_root_ns(steering->egress_root_ns);
+       steering->egress_root_ns = NULL;
+       return err;
 }
 
 int mlx5_init_fs(struct mlx5_core_dev *dev)
@@ -2614,7 +2629,7 @@ int mlx5_init_fs(struct mlx5_core_dev *dev)
                        goto err;
        }
 
-       if (MLX5_IPSEC_DEV(dev)) {
+       if (MLX5_IPSEC_DEV(dev) || MLX5_CAP_FLOWTABLE_NIC_TX(dev, ft_support)) {
                err = init_egress_root_ns(steering);
                if (err)
                        goto err;