net/bnxt: update RM to support HCAPI only
[dpdk.git] / drivers / net / bnxt / tf_core / tf_session.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
8 #include <rte_common.h>
9
10 #include "tf_session.h"
11 #include "tf_common.h"
12 #include "tf_msg.h"
13 #include "tfp.h"
14
15 int
16 tf_session_open_session(struct tf *tfp,
17                         struct tf_session_open_session_parms *parms)
18 {
19         int rc;
20         struct tf_session *session = NULL;
21         struct tfp_calloc_parms cparms;
22         uint8_t fw_session_id;
23         union tf_session_id *session_id;
24
25         TF_CHECK_PARMS2(tfp, parms);
26
27         /* Open FW session and get a new session_id */
28         rc = tf_msg_session_open(tfp,
29                                  parms->open_cfg->ctrl_chan_name,
30                                  &fw_session_id);
31         if (rc) {
32                 /* Log error */
33                 if (rc == -EEXIST)
34                         TFP_DRV_LOG(ERR,
35                                     "Session is already open, rc:%s\n",
36                                     strerror(-rc));
37                 else
38                         TFP_DRV_LOG(ERR,
39                                     "Open message send failed, rc:%s\n",
40                                     strerror(-rc));
41
42                 parms->open_cfg->session_id.id = TF_FW_SESSION_ID_INVALID;
43                 return rc;
44         }
45
46         /* Allocate session */
47         cparms.nitems = 1;
48         cparms.size = sizeof(struct tf_session_info);
49         cparms.alignment = 0;
50         rc = tfp_calloc(&cparms);
51         if (rc) {
52                 /* Log error */
53                 TFP_DRV_LOG(ERR,
54                             "Failed to allocate session info, rc:%s\n",
55                             strerror(-rc));
56                 goto cleanup;
57         }
58         tfp->session = (struct tf_session_info *)cparms.mem_va;
59
60         /* Allocate core data for the session */
61         cparms.nitems = 1;
62         cparms.size = sizeof(struct tf_session);
63         cparms.alignment = 0;
64         rc = tfp_calloc(&cparms);
65         if (rc) {
66                 /* Log error */
67                 TFP_DRV_LOG(ERR,
68                             "Failed to allocate session data, rc:%s\n",
69                             strerror(-rc));
70                 goto cleanup;
71         }
72         tfp->session->core_data = cparms.mem_va;
73
74         /* Initialize Session and Device */
75         session = (struct tf_session *)tfp->session->core_data;
76         session->ver.major = 0;
77         session->ver.minor = 0;
78         session->ver.update = 0;
79
80         session_id = &parms->open_cfg->session_id;
81         session->session_id.internal.domain = session_id->internal.domain;
82         session->session_id.internal.bus = session_id->internal.bus;
83         session->session_id.internal.device = session_id->internal.device;
84         session->session_id.internal.fw_session_id = fw_session_id;
85         /* Return the allocated fw session id */
86         session_id->internal.fw_session_id = fw_session_id;
87
88         session->shadow_copy = parms->open_cfg->shadow_copy;
89
90         tfp_memcpy(session->ctrl_chan_name,
91                    parms->open_cfg->ctrl_chan_name,
92                    TF_SESSION_NAME_MAX);
93
94         rc = tf_dev_bind(tfp,
95                          parms->open_cfg->device_type,
96                          session->shadow_copy,
97                          &parms->open_cfg->resources,
98                          &session->dev);
99         /* Logging handled by dev_bind */
100         if (rc)
101                 return rc;
102
103         session->ref_count++;
104
105         return 0;
106
107  cleanup:
108         tfp_free(tfp->session->core_data);
109         tfp_free(tfp->session);
110         tfp->session = NULL;
111         return rc;
112 }
113
114 int
115 tf_session_attach_session(struct tf *tfp __rte_unused,
116                           struct tf_session_attach_session_parms *parms __rte_unused)
117 {
118         int rc = -EOPNOTSUPP;
119
120         TF_CHECK_PARMS2(tfp, parms);
121
122         TFP_DRV_LOG(ERR,
123                     "Attach not yet supported, rc:%s\n",
124                     strerror(-rc));
125         return rc;
126 }
127
128 int
129 tf_session_close_session(struct tf *tfp,
130                          struct tf_session_close_session_parms *parms)
131 {
132         int rc;
133         struct tf_session *tfs = NULL;
134         struct tf_dev_info *tfd = NULL;
135
136         TF_CHECK_PARMS2(tfp, parms);
137
138         rc = tf_session_get_session(tfp, &tfs);
139         if (rc) {
140                 TFP_DRV_LOG(ERR,
141                             "Session lookup failed, rc:%s\n",
142                             strerror(-rc));
143                 return rc;
144         }
145
146         if (tfs->session_id.id == TF_SESSION_ID_INVALID) {
147                 rc = -EINVAL;
148                 TFP_DRV_LOG(ERR,
149                             "Invalid session id, unable to close, rc:%s\n",
150                             strerror(-rc));
151                 return rc;
152         }
153
154         tfs->ref_count--;
155
156         /* Record the session we're closing so the caller knows the
157          * details.
158          */
159         *parms->session_id = tfs->session_id;
160
161         rc = tf_session_get_device(tfs, &tfd);
162         if (rc) {
163                 TFP_DRV_LOG(ERR,
164                             "Device lookup failed, rc:%s\n",
165                             strerror(-rc));
166                 return rc;
167         }
168
169         if (tfs->ref_count > 0) {
170                 /* In case we're attached only the session client gets
171                  * closed.
172                  */
173                 rc = tf_msg_session_close(tfp);
174                 if (rc) {
175                         /* Log error */
176                         TFP_DRV_LOG(ERR,
177                                     "FW Session close failed, rc:%s\n",
178                                     strerror(-rc));
179                 }
180
181                 return 0;
182         }
183
184         /* Final cleanup as we're last user of the session */
185
186         /* Unbind the device */
187         rc = tf_dev_unbind(tfp, tfd);
188         if (rc) {
189                 /* Log error */
190                 TFP_DRV_LOG(ERR,
191                             "Device unbind failed, rc:%s\n",
192                             strerror(-rc));
193         }
194
195         /* In case we're attached only the session client gets closed */
196         rc = tf_msg_session_close(tfp);
197         if (rc) {
198                 /* Log error */
199                 TFP_DRV_LOG(ERR,
200                             "FW Session close failed, rc:%s\n",
201                             strerror(-rc));
202         }
203
204         tfp_free(tfp->session->core_data);
205         tfp_free(tfp->session);
206         tfp->session = NULL;
207
208         return 0;
209 }
210
211 int
212 tf_session_get_session(struct tf *tfp,
213                        struct tf_session **tfs)
214 {
215         int rc;
216
217         if (tfp->session == NULL || tfp->session->core_data == NULL) {
218                 rc = -EINVAL;
219                 TFP_DRV_LOG(ERR,
220                             "Session not created, rc:%s\n",
221                             strerror(-rc));
222                 return rc;
223         }
224
225         *tfs = (struct tf_session *)(tfp->session->core_data);
226
227         return 0;
228 }
229
230 int
231 tf_session_get_device(struct tf_session *tfs,
232                       struct tf_dev_info **tfd)
233 {
234         *tfd = &tfs->dev;
235
236         return 0;
237 }
238
239 int
240 tf_session_get_fw_session_id(struct tf *tfp,
241                              uint8_t *fw_session_id)
242 {
243         int rc;
244         struct tf_session *tfs = NULL;
245
246         if (tfp->session == NULL) {
247                 rc = -EINVAL;
248                 TFP_DRV_LOG(ERR,
249                             "Session not created, rc:%s\n",
250                             strerror(-rc));
251                 return rc;
252         }
253
254         rc = tf_session_get_session(tfp, &tfs);
255         if (rc)
256                 return rc;
257
258         *fw_session_id = tfs->session_id.internal.fw_session_id;
259
260         return 0;
261 }