xref: /dpdk/drivers/bus/fslmc/mc/dpci.c (revision 200bc52e5aa0d72e70464c9cd22b55cf536ed13c)
1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2  *
3  * Copyright 2013-2016 Freescale Semiconductor Inc.
4  *
5  */
6 #include <fsl_mc_sys.h>
7 #include <fsl_mc_cmd.h>
8 #include <fsl_dpci.h>
9 #include <fsl_dpci_cmd.h>
10 
11 /**
12  * dpci_open() - Open a control session for the specified object
13  * @mc_io:	Pointer to MC portal's I/O object
14  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
15  * @dpci_id:	DPCI unique ID
16  * @token:	Returned token; use in subsequent API calls
17  *
18  * This function can be used to open a control session for an
19  * already created object; an object may have been declared in
20  * the DPL or by calling the dpci_create() function.
21  * This function returns a unique authentication token,
22  * associated with the specific object ID and the specific MC
23  * portal; this token must be used in all subsequent commands for
24  * this specific object.
25  *
26  * Return:	'0' on Success; Error code otherwise.
27  */
28 int dpci_open(struct fsl_mc_io *mc_io,
29 	      uint32_t cmd_flags,
30 	      int dpci_id,
31 	      uint16_t *token)
32 {
33 	struct dpci_cmd_open *cmd_params;
34 	struct mc_command cmd = { 0 };
35 	int err;
36 
37 	/* prepare command */
38 	cmd.header = mc_encode_cmd_header(DPCI_CMDID_OPEN,
39 					  cmd_flags,
40 					  0);
41 	cmd_params = (struct dpci_cmd_open *)cmd.params;
42 	cmd_params->dpci_id = cpu_to_le32(dpci_id);
43 
44 	/* send command to mc*/
45 	err = mc_send_command(mc_io, &cmd);
46 	if (err)
47 		return err;
48 
49 	/* retrieve response parameters */
50 	*token = mc_cmd_hdr_read_token(&cmd);
51 
52 	return 0;
53 }
54 
55 /**
56  * dpci_close() - Close the control session of the object
57  * @mc_io:	Pointer to MC portal's I/O object
58  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
59  * @token:	Token of DPCI object
60  *
61  * After this function is called, no further operations are
62  * allowed on the object without opening a new control session.
63  *
64  * Return:	'0' on Success; Error code otherwise.
65  */
66 int dpci_close(struct fsl_mc_io *mc_io,
67 	       uint32_t cmd_flags,
68 	       uint16_t token)
69 {
70 	struct mc_command cmd = { 0 };
71 
72 	/* prepare command */
73 	cmd.header = mc_encode_cmd_header(DPCI_CMDID_CLOSE,
74 					  cmd_flags,
75 					  token);
76 
77 	/* send command to mc*/
78 	return mc_send_command(mc_io, &cmd);
79 }
80 
81 /**
82  * dpci_create() - Create the DPCI object.
83  * @mc_io:	Pointer to MC portal's I/O object
84  * @dprc_token:	Parent container token; '0' for default container
85  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
86  * @cfg:	Configuration structure
87  * @obj_id:	Returned object id
88  *
89  * Create the DPCI object, allocate required resources and perform required
90  * initialization.
91  *
92  * The object can be created either by declaring it in the
93  * DPL file, or by calling this function.
94  *
95  * The function accepts an authentication token of a parent
96  * container that this object should be assigned to. The token
97  * can be '0' so the object will be assigned to the default container.
98  * The newly created object can be opened with the returned
99  * object id and using the container's associated tokens and MC portals.
100  *
101  * Return:	'0' on Success; Error code otherwise.
102  */
103 int dpci_create(struct fsl_mc_io *mc_io,
104 		uint16_t dprc_token,
105 		uint32_t cmd_flags,
106 		const struct dpci_cfg *cfg,
107 		uint32_t *obj_id)
108 {
109 	struct dpci_cmd_create *cmd_params;
110 	struct mc_command cmd = { 0 };
111 	int err;
112 
113 	/* prepare command */
114 	cmd.header = mc_encode_cmd_header(DPCI_CMDID_CREATE,
115 					  cmd_flags,
116 					  dprc_token);
117 	cmd_params = (struct dpci_cmd_create *)cmd.params;
118 	cmd_params->num_of_priorities = cfg->num_of_priorities;
119 
120 	/* send command to mc*/
121 	err = mc_send_command(mc_io, &cmd);
122 	if (err)
123 		return err;
124 
125 	/* retrieve response parameters */
126 	*obj_id = mc_cmd_read_object_id(&cmd);
127 
128 	return 0;
129 }
130 
131 /**
132  * dpci_destroy() - Destroy the DPCI object and release all its resources.
133  * @mc_io:	Pointer to MC portal's I/O object
134  * @dprc_token: Parent container token; '0' for default container
135  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
136  * @object_id:	The object id; it must be a valid id within the container that
137  * created this object;
138  *
139  * The function accepts the authentication token of the parent container that
140  * created the object (not the one that currently owns the object). The object
141  * is searched within parent using the provided 'object_id'.
142  * All tokens to the object must be closed before calling destroy.
143  *
144  * Return:	'0' on Success; error code otherwise.
145  */
146 int dpci_destroy(struct fsl_mc_io *mc_io,
147 		 uint16_t dprc_token,
148 		 uint32_t cmd_flags,
149 		 uint32_t object_id)
150 {
151 	struct dpci_cmd_destroy *cmd_params;
152 	struct mc_command cmd = { 0 };
153 
154 	/* prepare command */
155 	cmd.header = mc_encode_cmd_header(DPCI_CMDID_DESTROY,
156 					  cmd_flags,
157 					  dprc_token);
158 	cmd_params = (struct dpci_cmd_destroy *)cmd.params;
159 	cmd_params->dpci_id = cpu_to_le32(object_id);
160 
161 	/* send command to mc*/
162 	return mc_send_command(mc_io, &cmd);
163 }
164 
165 /**
166  * dpci_enable() - Enable the DPCI, allow sending and receiving frames.
167  * @mc_io:	Pointer to MC portal's I/O object
168  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
169  * @token:	Token of DPCI object
170  *
171  * Return:	'0' on Success; Error code otherwise.
172  */
173 int dpci_enable(struct fsl_mc_io *mc_io,
174 		uint32_t cmd_flags,
175 		uint16_t token)
176 {
177 	struct mc_command cmd = { 0 };
178 
179 	/* prepare command */
180 	cmd.header = mc_encode_cmd_header(DPCI_CMDID_ENABLE,
181 					  cmd_flags,
182 					  token);
183 
184 	/* send command to mc*/
185 	return mc_send_command(mc_io, &cmd);
186 }
187 
188 /**
189  * dpci_disable() - Disable the DPCI, stop sending and receiving frames.
190  * @mc_io:	Pointer to MC portal's I/O object
191  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
192  * @token:	Token of DPCI object
193  *
194  * Return:	'0' on Success; Error code otherwise.
195  */
196 int dpci_disable(struct fsl_mc_io *mc_io,
197 		 uint32_t cmd_flags,
198 		 uint16_t token)
199 {
200 	struct mc_command cmd = { 0 };
201 
202 	/* prepare command */
203 	cmd.header = mc_encode_cmd_header(DPCI_CMDID_DISABLE,
204 					  cmd_flags,
205 					  token);
206 
207 	/* send command to mc*/
208 	return mc_send_command(mc_io, &cmd);
209 }
210 
211 /**
212  * dpci_is_enabled() - Check if the DPCI is enabled.
213  * @mc_io:	Pointer to MC portal's I/O object
214  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
215  * @token:	Token of DPCI object
216  * @en:		Returns '1' if object is enabled; '0' otherwise
217  *
218  * Return:	'0' on Success; Error code otherwise.
219  */
220 int dpci_is_enabled(struct fsl_mc_io *mc_io,
221 		    uint32_t cmd_flags,
222 		    uint16_t token,
223 		    int *en)
224 {
225 	struct dpci_rsp_is_enabled *rsp_params;
226 	struct mc_command cmd = { 0 };
227 	int err;
228 
229 	/* prepare command */
230 	cmd.header = mc_encode_cmd_header(DPCI_CMDID_IS_ENABLED, cmd_flags,
231 					  token);
232 
233 	/* send command to mc*/
234 	err = mc_send_command(mc_io, &cmd);
235 	if (err)
236 		return err;
237 
238 	/* retrieve response parameters */
239 	rsp_params = (struct dpci_rsp_is_enabled *)cmd.params;
240 	*en = dpci_get_field(rsp_params->en, ENABLE);
241 
242 	return 0;
243 }
244 
245 /**
246  * dpci_reset() - Reset the DPCI, returns the object to initial state.
247  * @mc_io:	Pointer to MC portal's I/O object
248  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
249  * @token:	Token of DPCI object
250  *
251  * Return:	'0' on Success; Error code otherwise.
252  */
253 int dpci_reset(struct fsl_mc_io *mc_io,
254 	       uint32_t cmd_flags,
255 	       uint16_t token)
256 {
257 	struct mc_command cmd = { 0 };
258 
259 	/* prepare command */
260 	cmd.header = mc_encode_cmd_header(DPCI_CMDID_RESET,
261 					  cmd_flags,
262 					  token);
263 
264 	/* send command to mc*/
265 	return mc_send_command(mc_io, &cmd);
266 }
267 
268 /**
269  * dpci_get_attributes() - Retrieve DPCI attributes.
270  * @mc_io:	Pointer to MC portal's I/O object
271  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
272  * @token:	Token of DPCI object
273  * @attr:	Returned object's attributes
274  *
275  * Return:	'0' on Success; Error code otherwise.
276  */
277 int dpci_get_attributes(struct fsl_mc_io *mc_io,
278 			uint32_t cmd_flags,
279 			uint16_t token,
280 			struct dpci_attr *attr)
281 {
282 	struct dpci_rsp_get_attr *rsp_params;
283 	struct mc_command cmd = { 0 };
284 	int err;
285 
286 	/* prepare command */
287 	cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_ATTR,
288 					  cmd_flags,
289 					  token);
290 
291 	/* send command to mc*/
292 	err = mc_send_command(mc_io, &cmd);
293 	if (err)
294 		return err;
295 
296 	/* retrieve response parameters */
297 	rsp_params = (struct dpci_rsp_get_attr *)cmd.params;
298 	attr->id = le32_to_cpu(rsp_params->id);
299 	attr->num_of_priorities = rsp_params->num_of_priorities;
300 
301 	return 0;
302 }
303 
304 /**
305  * dpci_set_rx_queue() - Set Rx queue configuration
306  * @mc_io:	Pointer to MC portal's I/O object
307  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
308  * @token:	Token of DPCI object
309  * @priority:	Select the queue relative to number of
310  *			priorities configured at DPCI creation; use
311  *			DPCI_ALL_QUEUES to configure all Rx queues
312  *			identically.
313  * @cfg:	Rx queue configuration
314  *
315  * Return:	'0' on Success; Error code otherwise.
316  */
317 int dpci_set_rx_queue(struct fsl_mc_io *mc_io,
318 		      uint32_t cmd_flags,
319 		      uint16_t token,
320 		      uint8_t priority,
321 		      const struct dpci_rx_queue_cfg *cfg)
322 {
323 	struct dpci_cmd_set_rx_queue *cmd_params;
324 	struct mc_command cmd = { 0 };
325 
326 	/* prepare command */
327 	cmd.header = mc_encode_cmd_header(DPCI_CMDID_SET_RX_QUEUE,
328 					  cmd_flags,
329 					  token);
330 	cmd_params = (struct dpci_cmd_set_rx_queue *)cmd.params;
331 	cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
332 	cmd_params->dest_priority = cfg->dest_cfg.priority;
333 	cmd_params->priority = priority;
334 	cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx);
335 	cmd_params->options = cpu_to_le32(cfg->options);
336 	dpci_set_field(cmd_params->dest_type,
337 		       DEST_TYPE,
338 		       cfg->dest_cfg.dest_type);
339 	dpci_set_field(cmd_params->dest_type,
340 		       ORDER_PRESERVATION,
341 		       cfg->order_preservation_en);
342 
343 	/* send command to mc*/
344 	return mc_send_command(mc_io, &cmd);
345 }
346 
347 /**
348  * dpci_get_rx_queue() - Retrieve Rx queue attributes.
349  * @mc_io:	Pointer to MC portal's I/O object
350  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
351  * @token:	Token of DPCI object
352  * @priority:	Select the queue relative to number of
353  *		priorities configured at DPCI creation
354  * @attr:	Returned Rx queue attributes
355  *
356  * Return:	'0' on Success; Error code otherwise.
357  */
358 int dpci_get_rx_queue(struct fsl_mc_io *mc_io,
359 		      uint32_t cmd_flags,
360 		      uint16_t token,
361 		      uint8_t priority,
362 		      struct dpci_rx_queue_attr *attr)
363 {
364 	struct dpci_cmd_get_queue *cmd_params;
365 	struct dpci_rsp_get_rx_queue *rsp_params;
366 	struct mc_command cmd = { 0 };
367 	int err;
368 
369 	/* prepare command */
370 	cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_RX_QUEUE,
371 					  cmd_flags,
372 					  token);
373 	cmd_params = (struct dpci_cmd_get_queue *)cmd.params;
374 	cmd_params->priority = priority;
375 
376 	/* send command to mc*/
377 	err = mc_send_command(mc_io, &cmd);
378 	if (err)
379 		return err;
380 
381 	/* retrieve response parameters */
382 	rsp_params = (struct dpci_rsp_get_rx_queue *)cmd.params;
383 	attr->user_ctx = le64_to_cpu(rsp_params->user_ctx);
384 	attr->fqid = le32_to_cpu(rsp_params->fqid);
385 	attr->dest_cfg.dest_id = le32_to_cpu(rsp_params->dest_id);
386 	attr->dest_cfg.priority = rsp_params->dest_priority;
387 	attr->dest_cfg.dest_type = dpci_get_field(rsp_params->dest_type,
388 						  DEST_TYPE);
389 
390 	return 0;
391 }
392 
393 /**
394  * dpci_get_tx_queue() - Retrieve Tx queue attributes.
395  * @mc_io:	Pointer to MC portal's I/O object
396  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
397  * @token:	Token of DPCI object
398  * @priority:	Select the queue relative to number of
399  *		priorities of the peer DPCI object
400  * @attr:	Returned Tx queue attributes
401  *
402  * Return:	'0' on Success; Error code otherwise.
403  */
404 int dpci_get_tx_queue(struct fsl_mc_io *mc_io,
405 		      uint32_t cmd_flags,
406 		      uint16_t token,
407 		      uint8_t priority,
408 		      struct dpci_tx_queue_attr *attr)
409 {
410 	struct dpci_cmd_get_queue *cmd_params;
411 	struct dpci_rsp_get_tx_queue *rsp_params;
412 	struct mc_command cmd = { 0 };
413 	int err;
414 
415 	/* prepare command */
416 	cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_TX_QUEUE,
417 					  cmd_flags,
418 					  token);
419 	cmd_params = (struct dpci_cmd_get_queue *)cmd.params;
420 	cmd_params->priority = priority;
421 
422 	/* send command to mc*/
423 	err = mc_send_command(mc_io, &cmd);
424 	if (err)
425 		return err;
426 
427 	/* retrieve response parameters */
428 	rsp_params = (struct dpci_rsp_get_tx_queue *)cmd.params;
429 	attr->fqid = le32_to_cpu(rsp_params->fqid);
430 
431 	return 0;
432 }
433 
434 /**
435  * dpci_get_api_version() - Get communication interface API version
436  * @mc_io:	Pointer to MC portal's I/O object
437  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
438  * @major_ver:	Major version of data path communication interface API
439  * @minor_ver:	Minor version of data path communication interface API
440  *
441  * Return:  '0' on Success; Error code otherwise.
442  */
443 int dpci_get_api_version(struct fsl_mc_io *mc_io,
444 			 uint32_t cmd_flags,
445 			 uint16_t *major_ver,
446 			 uint16_t *minor_ver)
447 {
448 	struct dpci_rsp_get_api_version *rsp_params;
449 	struct mc_command cmd = { 0 };
450 	int err;
451 
452 	cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_API_VERSION,
453 					cmd_flags,
454 					0);
455 
456 	err = mc_send_command(mc_io, &cmd);
457 	if (err)
458 		return err;
459 
460 	rsp_params = (struct dpci_rsp_get_api_version *)cmd.params;
461 	*major_ver = le16_to_cpu(rsp_params->major);
462 	*minor_ver = le16_to_cpu(rsp_params->minor);
463 
464 	return 0;
465 }
466 
467 /**
468  * dpci_set_opr() - Set Order Restoration configuration.
469  * @mc_io:	Pointer to MC portal's I/O object
470  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
471  * @token:	Token of DPCI object
472  * @index:	The queue index
473  * @options:	Configuration mode options
474  *		can be OPR_OPT_CREATE or OPR_OPT_RETIRE
475  * @cfg:	Configuration options for the OPR
476  *
477  * Return:	'0' on Success; Error code otherwise.
478  */
479 int dpci_set_opr(struct fsl_mc_io *mc_io,
480 		 uint32_t cmd_flags,
481 		 uint16_t token,
482 		 uint8_t index,
483 		 uint8_t options,
484 		 struct opr_cfg *cfg)
485 {
486 	struct dpci_cmd_set_opr *cmd_params;
487 	struct mc_command cmd = { 0 };
488 
489 	/* prepare command */
490 	cmd.header = mc_encode_cmd_header(DPCI_CMDID_SET_OPR,
491 					  cmd_flags,
492 					  token);
493 	cmd_params = (struct dpci_cmd_set_opr *)cmd.params;
494 	cmd_params->index = index;
495 	cmd_params->options = options;
496 	cmd_params->oloe = cfg->oloe;
497 	cmd_params->oeane = cfg->oeane;
498 	cmd_params->olws = cfg->olws;
499 	cmd_params->oa = cfg->oa;
500 	cmd_params->oprrws = cfg->oprrws;
501 
502 	/* send command to mc*/
503 	return mc_send_command(mc_io, &cmd);
504 }
505 
506 /**
507  * dpci_get_opr() - Retrieve Order Restoration config and query.
508  * @mc_io:	Pointer to MC portal's I/O object
509  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
510  * @token:	Token of DPCI object
511  * @index:	The queue index
512  * @cfg:	Returned OPR configuration
513  * @qry:	Returned OPR query
514  *
515  * Return:	'0' on Success; Error code otherwise.
516  */
517 int dpci_get_opr(struct fsl_mc_io *mc_io,
518 		 uint32_t cmd_flags,
519 		 uint16_t token,
520 		 uint8_t index,
521 		 struct opr_cfg *cfg,
522 		 struct opr_qry *qry)
523 {
524 	struct dpci_rsp_get_opr *rsp_params;
525 	struct dpci_cmd_get_opr *cmd_params;
526 	struct mc_command cmd = { 0 };
527 	int err;
528 
529 	/* prepare command */
530 	cmd.header = mc_encode_cmd_header(DPCI_CMDID_GET_OPR,
531 					  cmd_flags,
532 					  token);
533 	cmd_params = (struct dpci_cmd_get_opr *)cmd.params;
534 	cmd_params->index = index;
535 
536 	/* send command to mc*/
537 	err = mc_send_command(mc_io, &cmd);
538 	if (err)
539 		return err;
540 
541 	/* retrieve response parameters */
542 	rsp_params = (struct dpci_rsp_get_opr *)cmd.params;
543 	cfg->oloe = rsp_params->oloe;
544 	cfg->oeane = rsp_params->oeane;
545 	cfg->olws = rsp_params->olws;
546 	cfg->oa = rsp_params->oa;
547 	cfg->oprrws = rsp_params->oprrws;
548 	qry->rip = dpci_get_field(rsp_params->flags, RIP);
549 	qry->enable = dpci_get_field(rsp_params->flags, OPR_ENABLE);
550 	qry->nesn = le16_to_cpu(rsp_params->nesn);
551 	qry->ndsn = le16_to_cpu(rsp_params->ndsn);
552 	qry->ea_tseq = le16_to_cpu(rsp_params->ea_tseq);
553 	qry->tseq_nlis = dpci_get_field(rsp_params->tseq_nlis, TSEQ_NLIS);
554 	qry->ea_hseq = le16_to_cpu(rsp_params->ea_hseq);
555 	qry->hseq_nlis = dpci_get_field(rsp_params->hseq_nlis, HSEQ_NLIS);
556 	qry->ea_hptr = le16_to_cpu(rsp_params->ea_hptr);
557 	qry->ea_tptr = le16_to_cpu(rsp_params->ea_tptr);
558 	qry->opr_vid = le16_to_cpu(rsp_params->opr_vid);
559 	qry->opr_id = le16_to_cpu(rsp_params->opr_id);
560 
561 	return 0;
562 }
563