drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_ptrn.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_ptrn.c
Extension
.c
Size
6084 bytes
Lines
245
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 mlx5dr_ptrn_mgr {
	struct mlx5dr_domain *dmn;
	struct mlx5dr_icm_pool *ptrn_icm_pool;
	/* cache for modify_header ptrn */
	struct list_head ptrn_list;
	struct mutex modify_hdr_mutex; /* protect the pattern cache */
};

/* Cache structure and functions */
static bool dr_ptrn_compare_modify_hdr(size_t cur_num_of_actions,
				       __be64 cur_hw_actions[],
				       size_t num_of_actions,
				       __be64 hw_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(ste_double_action_set_v1, &hw_actions[i], action_id);

		if (action_id == DR_PTRN_MODIFY_HDR_ACTION_ID_COPY) {
			if (hw_actions[i] != cur_hw_actions[i])
				return false;
		} else {
			if ((__force __be32)hw_actions[i] !=
			    (__force __be32)cur_hw_actions[i])
				return false;
		}
	}

	return true;
}

static struct mlx5dr_ptrn_obj *
dr_ptrn_find_cached_pattern(struct mlx5dr_ptrn_mgr *mgr,
			    size_t num_of_actions,
			    __be64 hw_actions[])
{
	struct mlx5dr_ptrn_obj *cached_pattern;
	struct mlx5dr_ptrn_obj *tmp;

	list_for_each_entry_safe(cached_pattern, tmp, &mgr->ptrn_list, list) {
		if (dr_ptrn_compare_modify_hdr(cached_pattern->num_of_actions,
					       (__be64 *)cached_pattern->data,
					       num_of_actions,
					       hw_actions)) {
			/* Put this pattern in the head of the list,
			 * as we will probably use it more.
			 */
			list_del_init(&cached_pattern->list);
			list_add(&cached_pattern->list, &mgr->ptrn_list);
			return cached_pattern;
		}
	}

	return NULL;
}

static struct mlx5dr_ptrn_obj *
dr_ptrn_alloc_pattern(struct mlx5dr_ptrn_mgr *mgr,
		      u16 num_of_actions, u8 *data)
{
	struct mlx5dr_ptrn_obj *pattern;
	struct mlx5dr_icm_chunk *chunk;
	u32 chunk_size;
	u32 index;

	chunk_size = ilog2(roundup_pow_of_two(num_of_actions));
	/* HW modify action index granularity is at least 64B */
	chunk_size = max_t(u32, chunk_size, DR_CHUNK_SIZE_8);

	chunk = mlx5dr_icm_alloc_chunk(mgr->ptrn_icm_pool, chunk_size);
	if (!chunk)
		return NULL;

	index = (mlx5dr_icm_pool_get_chunk_icm_addr(chunk) -
		 mgr->dmn->info.caps.hdr_modify_pattern_icm_addr) /
		DR_ACTION_CACHE_LINE_SIZE;

	pattern = kzalloc_obj(*pattern);
	if (!pattern)
		goto free_chunk;

	pattern->data = kzalloc(num_of_actions * DR_MODIFY_ACTION_SIZE *
				sizeof(*pattern->data), GFP_KERNEL);
	if (!pattern->data)
		goto free_pattern;

Annotation

Implementation Notes