ba6aa7ac1557333c22b63178d9c197f091a38881
[dpdk.git] / drivers / net / bnxt / tf_core / tf_em_common.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2020 Broadcom
3  * All rights reserved.
4  */
5
6 #include <string.h>
7 #include <math.h>
8 #include <sys/param.h>
9 #include <rte_common.h>
10 #include <rte_errno.h>
11 #include <rte_log.h>
12
13 #include "tf_core.h"
14 #include "tf_util.h"
15 #include "tf_common.h"
16 #include "tf_em.h"
17 #include "tf_em_common.h"
18 #include "tf_msg.h"
19 #include "tfp.h"
20 #include "tf_device.h"
21 #include "tf_ext_flow_handle.h"
22 #include "cfa_resource_types.h"
23
24 #include "bnxt.h"
25
26
27 /**
28  * EM DBs.
29  */
30 void *eem_db[TF_DIR_MAX];
31
32 /**
33  * Init flag, set on bind and cleared on unbind
34  */
35 static uint8_t init;
36
37 /**
38  * Host or system
39  */
40 static enum tf_mem_type mem_type;
41
42 /* API defined in tf_em.h */
43 struct tf_tbl_scope_cb *
44 tbl_scope_cb_find(struct tf_session *session,
45                   uint32_t tbl_scope_id)
46 {
47         int i;
48         struct tf_rm_is_allocated_parms parms;
49         int allocated;
50
51         /* Check that id is valid */
52         parms.rm_db = eem_db[TF_DIR_RX];
53         parms.db_index = 1/**** TYPE TABLE-SCOPE??? ****/;
54         parms.index = tbl_scope_id + TF_HACK_TBL_SCOPE_BASE;
55         parms.allocated = &allocated;
56
57         i = tf_rm_is_allocated(&parms);
58
59         if (i < 0 || !allocated)
60                 return NULL;
61
62         for (i = 0; i < TF_NUM_TBL_SCOPE; i++) {
63                 if (session->tbl_scopes[i].tbl_scope_id == tbl_scope_id)
64                         return &session->tbl_scopes[i];
65         }
66
67         return NULL;
68 }
69
70 int
71 tf_create_tbl_pool_external(enum tf_dir dir,
72                             struct tf_tbl_scope_cb *tbl_scope_cb,
73                             uint32_t num_entries,
74                             uint32_t entry_sz_bytes)
75 {
76         struct tfp_calloc_parms parms;
77         uint32_t i;
78         int32_t j;
79         int rc = 0;
80         struct stack *pool = &tbl_scope_cb->ext_act_pool[dir];
81
82         parms.nitems = num_entries;
83         parms.size = sizeof(uint32_t);
84         parms.alignment = 0;
85
86         if (tfp_calloc(&parms) != 0) {
87                 TFP_DRV_LOG(ERR, "%s: TBL: external pool failure %s\n",
88                             tf_dir_2_str(dir), strerror(ENOMEM));
89                 return -ENOMEM;
90         }
91
92         /* Create empty stack
93          */
94         rc = stack_init(num_entries, parms.mem_va, pool);
95
96         if (rc != 0) {
97                 TFP_DRV_LOG(ERR, "%s: TBL: stack init failure %s\n",
98                             tf_dir_2_str(dir), strerror(-rc));
99                 goto cleanup;
100         }
101
102         /* Save the  malloced memory address so that it can
103          * be freed when the table scope is freed.
104          */
105         tbl_scope_cb->ext_act_pool_mem[dir] = (uint32_t *)parms.mem_va;
106
107         /* Fill pool with indexes in reverse
108          */
109         j = (num_entries - 1) * entry_sz_bytes;
110
111         for (i = 0; i < num_entries; i++) {
112                 rc = stack_push(pool, j);
113                 if (rc != 0) {
114                         TFP_DRV_LOG(ERR, "%s TBL: stack failure %s\n",
115                                     tf_dir_2_str(dir), strerror(-rc));
116                         goto cleanup;
117                 }
118
119                 if (j < 0) {
120                         TFP_DRV_LOG(ERR, "%d TBL: invalid offset (%d)\n",
121                                     dir, j);
122                         goto cleanup;
123                 }
124                 j -= entry_sz_bytes;
125         }
126
127         if (!stack_is_full(pool)) {
128                 rc = -EINVAL;
129                 TFP_DRV_LOG(ERR, "%s TBL: stack failure %s\n",
130                             tf_dir_2_str(dir), strerror(-rc));
131                 goto cleanup;
132         }
133         return 0;
134 cleanup:
135         tfp_free((void *)parms.mem_va);
136         return rc;
137 }
138
139 /**
140  * Destroy External Tbl pool of memory indexes.
141  *
142  * [in] dir
143  *   direction
144  * [in] tbl_scope_cb
145  *   pointer to the table scope
146  */
147 void
148 tf_destroy_tbl_pool_external(enum tf_dir dir,
149                              struct tf_tbl_scope_cb *tbl_scope_cb)
150 {
151         uint32_t *ext_act_pool_mem =
152                 tbl_scope_cb->ext_act_pool_mem[dir];
153
154         tfp_free(ext_act_pool_mem);
155 }
156
157 uint32_t
158 tf_em_get_key_mask(int num_entries)
159 {
160         uint32_t mask = num_entries - 1;
161
162         if (num_entries & TF_EM_MAX_MASK)
163                 return 0;
164
165         if (num_entries > TF_EM_MAX_ENTRY)
166                 return 0;
167
168         return mask;
169 }
170
171 void
172 tf_em_create_key_entry(struct cfa_p4_eem_entry_hdr *result,
173                        uint8_t *in_key,
174                        struct cfa_p4_eem_64b_entry *key_entry)
175 {
176         key_entry->hdr.word1 = result->word1;
177
178         if (result->word1 & CFA_P4_EEM_ENTRY_ACT_REC_INT_MASK)
179                 key_entry->hdr.pointer = result->pointer;
180         else
181                 key_entry->hdr.pointer = result->pointer;
182
183         memcpy(key_entry->key, in_key, TF_HW_EM_KEY_MAX_SIZE + 4);
184
185 #ifdef TF_EEM_DEBUG
186         dump_raw((uint8_t *)key_entry, TF_EM_KEY_RECORD_SIZE, "Create raw:");
187 #endif
188 }
189
190 int
191 tf_em_ext_common_bind(struct tf *tfp,
192                       struct tf_em_cfg_parms *parms)
193 {
194         int rc;
195         int i;
196         struct tf_rm_create_db_parms db_cfg = { 0 };
197
198         TF_CHECK_PARMS2(tfp, parms);
199
200         if (init) {
201                 TFP_DRV_LOG(ERR,
202                             "Identifier already initialized\n");
203                 return -EINVAL;
204         }
205
206         db_cfg.type = TF_DEVICE_MODULE_TYPE_EM;
207         db_cfg.num_elements = parms->num_elements;
208         db_cfg.cfg = parms->cfg;
209
210         for (i = 0; i < TF_DIR_MAX; i++) {
211                 db_cfg.dir = i;
212                 db_cfg.alloc_cnt = parms->resources->em_cnt[i].cnt;
213                 db_cfg.rm_db = &eem_db[i];
214                 rc = tf_rm_create_db(tfp, &db_cfg);
215                 if (rc) {
216                         TFP_DRV_LOG(ERR,
217                                     "%s: EM DB creation failed\n",
218                                     tf_dir_2_str(i));
219
220                         return rc;
221                 }
222         }
223
224         mem_type = parms->mem_type;
225         init = 1;
226
227         return 0;
228 }
229
230 int
231 tf_em_ext_common_unbind(struct tf *tfp)
232 {
233         int rc;
234         int i;
235         struct tf_rm_free_db_parms fparms = { 0 };
236
237         TF_CHECK_PARMS1(tfp);
238
239         /* Bail if nothing has been initialized done silent as to
240          * allow for creation cleanup.
241          */
242         if (!init) {
243                 TFP_DRV_LOG(ERR,
244                             "No EM DBs created\n");
245                 return -EINVAL;
246         }
247
248         for (i = 0; i < TF_DIR_MAX; i++) {
249                 fparms.dir = i;
250                 fparms.rm_db = eem_db[i];
251                 rc = tf_rm_free_db(tfp, &fparms);
252                 if (rc)
253                         return rc;
254
255                 eem_db[i] = NULL;
256         }
257
258         init = 0;
259
260         return 0;
261 }
262
263 int
264 tf_em_ext_common_alloc(struct tf *tfp,
265                        struct tf_alloc_tbl_scope_parms *parms)
266 {
267         if (mem_type == TF_EEM_MEM_TYPE_HOST)
268                 return tf_em_ext_host_alloc(tfp, parms);
269         else
270                 return tf_em_ext_system_alloc(tfp, parms);
271 }
272
273 int
274 tf_em_ext_common_free(struct tf *tfp,
275                       struct tf_free_tbl_scope_parms *parms)
276 {
277         if (mem_type == TF_EEM_MEM_TYPE_HOST)
278                 return tf_em_ext_host_free(tfp, parms);
279         else
280                 return tf_em_ext_system_free(tfp, parms);
281 }