Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2021-2023 Broadcom
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include <errno.h>
7 : :
8 : : #include "tfp.h"
9 : : #include "tf_tcam.h"
10 : : #include "cfa_tcam_mgr.h"
11 : : #include "tf_tcam_mgr_msg.h"
12 : :
13 : : /*
14 : : * Table to convert TCAM type to logical TCAM type for applications.
15 : : * Index is tf_tcam_tbl_type.
16 : : */
17 : : static enum cfa_tcam_mgr_tbl_type tcam_types[TF_TCAM_TBL_TYPE_MAX] = {
18 : : [TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_HIGH] =
19 : : CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_HIGH_APPS,
20 : : [TF_TCAM_TBL_TYPE_L2_CTXT_TCAM_LOW] =
21 : : CFA_TCAM_MGR_TBL_TYPE_L2_CTXT_TCAM_LOW_APPS,
22 : : [TF_TCAM_TBL_TYPE_PROF_TCAM] =
23 : : CFA_TCAM_MGR_TBL_TYPE_PROF_TCAM_APPS,
24 : : [TF_TCAM_TBL_TYPE_WC_TCAM] =
25 : : CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_APPS,
26 : : [TF_TCAM_TBL_TYPE_SP_TCAM] =
27 : : CFA_TCAM_MGR_TBL_TYPE_SP_TCAM_APPS,
28 : : [TF_TCAM_TBL_TYPE_CT_RULE_TCAM] =
29 : : CFA_TCAM_MGR_TBL_TYPE_CT_RULE_TCAM_APPS,
30 : : [TF_TCAM_TBL_TYPE_VEB_TCAM] =
31 : : CFA_TCAM_MGR_TBL_TYPE_VEB_TCAM_APPS,
32 : : [TF_TCAM_TBL_TYPE_WC_TCAM_HIGH] =
33 : : CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_HIGH_APPS,
34 : : [TF_TCAM_TBL_TYPE_WC_TCAM_LOW] =
35 : : CFA_TCAM_MGR_TBL_TYPE_WC_TCAM_LOW_APPS,
36 : : };
37 : :
38 : : static uint16_t hcapi_type[TF_TCAM_TBL_TYPE_MAX];
39 : :
40 : : /*
41 : : * This is the glue between the core tf_tcam and the TCAM manager. It is
42 : : * intended to abstract out the location of the TCAM manager so that the core
43 : : * code will be the same if the TCAM manager is in the core or in firmware.
44 : : *
45 : : * If the TCAM manager is in the core, then this file will just translate to
46 : : * TCAM manager APIs. If TCAM manager is in firmware, then this file will cause
47 : : * messages to be sent (except for bind and unbind).
48 : : */
49 : :
50 : : int
51 : 0 : tf_tcam_mgr_qcaps_msg(struct tf *tfp,
52 : : struct tf_dev_info *dev __rte_unused,
53 : : uint32_t *rx_tcam_supported,
54 : : uint32_t *tx_tcam_supported)
55 : : {
56 : : struct cfa_tcam_mgr_context context;
57 : : struct cfa_tcam_mgr_qcaps_parms mgr_parms;
58 : : int rc;
59 : :
60 : 0 : context.tfp = tfp;
61 : : memset(&mgr_parms, 0, sizeof(mgr_parms));
62 : 0 : rc = cfa_tcam_mgr_qcaps(&context, &mgr_parms);
63 [ # # ]: 0 : if (rc >= 0) {
64 : 0 : *rx_tcam_supported = mgr_parms.rx_tcam_supported;
65 : 0 : *tx_tcam_supported = mgr_parms.tx_tcam_supported;
66 : : }
67 : 0 : return rc;
68 : : }
69 : :
70 : : int
71 : 0 : tf_tcam_mgr_bind_msg(struct tf *tfp,
72 : : struct tf_dev_info *dev __rte_unused,
73 : : struct tf_tcam_cfg_parms *parms,
74 : : struct tf_resource_info resv_res[][TF_TCAM_TBL_TYPE_MAX]
75 : : __rte_unused
76 : : )
77 : : {
78 : : /* Common Code */
79 : : int type;
80 : :
81 [ # # ]: 0 : if (parms->num_elements != TF_TCAM_TBL_TYPE_MAX) {
82 : 0 : TFP_DRV_LOG(ERR,
83 : : "Invalid number of elements in bind request.\n");
84 : 0 : TFP_DRV_LOG(ERR,
85 : : "Expected %d, received %d.\n",
86 : : TF_TCAM_TBL_TYPE_MAX,
87 : : parms->num_elements);
88 : 0 : return -EINVAL;
89 : : }
90 : :
91 [ # # ]: 0 : for (type = 0; type < TF_TCAM_TBL_TYPE_MAX; type++)
92 : 0 : hcapi_type[type] = parms->cfg[type].hcapi_type;
93 : :
94 : : struct cfa_tcam_mgr_context context;
95 : : struct cfa_tcam_mgr_cfg_parms mgr_parms;
96 : : struct tf_rm_resc_entry
97 : : mgr_resv_res[TF_DIR_MAX][CFA_TCAM_MGR_TBL_TYPE_MAX];
98 : : int dir, rc;
99 : :
100 : 0 : context.tfp = tfp;
101 : :
102 : : memset(&mgr_parms, 0, sizeof(mgr_parms));
103 : :
104 : 0 : mgr_parms.num_elements = CFA_TCAM_MGR_TBL_TYPE_MAX;
105 : :
106 : : /* Convert the data to logical tables */
107 [ # # ]: 0 : for (dir = 0; dir < TF_DIR_MAX; dir++) {
108 [ # # ]: 0 : for (type = 0; type < TF_TCAM_TBL_TYPE_MAX; type++) {
109 : 0 : mgr_parms.tcam_cnt[dir][tcam_types[type]] =
110 : 0 : parms->resources->tcam_cnt[dir].cnt[type];
111 : 0 : mgr_resv_res[dir][tcam_types[type]].start =
112 : 0 : resv_res[dir][type].start;
113 : 0 : mgr_resv_res[dir][tcam_types[type]].stride =
114 : 0 : resv_res[dir][type].stride;
115 : : }
116 : : }
117 : 0 : mgr_parms.resv_res = mgr_resv_res;
118 : :
119 : 0 : rc = cfa_tcam_mgr_bind(&context, &mgr_parms);
120 : :
121 : 0 : return rc;
122 : : }
123 : :
124 : : int
125 : 0 : tf_tcam_mgr_unbind_msg(struct tf *tfp,
126 : : struct tf_dev_info *dev __rte_unused)
127 : : {
128 : : struct cfa_tcam_mgr_context context;
129 : :
130 : 0 : context.tfp = tfp;
131 : :
132 : 0 : return cfa_tcam_mgr_unbind(&context);
133 : : }
134 : :
135 : : int
136 : 0 : tf_tcam_mgr_alloc_msg(struct tf *tfp,
137 : : struct tf_dev_info *dev __rte_unused,
138 : : struct tf_tcam_alloc_parms *parms)
139 : : {
140 : : struct cfa_tcam_mgr_context context;
141 : : struct cfa_tcam_mgr_alloc_parms mgr_parms;
142 : : int rc;
143 : :
144 [ # # ]: 0 : if (parms->type >= TF_TCAM_TBL_TYPE_MAX) {
145 : 0 : TFP_DRV_LOG(ERR,
146 : : "No such TCAM table %d.\n",
147 : : parms->type);
148 : 0 : return -EINVAL;
149 : : }
150 : :
151 : 0 : context.tfp = tfp;
152 : :
153 : 0 : mgr_parms.dir = parms->dir;
154 : 0 : mgr_parms.type = tcam_types[parms->type];
155 : 0 : mgr_parms.hcapi_type = hcapi_type[parms->type];
156 : 0 : mgr_parms.key_size = parms->key_size;
157 [ # # ]: 0 : if (parms->priority > TF_TCAM_PRIORITY_MAX)
158 : 0 : mgr_parms.priority = 0;
159 : : else
160 : 0 : mgr_parms.priority = TF_TCAM_PRIORITY_MAX - parms->priority - 1;
161 : :
162 : 0 : rc = cfa_tcam_mgr_alloc(&context, &mgr_parms);
163 [ # # ]: 0 : if (rc)
164 : : return rc;
165 : :
166 : 0 : parms->idx = mgr_parms.id;
167 : 0 : return 0;
168 : : }
169 : :
170 : : int
171 : 0 : tf_tcam_mgr_free_msg(struct tf *tfp,
172 : : struct tf_dev_info *dev __rte_unused,
173 : : struct tf_tcam_free_parms *parms)
174 : : {
175 : : struct cfa_tcam_mgr_context context;
176 : : struct cfa_tcam_mgr_free_parms mgr_parms;
177 : :
178 [ # # ]: 0 : if (parms->type >= TF_TCAM_TBL_TYPE_MAX) {
179 : 0 : TFP_DRV_LOG(ERR,
180 : : "No such TCAM table %d.\n",
181 : : parms->type);
182 : 0 : return -EINVAL;
183 : : }
184 : :
185 : 0 : context.tfp = tfp;
186 : 0 : mgr_parms.dir = parms->dir;
187 : 0 : mgr_parms.type = tcam_types[parms->type];
188 : 0 : mgr_parms.hcapi_type = hcapi_type[parms->type];
189 : 0 : mgr_parms.id = parms->idx;
190 : :
191 : 0 : return cfa_tcam_mgr_free(&context, &mgr_parms);
192 : : }
193 : :
194 : : int
195 : 0 : tf_tcam_mgr_set_msg(struct tf *tfp,
196 : : struct tf_dev_info *dev __rte_unused,
197 : : struct tf_tcam_set_parms *parms)
198 : : {
199 : : struct cfa_tcam_mgr_context context;
200 : : struct cfa_tcam_mgr_set_parms mgr_parms;
201 : :
202 [ # # ]: 0 : if (parms->type >= TF_TCAM_TBL_TYPE_MAX) {
203 : 0 : TFP_DRV_LOG(ERR,
204 : : "No such TCAM table %d.\n",
205 : : parms->type);
206 : 0 : return -EINVAL;
207 : : }
208 : :
209 : 0 : context.tfp = tfp;
210 : 0 : mgr_parms.dir = parms->dir;
211 : 0 : mgr_parms.type = tcam_types[parms->type];
212 : 0 : mgr_parms.hcapi_type = hcapi_type[parms->type];
213 : 0 : mgr_parms.id = parms->idx;
214 : 0 : mgr_parms.key = parms->key;
215 : 0 : mgr_parms.mask = parms->mask;
216 : 0 : mgr_parms.key_size = parms->key_size;
217 : 0 : mgr_parms.result = parms->result;
218 : 0 : mgr_parms.result_size = parms->result_size;
219 : :
220 : 0 : return cfa_tcam_mgr_set(&context, &mgr_parms);
221 : : }
222 : :
223 : : int
224 : 0 : tf_tcam_mgr_get_msg(struct tf *tfp,
225 : : struct tf_dev_info *dev __rte_unused,
226 : : struct tf_tcam_get_parms *parms)
227 : : {
228 : : int rc;
229 : : struct cfa_tcam_mgr_context context;
230 : : struct cfa_tcam_mgr_get_parms mgr_parms;
231 : :
232 [ # # ]: 0 : if (parms->type >= TF_TCAM_TBL_TYPE_MAX) {
233 : 0 : TFP_DRV_LOG(ERR,
234 : : "No such TCAM table %d.\n",
235 : : parms->type);
236 : 0 : return -EINVAL;
237 : : }
238 : :
239 : 0 : context.tfp = tfp;
240 : 0 : mgr_parms.dir = parms->dir;
241 : 0 : mgr_parms.type = tcam_types[parms->type];
242 : 0 : mgr_parms.hcapi_type = hcapi_type[parms->type];
243 : 0 : mgr_parms.id = parms->idx;
244 : 0 : mgr_parms.key = parms->key;
245 : 0 : mgr_parms.mask = parms->mask;
246 : 0 : mgr_parms.key_size = parms->key_size;
247 : 0 : mgr_parms.result = parms->result;
248 : 0 : mgr_parms.result_size = parms->result_size;
249 : :
250 : 0 : rc = cfa_tcam_mgr_get(&context, &mgr_parms);
251 [ # # ]: 0 : if (rc)
252 : : return rc;
253 : :
254 : 0 : parms->key_size = mgr_parms.key_size;
255 : 0 : parms->result_size = mgr_parms.result_size;
256 : :
257 : 0 : return rc;
258 : : }
259 : :
260 : : int
261 : 0 : tf_tcam_mgr_shared_clear_msg(struct tf *tfp,
262 : : struct tf_clear_tcam_shared_entries_parms *parms)
263 : : {
264 : : struct cfa_tcam_mgr_context context;
265 : : struct cfa_tcam_mgr_shared_clear_parms mgr_parms;
266 : :
267 : 0 : context.tfp = tfp;
268 : 0 : mgr_parms.dir = parms->dir;
269 : 0 : mgr_parms.type = tcam_types[parms->tcam_tbl_type];
270 : :
271 : 0 : return cfa_tcam_mgr_shared_clear(&context, &mgr_parms);
272 : : }
273 : :
274 : : int
275 : 0 : tf_tcam_mgr_shared_move_msg(struct tf *tfp,
276 : : struct tf_move_tcam_shared_entries_parms *parms)
277 : : {
278 : : struct cfa_tcam_mgr_context context;
279 : : struct cfa_tcam_mgr_shared_move_parms mgr_parms;
280 : :
281 : 0 : context.tfp = tfp;
282 : 0 : mgr_parms.dir = parms->dir;
283 : 0 : mgr_parms.type = tcam_types[parms->tcam_tbl_type];
284 : :
285 : 0 : return cfa_tcam_mgr_shared_move(&context, &mgr_parms);
286 : : }
|