drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c
Extension
.c
Size
15355 bytes
Lines
583
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

switch (action_id) {
		case MLX5_MODIFICATION_TYPE_NOP:
			field = MLX5_MODI_OUT_NONE;
			break;

		case MLX5_MODIFICATION_TYPE_SET:
		case MLX5_MODIFICATION_TYPE_ADD:
			field = MLX5_GET(set_action_in, &actions[i], field);
			break;

		case MLX5_MODIFICATION_TYPE_COPY:
		case MLX5_MODIFICATION_TYPE_ADD_FIELD:
			field = MLX5_GET(copy_action_in, &actions[i], dst_field);
			break;

		default:
			/* Insert/Remove/Unknown actions require reparse */
			return true;
		}

		/* Below fields can change packet structure require a reparse */
		if (field == MLX5_MODI_OUT_ETHERTYPE ||
		    field == MLX5_MODI_OUT_IPV6_NEXT_HDR)
			return true;
	}

	return false;
}

/* Cache and cache element handling */
int mlx5hws_pat_init_pattern_cache(struct mlx5hws_pattern_cache **cache)
{
	struct mlx5hws_pattern_cache *new_cache;

	new_cache = kzalloc_obj(*new_cache);
	if (!new_cache)
		return -ENOMEM;

	INIT_LIST_HEAD(&new_cache->ptrn_list);
	mutex_init(&new_cache->lock);

	*cache = new_cache;

	return 0;
}

void mlx5hws_pat_uninit_pattern_cache(struct mlx5hws_pattern_cache *cache)
{
	mutex_destroy(&cache->lock);
	kfree(cache);
}

static bool mlx5hws_pat_compare_pattern(int cur_num_of_actions,
					__be64 cur_actions[],
					int num_of_actions,
					__be64 actions[])
{
	int i;

	if (cur_num_of_actions != num_of_actions)
		return false;

	for (i = 0; i < num_of_actions; i++) {
		u8 action_id =
			MLX5_GET(set_action_in, &actions[i], action_type);

		if (action_id == MLX5_MODIFICATION_TYPE_COPY ||
		    action_id == MLX5_MODIFICATION_TYPE_ADD_FIELD) {
			if (actions[i] != cur_actions[i])
				return false;
		} else {
			/* Compare just the control, not the values */
			if ((__force __be32)actions[i] !=
			    (__force __be32)cur_actions[i])
				return false;
		}
	}

	return true;
}

static struct mlx5hws_pattern_cache_item *
mlx5hws_pat_find_cached_pattern(struct mlx5hws_pattern_cache *cache,
				u16 num_of_actions,
				__be64 *actions)
{
	struct mlx5hws_pattern_cache_item *cached_pat = NULL;

	list_for_each_entry(cached_pat, &cache->ptrn_list, ptrn_list_node) {
		if (mlx5hws_pat_compare_pattern(cached_pat->mh_data.num_of_actions,

Annotation

Implementation Notes