1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2021 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
tf_em_hash_insert_int_entry(struct tf * tfp,struct tf_insert_em_entry_parms * parms)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(ERR,
66 			    "%s, EM entry index allocation failed\n",
67 			    tf_dir_2_str(parms->dir));
68 		return -1;
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 -1;
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 	return 0;
112 }
113 
114 /** Delete EM internal entry API
115  *
116  * returns:
117  * 0
118  * -EINVAL
119  */
120 int
tf_em_hash_delete_int_entry(struct tf * tfp,struct tf_delete_em_entry_parms * parms)121 tf_em_hash_delete_int_entry(struct tf *tfp,
122 			    struct tf_delete_em_entry_parms *parms)
123 {
124 	int rc = 0;
125 	struct tf_session *tfs;
126 	struct dpool *pool;
127 	/* Retrieve the session information */
128 	rc = tf_session_get_session(tfp, &tfs);
129 	if (rc) {
130 		TFP_DRV_LOG(ERR,
131 			    "%s: Failed to lookup session, rc:%s\n",
132 			    tf_dir_2_str(parms->dir),
133 			    strerror(-rc));
134 		return rc;
135 	}
136 
137 	rc = tf_msg_delete_em_entry(tfp, parms);
138 
139 	/* Return resource to pool */
140 	if (rc == 0) {
141 		pool = (struct dpool *)tfs->em_pool[parms->dir];
142 		dpool_free(pool, parms->index);
143 	}
144 
145 	return rc;
146 }
147 
148 /** Move EM internal entry API
149  *
150  * returns:
151  * 0
152  * -EINVAL
153  */
154 int
tf_em_move_int_entry(struct tf * tfp,struct tf_move_em_entry_parms * parms)155 tf_em_move_int_entry(struct tf *tfp,
156 		     struct tf_move_em_entry_parms *parms)
157 {
158 	int rc = 0;
159 	struct dpool *pool;
160 	struct tf_session *tfs;
161 
162 	/* Retrieve the session information */
163 	rc = tf_session_get_session(tfp, &tfs);
164 	if (rc) {
165 		TFP_DRV_LOG(ERR,
166 			    "%s: Failed to lookup session, rc:%s\n",
167 			    tf_dir_2_str(parms->dir),
168 			    strerror(-rc));
169 		return rc;
170 	}
171 
172 	rc = tf_msg_move_em_entry(tfp, parms);
173 
174 	/* Return resource to pool */
175 	if (rc == 0) {
176 		pool = (struct dpool *)tfs->em_pool[parms->dir];
177 		dpool_free(pool, parms->index);
178 	}
179 
180 	return rc;
181 }
182