net/bnxt: support ULP session manager init
[dpdk.git] / drivers / net / bnxt / tf_ulp / ulp_flow_db.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2014-2020 Broadcom
3  * All rights reserved.
4  */
5
6 #include <rte_malloc.h>
7 #include "bnxt.h"
8 #include "bnxt_tf_common.h"
9 #include "ulp_flow_db.h"
10 #include "ulp_template_struct.h"
11
12 /*
13  * Helper function to allocate the flow table and initialize
14  * the stack for allocation operations.
15  *
16  * flow_db [in] Ptr to flow database structure
17  * tbl_idx [in] The index to table creation.
18  *
19  * Returns 0 on success or negative number on failure.
20  */
21 static int32_t
22 ulp_flow_db_alloc_resource(struct bnxt_ulp_flow_db *flow_db,
23                            enum bnxt_ulp_flow_db_tables tbl_idx)
24 {
25         uint32_t                        idx = 0;
26         struct bnxt_ulp_flow_tbl        *flow_tbl;
27         uint32_t                        size;
28
29         flow_tbl = &flow_db->flow_tbl[tbl_idx];
30
31         size = sizeof(struct ulp_fdb_resource_info) * flow_tbl->num_resources;
32         flow_tbl->flow_resources =
33                         rte_zmalloc("ulp_fdb_resource_info", size, 0);
34
35         if (!flow_tbl->flow_resources) {
36                 BNXT_TF_DBG(ERR, "Failed to alloc memory for flow table\n");
37                 return -ENOMEM;
38         }
39         size = sizeof(uint32_t) * flow_tbl->num_resources;
40         flow_tbl->flow_tbl_stack = rte_zmalloc("flow_tbl_stack", size, 0);
41         if (!flow_tbl->flow_tbl_stack) {
42                 BNXT_TF_DBG(ERR, "Failed to alloc memory flow tbl stack\n");
43                 return -ENOMEM;
44         }
45         size = (flow_tbl->num_flows / sizeof(uint64_t)) + 1;
46         flow_tbl->active_flow_tbl = rte_zmalloc("active flow tbl", size, 0);
47         if (!flow_tbl->active_flow_tbl) {
48                 BNXT_TF_DBG(ERR, "Failed to alloc memory active tbl\n");
49                 return -ENOMEM;
50         }
51
52         /* Initialize the stack table. */
53         for (idx = 0; idx < flow_tbl->num_resources; idx++)
54                 flow_tbl->flow_tbl_stack[idx] = idx;
55
56         /* Ignore the first element in the list. */
57         flow_tbl->head_index = 1;
58         /* Tail points to the last entry in the list. */
59         flow_tbl->tail_index = flow_tbl->num_resources - 1;
60         return 0;
61 }
62
63 /*
64  * Helper function to de allocate the flow table.
65  *
66  * flow_db [in] Ptr to flow database structure
67  * tbl_idx [in] The index to table creation.
68  *
69  * Returns none.
70  */
71 static void
72 ulp_flow_db_dealloc_resource(struct bnxt_ulp_flow_db *flow_db,
73                              enum bnxt_ulp_flow_db_tables tbl_idx)
74 {
75         struct bnxt_ulp_flow_tbl        *flow_tbl;
76
77         flow_tbl = &flow_db->flow_tbl[tbl_idx];
78
79         /* Free all the allocated tables in the flow table. */
80         if (flow_tbl->active_flow_tbl) {
81                 rte_free(flow_tbl->active_flow_tbl);
82                 flow_tbl->active_flow_tbl = NULL;
83         }
84
85         if (flow_tbl->flow_tbl_stack) {
86                 rte_free(flow_tbl->flow_tbl_stack);
87                 flow_tbl->flow_tbl_stack = NULL;
88         }
89
90         if (flow_tbl->flow_resources) {
91                 rte_free(flow_tbl->flow_resources);
92                 flow_tbl->flow_resources = NULL;
93         }
94 }
95
96 /*
97  * Initialize the flow database. Memory is allocated in this
98  * call and assigned to the flow database.
99  *
100  * ulp_ctxt [in] Ptr to ulp context
101  *
102  * Returns 0 on success or negative number on failure.
103  */
104 int32_t ulp_flow_db_init(struct bnxt_ulp_context *ulp_ctxt)
105 {
106         struct bnxt_ulp_device_params           *dparms;
107         struct bnxt_ulp_flow_tbl                *flow_tbl;
108         struct bnxt_ulp_flow_db                 *flow_db;
109         uint32_t                                dev_id;
110
111         /* Get the dev specific number of flows that needed to be supported. */
112         if (bnxt_ulp_cntxt_dev_id_get(ulp_ctxt, &dev_id)) {
113                 BNXT_TF_DBG(ERR, "Invalid device id\n");
114                 return -EINVAL;
115         }
116
117         dparms = bnxt_ulp_device_params_get(dev_id);
118         if (!dparms) {
119                 BNXT_TF_DBG(ERR, "could not fetch the device params\n");
120                 return -ENODEV;
121         }
122
123         flow_db = rte_zmalloc("bnxt_ulp_flow_db",
124                               sizeof(struct bnxt_ulp_flow_db), 0);
125         if (!flow_db) {
126                 BNXT_TF_DBG(ERR,
127                             "Failed to allocate memory for flow table ptr\n");
128                 goto error_free;
129         }
130
131         /* Attach the flow database to the ulp context. */
132         bnxt_ulp_cntxt_ptr2_flow_db_set(ulp_ctxt, flow_db);
133
134         /* Populate the regular flow table limits. */
135         flow_tbl = &flow_db->flow_tbl[BNXT_ULP_REGULAR_FLOW_TABLE];
136         flow_tbl->num_flows = dparms->num_flows + 1;
137         flow_tbl->num_resources = (flow_tbl->num_flows *
138                                    dparms->num_resources_per_flow);
139
140         /* Populate the default flow table limits. */
141         flow_tbl = &flow_db->flow_tbl[BNXT_ULP_DEFAULT_FLOW_TABLE];
142         flow_tbl->num_flows = BNXT_FLOW_DB_DEFAULT_NUM_FLOWS + 1;
143         flow_tbl->num_resources = (flow_tbl->num_flows *
144                                    BNXT_FLOW_DB_DEFAULT_NUM_RESOURCES);
145
146         /* Allocate the resource for the regular flow table. */
147         if (ulp_flow_db_alloc_resource(flow_db, BNXT_ULP_REGULAR_FLOW_TABLE))
148                 goto error_free;
149         if (ulp_flow_db_alloc_resource(flow_db, BNXT_ULP_DEFAULT_FLOW_TABLE))
150                 goto error_free;
151
152         /* All good so return. */
153         return 0;
154 error_free:
155         ulp_flow_db_deinit(ulp_ctxt);
156         return -ENOMEM;
157 }
158
159 /*
160  * Deinitialize the flow database. Memory is deallocated in
161  * this call and all flows should have been purged before this
162  * call.
163  *
164  * ulp_ctxt [in] Ptr to ulp context
165  *
166  * Returns 0 on success.
167  */
168 int32_t ulp_flow_db_deinit(struct bnxt_ulp_context *ulp_ctxt)
169 {
170         struct bnxt_ulp_flow_db                 *flow_db;
171
172         flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
173         if (!flow_db) {
174                 BNXT_TF_DBG(ERR, "Invalid Arguments\n");
175                 return -EINVAL;
176         }
177
178         /* Detach the flow database from the ulp context. */
179         bnxt_ulp_cntxt_ptr2_flow_db_set(ulp_ctxt, NULL);
180
181         /* Free up all the memory. */
182         ulp_flow_db_dealloc_resource(flow_db, BNXT_ULP_REGULAR_FLOW_TABLE);
183         ulp_flow_db_dealloc_resource(flow_db, BNXT_ULP_DEFAULT_FLOW_TABLE);
184         rte_free(flow_db);
185
186         return 0;
187 }