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