drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c
Extension
.c
Size
40062 bytes
Lines
1241
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

mlx5_lag_is_master(dev)) {
		struct mlx5_core_dev *peer_dev;
		int i, j;

		mlx5_lag_for_each_peer_mdev(dev, peer_dev, i) {
			err = mlx5_cmd_set_slave_root_fdb(dev, peer_dev, !disconnect,
							  (!disconnect) ? ft->id : 0);
			if (err && !disconnect) {
				mlx5_lag_for_each_peer_mdev(dev, peer_dev, j) {
					if (j < i)
						mlx5_cmd_set_slave_root_fdb(dev, peer_dev, 1,
									    ns->root_ft->id);
					else
						break;
				}

				MLX5_SET(set_flow_table_root_in, in, op_mod, 0);
				MLX5_SET(set_flow_table_root_in, in, table_id,
					 ns->root_ft->id);
				mlx5_cmd_exec_in(dev, set_flow_table_root, in);
			}
			if (err)
				break;
		}

	}

	return err;
}

static int mlx5_cmd_create_flow_table(struct mlx5_flow_root_namespace *ns,
				      struct mlx5_flow_table *ft,
				      struct mlx5_flow_table_attr *ft_attr,
				      struct mlx5_flow_table *next_ft)
{
	int en_encap = !!(ft->flags & MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT);
	int en_decap = !!(ft->flags & MLX5_FLOW_TABLE_TUNNEL_EN_DECAP);
	int term = !!(ft->flags & MLX5_FLOW_TABLE_TERMINATION);
	u32 out[MLX5_ST_SZ_DW(create_flow_table_out)] = {};
	u32 in[MLX5_ST_SZ_DW(create_flow_table_in)] = {};
	struct mlx5_core_dev *dev = ns->dev;
	unsigned int size;
	int err;

	size = mlx5_ft_pool_get_avail_sz(dev, ft->type, ft_attr->max_fte);
	if (!size)
		return -ENOSPC;

	MLX5_SET(create_flow_table_in, in, opcode,
		 MLX5_CMD_OP_CREATE_FLOW_TABLE);

	MLX5_SET(create_flow_table_in, in, uid, ft_attr->uid);
	MLX5_SET(create_flow_table_in, in, table_type, ft->type);
	MLX5_SET(create_flow_table_in, in, flow_table_context.level, ft->level);
	MLX5_SET(create_flow_table_in, in, flow_table_context.log_size, size ? ilog2(size) : 0);
	MLX5_SET(create_flow_table_in, in, vport_number, ft->vport);
	MLX5_SET(create_flow_table_in, in, other_vport,
		 !!(ft->flags & MLX5_FLOW_TABLE_OTHER_VPORT));
	MLX5_SET(create_flow_table_in, in, eswitch_owner_vhca_id,
		 ft->esw_owner_vhca_id);
	MLX5_SET(create_flow_table_in, in, other_eswitch,
		 !!(ft->flags & MLX5_FLOW_TABLE_OTHER_ESWITCH));

	MLX5_SET(create_flow_table_in, in, flow_table_context.decap_en,
		 en_decap);
	MLX5_SET(create_flow_table_in, in, flow_table_context.reformat_en,
		 en_encap);
	MLX5_SET(create_flow_table_in, in, flow_table_context.termination_table,
		 term);

	switch (ft->op_mod) {
	case FS_FT_OP_MOD_NORMAL:
		if (next_ft) {
			MLX5_SET(create_flow_table_in, in,
				 flow_table_context.table_miss_action,
				 MLX5_FLOW_TABLE_MISS_ACTION_FWD);
			MLX5_SET(create_flow_table_in, in,
				 flow_table_context.table_miss_id, next_ft->id);
		} else {
			MLX5_SET(create_flow_table_in, in,
				 flow_table_context.table_miss_action,
				 ft->def_miss_action);
		}
		break;

	case FS_FT_OP_MOD_LAG_DEMUX:
		MLX5_SET(create_flow_table_in, in, op_mod, 0x1);
		if (next_ft)
			MLX5_SET(create_flow_table_in, in,
				 flow_table_context.lag_master_next_table_id,

Annotation

Implementation Notes