1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019-2020 Broadcom
7 #include <rte_common.h>
16 #include "tf_ext_flow_handle.h"
21 static uint32_t tf_em_get_key_mask(int num_entries)
23 uint32_t mask = num_entries - 1;
25 if (num_entries & 0x7FFF)
28 if (num_entries > (128 * 1024 * 1024))
34 static void tf_em_create_key_entry(struct cfa_p4_eem_entry_hdr *result,
36 struct cfa_p4_eem_64b_entry *key_entry)
38 key_entry->hdr.word1 = result->word1;
40 if (result->word1 & CFA_P4_EEM_ENTRY_ACT_REC_INT_MASK)
41 key_entry->hdr.pointer = result->pointer;
43 key_entry->hdr.pointer = result->pointer;
45 memcpy(key_entry->key, in_key, TF_HW_EM_KEY_MAX_SIZE + 4);
48 dump_raw((uint8_t *)key_entry, TF_EM_KEY_RECORD_SIZE, "Create raw:");
52 /** insert EEM entry API
56 * TF_ERR - unable to get lock
58 * insert callback returns:
60 * TF_ERR_EM_DUP - key is already in table
62 static int tf_insert_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb,
63 struct tf_insert_em_entry_parms *parms)
70 struct cfa_p4_eem_64b_entry key_entry;
72 enum hcapi_cfa_em_table_type table_type;
74 struct hcapi_cfa_hwop op;
75 struct hcapi_cfa_key_tbl key_tbl;
76 struct hcapi_cfa_key_data key_obj;
77 struct hcapi_cfa_key_loc key_loc;
81 /* Get mask to use on hash */
82 mask = tf_em_get_key_mask(tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY0_TABLE].num_entries);
88 dump_raw((uint8_t *)parms->key, TF_HW_EM_KEY_MAX_SIZE + 4, "In Key");
91 big_hash = hcapi_cfa_key_hash((uint64_t *)parms->key,
92 (TF_HW_EM_KEY_MAX_SIZE + 4) * 8);
93 key0_hash = (uint32_t)(big_hash >> 32);
94 key1_hash = (uint32_t)(big_hash & 0xFFFFFFFF);
96 key0_index = key0_hash & mask;
97 key1_index = key1_hash & mask;
100 TFP_DRV_LOG(DEBUG, "Key0 hash:0x%08x\n", key0_hash);
101 TFP_DRV_LOG(DEBUG, "Key1 hash:0x%08x\n", key1_hash);
104 * Use the "result" arg to populate all of the key entry then
105 * store the byte swapped "raw" entry in a local copy ready
106 * for insertion in to the table.
108 tf_em_create_key_entry((struct cfa_p4_eem_entry_hdr *)parms->em_record,
109 ((uint8_t *)parms->key),
113 * Try to add to Key0 table, if that does not work then
114 * try the key1 table.
117 op.opcode = HCAPI_CFA_HWOPS_ADD;
118 key_tbl.base0 = (uint8_t *)
119 &tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY0_TABLE];
120 key_obj.offset = (index * TF_EM_KEY_RECORD_SIZE) % TF_EM_PAGE_SIZE;
121 key_obj.data = (uint8_t *)&key_entry;
122 key_obj.size = TF_EM_KEY_RECORD_SIZE;
124 rc = hcapi_cfa_key_hw_op(&op,
130 table_type = TF_KEY0_TABLE;
134 key_tbl.base0 = (uint8_t *)
135 &tbl_scope_cb->em_ctx_info[parms->dir].em_tables[TF_KEY1_TABLE];
137 (index * TF_EM_KEY_RECORD_SIZE) % TF_EM_PAGE_SIZE;
139 rc = hcapi_cfa_key_hw_op(&op,
146 table_type = TF_KEY1_TABLE;
152 TF_SET_FLOW_ID(parms->flow_id,
154 TF_GFID_TABLE_EXTERNAL,
156 TF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle,
168 * Insert EM internal entry API
173 static int tf_insert_em_internal_entry(struct tf *tfp,
174 struct tf_insert_em_entry_parms *parms)
178 uint16_t rptr_index = 0;
179 uint8_t rptr_entry = 0;
180 uint8_t num_of_entries = 0;
181 struct tf_session *session =
182 (struct tf_session *)(tfp->session->core_data);
183 struct stack *pool = &session->em_pool[parms->dir];
186 rc = stack_pop(pool, &index);
190 "dir:%d, EM entry index allocation failed\n",
195 rptr_index = index * TF_SESSION_EM_ENTRY_SIZE;
196 rc = tf_msg_insert_em_internal_entry(tfp,
205 "Internal entry @ Index:%d rptr_index:0x%x rptr_entry:0x%x num_of_entries:%d\n",
206 index * TF_SESSION_EM_ENTRY_SIZE,
212 ((rptr_index << TF_EM_INTERNAL_INDEX_SHIFT) |
214 0); /* N/A for internal table */
216 TF_SET_FLOW_ID(parms->flow_id,
218 TF_GFID_TABLE_INTERNAL,
221 TF_SET_FIELDS_IN_FLOW_HANDLE(parms->flow_handle,
231 /** Delete EM internal entry API
237 static int tf_delete_em_internal_entry(struct tf *tfp,
238 struct tf_delete_em_entry_parms *parms)
241 struct tf_session *session =
242 (struct tf_session *)(tfp->session->core_data);
243 struct stack *pool = &session->em_pool[parms->dir];
245 rc = tf_msg_delete_em_entry(tfp, parms);
247 /* Return resource to pool */
249 stack_push(pool, parms->index / TF_SESSION_EM_ENTRY_SIZE);
255 /** delete EEM hash entry API
259 * -EINVAL - parameter error
260 * TF_NO_SESSION - bad session ID
261 * TF_ERR_TBL_SCOPE - invalid table scope
262 * TF_ERR_TBL_IF - invalid table interface
264 * insert callback returns
266 * TF_NO_EM_MATCH - entry not found
268 static int tf_delete_eem_entry(struct tf_tbl_scope_cb *tbl_scope_cb,
269 struct tf_delete_em_entry_parms *parms)
271 enum hcapi_cfa_em_table_type hash_type;
273 struct hcapi_cfa_hwop op;
274 struct hcapi_cfa_key_tbl key_tbl;
275 struct hcapi_cfa_key_data key_obj;
276 struct hcapi_cfa_key_loc key_loc;
279 if (parms->flow_handle == 0)
282 TF_GET_HASH_TYPE_FROM_FLOW_HANDLE(parms->flow_handle, hash_type);
283 TF_GET_INDEX_FROM_FLOW_HANDLE(parms->flow_handle, index);
285 op.opcode = HCAPI_CFA_HWOPS_DEL;
286 key_tbl.base0 = (uint8_t *)
287 &tbl_scope_cb->em_ctx_info[parms->dir].em_tables[(hash_type == 0 ?
290 key_obj.offset = (index * TF_EM_KEY_RECORD_SIZE) % TF_EM_PAGE_SIZE;
292 key_obj.size = TF_EM_KEY_RECORD_SIZE;
294 rc = hcapi_cfa_key_hw_op(&op,
305 /** insert EM hash entry API
311 int tf_em_insert_entry(struct tf *tfp,
312 struct tf_insert_em_entry_parms *parms)
314 struct tf_tbl_scope_cb *tbl_scope_cb;
316 tbl_scope_cb = tbl_scope_cb_find
317 ((struct tf_session *)(tfp->session->core_data),
318 parms->tbl_scope_id);
319 if (tbl_scope_cb == NULL) {
320 TFP_DRV_LOG(ERR, "Invalid tbl_scope_cb\n");
324 /* Process the EM entry per Table Scope type */
325 if (parms->mem == TF_MEM_EXTERNAL)
327 return tf_insert_eem_entry
328 (tbl_scope_cb, parms);
329 else if (parms->mem == TF_MEM_INTERNAL)
331 return tf_insert_em_internal_entry(tfp, parms);
336 /** Delete EM hash entry API
342 int tf_em_delete_entry(struct tf *tfp,
343 struct tf_delete_em_entry_parms *parms)
345 struct tf_tbl_scope_cb *tbl_scope_cb;
347 tbl_scope_cb = tbl_scope_cb_find
348 ((struct tf_session *)(tfp->session->core_data),
349 parms->tbl_scope_id);
350 if (tbl_scope_cb == NULL) {
351 TFP_DRV_LOG(ERR, "Invalid tbl_scope_cb\n");
354 if (parms->mem == TF_MEM_EXTERNAL)
355 return tf_delete_eem_entry(tbl_scope_cb, parms);
356 else if (parms->mem == TF_MEM_INTERNAL)
357 return tf_delete_em_internal_entry(tfp, parms);