Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d40d162 authored by Maor Gottlieb's avatar Maor Gottlieb Committed by David S. Miller
Browse files

net/mlx5_core: Initialize namespaces only when supported by device



Before we create the sub tree of a steering namespaces(kernel, bypass,
leftovers) we check that the device has the required capabilities
in order to create this subtree.

Signed-off-by: default avatarMaor Gottlieb <maorg@mellanox.com>
Signed-off-by: default avatarMoni Shoua <monis@mellanox.com>
Signed-off-by: default avatarMatan Barak <matanb@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 655227ed
Loading
Loading
Loading
Loading
+49 −21
Original line number Diff line number Diff line
@@ -40,20 +40,17 @@
#define INIT_TREE_NODE_ARRAY_SIZE(...)	(sizeof((struct init_tree_node[]){__VA_ARGS__}) /\
					 sizeof(struct init_tree_node))

#define INIT_PRIO(min_level_val, max_ft_val,\
#define ADD_PRIO(min_level_val, max_ft_val, caps_val,\
		 ...) {.type = FS_TYPE_PRIO,\
	.min_ft_level = min_level_val,\
	.max_ft = max_ft_val,\
	.caps = caps_val,\
	.children = (struct init_tree_node[]) {__VA_ARGS__},\
	.ar_size = INIT_TREE_NODE_ARRAY_SIZE(__VA_ARGS__) \
}

#define ADD_PRIO(min_level_val, max_ft_val, ...)\
	INIT_PRIO(min_level_val, max_ft_val,\
		  __VA_ARGS__)\

#define ADD_FT_PRIO(max_ft_val, ...)\
	INIT_PRIO(0, max_ft_val,\
	ADD_PRIO(0, max_ft_val, {},\
		  __VA_ARGS__)\

#define ADD_NS(...) {.type = FS_TYPE_NAMESPACE,\
@@ -61,12 +58,26 @@
	.ar_size = INIT_TREE_NODE_ARRAY_SIZE(__VA_ARGS__) \
}

#define INIT_CAPS_ARRAY_SIZE(...) (sizeof((long[]){__VA_ARGS__}) /\
				   sizeof(long))

#define FS_CAP(cap) (__mlx5_bit_off(flow_table_nic_cap, cap))

#define FS_REQUIRED_CAPS(...) {.arr_sz = INIT_CAPS_ARRAY_SIZE(__VA_ARGS__), \
			       .caps = (long[]) {__VA_ARGS__} }

#define KERNEL_MAX_FT 2
#define KENREL_MIN_LEVEL 2

struct node_caps {
	size_t	arr_sz;
	long	*caps;
};
static struct init_tree_node {
	enum fs_node_type	type;
	struct init_tree_node *children;
	int ar_size;
	struct node_caps caps;
	int min_ft_level;
	int prio;
	int max_ft;
@@ -74,7 +85,7 @@ static struct init_tree_node {
	.type = FS_TYPE_NAMESPACE,
	.ar_size = 1,
	.children = (struct init_tree_node[]) {
		ADD_PRIO(KENREL_MIN_LEVEL, 0,
		ADD_PRIO(KENREL_MIN_LEVEL, 0, {},
			 ADD_NS(ADD_FT_PRIO(KERNEL_MAX_FT))),
	}
};
@@ -1153,11 +1164,31 @@ static struct mlx5_flow_namespace *fs_create_namespace(struct fs_prio *prio)
	return ns;
}

static int init_root_tree_recursive(int max_ft_level, struct init_tree_node *init_node,
#define FLOW_TABLE_BIT_SZ 1
#define GET_FLOW_TABLE_CAP(dev, offset) \
	((be32_to_cpu(*((__be32 *)(dev->hca_caps_cur[MLX5_CAP_FLOW_TABLE]) +	\
			offset / 32)) >>					\
	  (32 - FLOW_TABLE_BIT_SZ - (offset & 0x1f))) & FLOW_TABLE_BIT_SZ)
static bool has_required_caps(struct mlx5_core_dev *dev, struct node_caps *caps)
{
	int i;

	for (i = 0; i < caps->arr_sz; i++) {
		if (!GET_FLOW_TABLE_CAP(dev, caps->caps[i]))
			return false;
	}
	return true;
}

static int init_root_tree_recursive(struct mlx5_core_dev *dev,
				    struct init_tree_node *init_node,
				    struct fs_node *fs_parent_node,
				    struct init_tree_node *init_parent_node,
				    int index)
{
	int max_ft_level = MLX5_CAP_FLOWTABLE(dev,
					      flow_table_properties_nic_receive.
					      max_ft_level);
	struct mlx5_flow_namespace *fs_ns;
	struct fs_prio *fs_prio;
	struct fs_node *base;
@@ -1165,8 +1196,9 @@ static int init_root_tree_recursive(int max_ft_level, struct init_tree_node *ini
	int err;

	if (init_node->type == FS_TYPE_PRIO) {
		if (init_node->min_ft_level > max_ft_level)
			return -ENOTSUPP;
		if ((init_node->min_ft_level > max_ft_level) ||
		    !has_required_caps(dev, &init_node->caps))
			return 0;

		fs_get_obj(fs_ns, fs_parent_node);
		fs_prio = fs_create_prio(fs_ns, index, init_node->max_ft);
@@ -1183,9 +1215,8 @@ static int init_root_tree_recursive(int max_ft_level, struct init_tree_node *ini
		return -EINVAL;
	}
	for (i = 0; i < init_node->ar_size; i++) {
		err = init_root_tree_recursive(max_ft_level,
					       &init_node->children[i], base,
					       init_node, i);
		err = init_root_tree_recursive(dev, &init_node->children[i],
					       base, init_node, i);
		if (err)
			return err;
	}
@@ -1193,7 +1224,8 @@ static int init_root_tree_recursive(int max_ft_level, struct init_tree_node *ini
	return 0;
}

static int init_root_tree(int max_ft_level, struct init_tree_node *init_node,
static int init_root_tree(struct mlx5_core_dev *dev,
			  struct init_tree_node *init_node,
			  struct fs_node *fs_parent_node)
{
	int i;
@@ -1202,8 +1234,7 @@ static int init_root_tree(int max_ft_level, struct init_tree_node *init_node,

	fs_get_obj(fs_ns, fs_parent_node);
	for (i = 0; i < init_node->ar_size; i++) {
		err = init_root_tree_recursive(max_ft_level,
					       &init_node->children[i],
		err = init_root_tree_recursive(dev, &init_node->children[i],
					       &fs_ns->node,
					       init_node, i);
		if (err)
@@ -1278,15 +1309,12 @@ static void set_prio_attrs(struct mlx5_flow_root_namespace *root_ns)

static int init_root_ns(struct mlx5_core_dev *dev)
{
	int max_ft_level = MLX5_CAP_FLOWTABLE(dev,
					      flow_table_properties_nic_receive.
					      max_ft_level);

	dev->priv.root_ns = create_root_ns(dev, FS_FT_NIC_RX);
	if (IS_ERR_OR_NULL(dev->priv.root_ns))
		goto cleanup;

	if (init_root_tree(max_ft_level, &root_fs, &dev->priv.root_ns->ns.node))
	if (init_root_tree(dev, &root_fs, &dev->priv.root_ns->ns.node))
		goto cleanup;

	set_prio_attrs(dev->priv.root_ns);