net/bnxt: modify resource reservation strategy
[dpdk.git] / drivers / net / bnxt / tf_core / tf_identifier.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2021 Broadcom
3  * All rights reserved.
4  */
5
6 #include <rte_common.h>
7
8 #include "tf_identifier.h"
9 #include "tf_shadow_identifier.h"
10 #include "tf_common.h"
11 #include "tf_rm.h"
12 #include "tf_util.h"
13 #include "tfp.h"
14 #include "tf_session.h"
15
16 struct tf;
17
18 /**
19  * Identifier shadow DBs.
20  */
21 static void *ident_shadow_db[TF_DIR_MAX];
22
23 /**
24  * Shadow DB Init flag, set on bind and cleared on unbind
25  */
26 static uint8_t shadow_init;
27
28 int
29 tf_ident_bind(struct tf *tfp,
30               struct tf_ident_cfg_parms *parms)
31 {
32         int rc;
33         int db_rc[TF_DIR_MAX] = { 0 };
34         int i;
35         struct tf_rm_create_db_parms db_cfg = { 0 };
36         struct tf_shadow_ident_cfg_parms shadow_cfg = { 0 };
37         struct tf_shadow_ident_create_db_parms shadow_cdb = { 0 };
38         struct ident_rm_db *ident_db;
39         struct tfp_calloc_parms cparms;
40         struct tf_session *tfs;
41
42         TF_CHECK_PARMS2(tfp, parms);
43
44         /* Retrieve the session information */
45         rc = tf_session_get_session_internal(tfp, &tfs);
46         if (rc)
47                 return rc;
48
49         memset(&db_cfg, 0, sizeof(db_cfg));
50         cparms.nitems = 1;
51         cparms.size = sizeof(struct ident_rm_db);
52         cparms.alignment = 0;
53         if (tfp_calloc(&cparms) != 0) {
54                 TFP_DRV_LOG(ERR, "ident_rm_db alloc error %s\n",
55                             strerror(ENOMEM));
56                 return -ENOMEM;
57         }
58
59         ident_db = cparms.mem_va;
60         for (i = 0; i < TF_DIR_MAX; i++)
61                 ident_db->ident_db[i] = NULL;
62         tf_session_set_db(tfp, TF_MODULE_TYPE_IDENTIFIER, ident_db);
63
64         db_cfg.module = TF_MODULE_TYPE_IDENTIFIER;
65         db_cfg.num_elements = parms->num_elements;
66         db_cfg.cfg = parms->cfg;
67
68         for (i = 0; i < TF_DIR_MAX; i++) {
69                 db_cfg.rm_db = (void *)&ident_db->ident_db[i];
70                 db_cfg.dir = i;
71                 db_cfg.alloc_cnt = parms->resources->ident_cnt[i].cnt;
72                 if (tf_session_is_shared_session(tfs) &&
73                         (!tf_session_is_shared_session_creator(tfs)))
74                         db_rc[i] = tf_rm_create_db_no_reservation(tfp, &db_cfg);
75                 else
76                         db_rc[i] = tf_rm_create_db(tfp, &db_cfg);
77                 if (db_rc[i]) {
78                         TFP_DRV_LOG(INFO,
79                                     "%s: Identifier DB creation failed\n",
80                                     tf_dir_2_str(i));
81                 }
82
83                 if (parms->shadow_copy) {
84                         shadow_cfg.alloc_cnt =
85                                 parms->resources->ident_cnt[i].cnt;
86                         shadow_cdb.num_elements = parms->num_elements;
87                         shadow_cdb.tf_shadow_ident_db = &ident_shadow_db[i];
88                         shadow_cdb.cfg = &shadow_cfg;
89                         rc = tf_shadow_ident_create_db(&shadow_cdb);
90                         if (rc) {
91                                 TFP_DRV_LOG(ERR,
92                                     "%s: Ident shadow DB creation failed\n",
93                                     tf_dir_2_str(i));
94
95                                 return rc;
96                         }
97                         shadow_init = 1;
98                 }
99         }
100
101         /* No db created */
102         if (db_rc[TF_DIR_RX] && db_rc[TF_DIR_TX])
103                 return db_rc[TF_DIR_RX];
104
105         TFP_DRV_LOG(INFO,
106                     "Identifier - initialized\n");
107
108         return 0;
109 }
110
111 int
112 tf_ident_unbind(struct tf *tfp)
113 {
114         int rc = 0;
115         int i;
116         struct tf_rm_free_db_parms fparms = { 0 };
117         struct tf_shadow_ident_free_db_parms sparms = { 0 };
118         struct ident_rm_db *ident_db;
119         void *ident_db_ptr = NULL;
120
121         TF_CHECK_PARMS1(tfp);
122
123         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
124         if (rc) {
125                 TFP_DRV_LOG(INFO,
126                             "Ident_db is not initialized, rc:%s\n",
127                             strerror(-rc));
128                 return 0;
129         }
130         ident_db = (struct ident_rm_db *)ident_db_ptr;
131
132         for (i = 0; i < TF_DIR_MAX; i++) {
133                 if (ident_db->ident_db[i] == NULL)
134                         continue;
135                 fparms.rm_db = ident_db->ident_db[i];
136                 fparms.dir = i;
137                 rc = tf_rm_free_db(tfp, &fparms);
138                 if (rc) {
139                         TFP_DRV_LOG(ERR,
140                                     "rm free failed on unbind\n");
141                 }
142                 if (shadow_init) {
143                         sparms.tf_shadow_ident_db = ident_shadow_db[i];
144                         rc = tf_shadow_ident_free_db(&sparms);
145                         if (rc) {
146                                 /* TODO: If there are failures on unbind we
147                                  * really just have to try until all DBs are
148                                  * attempted to be cleared.
149                                  */
150                         }
151                         ident_shadow_db[i] = NULL;
152                 }
153                 ident_db->ident_db[i] = NULL;
154         }
155
156         shadow_init = 0;
157
158         return 0;
159 }
160
161 int
162 tf_ident_alloc(struct tf *tfp __rte_unused,
163                struct tf_ident_alloc_parms *parms)
164 {
165         int rc;
166         uint32_t id;
167         uint32_t base_id;
168         struct tf_rm_allocate_parms aparms = { 0 };
169         struct tf_shadow_ident_insert_parms iparms = { 0 };
170         struct ident_rm_db *ident_db;
171         void *ident_db_ptr = NULL;
172
173         TF_CHECK_PARMS2(tfp, parms);
174
175         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
176         if (rc) {
177                 TFP_DRV_LOG(ERR,
178                             "Failed to get ident_db from session, rc:%s\n",
179                             strerror(-rc));
180                 return rc;
181         }
182         ident_db = (struct ident_rm_db *)ident_db_ptr;
183
184         aparms.rm_db = ident_db->ident_db[parms->dir];
185         aparms.subtype = parms->type;
186         aparms.index = &id;
187         aparms.base_index = &base_id;
188         rc = tf_rm_allocate(&aparms);
189         if (rc) {
190                 TFP_DRV_LOG(ERR,
191                             "%s: Failed allocate, type:%d\n",
192                             tf_dir_2_str(parms->dir),
193                             parms->type);
194                 return rc;
195         }
196
197         if (shadow_init) {
198                 iparms.tf_shadow_ident_db = ident_shadow_db[parms->dir];
199                 iparms.type = parms->type;
200                 iparms.id = base_id;
201
202                 rc = tf_shadow_ident_insert(&iparms);
203                 if (rc) {
204                         TFP_DRV_LOG(ERR,
205                                     "%s: Failed insert shadow DB, type:%d\n",
206                                     tf_dir_2_str(parms->dir),
207                                     parms->type);
208                         return rc;
209                 }
210         }
211
212         *parms->id = id;
213
214         return 0;
215 }
216
217 int
218 tf_ident_free(struct tf *tfp __rte_unused,
219               struct tf_ident_free_parms *parms)
220 {
221         int rc;
222         struct tf_rm_is_allocated_parms aparms = { 0 };
223         struct tf_rm_free_parms fparms = { 0 };
224         struct tf_shadow_ident_remove_parms rparms = { 0 };
225         int allocated = 0;
226         uint32_t base_id;
227         struct ident_rm_db *ident_db;
228         void *ident_db_ptr = NULL;
229
230         TF_CHECK_PARMS2(tfp, parms);
231
232         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
233         if (rc) {
234                 TFP_DRV_LOG(ERR,
235                             "Failed to get ident_db from session, rc:%s\n",
236                             strerror(-rc));
237                 return rc;
238         }
239         ident_db = (struct ident_rm_db *)ident_db_ptr;
240
241         /* Check if element is in use */
242         aparms.rm_db = ident_db->ident_db[parms->dir];
243         aparms.subtype = parms->type;
244         aparms.index = parms->id;
245         aparms.base_index = &base_id;
246         aparms.allocated = &allocated;
247         rc = tf_rm_is_allocated(&aparms);
248         if (rc)
249                 return rc;
250
251         if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
252                 TFP_DRV_LOG(ERR,
253                             "%s: Entry already free, type:%d, index:%d\n",
254                             tf_dir_2_str(parms->dir),
255                             parms->type,
256                             parms->id);
257                 return -EINVAL;
258         }
259
260         if (shadow_init) {
261                 rparms.tf_shadow_ident_db = ident_shadow_db[parms->dir];
262                 rparms.type = parms->type;
263                 rparms.id = base_id;
264                 rparms.ref_cnt = parms->ref_cnt;
265
266                 rc = tf_shadow_ident_remove(&rparms);
267                 if (rc) {
268                         TFP_DRV_LOG(ERR,
269                                     "%s: ref_cnt was 0 in shadow DB,"
270                                     " type:%d, index:%d\n",
271                                     tf_dir_2_str(parms->dir),
272                                     parms->type,
273                                     parms->id);
274                         return rc;
275                 }
276
277                 if (*rparms.ref_cnt > 0)
278                         return 0;
279         }
280
281         /* Free requested element */
282         fparms.rm_db = ident_db->ident_db[parms->dir];
283         fparms.subtype = parms->type;
284         fparms.index = parms->id;
285         rc = tf_rm_free(&fparms);
286         if (rc) {
287                 TFP_DRV_LOG(ERR,
288                             "%s: Free failed, type:%d, index:%d\n",
289                             tf_dir_2_str(parms->dir),
290                             parms->type,
291                             parms->id);
292                 return rc;
293         }
294
295         return 0;
296 }
297
298 int
299 tf_ident_search(struct tf *tfp __rte_unused,
300                 struct tf_ident_search_parms *parms)
301 {
302         int rc;
303         struct tf_rm_is_allocated_parms aparms = { 0 };
304         struct tf_shadow_ident_search_parms sparms = { 0 };
305         int allocated = 0;
306         uint32_t base_id;
307         struct ident_rm_db *ident_db;
308         void *ident_db_ptr = NULL;
309
310         TF_CHECK_PARMS2(tfp, parms);
311
312         if (!shadow_init) {
313                 TFP_DRV_LOG(ERR,
314                             "%s: Identifier Shadow copy is not enabled\n",
315                             tf_dir_2_str(parms->dir));
316                 return -EINVAL;
317         }
318
319         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
320         if (rc) {
321                 TFP_DRV_LOG(ERR,
322                             "Failed to get ident_db from session, rc:%s\n",
323                             strerror(-rc));
324                 return rc;
325         }
326         ident_db = (struct ident_rm_db *)ident_db_ptr;
327
328         /* Check if element is in use */
329         aparms.rm_db = ident_db->ident_db[parms->dir];
330         aparms.subtype = parms->type;
331         aparms.index = parms->search_id;
332         aparms.base_index = &base_id;
333         aparms.allocated = &allocated;
334         rc = tf_rm_is_allocated(&aparms);
335         if (rc)
336                 return rc;
337
338         if (allocated != TF_RM_ALLOCATED_ENTRY_IN_USE) {
339                 TFP_DRV_LOG(ERR,
340                             "%s: Entry not allocated, type:%d, index:%d\n",
341                             tf_dir_2_str(parms->dir),
342                             parms->type,
343                             parms->search_id);
344                 return -EINVAL;
345         }
346
347         sparms.tf_shadow_ident_db = ident_shadow_db[parms->dir];
348         sparms.type = parms->type;
349         sparms.search_id = base_id;
350         sparms.hit = parms->hit;
351         sparms.ref_cnt = parms->ref_cnt;
352
353         rc = tf_shadow_ident_search(&sparms);
354         if (rc) {
355                 TFP_DRV_LOG(ERR,
356                             "%s: Failed search shadow DB, type:%d\n",
357                             tf_dir_2_str(parms->dir),
358                             parms->type);
359                 return rc;
360         }
361
362         return 0;
363 }
364
365 int
366 tf_ident_get_resc_info(struct tf *tfp,
367                        struct tf_identifier_resource_info *ident)
368 {
369         int rc;
370         int d;
371         struct tf_resource_info *dinfo;
372         struct tf_rm_get_alloc_info_parms ainfo;
373         void *ident_db_ptr = NULL;
374         struct ident_rm_db *ident_db;
375
376         TF_CHECK_PARMS2(tfp, ident);
377
378         rc = tf_session_get_db(tfp, TF_MODULE_TYPE_IDENTIFIER, &ident_db_ptr);
379         if (rc) {
380                 TFP_DRV_LOG(INFO,
381                             "No resource allocated for ident from session\n");
382                 return 0;
383         }
384         ident_db = (struct ident_rm_db *)ident_db_ptr;
385
386         /* check if reserved resource for WC is multiple of num_slices */
387         for (d = 0; d < TF_DIR_MAX; d++) {
388                 ainfo.rm_db = ident_db->ident_db[d];
389                 dinfo = ident[d].info;
390
391                 ainfo.info = (struct tf_rm_alloc_info *)dinfo;
392                 ainfo.subtype = 0;
393                 rc = tf_rm_get_all_info(&ainfo, TF_IDENT_TYPE_MAX);
394                 if (rc)
395                         return rc;
396         }
397
398         return 0;
399 }