xref: /dpdk/drivers/net/bnxt/tf_core/tf_em_hash_internal.c (revision 580fcb3d718069a8058f4395dd64d19fed0c1f65)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2024 Broadcom
3  * All rights reserved.
4  */
5 
6 #include <string.h>
7 #include <rte_common.h>
8 #include <rte_errno.h>
9 #include <rte_log.h>
10 
11 #include "tf_core.h"
12 #include "tf_util.h"
13 #include "tf_common.h"
14 #include "tf_em.h"
15 #include "tf_msg.h"
16 #include "tfp.h"
17 #include "tf_ext_flow_handle.h"
18 #include "tf_device.h"
19 
20 #include "bnxt.h"
21 
22 /**
23  * EM Pool
24  */
25 #include "dpool.h"
26 
27 /**
28  * Insert EM internal entry API
29  *
30  *  returns:
31  *     0 - Success
32  */
33 int
34 tf_em_hash_insert_int_entry(struct tf *tfp,
35 			    struct tf_insert_em_entry_parms *parms)
36 {
37 	int rc;
38 	uint32_t gfid;
39 	uint16_t rptr_index = 0;
40 	uint8_t rptr_entry = 0;
41 	uint8_t num_of_entries = 0;
42 	struct dpool *pool;
43 	uint32_t index;
44 	uint32_t key0_hash;
45 	uint32_t key1_hash;
46 	uint64_t big_hash;
47 	struct tf_dev_info *dev;
48 	struct tf_session *tfs;
49 
50 	/* Retrieve the session information */
51 	rc = tf_session_get_session_internal(tfp, &tfs);
52 	if (rc)
53 		return rc;
54 
55 	/* Retrieve the device information */
56 	rc = tf_session_get_device(tfs, &dev);
57 	if (rc)
58 		return rc;
59 	pool = (struct dpool *)tfs->em_pool[parms->dir];
60 	index = dpool_alloc(pool,
61 			    parms->em_record_sz_in_bits / 128,
62 			    DP_DEFRAG_TO_FIT);
63 
64 	if (index == DP_INVALID_INDEX) {
65 		PMD_DRV_LOG_LINE(ERR,
66 			    "%s, EM entry index allocation failed",
67 			    tf_dir_2_str(parms->dir));
68 		return -ENOMEM; /* no more space to add entries */
69 	}
70 
71 	if (dev->ops->tf_dev_cfa_key_hash == NULL)
72 		return -EINVAL;
73 
74 	big_hash = dev->ops->tf_dev_cfa_key_hash((uint64_t *)parms->key,
75 					TF_P58_HW_EM_KEY_MAX_SIZE * 8);
76 	key0_hash = (uint32_t)(big_hash >> 32);
77 	key1_hash = (uint32_t)(big_hash & 0xFFFFFFFF);
78 
79 	rptr_index = index;
80 	rc = tf_msg_hash_insert_em_internal_entry(tfp,
81 						  parms,
82 						  key0_hash,
83 						  key1_hash,
84 						  &rptr_index,
85 						  &rptr_entry,
86 						  &num_of_entries);
87 	if (rc) {
88 		/* Free the allocated index before returning */
89 		dpool_free(pool, index);
90 		return rc;
91 	}
92 
93 	TF_SET_GFID(gfid,
94 		    ((rptr_index << TF_EM_INTERNAL_INDEX_SHIFT) |
95 		     rptr_entry),
96 		    0); /* N/A for internal table */
97 
98 	TF_SET_FLOW_ID(parms->flow_id,
99 		       gfid,
100 		       TF_GFID_TABLE_INTERNAL,
101 		       parms->dir);
102 
103 	TF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle,
104 				     (uint32_t)num_of_entries,
105 				     0,
106 				     TF_FLAGS_FLOW_HANDLE_INTERNAL,
107 				     rptr_index,
108 				     rptr_entry,
109 				     0);
110 	dpool_set_entry_data(pool, index, parms->flow_handle);
111 
112 #ifdef TF_FLOW_SCALE_QUERY
113 	/* Update usage state buffer for EM */
114 	tf_em_usage_update(tfp,
115 			   parms->dir,
116 			   num_of_entries,
117 			   TF_RESC_ALLOC);
118 #endif /* TF_FLOW_SCALE_QUERY */
119 
120 	return 0;
121 }
122 
123 /** Delete EM internal entry API
124  *
125  * returns:
126  * 0
127  * -EINVAL
128  */
129 int
130 tf_em_hash_delete_int_entry(struct tf *tfp,
131 			    struct tf_delete_em_entry_parms *parms)
132 {
133 	int rc = 0;
134 	struct tf_session *tfs;
135 	struct dpool *pool;
136 #ifdef TF_FLOW_SCALE_QUERY
137 	uint32_t size;
138 #endif /* TF_FLOW_SCALE_QUERY */
139 
140 	/* Retrieve the session information */
141 	rc = tf_session_get_session(tfp, &tfs);
142 	if (rc) {
143 		TFP_DRV_LOG(ERR,
144 			    "%s: Failed to lookup session, rc:%s\n",
145 			    tf_dir_2_str(parms->dir),
146 			    strerror(-rc));
147 		return rc;
148 	}
149 
150 	rc = tf_msg_delete_em_entry(tfp, parms);
151 
152 	/* Return resource to pool */
153 	pool = (struct dpool *)tfs->em_pool[parms->dir];
154 
155 #ifdef TF_FLOW_SCALE_QUERY
156 	/* Update usage state buffer for EM */
157 	size = DP_FLAGS_SIZE(pool->entry[parms->index - pool->start_index].flags);
158 	tf_em_usage_update(tfp,
159 			   parms->dir,
160 			   size,
161 			   TF_RESC_FREE);
162 #endif /* TF_FLOW_SCALE_QUERY */
163 
164 	dpool_free(pool, parms->index);
165 	return rc;
166 }
167 
168 /** Move EM internal entry API
169  *
170  * returns:
171  * 0
172  * -EINVAL
173  */
174 int
175 tf_em_move_int_entry(struct tf *tfp,
176 		     struct tf_move_em_entry_parms *parms)
177 {
178 	int rc = 0;
179 	struct dpool *pool;
180 	struct tf_session *tfs;
181 
182 	/* Retrieve the session information */
183 	rc = tf_session_get_session(tfp, &tfs);
184 	if (rc) {
185 		TFP_DRV_LOG(ERR,
186 			    "%s: Failed to lookup session, rc:%s\n",
187 			    tf_dir_2_str(parms->dir),
188 			    strerror(-rc));
189 		return rc;
190 	}
191 
192 	rc = tf_msg_move_em_entry(tfp, parms);
193 
194 	/* Return resource to pool */
195 	if (rc == 0) {
196 		pool = (struct dpool *)tfs->em_pool[parms->dir];
197 		dpool_free(pool, parms->index);
198 	}
199 
200 	return rc;
201 }
202