net/bnxt: update table get to use new design
[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         uint8_t db_exists = 0;
198
199         TF_CHECK_PARMS2(tfp, parms);
200
201         if (init) {
202                 TFP_DRV_LOG(ERR,
203                             "EM Ext DB already initialized\n");
204                 return -EINVAL;
205         }
206
207         db_cfg.type = TF_DEVICE_MODULE_TYPE_EM;
208         db_cfg.num_elements = parms->num_elements;
209         db_cfg.cfg = parms->cfg;
210
211         for (i = 0; i < TF_DIR_MAX; i++) {
212                 db_cfg.dir = i;
213                 db_cfg.alloc_cnt = parms->resources->em_cnt[i].cnt;
214
215                 /* Check if we got any request to support EEM, if so
216                  * we build an EM Ext DB holding Table Scopes.
217                  */
218                 if (db_cfg.alloc_cnt[TF_EM_TBL_TYPE_TBL_SCOPE] == 0)
219                         continue;
220
221                 db_cfg.rm_db = &eem_db[i];
222                 rc = tf_rm_create_db(tfp, &db_cfg);
223                 if (rc) {
224                         TFP_DRV_LOG(ERR,
225                                     "%s: EM Ext DB creation failed\n",
226                                     tf_dir_2_str(i));
227
228                         return rc;
229                 }
230                 db_exists = 1;
231         }
232
233         if (db_exists) {
234                 mem_type = parms->mem_type;
235                 init = 1;
236         }
237
238         return 0;
239 }
240
241 int
242 tf_em_ext_common_unbind(struct tf *tfp)
243 {
244         int rc;
245         int i;
246         struct tf_rm_free_db_parms fparms = { 0 };
247
248         TF_CHECK_PARMS1(tfp);
249
250         /* Bail if nothing has been initialized */
251         if (!init) {
252                 TFP_DRV_LOG(INFO,
253                             "No EM Ext DBs created\n");
254                 return 0;
255         }
256
257         for (i = 0; i < TF_DIR_MAX; i++) {
258                 fparms.dir = i;
259                 fparms.rm_db = eem_db[i];
260                 rc = tf_rm_free_db(tfp, &fparms);
261                 if (rc)
262                         return rc;
263
264                 eem_db[i] = NULL;
265         }
266
267         init = 0;
268
269         return 0;
270 }
271
272 int
273 tf_em_ext_common_alloc(struct tf *tfp,
274                        struct tf_alloc_tbl_scope_parms *parms)
275 {
276         if (mem_type == TF_EEM_MEM_TYPE_HOST)
277                 return tf_em_ext_host_alloc(tfp, parms);
278         else
279                 return tf_em_ext_system_alloc(tfp, parms);
280 }
281
282 int
283 tf_em_ext_common_free(struct tf *tfp,
284                       struct tf_free_tbl_scope_parms *parms)
285 {
286         if (mem_type == TF_EEM_MEM_TYPE_HOST)
287                 return tf_em_ext_host_free(tfp, parms);
288         else
289                 return tf_em_ext_system_free(tfp, parms);
290 }