390d22f81ec3cbd5fb8a62cc31790b65b2869574
[dpdk.git] / drivers / net / bnxt / tf_core / tf_shadow_identifier.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019-2020 Broadcom
3  * All rights reserved.
4  */
5
6 #include <rte_common.h>
7
8 #include "tf_shadow_identifier.h"
9 #include "tf_common.h"
10 #include "tf_util.h"
11 #include "tfp.h"
12
13 /**
14  * Shadow identifier DB element
15  */
16 struct tf_shadow_ident_element {
17         /**
18          * Identifier
19          */
20         uint32_t *id;
21
22         /**
23          * Reference count, array of number of identifier type entries
24          */
25         uint32_t *ref_count;
26 };
27
28 /**
29  * Shadow identifier DB definition
30  */
31 struct tf_shadow_ident_db {
32         /**
33          * Number of elements in the DB
34          */
35         uint16_t num_entries;
36
37         /**
38          * The DB consists of an array of elements
39          */
40         struct tf_shadow_ident_element *db;
41 };
42
43 int
44 tf_shadow_ident_create_db(struct tf_shadow_ident_create_db_parms *parms)
45 {
46         int rc;
47         int i;
48         struct tfp_calloc_parms cparms;
49         struct tf_shadow_ident_db *shadow_db;
50         struct tf_shadow_ident_element *db;
51
52         TF_CHECK_PARMS1(parms);
53
54         /* Build the shadow DB per the request */
55         cparms.nitems = 1;
56         cparms.size = sizeof(struct tf_shadow_ident_db);
57         cparms.alignment = 0;
58         rc = tfp_calloc(&cparms);
59         if (rc)
60                 return rc;
61         shadow_db = (void *)cparms.mem_va;
62
63         /* Build the DB within shadow DB */
64         cparms.nitems = parms->num_elements;
65         cparms.size = sizeof(struct tf_shadow_ident_element);
66         rc = tfp_calloc(&cparms);
67         if (rc)
68                 return rc;
69         shadow_db->db = (struct tf_shadow_ident_element *)cparms.mem_va;
70         shadow_db->num_entries = parms->num_elements;
71
72         db = shadow_db->db;
73         for (i = 0; i < parms->num_elements; i++) {
74                 /* If the element didn't request an allocation no need
75                  * to create a pool nor verify if we got a reservation.
76                  */
77                 if (parms->cfg->alloc_cnt[i] == 0)
78                         continue;
79
80                 /* Create array */
81                 cparms.nitems = parms->cfg->alloc_cnt[i];
82                 cparms.size = sizeof(uint32_t);
83                 rc = tfp_calloc(&cparms);
84                 if (rc) {
85                         TFP_DRV_LOG(ERR,
86                                     "%s: Array alloc failed, type:%d\n",
87                                     tf_dir_2_str(parms->dir),
88                                     i);
89                         goto fail;
90                 }
91                 db[i].ref_count = (uint32_t *)cparms.mem_va;
92         }
93
94         *parms->tf_shadow_ident_db = (void *)shadow_db;
95
96         return 0;
97 fail:
98         tfp_free((void *)db->ref_count);
99         tfp_free((void *)db);
100         tfp_free((void *)shadow_db);
101         parms->tf_shadow_ident_db = NULL;
102
103         return -EINVAL;
104 }
105
106 int
107 tf_shadow_ident_free_db(struct tf_shadow_ident_free_db_parms *parms)
108 {
109         int i;
110         struct tf_shadow_ident_db *shadow_db;
111
112         TF_CHECK_PARMS1(parms);
113
114         shadow_db = (struct tf_shadow_ident_db *)parms->tf_shadow_ident_db;
115         for (i = 0; i < shadow_db->num_entries; i++)
116                 tfp_free((void *)shadow_db->db[i].ref_count);
117
118         tfp_free((void *)shadow_db->db);
119         tfp_free((void *)parms->tf_shadow_ident_db);
120
121         return 0;
122 }
123
124 int
125 tf_shadow_ident_search(struct tf_shadow_ident_search_parms *parms)
126 {
127         struct tf_shadow_ident_db *shadow_db;
128         uint32_t ref_cnt = 0;
129
130         TF_CHECK_PARMS1(parms);
131
132         shadow_db = (struct tf_shadow_ident_db *)parms->tf_shadow_ident_db;
133         ref_cnt = shadow_db->db[parms->type].ref_count[parms->search_id];
134         if (ref_cnt > 0) {
135                 *parms->hit = 1;
136                 *parms->ref_cnt = ++ref_cnt;
137                 shadow_db->db[parms->type].ref_count[parms->search_id] =
138                                                                 ref_cnt;
139         } else {
140                 *parms->hit = 0;
141                 *parms->ref_cnt = 0;
142         }
143
144
145         return 0;
146 }
147
148 #define ID_REF_CNT_MAX 0xffffffff
149 int
150 tf_shadow_ident_insert(struct tf_shadow_ident_insert_parms *parms)
151 {
152         struct tf_shadow_ident_db *shadow_db;
153
154         TF_CHECK_PARMS1(parms);
155
156         shadow_db = (struct tf_shadow_ident_db *)parms->tf_shadow_ident_db;
157
158         /* In case of overflow, ref count keeps the max value */
159         if (shadow_db->db[parms->type].ref_count[parms->id] < ID_REF_CNT_MAX)
160                 shadow_db->db[parms->type].ref_count[parms->id]++;
161         else
162                 TFP_DRV_LOG(ERR,
163                             "Identifier %d in type %d reaches the max ref_cnt\n",
164                             parms->type,
165                             parms->id);
166
167         parms->ref_cnt = shadow_db->db[parms->type].ref_count[parms->id];
168
169         return 0;
170 }
171
172 int
173 tf_shadow_ident_remove(struct tf_shadow_ident_remove_parms *parms)
174 {
175         struct tf_shadow_ident_db *shadow_db;
176         uint32_t ref_cnt = 0;
177
178         TF_CHECK_PARMS1(parms);
179
180         shadow_db = (struct tf_shadow_ident_db *)parms->tf_shadow_ident_db;
181         ref_cnt = shadow_db->db[parms->type].ref_count[parms->id];
182         if (ref_cnt > 0)
183                 shadow_db->db[parms->type].ref_count[parms->id]--;
184         else
185                 return -EINVAL;
186
187         *parms->ref_cnt = shadow_db->db[parms->type].ref_count[parms->id];
188
189         return 0;
190 }