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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_hmfs.c
Extension
.c
Size
9255 bytes
Lines
295
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 mlx5_ct_fs_hmfs_matcher {
	struct mlx5hws_bwc_matcher *hws_bwc_matcher;
	refcount_t ref;
};

/* We need {ipv4, ipv6} x {tcp, udp, gre}  matchers. */
#define NUM_MATCHERS (2 * 3)

struct mlx5_ct_fs_hmfs {
	struct mlx5hws_table *ct_tbl;
	struct mlx5hws_table *ct_nat_tbl;
	struct mlx5_flow_table *ct_nat;
	struct mlx5hws_action *fwd_action;
	struct mlx5hws_action *last_action;
	struct mlx5hws_context *ctx;
	struct mutex lock;   /* Guards matchers */
	struct mlx5_ct_fs_hmfs_matcher matchers[NUM_MATCHERS];
	struct mlx5_ct_fs_hmfs_matcher matchers_nat[NUM_MATCHERS];
};

struct mlx5_ct_fs_hmfs_rule {
	struct mlx5_ct_fs_rule fs_rule;
	struct mlx5hws_bwc_rule *hws_bwc_rule;
	struct mlx5_ct_fs_hmfs_matcher *hmfs_matcher;
	struct mlx5_fc *counter;
};

static u32 get_matcher_idx(bool ipv4, bool tcp, bool gre)
{
	return ipv4 * 3 + tcp * 2 + gre;
}

static int mlx5_ct_fs_hmfs_init(struct mlx5_ct_fs *fs, struct mlx5_flow_table *ct,
				struct mlx5_flow_table *ct_nat, struct mlx5_flow_table *post_ct)
{
	u32 flags = MLX5HWS_ACTION_FLAG_HWS_FDB | MLX5HWS_ACTION_FLAG_SHARED;
	struct mlx5hws_table *ct_tbl, *ct_nat_tbl, *post_ct_tbl;
	struct mlx5_ct_fs_hmfs *fs_hmfs = mlx5_ct_fs_priv(fs);

	ct_tbl = ct->fs_hws_table.hws_table;
	ct_nat_tbl = ct_nat->fs_hws_table.hws_table;
	post_ct_tbl = post_ct->fs_hws_table.hws_table;
	fs_hmfs->ct_nat = ct_nat;

	if (!ct_tbl || !ct_nat_tbl || !post_ct_tbl) {
		netdev_warn(fs->netdev, "ct_fs_hmfs: failed to init, missing backing hws tables");
		return -EOPNOTSUPP;
	}

	netdev_dbg(fs->netdev, "using hmfs steering");

	fs_hmfs->ct_tbl = ct_tbl;
	fs_hmfs->ct_nat_tbl = ct_nat_tbl;
	fs_hmfs->ctx = ct_tbl->ctx;
	mutex_init(&fs_hmfs->lock);

	fs_hmfs->fwd_action = mlx5hws_action_create_dest_table(ct_tbl->ctx, post_ct_tbl, flags);
	if (!fs_hmfs->fwd_action) {
		netdev_warn(fs->netdev, "ct_fs_hmfs: failed to create fwd action\n");
		return -EINVAL;
	}
	fs_hmfs->last_action = mlx5hws_action_create_last(ct_tbl->ctx, flags);
	if (!fs_hmfs->last_action) {
		netdev_warn(fs->netdev, "ct_fs_hmfs: failed to create last action\n");
		mlx5hws_action_destroy(fs_hmfs->fwd_action);
		return -EINVAL;
	}

	return 0;
}

static void mlx5_ct_fs_hmfs_destroy(struct mlx5_ct_fs *fs)
{
	struct mlx5_ct_fs_hmfs *fs_hmfs = mlx5_ct_fs_priv(fs);

	mlx5hws_action_destroy(fs_hmfs->last_action);
	mlx5hws_action_destroy(fs_hmfs->fwd_action);
}

static struct mlx5hws_bwc_matcher *
mlx5_ct_fs_hmfs_matcher_create(struct mlx5_ct_fs *fs, struct mlx5hws_table *tbl,
			       struct mlx5_flow_spec *spec, bool ipv4, bool tcp, bool gre)
{
	u8 match_criteria_enable = MLX5_MATCH_MISC_PARAMETERS_2 | MLX5_MATCH_OUTER_HEADERS;
	struct mlx5hws_match_parameters mask = {
		.match_buf = spec->match_criteria,
		.match_sz = sizeof(spec->match_criteria),
	};
	u32 priority = get_matcher_idx(ipv4, tcp, gre);  /* Static priority based on params. */
	struct mlx5hws_bwc_matcher *hws_bwc_matcher;

Annotation

Implementation Notes