FILE
dr_definer.c
File preview with syntax highlighting.
linux-6.19.14/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_definer.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.