File Index
Files and directories
Sign in
FILE

dr_definer.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_definer.c C
  1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
  2// Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
  3
  4#include "dr_types.h"
  5#include "dr_ste.h"
  6
  7struct dr_definer_object {
  8	u32 id;
  9	u16 format_id;
 10	u8 dw_selectors[MLX5_IFC_DEFINER_DW_SELECTORS_NUM];
 11	u8 byte_selectors[MLX5_IFC_DEFINER_BYTE_SELECTORS_NUM];
 12	u8 match_mask[DR_STE_SIZE_MATCH_TAG];
 13	refcount_t refcount;
 14};
 15
 16static bool dr_definer_compare(struct dr_definer_object *definer,
 17			       u16 format_id, u8 *dw_selectors,
 18			       u8 *byte_selectors, u8 *match_mask)
 19{
 20	int i;
 21
 22	if (definer->format_id != format_id)
 23		return false;
 24
 25	for (i = 0; i < MLX5_IFC_DEFINER_DW_SELECTORS_NUM; i++)
 26		if (definer->dw_selectors[i] != dw_selectors[i])
 27			return false;
 28
 29	for (i = 0; i < MLX5_IFC_DEFINER_BYTE_SELECTORS_NUM; i++)
 30		if (definer->byte_selectors[i] != byte_selectors[i])
 31			return false;
 32
 33	if (memcmp(definer->match_mask, match_mask, DR_STE_SIZE_MATCH_TAG))
 34		return false;
 35
 36	return true;
 37}
 38
 39static struct dr_definer_object *
 40dr_definer_find_obj(struct mlx5dr_domain *dmn, u16 format_id,
 41		    u8 *dw_selectors, u8 *byte_selectors, u8 *match_mask)
 42{
 43	struct dr_definer_object *definer_obj;
 44	unsigned long id;
 45
 46	xa_for_each(&dmn->definers_xa, id, definer_obj) {
 47		if (dr_definer_compare(definer_obj, format_id,
 48				       dw_selectors, byte_selectors,
 49				       match_mask))
 50			return definer_obj;
 51	}
 52
 53	return NULL;
 54}
 55
 56static struct dr_definer_object *
 57dr_definer_create_obj(struct mlx5dr_domain *dmn, u16 format_id,
 58		      u8 *dw_selectors, u8 *byte_selectors, u8 *match_mask)
 59{
 60	struct dr_definer_object *definer_obj;
 61	int ret = 0;
 62
 63	definer_obj = kzalloc(sizeof(*definer_obj), GFP_KERNEL);
 64	if (!definer_obj)
 65		return NULL;
 66
 67	ret = mlx5dr_cmd_create_definer(dmn->mdev,
 68					format_id,
 69					dw_selectors,
 70					byte_selectors,
 71					match_mask,
 72					&definer_obj->id);
 73	if (ret)
 74		goto err_free_definer_obj;
 75
 76	/* Definer ID can have 32 bits, but STE format
 77	 * supports only definers with 8 bit IDs.
 78	 */
 79	if (definer_obj->id > 0xff) {
 80		mlx5dr_err(dmn, "Unsupported definer ID (%d)\n", definer_obj->id);
 81		goto err_destroy_definer;
 82	}
 83
 84	definer_obj->format_id = format_id;
 85	memcpy(definer_obj->dw_selectors, dw_selectors, sizeof(definer_obj->dw_selectors));
 86	memcpy(definer_obj->byte_selectors, byte_selectors, sizeof(definer_obj->byte_selectors));
 87	memcpy(definer_obj->match_mask, match_mask, sizeof(definer_obj->match_mask));
 88
 89	refcount_set(&definer_obj->refcount, 1);
 90
 91	ret = xa_insert(&dmn->definers_xa, definer_obj->id, definer_obj, GFP_KERNEL);
 92	if (ret) {
 93		mlx5dr_dbg(dmn, "Couldn't insert new definer into xarray (%d)\n", ret);
 94		goto err_destroy_definer;
 95	}
 96
 97	return definer_obj;
 98
 99err_destroy_definer:
100	mlx5dr_cmd_destroy_definer(dmn->mdev, definer_obj->id);
101err_free_definer_obj:
102	kfree(definer_obj);
103
104	return NULL;
105}
106
107static void dr_definer_destroy_obj(struct mlx5dr_domain *dmn,
108				   struct dr_definer_object *definer_obj)
109{
110	mlx5dr_cmd_destroy_definer(dmn->mdev, definer_obj->id);
111	xa_erase(&dmn->definers_xa, definer_obj->id);
112	kfree(definer_obj);
113}
114
115int mlx5dr_definer_get(struct mlx5dr_domain *dmn, u16 format_id,
116		       u8 *dw_selectors, u8 *byte_selectors,
117		       u8 *match_mask, u32 *definer_id)
118{
119	struct dr_definer_object *definer_obj;
120	int ret = 0;
121
122	definer_obj = dr_definer_find_obj(dmn, format_id, dw_selectors,
123					  byte_selectors, match_mask);
124	if (!definer_obj) {
125		definer_obj = dr_definer_create_obj(dmn, format_id,
126						    dw_selectors, byte_selectors,
127						    match_mask);
128		if (!definer_obj)
129			return -ENOMEM;
130	} else {
131		refcount_inc(&definer_obj->refcount);
132	}
133
134	*definer_id = definer_obj->id;
135
136	return ret;
137}
138
139void mlx5dr_definer_put(struct mlx5dr_domain *dmn, u32 definer_id)
140{
141	struct dr_definer_object *definer_obj;
142
143	definer_obj = xa_load(&dmn->definers_xa, definer_id);
144	if (!definer_obj) {
145		mlx5dr_err(dmn, "Definer ID %d not found\n", definer_id);
146		return;
147	}
148
149	if (refcount_dec_and_test(&definer_obj->refcount))
150		dr_definer_destroy_obj(dmn, definer_obj);
151}
~/ Read-only file preview.