1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Freescale Layerscape MC I/O wrapper
4 *
5 * Copyright 2013-2016 Freescale Semiconductor, Inc.
6 * Copyright 2017, 2023 NXP
7 */
8
9 #include <fsl-mc/fsl_mc_sys.h>
10 #include <fsl-mc/fsl_mc_cmd.h>
11 #include <fsl-mc/fsl_dprc.h>
12
13 /**
14 * dprc_get_container_id - Get container ID associated with a given portal.
15 * @mc_io: Pointer to Mc portal's I/O object
16 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
17 * @container_id: Requested container id
18 *
19 * Return: '0' on Success; Error code otherwise.
20 */
dprc_get_container_id(struct fsl_mc_io * mc_io,u32 cmd_flags,int * container_id)21 int dprc_get_container_id(struct fsl_mc_io *mc_io, u32 cmd_flags, int *container_id)
22 {
23 struct mc_command cmd = { 0 };
24 int err;
25
26 /* prepare command */
27 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONT_ID,
28 cmd_flags,
29 0);
30
31 /* send command to mc*/
32 err = mc_send_command(mc_io, &cmd);
33 if (err)
34 return err;
35
36 /* retrieve response parameters */
37 *container_id = (int)mc_cmd_read_object_id(&cmd);
38
39 return 0;
40 }
41
42 /**
43 * dprc_open() - Open DPRC object for use
44 * @mc_io: Pointer to MC portal's I/O object
45 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
46 * @container_id: Container ID to open
47 * @token: Returned token of DPRC object
48 *
49 * Return: '0' on Success; Error code otherwise.
50 *
51 * @warning Required before any operation on the object.
52 */
dprc_open(struct fsl_mc_io * mc_io,u32 cmd_flags,int container_id,u16 * token)53 int dprc_open(struct fsl_mc_io *mc_io, u32 cmd_flags, int container_id, u16 *token)
54 {
55 struct dprc_cmd_open *cmd_params;
56 struct mc_command cmd = { 0 };
57 int err;
58
59 /* prepare command */
60 cmd.header = mc_encode_cmd_header(DPRC_CMDID_OPEN, cmd_flags,
61 0);
62 cmd_params = (struct dprc_cmd_open *)cmd.params;
63 cmd_params->container_id = cpu_to_le32(container_id);
64
65 /* send command to mc*/
66 err = mc_send_command(mc_io, &cmd);
67 if (err)
68 return err;
69
70 /* retrieve response parameters */
71 *token = mc_cmd_hdr_read_token(&cmd);
72
73 return 0;
74 }
75
76 /**
77 * dprc_close() - Close the control session of the object
78 * @mc_io: Pointer to MC portal's I/O object
79 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
80 * @token: Token of DPRC object
81 *
82 * After this function is called, no further operations are
83 * allowed on the object without opening a new control session.
84 *
85 * Return: '0' on Success; Error code otherwise.
86 */
dprc_close(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token)87 int dprc_close(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)
88 {
89 struct mc_command cmd = { 0 };
90
91 /* prepare command */
92 cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLOSE, cmd_flags,
93 token);
94
95 /* send command to mc*/
96 return mc_send_command(mc_io, &cmd);
97 }
98
99 /**
100 * dprc_create_container() - Create child container
101 * @mc_io: Pointer to MC portal's I/O object
102 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
103 * @token: Token of DPRC object
104 * @cfg: Child container configuration
105 * @child_container_id: Returned child container ID
106 * @child_portal_offset:Returned child portal offset from MC portal base
107 *
108 * Return: '0' on Success; Error code otherwise.
109 */
dprc_create_container(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,struct dprc_cfg * cfg,int * child_container_id,uint64_t * child_portal_offset)110 int dprc_create_container(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
111 struct dprc_cfg *cfg, int *child_container_id,
112 uint64_t *child_portal_offset)
113 {
114 struct dprc_cmd_create_container *cmd_params;
115 struct dprc_rsp_create_container *rsp_params;
116 struct mc_command cmd = { 0 };
117 int err, i;
118
119 /* prepare command */
120 cmd.header = mc_encode_cmd_header(DPRC_CMDID_CREATE_CONT,
121 cmd_flags, token);
122 cmd_params = (struct dprc_cmd_create_container *)cmd.params;
123 cmd_params->options = cpu_to_le32(cfg->options);
124 cmd_params->icid = cpu_to_le32(cfg->icid);
125 cmd_params->portal_id = cpu_to_le32(cfg->portal_id);
126 for (i = 0; i < 16; i++)
127 cmd_params->label[i] = cfg->label[i];
128
129 /* send command to mc*/
130 err = mc_send_command(mc_io, &cmd);
131 if (err)
132 return err;
133
134 /* retrieve response parameters */
135 rsp_params = (struct dprc_rsp_create_container *)cmd.params;
136 *child_container_id = le32_to_cpu(rsp_params->child_container_id);
137 *child_portal_offset = le64_to_cpu(rsp_params->child_portal_addr);
138
139 return 0;
140 }
141
142 /**
143 * dprc_destroy_container() - Destroy child container.
144 * @mc_io: Pointer to MC portal's I/O object
145 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
146 * @token: Token of DPRC object
147 * @child_container_id: ID of the container to destroy
148 *
149 * This function terminates the child container, so following this call the
150 * child container ID becomes invalid.
151 *
152 * Notes:
153 * - All resources and objects of the destroyed container are returned to the
154 * parent container or destroyed if were created be the destroyed container.
155 * - This function destroy all the child containers of the specified
156 * container prior to destroying the container itself.
157 *
158 * warning: Only the parent container is allowed to destroy a child policy
159 * Container 0 can't be destroyed
160 *
161 * Return: '0' on Success; Error code otherwise.
162 *
163 */
dprc_destroy_container(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,int child_container_id)164 int dprc_destroy_container(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
165 int child_container_id)
166 {
167 struct dprc_cmd_destroy_container *cmd_params;
168 struct mc_command cmd = { 0 };
169
170 /* prepare command */
171 cmd.header = mc_encode_cmd_header(DPRC_CMDID_DESTROY_CONT,
172 cmd_flags, token);
173 cmd_params = (struct dprc_cmd_destroy_container *)cmd.params;
174 cmd_params->child_container_id = cpu_to_le32(child_container_id);
175
176 /* send command to mc*/
177 return mc_send_command(mc_io, &cmd);
178 }
179
180 /**
181 * dprc_connect() - Connect two endpoints to create a network link between them
182 * @mc_io: Pointer to MC portal's I/O object
183 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
184 * @token: Token of DPRC object
185 * @endpoint1: Endpoint 1 configuration parameters
186 * @endpoint2: Endpoint 2 configuration parameters
187 * @cfg: Connection configuration. The connection configuration
188 * is ignored for connections made to DPMAC objects, where
189 * rate is retrieved from the MAC configuration.
190 *
191 * Return: '0' on Success; Error code otherwise.
192 */
dprc_connect(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,const struct dprc_endpoint * endpoint1,const struct dprc_endpoint * endpoint2,const struct dprc_connection_cfg * cfg)193 int dprc_connect(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
194 const struct dprc_endpoint *endpoint1,
195 const struct dprc_endpoint *endpoint2,
196 const struct dprc_connection_cfg *cfg)
197 {
198 struct dprc_cmd_connect *cmd_params;
199 struct mc_command cmd = { 0 };
200 int i;
201
202 /* prepare command */
203 cmd.header = mc_encode_cmd_header(DPRC_CMDID_CONNECT,
204 cmd_flags,
205 token);
206 cmd_params = (struct dprc_cmd_connect *)cmd.params;
207 cmd_params->ep1_id = cpu_to_le32(endpoint1->id);
208 cmd_params->ep1_interface_id = cpu_to_le16(endpoint1->if_id);
209 cmd_params->ep2_id = cpu_to_le32(endpoint2->id);
210 cmd_params->ep2_interface_id = cpu_to_le16(endpoint2->if_id);
211 cmd_params->max_rate = cpu_to_le32(cfg->max_rate);
212 cmd_params->committed_rate = cpu_to_le32(cfg->committed_rate);
213 for (i = 0; i < 16; i++) {
214 cmd_params->ep1_type[i] = endpoint1->type[i];
215 cmd_params->ep2_type[i] = endpoint2->type[i];
216 }
217
218 /* send command to mc*/
219 return mc_send_command(mc_io, &cmd);
220 }
221
222 /**
223 * dprc_disconnect() - Disconnect one endpoint to remove its network connection
224 * @mc_io: Pointer to MC portal's I/O object
225 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
226 * @token: Token of DPRC object
227 * @endpoint: Endpoint configuration parameters
228 *
229 * Return: '0' on Success; Error code otherwise.
230 */
dprc_disconnect(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,const struct dprc_endpoint * endpoint)231 int dprc_disconnect(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
232 const struct dprc_endpoint *endpoint)
233 {
234 struct dprc_cmd_disconnect *cmd_params;
235 struct mc_command cmd = { 0 };
236 int i;
237
238 /* prepare command */
239 cmd.header = mc_encode_cmd_header(DPRC_CMDID_DISCONNECT,
240 cmd_flags,
241 token);
242 cmd_params = (struct dprc_cmd_disconnect *)cmd.params;
243 cmd_params->id = cpu_to_le32(endpoint->id);
244 cmd_params->interface_id = cpu_to_le32(endpoint->if_id);
245 for (i = 0; i < 16; i++)
246 cmd_params->type[i] = endpoint->type[i];
247
248 /* send command to mc*/
249 return mc_send_command(mc_io, &cmd);
250 }
251
252 /**
253 * dprc_get_connection() - Get connected endpoint and link status if connection
254 * exists.
255 * @mc_io: Pointer to MC portal's I/O object
256 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
257 * @token: Token of DPRC object
258 * @endpoint1: Endpoint 1 configuration parameters
259 * @endpoint2: Returned endpoint 2 configuration parameters
260 * @state: Returned link state:
261 * 1 - link is up;
262 * 0 - link is down;
263 * -1 - no connection (endpoint2 information is irrelevant)
264 *
265 * Return: '0' on Success; -ENAVAIL if connection does not exist.
266 */
dprc_get_connection(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,const struct dprc_endpoint * endpoint1,struct dprc_endpoint * endpoint2,int * state)267 int dprc_get_connection(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
268 const struct dprc_endpoint *endpoint1,
269 struct dprc_endpoint *endpoint2, int *state)
270 {
271 struct dprc_cmd_get_connection *cmd_params;
272 struct dprc_rsp_get_connection *rsp_params;
273 struct mc_command cmd = { 0 };
274 int err, i;
275
276 /* prepare command */
277 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONNECTION,
278 cmd_flags,
279 token);
280 cmd_params = (struct dprc_cmd_get_connection *)cmd.params;
281 cmd_params->ep1_id = cpu_to_le32(endpoint1->id);
282 cmd_params->ep1_interface_id = cpu_to_le16(endpoint1->if_id);
283 for (i = 0; i < 16; i++)
284 cmd_params->ep1_type[i] = endpoint1->type[i];
285
286 /* send command to mc*/
287 err = mc_send_command(mc_io, &cmd);
288 if (err)
289 return err;
290
291 /* retrieve response parameters */
292 rsp_params = (struct dprc_rsp_get_connection *)cmd.params;
293 endpoint2->id = le32_to_cpu(rsp_params->ep2_id);
294 endpoint2->if_id = le16_to_cpu(rsp_params->ep2_interface_id);
295 *state = le32_to_cpu(rsp_params->state);
296 for (i = 0; i < 16; i++)
297 endpoint2->type[i] = rsp_params->ep2_type[i];
298
299 return 0;
300 }
301
302 /**
303 * dprc_get_api_version - Get Data Path Resource Container API version
304 * @mc_io: Pointer to Mc portal's I/O object
305 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
306 * @major_ver: Major version of Data Path Resource Container API
307 * @minor_ver: Minor version of Data Path Resource Container API
308 *
309 * Return: '0' on Success; Error code otherwise.
310 */
dprc_get_api_version(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 * major_ver,u16 * minor_ver)311 int dprc_get_api_version(struct fsl_mc_io *mc_io, u32 cmd_flags,
312 u16 *major_ver, u16 *minor_ver)
313 {
314 struct mc_command cmd = { 0 };
315 int err;
316
317 /* prepare command */
318 cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_API_VERSION,
319 cmd_flags, 0);
320
321 /* send command to mc */
322 err = mc_send_command(mc_io, &cmd);
323 if (err)
324 return err;
325
326 /* retrieve response parameters */
327 mc_cmd_read_api_version(&cmd, major_ver, minor_ver);
328
329 return 0;
330 }
331