xref: /dpdk/drivers/net/bnxt/tf_core/tf_session.c (revision 48d3dff2b98680c6315593e8b6495b64e678b004)
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 = 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 	/* Record the session we're closing so the caller knows the
155 	 * details.
156 	 */
157 	*parms->session_id = tfs->session_id;
158 
159 	rc = tf_session_get_device(tfs, &tfd);
160 	if (rc) {
161 		TFP_DRV_LOG(ERR,
162 			    "Device lookup failed, rc:%s\n",
163 			    strerror(-rc));
164 		return rc;
165 	}
166 
167 	/* In case we're attached only the session client gets closed */
168 	rc = tf_msg_session_close(tfp);
169 	if (rc) {
170 		/* Log error */
171 		TFP_DRV_LOG(ERR,
172 			    "FW Session close failed, rc:%s\n",
173 			    strerror(-rc));
174 	}
175 
176 	tfs->ref_count--;
177 
178 	/* Final cleanup as we're last user of the session */
179 	if (tfs->ref_count == 0) {
180 		/* Unbind the device */
181 		rc = dev_unbind(tfp, tfd);
182 		if (rc) {
183 			/* Log error */
184 			TFP_DRV_LOG(ERR,
185 				    "Device unbind failed, rc:%s\n",
186 				    strerror(-rc));
187 		}
188 
189 		tfp_free(tfp->session->core_data);
190 		tfp_free(tfp->session);
191 		tfp->session = NULL;
192 	}
193 
194 	return 0;
195 }
196 
197 int
198 tf_session_get_session(struct tf *tfp,
199 		       struct tf_session **tfs)
200 {
201 	int rc;
202 
203 	if (tfp->session == NULL || tfp->session->core_data == NULL) {
204 		rc = -EINVAL;
205 		TFP_DRV_LOG(ERR,
206 			    "Session not created, rc:%s\n",
207 			    strerror(-rc));
208 		return rc;
209 	}
210 
211 	*tfs = (struct tf_session *)(tfp->session->core_data);
212 
213 	return 0;
214 }
215 
216 int
217 tf_session_get_device(struct tf_session *tfs,
218 		      struct tf_dev_info **tfd)
219 {
220 	*tfd = &tfs->dev;
221 
222 	return 0;
223 }
224 
225 int
226 tf_session_get_fw_session_id(struct tf *tfp,
227 			     uint8_t *fw_session_id)
228 {
229 	int rc;
230 	struct tf_session *tfs = NULL;
231 
232 	if (tfp->session == NULL) {
233 		rc = -EINVAL;
234 		TFP_DRV_LOG(ERR,
235 			    "Session not created, rc:%s\n",
236 			    strerror(-rc));
237 		return rc;
238 	}
239 
240 	rc = tf_session_get_session(tfp, &tfs);
241 	if (rc)
242 		return rc;
243 
244 	*fw_session_id = tfs->session_id.internal.fw_session_id;
245 
246 	return 0;
247 }
248