drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c
Extension
.c
Size
4665 bytes
Lines
182
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct mlx5e_post_act {
	enum mlx5_flow_namespace_type ns_type;
	struct mlx5_fs_chains *chains;
	struct mlx5_flow_table *ft;
	struct mlx5e_priv *priv;
	struct xarray ids;
};

struct mlx5e_post_act_handle {
	enum mlx5_flow_namespace_type ns_type;
	struct mlx5_flow_attr *attr;
	struct mlx5_flow_handle *rule;
	u32 id;
};

#define MLX5_POST_ACTION_BITS MLX5_REG_MAPPING_MBITS(FTEID_TO_REG)
#define MLX5_POST_ACTION_MASK MLX5_REG_MAPPING_MASK(FTEID_TO_REG)
#define MLX5_POST_ACTION_MAX MLX5_POST_ACTION_MASK

struct mlx5e_post_act *
mlx5e_tc_post_act_init(struct mlx5e_priv *priv, struct mlx5_fs_chains *chains,
		       enum mlx5_flow_namespace_type ns_type)
{
	enum fs_flow_table_type table_type = ns_type == MLX5_FLOW_NAMESPACE_FDB ?
					     FS_FT_FDB : FS_FT_NIC_RX;
	struct mlx5e_post_act *post_act;
	int err;

	if (!MLX5_CAP_FLOWTABLE_TYPE(priv->mdev, ignore_flow_level, table_type)) {
		if (priv->mdev->coredev_type == MLX5_COREDEV_PF)
			mlx5_core_dbg(priv->mdev, "firmware flow level support is missing\n");
		err = -EOPNOTSUPP;
		goto err_check;
	}

	post_act = kzalloc_obj(*post_act);
	if (!post_act) {
		err = -ENOMEM;
		goto err_check;
	}
	post_act->ft = mlx5_chains_create_global_table(chains);
	if (IS_ERR(post_act->ft)) {
		err = PTR_ERR(post_act->ft);
		mlx5_core_warn(priv->mdev, "failed to create post action table, err: %d\n", err);
		goto err_ft;
	}
	post_act->chains = chains;
	post_act->ns_type = ns_type;
	post_act->priv = priv;
	xa_init_flags(&post_act->ids, XA_FLAGS_ALLOC1);
	return post_act;

err_ft:
	kfree(post_act);
err_check:
	return ERR_PTR(err);
}

void
mlx5e_tc_post_act_destroy(struct mlx5e_post_act *post_act)
{
	if (IS_ERR_OR_NULL(post_act))
		return;

	xa_destroy(&post_act->ids);
	mlx5_chains_destroy_global_table(post_act->chains, post_act->ft);
	kfree(post_act);
}

int
mlx5e_tc_post_act_offload(struct mlx5e_post_act *post_act,
			  struct mlx5e_post_act_handle *handle)
{
	struct mlx5_flow_spec *spec;
	int err;

	if (IS_ERR(post_act))
		return PTR_ERR(post_act);

	spec = kvzalloc_obj(*spec);
	if (!spec)
		return -ENOMEM;

	/* Post action rule matches on fte_id and executes original rule's tc rule action */
	mlx5e_tc_match_to_reg_match(spec, FTEID_TO_REG, handle->id, MLX5_POST_ACTION_MASK);

	handle->rule = mlx5e_tc_rule_offload(post_act->priv, spec, handle->attr);
	if (IS_ERR(handle->rule)) {
		err = PTR_ERR(handle->rule);
		netdev_warn(post_act->priv->netdev, "Failed to add post action rule");

Annotation

Implementation Notes