xref: /dpdk/drivers/net/dpaa2/mc/dpni.c (revision 27b549c12df2ef2db6b271795b4df7b14a2d9c2c)
1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2  *
3  * Copyright 2013-2016 Freescale Semiconductor Inc.
4  * Copyright 2016-2019 NXP
5  *
6  */
7 #include <fsl_mc_sys.h>
8 #include <fsl_mc_cmd.h>
9 #include <fsl_dpni.h>
10 #include <fsl_dpni_cmd.h>
11 
12 /**
13  * dpni_open() - Open a control session for the specified object
14  * @mc_io:	Pointer to MC portal's I/O object
15  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
16  * @dpni_id:	DPNI unique ID
17  * @token:	Returned token; use in subsequent API calls
18  *
19  * This function can be used to open a control session for an
20  * already created object; an object may have been declared in
21  * the DPL or by calling the dpni_create() function.
22  * This function returns a unique authentication token,
23  * associated with the specific object ID and the specific MC
24  * portal; this token must be used in all subsequent commands for
25  * this specific object.
26  *
27  * Return:	'0' on Success; Error code otherwise.
28  */
29 int dpni_open(struct fsl_mc_io *mc_io,
30 	      uint32_t cmd_flags,
31 	      int dpni_id,
32 	      uint16_t *token)
33 {
34 	struct mc_command cmd = { 0 };
35 	struct dpni_cmd_open *cmd_params;
36 
37 	int err;
38 
39 	/* prepare command */
40 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_OPEN,
41 					  cmd_flags,
42 					  0);
43 	cmd_params = (struct dpni_cmd_open *)cmd.params;
44 	cmd_params->dpni_id = cpu_to_le32(dpni_id);
45 
46 	/* send command to mc*/
47 	err = mc_send_command(mc_io, &cmd);
48 	if (err)
49 		return err;
50 
51 	/* retrieve response parameters */
52 	*token = mc_cmd_hdr_read_token(&cmd);
53 
54 	return 0;
55 }
56 
57 /**
58  * dpni_close() - Close the control session of the object
59  * @mc_io:	Pointer to MC portal's I/O object
60  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
61  * @token:	Token of DPNI object
62  *
63  * After this function is called, no further operations are
64  * allowed on the object without opening a new control session.
65  *
66  * Return:	'0' on Success; Error code otherwise.
67  */
68 int dpni_close(struct fsl_mc_io *mc_io,
69 	       uint32_t cmd_flags,
70 	       uint16_t token)
71 {
72 	struct mc_command cmd = { 0 };
73 
74 	/* prepare command */
75 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLOSE,
76 					  cmd_flags,
77 					  token);
78 
79 	/* send command to mc*/
80 	return mc_send_command(mc_io, &cmd);
81 }
82 
83 /**
84  * dpni_create() - Create the DPNI object
85  * @mc_io:	Pointer to MC portal's I/O object
86  * @dprc_token:	Parent container token; '0' for default container
87  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
88  * @cfg:	Configuration structure
89  * @obj_id:	Returned object id
90  *
91  * Create the DPNI object, allocate required resources and
92  * perform required initialization.
93  *
94  * The object can be created either by declaring it in the
95  * DPL file, or by calling this function.
96  *
97  * The function accepts an authentication token of a parent
98  * container that this object should be assigned to. The token
99  * can be '0' so the object will be assigned to the default container.
100  * The newly created object can be opened with the returned
101  * object id and using the container's associated tokens and MC portals.
102  *
103  * Return:	'0' on Success; Error code otherwise.
104  */
105 int dpni_create(struct fsl_mc_io *mc_io,
106 		uint16_t dprc_token,
107 		uint32_t cmd_flags,
108 		const struct dpni_cfg *cfg,
109 		uint32_t *obj_id)
110 {
111 	struct dpni_cmd_create *cmd_params;
112 	struct mc_command cmd = { 0 };
113 	int err;
114 
115 	/* prepare command */
116 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_CREATE,
117 					  cmd_flags,
118 					  dprc_token);
119 	cmd_params = (struct dpni_cmd_create *)cmd.params;
120 	cmd_params->options = cpu_to_le32(cfg->options);
121 	cmd_params->num_queues = cfg->num_queues;
122 	cmd_params->num_tcs = cfg->num_tcs;
123 	cmd_params->mac_filter_entries = cfg->mac_filter_entries;
124 	cmd_params->num_rx_tcs = cfg->num_rx_tcs;
125 	cmd_params->vlan_filter_entries =  cfg->vlan_filter_entries;
126 	cmd_params->qos_entries = cfg->qos_entries;
127 	cmd_params->fs_entries = cpu_to_le16(cfg->fs_entries);
128 	cmd_params->num_cgs = cfg->num_cgs;
129 
130 	/* send command to mc*/
131 	err = mc_send_command(mc_io, &cmd);
132 	if (err)
133 		return err;
134 
135 	/* retrieve response parameters */
136 	*obj_id = mc_cmd_read_object_id(&cmd);
137 
138 	return 0;
139 }
140 
141 /**
142  * dpni_destroy() - Destroy the DPNI object and release all its resources.
143  * @mc_io:	Pointer to MC portal's I/O object
144  * @dprc_token: Parent container token; '0' for default container
145  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
146  * @object_id:	The object id; it must be a valid id within the container that
147  * created this object;
148  *
149  * The function accepts the authentication token of the parent container that
150  * created the object (not the one that currently owns the object). The object
151  * is searched within parent using the provided 'object_id'.
152  * All tokens to the object must be closed before calling destroy.
153  *
154  * Return:	'0' on Success; error code otherwise.
155  */
156 int dpni_destroy(struct fsl_mc_io *mc_io,
157 		 uint16_t dprc_token,
158 		 uint32_t cmd_flags,
159 		 uint32_t object_id)
160 {
161 	struct dpni_cmd_destroy *cmd_params;
162 	struct mc_command cmd = { 0 };
163 
164 	/* prepare command */
165 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_DESTROY,
166 					  cmd_flags,
167 					  dprc_token);
168 	/* set object id to destroy */
169 	cmd_params = (struct dpni_cmd_destroy *)cmd.params;
170 	cmd_params->dpsw_id = cpu_to_le32(object_id);
171 
172 	/* send command to mc*/
173 	return mc_send_command(mc_io, &cmd);
174 }
175 
176 /**
177  * dpni_set_pools() - Set buffer pools configuration
178  * @mc_io:	Pointer to MC portal's I/O object
179  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
180  * @token:	Token of DPNI object
181  * @cfg:	Buffer pools configuration
182  *
183  * mandatory for DPNI operation
184  * warning:Allowed only when DPNI is disabled
185  *
186  * Return:	'0' on Success; Error code otherwise.
187  */
188 int dpni_set_pools(struct fsl_mc_io *mc_io,
189 		   uint32_t cmd_flags,
190 		   uint16_t token,
191 		   const struct dpni_pools_cfg *cfg)
192 {
193 	struct mc_command cmd = { 0 };
194 	struct dpni_cmd_set_pools *cmd_params;
195 	int i;
196 
197 	/* prepare command */
198 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_POOLS,
199 					  cmd_flags,
200 					  token);
201 	cmd_params = (struct dpni_cmd_set_pools *)cmd.params;
202 	cmd_params->num_dpbp = cfg->num_dpbp;
203 	cmd_params->pool_options = cfg->pool_options;
204 	for (i = 0; i < cmd_params->num_dpbp; i++) {
205 		cmd_params->pool[i].dpbp_id =
206 			cpu_to_le16(cfg->pools[i].dpbp_id);
207 		cmd_params->pool[i].priority_mask =
208 			cfg->pools[i].priority_mask;
209 		cmd_params->buffer_size[i] =
210 			cpu_to_le16(cfg->pools[i].buffer_size);
211 		cmd_params->backup_pool_mask |=
212 			DPNI_BACKUP_POOL(cfg->pools[i].backup_pool, i);
213 	}
214 
215 	/* send command to mc*/
216 	return mc_send_command(mc_io, &cmd);
217 }
218 
219 /**
220  * dpni_enable() - Enable the DPNI, allow sending and receiving frames.
221  * @mc_io:	Pointer to MC portal's I/O object
222  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
223  * @token:	Token of DPNI object
224  *
225  * Return:	'0' on Success; Error code otherwise.
226  */
227 int dpni_enable(struct fsl_mc_io *mc_io,
228 		uint32_t cmd_flags,
229 		uint16_t token)
230 {
231 	struct mc_command cmd = { 0 };
232 
233 	/* prepare command */
234 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE,
235 					  cmd_flags,
236 					  token);
237 
238 	/* send command to mc*/
239 	return mc_send_command(mc_io, &cmd);
240 }
241 
242 /**
243  * dpni_disable() - Disable the DPNI, stop sending and receiving frames.
244  * @mc_io:	Pointer to MC portal's I/O object
245  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
246  * @token:	Token of DPNI object
247  *
248  * Return:	'0' on Success; Error code otherwise.
249  */
250 int dpni_disable(struct fsl_mc_io *mc_io,
251 		 uint32_t cmd_flags,
252 		 uint16_t token)
253 {
254 	struct mc_command cmd = { 0 };
255 
256 	/* prepare command */
257 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_DISABLE,
258 					  cmd_flags,
259 					  token);
260 
261 	/* send command to mc*/
262 	return mc_send_command(mc_io, &cmd);
263 }
264 
265 /**
266  * dpni_is_enabled() - Check if the DPNI is enabled.
267  * @mc_io:	Pointer to MC portal's I/O object
268  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
269  * @token:	Token of DPNI object
270  * @en:		Returns '1' if object is enabled; '0' otherwise
271  *
272  * Return:	'0' on Success; Error code otherwise.
273  */
274 int dpni_is_enabled(struct fsl_mc_io *mc_io,
275 		    uint32_t cmd_flags,
276 		    uint16_t token,
277 		    int *en)
278 {
279 	struct mc_command cmd = { 0 };
280 	struct dpni_rsp_is_enabled *rsp_params;
281 	int err;
282 
283 	/* prepare command */
284 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_IS_ENABLED,
285 					  cmd_flags,
286 					  token);
287 
288 	/* send command to mc*/
289 	err = mc_send_command(mc_io, &cmd);
290 	if (err)
291 		return err;
292 
293 	/* retrieve response parameters */
294 	rsp_params = (struct dpni_rsp_is_enabled *)cmd.params;
295 	*en = dpni_get_field(rsp_params->enabled, ENABLE);
296 
297 	return 0;
298 }
299 
300 /**
301  * dpni_reset() - Reset the DPNI, returns the object to initial state.
302  * @mc_io:	Pointer to MC portal's I/O object
303  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
304  * @token:	Token of DPNI object
305  *
306  * Return:	'0' on Success; Error code otherwise.
307  */
308 int dpni_reset(struct fsl_mc_io *mc_io,
309 	       uint32_t cmd_flags,
310 	       uint16_t token)
311 {
312 	struct mc_command cmd = { 0 };
313 
314 	/* prepare command */
315 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET,
316 					  cmd_flags,
317 					  token);
318 
319 	/* send command to mc*/
320 	return mc_send_command(mc_io, &cmd);
321 }
322 
323 /**
324  * dpni_set_irq_enable() - Set overall interrupt state.
325  * @mc_io:	Pointer to MC portal's I/O object
326  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
327  * @token:	Token of DPNI object
328  * @irq_index:	The interrupt index to configure
329  * @en:		Interrupt state: - enable = 1, disable = 0
330  *
331  * Allows GPP software to control when interrupts are generated.
332  * Each interrupt can have up to 32 causes.  The enable/disable control's the
333  * overall interrupt state. if the interrupt is disabled no causes will cause
334  * an interrupt.
335  *
336  * Return:	'0' on Success; Error code otherwise.
337  */
338 int dpni_set_irq_enable(struct fsl_mc_io *mc_io,
339 			uint32_t cmd_flags,
340 			uint16_t token,
341 			uint8_t irq_index,
342 			uint8_t en)
343 {
344 	struct mc_command cmd = { 0 };
345 	struct dpni_cmd_set_irq_enable *cmd_params;
346 
347 	/* prepare command */
348 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_IRQ_ENABLE,
349 					  cmd_flags,
350 					  token);
351 	cmd_params = (struct dpni_cmd_set_irq_enable *)cmd.params;
352 	dpni_set_field(cmd_params->enable, ENABLE, en);
353 	cmd_params->irq_index = irq_index;
354 
355 	/* send command to mc*/
356 	return mc_send_command(mc_io, &cmd);
357 }
358 
359 /**
360  * dpni_get_irq_enable() - Get overall interrupt state
361  * @mc_io:	Pointer to MC portal's I/O object
362  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
363  * @token:	Token of DPNI object
364  * @irq_index:	The interrupt index to configure
365  * @en:		Returned interrupt state - enable = 1, disable = 0
366  *
367  * Return:	'0' on Success; Error code otherwise.
368  */
369 int dpni_get_irq_enable(struct fsl_mc_io *mc_io,
370 			uint32_t cmd_flags,
371 			uint16_t token,
372 			uint8_t irq_index,
373 			uint8_t *en)
374 {
375 	struct mc_command cmd = { 0 };
376 	struct dpni_cmd_get_irq_enable *cmd_params;
377 	struct dpni_rsp_get_irq_enable *rsp_params;
378 
379 	int err;
380 
381 	/* prepare command */
382 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_IRQ_ENABLE,
383 					  cmd_flags,
384 					  token);
385 	cmd_params = (struct dpni_cmd_get_irq_enable *)cmd.params;
386 	cmd_params->irq_index = irq_index;
387 
388 	/* send command to mc*/
389 	err = mc_send_command(mc_io, &cmd);
390 	if (err)
391 		return err;
392 
393 	/* retrieve response parameters */
394 	rsp_params = (struct dpni_rsp_get_irq_enable *)cmd.params;
395 	*en = dpni_get_field(rsp_params->enabled, ENABLE);
396 
397 	return 0;
398 }
399 
400 /**
401  * dpni_set_irq_mask() - Set interrupt mask.
402  * @mc_io:	Pointer to MC portal's I/O object
403  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
404  * @token:	Token of DPNI object
405  * @irq_index:	The interrupt index to configure
406  * @mask:	Event mask to trigger interrupt;
407  *		each bit:
408  *			0 = ignore event
409  *			1 = consider event for asserting IRQ
410  *
411  * Every interrupt can have up to 32 causes and the interrupt model supports
412  * masking/unmasking each cause independently
413  *
414  * Return:	'0' on Success; Error code otherwise.
415  */
416 int dpni_set_irq_mask(struct fsl_mc_io *mc_io,
417 		      uint32_t cmd_flags,
418 		      uint16_t token,
419 		      uint8_t irq_index,
420 		      uint32_t mask)
421 {
422 	struct mc_command cmd = { 0 };
423 	struct dpni_cmd_set_irq_mask *cmd_params;
424 
425 	/* prepare command */
426 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_IRQ_MASK,
427 					  cmd_flags,
428 					  token);
429 	cmd_params = (struct dpni_cmd_set_irq_mask *)cmd.params;
430 	cmd_params->mask = cpu_to_le32(mask);
431 	cmd_params->irq_index = irq_index;
432 
433 	/* send command to mc*/
434 	return mc_send_command(mc_io, &cmd);
435 }
436 
437 /**
438  * dpni_get_irq_mask() - Get interrupt mask.
439  * @mc_io:	Pointer to MC portal's I/O object
440  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
441  * @token:	Token of DPNI object
442  * @irq_index:	The interrupt index to configure
443  * @mask:	Returned event mask to trigger interrupt
444  *
445  * Every interrupt can have up to 32 causes and the interrupt model supports
446  * masking/unmasking each cause independently
447  *
448  * Return:	'0' on Success; Error code otherwise.
449  */
450 int dpni_get_irq_mask(struct fsl_mc_io *mc_io,
451 		      uint32_t cmd_flags,
452 		      uint16_t token,
453 		      uint8_t irq_index,
454 		      uint32_t *mask)
455 {
456 	struct mc_command cmd = { 0 };
457 	struct dpni_cmd_get_irq_mask *cmd_params;
458 	struct dpni_rsp_get_irq_mask *rsp_params;
459 	int err;
460 
461 	/* prepare command */
462 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_IRQ_MASK,
463 					  cmd_flags,
464 					  token);
465 	cmd_params = (struct dpni_cmd_get_irq_mask *)cmd.params;
466 	cmd_params->irq_index = irq_index;
467 
468 	/* send command to mc*/
469 	err = mc_send_command(mc_io, &cmd);
470 	if (err)
471 		return err;
472 
473 	/* retrieve response parameters */
474 	rsp_params = (struct dpni_rsp_get_irq_mask *)cmd.params;
475 	*mask = le32_to_cpu(rsp_params->mask);
476 
477 	return 0;
478 }
479 
480 /**
481  * dpni_get_irq_status() - Get the current status of any pending interrupts.
482  * @mc_io:	Pointer to MC portal's I/O object
483  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
484  * @token:	Token of DPNI object
485  * @irq_index:	The interrupt index to configure
486  * @status:	Returned interrupts status - one bit per cause:
487  *			0 = no interrupt pending
488  *			1 = interrupt pending
489  *
490  * Return:	'0' on Success; Error code otherwise.
491  */
492 int dpni_get_irq_status(struct fsl_mc_io *mc_io,
493 			uint32_t cmd_flags,
494 			uint16_t token,
495 			uint8_t irq_index,
496 			uint32_t *status)
497 {
498 	struct mc_command cmd = { 0 };
499 	struct dpni_cmd_get_irq_status *cmd_params;
500 	struct dpni_rsp_get_irq_status *rsp_params;
501 	int err;
502 
503 	/* prepare command */
504 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_IRQ_STATUS,
505 					  cmd_flags,
506 					  token);
507 	cmd_params = (struct dpni_cmd_get_irq_status *)cmd.params;
508 	cmd_params->status = cpu_to_le32(*status);
509 	cmd_params->irq_index = irq_index;
510 
511 	/* send command to mc*/
512 	err = mc_send_command(mc_io, &cmd);
513 	if (err)
514 		return err;
515 
516 	/* retrieve response parameters */
517 	rsp_params = (struct dpni_rsp_get_irq_status *)cmd.params;
518 	*status = le32_to_cpu(rsp_params->status);
519 
520 	return 0;
521 }
522 
523 /**
524  * dpni_clear_irq_status() - Clear a pending interrupt's status
525  * @mc_io:	Pointer to MC portal's I/O object
526  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
527  * @token:	Token of DPNI object
528  * @irq_index:	The interrupt index to configure
529  * @status:	bits to clear (W1C) - one bit per cause:
530  *			0 = don't change
531  *			1 = clear status bit
532  *
533  * Return:	'0' on Success; Error code otherwise.
534  */
535 int dpni_clear_irq_status(struct fsl_mc_io *mc_io,
536 			  uint32_t cmd_flags,
537 			  uint16_t token,
538 			  uint8_t irq_index,
539 			  uint32_t status)
540 {
541 	struct mc_command cmd = { 0 };
542 	struct dpni_cmd_clear_irq_status *cmd_params;
543 
544 	/* prepare command */
545 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLEAR_IRQ_STATUS,
546 					  cmd_flags,
547 					  token);
548 	cmd_params = (struct dpni_cmd_clear_irq_status *)cmd.params;
549 	cmd_params->irq_index = irq_index;
550 	cmd_params->status = cpu_to_le32(status);
551 
552 	/* send command to mc*/
553 	return mc_send_command(mc_io, &cmd);
554 }
555 
556 /**
557  * dpni_get_attributes() - Retrieve DPNI attributes.
558  * @mc_io:	Pointer to MC portal's I/O object
559  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
560  * @token:	Token of DPNI object
561  * @attr:	Object's attributes
562  *
563  * Return:	'0' on Success; Error code otherwise.
564  */
565 int dpni_get_attributes(struct fsl_mc_io *mc_io,
566 			uint32_t cmd_flags,
567 			uint16_t token,
568 			struct dpni_attr *attr)
569 {
570 	struct mc_command cmd = { 0 };
571 	struct dpni_rsp_get_attr *rsp_params;
572 
573 	int err;
574 
575 	/* prepare command */
576 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_ATTR,
577 					  cmd_flags,
578 					  token);
579 
580 	/* send command to mc*/
581 	err = mc_send_command(mc_io, &cmd);
582 	if (err)
583 		return err;
584 
585 	/* retrieve response parameters */
586 	rsp_params = (struct dpni_rsp_get_attr *)cmd.params;
587 	attr->options = le32_to_cpu(rsp_params->options);
588 	attr->num_queues = rsp_params->num_queues;
589 	attr->num_rx_tcs = rsp_params->num_rx_tcs;
590 	attr->num_tx_tcs = rsp_params->num_tx_tcs;
591 	attr->mac_filter_entries = rsp_params->mac_filter_entries;
592 	attr->vlan_filter_entries = rsp_params->vlan_filter_entries;
593 	attr->qos_entries = rsp_params->qos_entries;
594 	attr->fs_entries = le16_to_cpu(rsp_params->fs_entries);
595 	attr->qos_key_size = rsp_params->qos_key_size;
596 	attr->fs_key_size = rsp_params->fs_key_size;
597 	attr->wriop_version = le16_to_cpu(rsp_params->wriop_version);
598 	attr->num_cgs = rsp_params->num_cgs;
599 
600 	return 0;
601 }
602 
603 /**
604  * dpni_set_errors_behavior() - Set errors behavior
605  * @mc_io:	Pointer to MC portal's I/O object
606  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
607  * @token:	Token of DPNI object
608  * @cfg:	Errors configuration
609  *
610  * This function may be called numerous times with different
611  * error masks
612  *
613  * Return:	'0' on Success; Error code otherwise.
614  */
615 int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
616 			     uint32_t cmd_flags,
617 			     uint16_t token,
618 			     struct dpni_error_cfg *cfg)
619 {
620 	struct mc_command cmd = { 0 };
621 	struct dpni_cmd_set_errors_behavior *cmd_params;
622 
623 	/* prepare command */
624 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_ERRORS_BEHAVIOR,
625 					  cmd_flags,
626 					  token);
627 	cmd_params = (struct dpni_cmd_set_errors_behavior *)cmd.params;
628 	cmd_params->errors = cpu_to_le32(cfg->errors);
629 	dpni_set_field(cmd_params->flags, ERROR_ACTION, cfg->error_action);
630 	dpni_set_field(cmd_params->flags, FRAME_ANN, cfg->set_frame_annotation);
631 
632 	/* send command to mc*/
633 	return mc_send_command(mc_io, &cmd);
634 }
635 
636 /**
637  * dpni_get_buffer_layout() - Retrieve buffer layout attributes.
638  * @mc_io:	Pointer to MC portal's I/O object
639  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
640  * @token:	Token of DPNI object
641  * @qtype:	Type of queue to retrieve configuration for
642  * @layout:	Returns buffer layout attributes
643  *
644  * Return:	'0' on Success; Error code otherwise.
645  */
646 int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
647 			   uint32_t cmd_flags,
648 			   uint16_t token,
649 			   enum dpni_queue_type qtype,
650 			   struct dpni_buffer_layout *layout)
651 {
652 	struct mc_command cmd = { 0 };
653 	struct dpni_cmd_get_buffer_layout *cmd_params;
654 	struct dpni_rsp_get_buffer_layout *rsp_params;
655 	int err;
656 
657 	/* prepare command */
658 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_BUFFER_LAYOUT,
659 					  cmd_flags,
660 					  token);
661 	cmd_params = (struct dpni_cmd_get_buffer_layout *)cmd.params;
662 	cmd_params->qtype = qtype;
663 
664 	/* send command to mc*/
665 	err = mc_send_command(mc_io, &cmd);
666 	if (err)
667 		return err;
668 
669 	/* retrieve response parameters */
670 	rsp_params = (struct dpni_rsp_get_buffer_layout *)cmd.params;
671 	layout->pass_timestamp =
672 				(int)dpni_get_field(rsp_params->flags, PASS_TS);
673 	layout->pass_parser_result =
674 				(int)dpni_get_field(rsp_params->flags, PASS_PR);
675 	layout->pass_frame_status =
676 				(int)dpni_get_field(rsp_params->flags, PASS_FS);
677 	layout->pass_sw_opaque =
678 			(int)dpni_get_field(rsp_params->flags, PASS_SWO);
679 	layout->private_data_size = le16_to_cpu(rsp_params->private_data_size);
680 	layout->data_align = le16_to_cpu(rsp_params->data_align);
681 	layout->data_head_room = le16_to_cpu(rsp_params->head_room);
682 	layout->data_tail_room = le16_to_cpu(rsp_params->tail_room);
683 
684 	return 0;
685 }
686 
687 /**
688  * dpni_set_buffer_layout() - Set buffer layout configuration.
689  * @mc_io:	Pointer to MC portal's I/O object
690  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
691  * @token:	Token of DPNI object
692  * @qtype:	Type of queue this configuration applies to
693  * @layout:	Buffer layout configuration
694  *
695  * Return:	'0' on Success; Error code otherwise.
696  *
697  * @warning	Allowed only when DPNI is disabled
698  */
699 int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
700 			   uint32_t cmd_flags,
701 			   uint16_t token,
702 			   enum dpni_queue_type qtype,
703 			   const struct dpni_buffer_layout *layout)
704 {
705 	struct mc_command cmd = { 0 };
706 	struct dpni_cmd_set_buffer_layout *cmd_params;
707 
708 	/* prepare command */
709 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_BUFFER_LAYOUT,
710 					  cmd_flags,
711 					  token);
712 	cmd_params = (struct dpni_cmd_set_buffer_layout *)cmd.params;
713 	cmd_params->qtype = qtype;
714 	cmd_params->options = cpu_to_le16((uint16_t)layout->options);
715 	dpni_set_field(cmd_params->flags, PASS_TS, layout->pass_timestamp);
716 	dpni_set_field(cmd_params->flags, PASS_PR, layout->pass_parser_result);
717 	dpni_set_field(cmd_params->flags, PASS_FS, layout->pass_frame_status);
718 	dpni_set_field(cmd_params->flags, PASS_SWO, layout->pass_sw_opaque);
719 	cmd_params->private_data_size = cpu_to_le16(layout->private_data_size);
720 	cmd_params->data_align = cpu_to_le16(layout->data_align);
721 	cmd_params->head_room = cpu_to_le16(layout->data_head_room);
722 	cmd_params->tail_room = cpu_to_le16(layout->data_tail_room);
723 
724 	/* send command to mc*/
725 	return mc_send_command(mc_io, &cmd);
726 }
727 
728 /**
729  * dpni_set_offload() - Set DPNI offload configuration.
730  * @mc_io:	Pointer to MC portal's I/O object
731  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
732  * @token:	Token of DPNI object
733  * @type:	Type of DPNI offload
734  * @config:	Offload configuration.
735  *		For checksum offloads, non-zero value enables the offload
736  *
737  * Return:     '0' on Success; Error code otherwise.
738  *
739  * @warning    Allowed only when DPNI is disabled
740  */
741 
742 int dpni_set_offload(struct fsl_mc_io *mc_io,
743 		     uint32_t cmd_flags,
744 		     uint16_t token,
745 		     enum dpni_offload type,
746 		     uint32_t config)
747 {
748 	struct mc_command cmd = { 0 };
749 	struct dpni_cmd_set_offload *cmd_params;
750 
751 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_OFFLOAD,
752 					  cmd_flags,
753 					  token);
754 	cmd_params = (struct dpni_cmd_set_offload *)cmd.params;
755 	cmd_params->dpni_offload = type;
756 	cmd_params->config = cpu_to_le32(config);
757 
758 	return mc_send_command(mc_io, &cmd);
759 }
760 
761 /**
762  * dpni_get_offload() - Get DPNI offload configuration.
763  * @mc_io:	Pointer to MC portal's I/O object
764  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
765  * @token:	Token of DPNI object
766  * @type:	Type of DPNI offload
767  * @config:	Offload configuration.
768  *			For checksum offloads, a value of 1 indicates that the
769  *			offload is enabled.
770  *
771  * Return:	'0' on Success; Error code otherwise.
772  *
773  * @warning	Allowed only when DPNI is disabled
774  */
775 int dpni_get_offload(struct fsl_mc_io *mc_io,
776 		     uint32_t cmd_flags,
777 		     uint16_t token,
778 		     enum dpni_offload type,
779 		     uint32_t *config)
780 {
781 	struct mc_command cmd = { 0 };
782 	struct dpni_cmd_get_offload *cmd_params;
783 	struct dpni_rsp_get_offload *rsp_params;
784 	int err;
785 
786 	/* prepare command */
787 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_OFFLOAD,
788 					  cmd_flags,
789 					  token);
790 	cmd_params = (struct dpni_cmd_get_offload *)cmd.params;
791 	cmd_params->dpni_offload = type;
792 
793 	/* send command to mc*/
794 	err = mc_send_command(mc_io, &cmd);
795 	if (err)
796 		return err;
797 
798 	/* retrieve response parameters */
799 	rsp_params = (struct dpni_rsp_get_offload *)cmd.params;
800 	*config = le32_to_cpu(rsp_params->config);
801 
802 	return 0;
803 }
804 
805 /**
806  * dpni_get_qdid() - Get the Queuing Destination ID (QDID) that should be used
807  *			for enqueue operations
808  * @mc_io:	Pointer to MC portal's I/O object
809  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
810  * @token:	Token of DPNI object
811  * @qtype:	Type of queue to receive QDID for
812  * @qdid:	Returned virtual QDID value that should be used as an argument
813  *			in all enqueue operations
814  *
815  * Return:	'0' on Success; Error code otherwise.
816  */
817 int dpni_get_qdid(struct fsl_mc_io *mc_io,
818 		  uint32_t cmd_flags,
819 		  uint16_t token,
820 		  enum dpni_queue_type qtype,
821 		  uint16_t *qdid)
822 {
823 	struct mc_command cmd = { 0 };
824 	struct dpni_cmd_get_qdid *cmd_params;
825 	struct dpni_rsp_get_qdid *rsp_params;
826 	int err;
827 
828 	/* prepare command */
829 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QDID,
830 					  cmd_flags,
831 					  token);
832 	cmd_params = (struct dpni_cmd_get_qdid *)cmd.params;
833 	cmd_params->qtype = qtype;
834 
835 	/* send command to mc*/
836 	err = mc_send_command(mc_io, &cmd);
837 	if (err)
838 		return err;
839 
840 	/* retrieve response parameters */
841 	rsp_params = (struct dpni_rsp_get_qdid *)cmd.params;
842 	*qdid = le16_to_cpu(rsp_params->qdid);
843 
844 	return 0;
845 }
846 
847 /**
848  * dpni_get_tx_data_offset() - Get the Tx data offset (from start of buffer)
849  * @mc_io:	Pointer to MC portal's I/O object
850  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
851  * @token:	Token of DPNI object
852  * @data_offset: Tx data offset (from start of buffer)
853  *
854  * Return:	'0' on Success; Error code otherwise.
855  */
856 int dpni_get_tx_data_offset(struct fsl_mc_io *mc_io,
857 			    uint32_t cmd_flags,
858 			    uint16_t token,
859 			    uint16_t *data_offset)
860 {
861 	struct mc_command cmd = { 0 };
862 	struct dpni_rsp_get_tx_data_offset *rsp_params;
863 	int err;
864 
865 	/* prepare command */
866 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_DATA_OFFSET,
867 					  cmd_flags,
868 					  token);
869 
870 	/* send command to mc*/
871 	err = mc_send_command(mc_io, &cmd);
872 	if (err)
873 		return err;
874 
875 	/* retrieve response parameters */
876 	rsp_params = (struct dpni_rsp_get_tx_data_offset *)cmd.params;
877 	*data_offset = le16_to_cpu(rsp_params->data_offset);
878 
879 	return 0;
880 }
881 
882 /**
883  * dpni_set_link_cfg() - set the link configuration.
884  * @mc_io:	Pointer to MC portal's I/O object
885  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
886  * @token:	Token of DPNI object
887  * @cfg:	Link configuration
888  *
889  * Return:	'0' on Success; Error code otherwise.
890  */
891 int dpni_set_link_cfg(struct fsl_mc_io *mc_io,
892 		      uint32_t cmd_flags,
893 		      uint16_t token,
894 		      const struct dpni_link_cfg *cfg)
895 {
896 	struct mc_command cmd = { 0 };
897 	struct dpni_cmd_set_link_cfg *cmd_params;
898 
899 	/* prepare command */
900 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_LINK_CFG,
901 					  cmd_flags,
902 					  token);
903 	cmd_params = (struct dpni_cmd_set_link_cfg *)cmd.params;
904 	cmd_params->rate = cpu_to_le32(cfg->rate);
905 	cmd_params->options = cpu_to_le64(cfg->options);
906 	cmd_params->advertising = cpu_to_le64(cfg->advertising);
907 
908 	/* send command to mc*/
909 	return mc_send_command(mc_io, &cmd);
910 }
911 
912 /**
913  * dpni_get_link_state() - Return the link state (either up or down)
914  * @mc_io:	Pointer to MC portal's I/O object
915  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
916  * @token:	Token of DPNI object
917  * @state:	Returned link state;
918  *
919  * Return:	'0' on Success; Error code otherwise.
920  */
921 int dpni_get_link_state(struct fsl_mc_io *mc_io,
922 			uint32_t cmd_flags,
923 			uint16_t token,
924 			struct dpni_link_state *state)
925 {
926 	struct mc_command cmd = { 0 };
927 	struct dpni_rsp_get_link_state *rsp_params;
928 	int err;
929 
930 	/* prepare command */
931 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_STATE,
932 					  cmd_flags,
933 					  token);
934 
935 	/* send command to mc*/
936 	err = mc_send_command(mc_io, &cmd);
937 	if (err)
938 		return err;
939 
940 	/* retrieve response parameters */
941 	rsp_params = (struct dpni_rsp_get_link_state *)cmd.params;
942 	state->up = dpni_get_field(rsp_params->flags, LINK_STATE);
943 	state->state_valid = dpni_get_field(rsp_params->flags, STATE_VALID);
944 	state->rate = le32_to_cpu(rsp_params->rate);
945 	state->options = le64_to_cpu(rsp_params->options);
946 	state->supported = le64_to_cpu(rsp_params->supported);
947 	state->advertising = le64_to_cpu(rsp_params->advertising);
948 
949 	return 0;
950 }
951 
952 /**
953  * dpni_set_max_frame_length() - Set the maximum received frame length.
954  * @mc_io:		Pointer to MC portal's I/O object
955  * @cmd_flags:		Command flags; one or more of 'MC_CMD_FLAG_'
956  * @token:		Token of DPNI object
957  * @max_frame_length:	Maximum received frame length (in bytes);
958  *			frame is discarded if its length exceeds this value
959  *
960  * Return:	'0' on Success; Error code otherwise.
961  */
962 int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
963 			      uint32_t cmd_flags,
964 			      uint16_t token,
965 			      uint16_t max_frame_length)
966 {
967 	struct mc_command cmd = { 0 };
968 	struct dpni_cmd_set_max_frame_length *cmd_params;
969 
970 	/* prepare command */
971 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MAX_FRAME_LENGTH,
972 					  cmd_flags,
973 					  token);
974 	cmd_params = (struct dpni_cmd_set_max_frame_length *)cmd.params;
975 	cmd_params->max_frame_length = cpu_to_le16(max_frame_length);
976 
977 	/* send command to mc*/
978 	return mc_send_command(mc_io, &cmd);
979 }
980 
981 /**
982  * dpni_get_max_frame_length() - Get the maximum received frame length.
983  * @mc_io:		Pointer to MC portal's I/O object
984  * @cmd_flags:		Command flags; one or more of 'MC_CMD_FLAG_'
985  * @token:		Token of DPNI object
986  * @max_frame_length:	Maximum received frame length (in bytes);
987  *			frame is discarded if its length exceeds this value
988  *
989  * Return:	'0' on Success; Error code otherwise.
990  */
991 int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
992 			      uint32_t cmd_flags,
993 			      uint16_t token,
994 			      uint16_t *max_frame_length)
995 {
996 	struct mc_command cmd = { 0 };
997 	struct dpni_rsp_get_max_frame_length *rsp_params;
998 	int err;
999 
1000 	/* prepare command */
1001 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MAX_FRAME_LENGTH,
1002 					  cmd_flags,
1003 					  token);
1004 
1005 	/* send command to mc*/
1006 	err = mc_send_command(mc_io, &cmd);
1007 	if (err)
1008 		return err;
1009 
1010 	/* retrieve response parameters */
1011 	rsp_params = (struct dpni_rsp_get_max_frame_length *)cmd.params;
1012 	*max_frame_length = le16_to_cpu(rsp_params->max_frame_length);
1013 
1014 	return 0;
1015 }
1016 
1017 /**
1018  * dpni_set_multicast_promisc() - Enable/disable multicast promiscuous mode
1019  * @mc_io:	Pointer to MC portal's I/O object
1020  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1021  * @token:	Token of DPNI object
1022  * @en:		Set to '1' to enable; '0' to disable
1023  *
1024  * Return:	'0' on Success; Error code otherwise.
1025  */
1026 int dpni_set_multicast_promisc(struct fsl_mc_io *mc_io,
1027 			       uint32_t cmd_flags,
1028 			       uint16_t token,
1029 			       int en)
1030 {
1031 	struct mc_command cmd = { 0 };
1032 	struct dpni_cmd_set_multicast_promisc *cmd_params;
1033 
1034 	/* prepare command */
1035 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MCAST_PROMISC,
1036 					  cmd_flags,
1037 					  token);
1038 	cmd_params = (struct dpni_cmd_set_multicast_promisc *)cmd.params;
1039 	dpni_set_field(cmd_params->enable, ENABLE, en);
1040 
1041 	/* send command to mc*/
1042 	return mc_send_command(mc_io, &cmd);
1043 }
1044 
1045 /**
1046  * dpni_get_multicast_promisc() - Get multicast promiscuous mode
1047  * @mc_io:	Pointer to MC portal's I/O object
1048  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1049  * @token:	Token of DPNI object
1050  * @en:		Returns '1' if enabled; '0' otherwise
1051  *
1052  * Return:	'0' on Success; Error code otherwise.
1053  */
1054 int dpni_get_multicast_promisc(struct fsl_mc_io *mc_io,
1055 			       uint32_t cmd_flags,
1056 			       uint16_t token,
1057 			       int *en)
1058 {
1059 	struct mc_command cmd = { 0 };
1060 	struct dpni_rsp_get_multicast_promisc *rsp_params;
1061 	int err;
1062 
1063 	/* prepare command */
1064 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MCAST_PROMISC,
1065 					  cmd_flags,
1066 					  token);
1067 
1068 	/* send command to mc*/
1069 	err = mc_send_command(mc_io, &cmd);
1070 	if (err)
1071 		return err;
1072 
1073 	/* retrieve response parameters */
1074 	rsp_params = (struct dpni_rsp_get_multicast_promisc *)cmd.params;
1075 	*en = dpni_get_field(rsp_params->enabled, ENABLE);
1076 
1077 	return 0;
1078 }
1079 
1080 /**
1081  * dpni_set_unicast_promisc() - Enable/disable unicast promiscuous mode
1082  * @mc_io:	Pointer to MC portal's I/O object
1083  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1084  * @token:	Token of DPNI object
1085  * @en:		Set to '1' to enable; '0' to disable
1086  *
1087  * Return:	'0' on Success; Error code otherwise.
1088  */
1089 int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
1090 			     uint32_t cmd_flags,
1091 			     uint16_t token,
1092 			     int en)
1093 {
1094 	struct mc_command cmd = { 0 };
1095 	struct dpni_cmd_set_unicast_promisc *cmd_params;
1096 
1097 	/* prepare command */
1098 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_UNICAST_PROMISC,
1099 					  cmd_flags,
1100 					  token);
1101 	cmd_params = (struct dpni_cmd_set_unicast_promisc *)cmd.params;
1102 	dpni_set_field(cmd_params->enable, ENABLE, en);
1103 
1104 	/* send command to mc*/
1105 	return mc_send_command(mc_io, &cmd);
1106 }
1107 
1108 /**
1109  * dpni_get_unicast_promisc() - Get unicast promiscuous mode
1110  * @mc_io:	Pointer to MC portal's I/O object
1111  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1112  * @token:	Token of DPNI object
1113  * @en:		Returns '1' if enabled; '0' otherwise
1114  *
1115  * Return:	'0' on Success; Error code otherwise.
1116  */
1117 int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
1118 			     uint32_t cmd_flags,
1119 			     uint16_t token,
1120 			     int *en)
1121 {
1122 	struct mc_command cmd = { 0 };
1123 	struct dpni_rsp_get_unicast_promisc *rsp_params;
1124 	int err;
1125 
1126 	/* prepare command */
1127 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_UNICAST_PROMISC,
1128 					  cmd_flags,
1129 					  token);
1130 
1131 	/* send command to mc*/
1132 	err = mc_send_command(mc_io, &cmd);
1133 	if (err)
1134 		return err;
1135 
1136 	/* retrieve response parameters */
1137 	rsp_params = (struct dpni_rsp_get_unicast_promisc *)cmd.params;
1138 	*en = dpni_get_field(rsp_params->enabled, ENABLE);
1139 
1140 	return 0;
1141 }
1142 
1143 /**
1144  * dpni_set_primary_mac_addr() - Set the primary MAC address
1145  * @mc_io:	Pointer to MC portal's I/O object
1146  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1147  * @token:	Token of DPNI object
1148  * @mac_addr:	MAC address to set as primary address
1149  *
1150  * Return:	'0' on Success; Error code otherwise.
1151  */
1152 int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
1153 			      uint32_t cmd_flags,
1154 			      uint16_t token,
1155 			      const uint8_t mac_addr[6])
1156 {
1157 	struct mc_command cmd = { 0 };
1158 	struct dpni_cmd_set_primary_mac_addr *cmd_params;
1159 	int i;
1160 
1161 	/* prepare command */
1162 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_PRIM_MAC,
1163 					  cmd_flags,
1164 					  token);
1165 	cmd_params = (struct dpni_cmd_set_primary_mac_addr *)cmd.params;
1166 	for (i = 0; i < 6; i++)
1167 		cmd_params->mac_addr[i] = mac_addr[5 - i];
1168 
1169 	/* send command to mc*/
1170 	return mc_send_command(mc_io, &cmd);
1171 }
1172 
1173 /**
1174  * dpni_get_primary_mac_addr() - Get the primary MAC address
1175  * @mc_io:	Pointer to MC portal's I/O object
1176  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1177  * @token:	Token of DPNI object
1178  * @mac_addr:	Returned MAC address
1179  *
1180  * Return:	'0' on Success; Error code otherwise.
1181  */
1182 int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
1183 			      uint32_t cmd_flags,
1184 			      uint16_t token,
1185 			      uint8_t mac_addr[6])
1186 {
1187 	struct mc_command cmd = { 0 };
1188 	struct dpni_rsp_get_primary_mac_addr *rsp_params;
1189 	int i, err;
1190 
1191 	/* prepare command */
1192 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PRIM_MAC,
1193 					  cmd_flags,
1194 					  token);
1195 
1196 	/* send command to mc*/
1197 	err = mc_send_command(mc_io, &cmd);
1198 	if (err)
1199 		return err;
1200 
1201 	/* retrieve response parameters */
1202 	rsp_params = (struct dpni_rsp_get_primary_mac_addr *)cmd.params;
1203 	for (i = 0; i < 6; i++)
1204 		mac_addr[5 - i] = rsp_params->mac_addr[i];
1205 
1206 	return 0;
1207 }
1208 
1209 /**
1210  * dpni_add_mac_addr() - Add MAC address filter
1211  * @mc_io:	Pointer to MC portal's I/O object
1212  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1213  * @token:	Token of DPNI object
1214  * @mac_addr:	MAC address to add
1215  * @flags :	0 - tc_id and flow_id will be ignored.
1216  *		  Pkt with this mac_id will be passed to the next
1217  *		  classification stages
1218  *		DPNI_MAC_SET_QUEUE_ACTION
1219  *		  Pkt with this mac will be forward directly to
1220  *		  queue defined by the tc_id and flow_id
1221  * @tc_id : Traffic class selection (0-7)
1222  * @flow_id : Selects the specific queue out of the set allocated for the
1223  *            same as tc_id. Value must be in range 0 to NUM_QUEUES - 1
1224  * Return:	'0' on Success; Error code otherwise.
1225  */
1226 int dpni_add_mac_addr(struct fsl_mc_io *mc_io,
1227 		      uint32_t cmd_flags,
1228 		      uint16_t token,
1229 		      const uint8_t mac_addr[6],
1230 			  uint8_t flags,
1231 			  uint8_t tc_id,
1232 			  uint8_t flow_id)
1233 {
1234 	struct mc_command cmd = { 0 };
1235 	struct dpni_cmd_add_mac_addr *cmd_params;
1236 	int i;
1237 
1238 	/* prepare command */
1239 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_MAC_ADDR,
1240 					  cmd_flags,
1241 					  token);
1242 	cmd_params = (struct dpni_cmd_add_mac_addr *)cmd.params;
1243 	cmd_params->flags = flags;
1244 	cmd_params->tc_id = tc_id;
1245 	cmd_params->fq_id = flow_id;
1246 
1247 	for (i = 0; i < 6; i++)
1248 		cmd_params->mac_addr[i] = mac_addr[5 - i];
1249 
1250 	/* send command to mc*/
1251 	return mc_send_command(mc_io, &cmd);
1252 }
1253 
1254 /**
1255  * dpni_remove_mac_addr() - Remove MAC address filter
1256  * @mc_io:	Pointer to MC portal's I/O object
1257  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1258  * @token:	Token of DPNI object
1259  * @mac_addr:	MAC address to remove
1260  *
1261  * Return:	'0' on Success; Error code otherwise.
1262  */
1263 int dpni_remove_mac_addr(struct fsl_mc_io *mc_io,
1264 			 uint32_t cmd_flags,
1265 			 uint16_t token,
1266 			 const uint8_t mac_addr[6])
1267 {
1268 	struct mc_command cmd = { 0 };
1269 	struct dpni_cmd_remove_mac_addr *cmd_params;
1270 	int i;
1271 
1272 	/* prepare command */
1273 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_MAC_ADDR,
1274 					  cmd_flags,
1275 					  token);
1276 	cmd_params = (struct dpni_cmd_remove_mac_addr *)cmd.params;
1277 	for (i = 0; i < 6; i++)
1278 		cmd_params->mac_addr[i] = mac_addr[5 - i];
1279 
1280 	/* send command to mc*/
1281 	return mc_send_command(mc_io, &cmd);
1282 }
1283 
1284 /**
1285  * dpni_clear_mac_filters() - Clear all unicast and/or multicast MAC filters
1286  * @mc_io:	Pointer to MC portal's I/O object
1287  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1288  * @token:	Token of DPNI object
1289  * @unicast:	Set to '1' to clear unicast addresses
1290  * @multicast:	Set to '1' to clear multicast addresses
1291  *
1292  * The primary MAC address is not cleared by this operation.
1293  *
1294  * Return:	'0' on Success; Error code otherwise.
1295  */
1296 int dpni_clear_mac_filters(struct fsl_mc_io *mc_io,
1297 			   uint32_t cmd_flags,
1298 			   uint16_t token,
1299 			   int unicast,
1300 			   int multicast)
1301 {
1302 	struct mc_command cmd = { 0 };
1303 	struct dpni_cmd_clear_mac_filters *cmd_params;
1304 
1305 	/* prepare command */
1306 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_MAC_FILTERS,
1307 					  cmd_flags,
1308 					  token);
1309 	cmd_params = (struct dpni_cmd_clear_mac_filters *)cmd.params;
1310 	dpni_set_field(cmd_params->flags, UNICAST_FILTERS, unicast);
1311 	dpni_set_field(cmd_params->flags, MULTICAST_FILTERS, multicast);
1312 
1313 	/* send command to mc*/
1314 	return mc_send_command(mc_io, &cmd);
1315 }
1316 
1317 /**
1318  * dpni_get_port_mac_addr() - Retrieve MAC address associated to the physical
1319  *			port the DPNI is attached to
1320  * @mc_io:	Pointer to MC portal's I/O object
1321  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1322  * @token:	Token of DPNI object
1323  * @mac_addr:	MAC address of the physical port, if any, otherwise 0
1324  *
1325  * The primary MAC address is not cleared by this operation.
1326  *
1327  * Return:	'0' on Success; Error code otherwise.
1328  */
1329 int dpni_get_port_mac_addr(struct fsl_mc_io *mc_io,
1330 			   uint32_t cmd_flags,
1331 			   uint16_t token,
1332 			   uint8_t mac_addr[6])
1333 {
1334 	struct mc_command cmd = { 0 };
1335 	struct dpni_rsp_get_port_mac_addr *rsp_params;
1336 	int i, err;
1337 
1338 	/* prepare command */
1339 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PORT_MAC_ADDR,
1340 					  cmd_flags,
1341 					  token);
1342 
1343 	/* send command to mc*/
1344 	err = mc_send_command(mc_io, &cmd);
1345 	if (err)
1346 		return err;
1347 
1348 	/* retrieve response parameters */
1349 	rsp_params = (struct dpni_rsp_get_port_mac_addr *)cmd.params;
1350 	for (i = 0; i < 6; i++)
1351 		mac_addr[5 - i] = rsp_params->mac_addr[i];
1352 
1353 	return 0;
1354 }
1355 
1356 /**
1357  * dpni_enable_vlan_filter() - Enable/disable VLAN filtering mode
1358  * @mc_io:	Pointer to MC portal's I/O object
1359  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1360  * @token:	Token of DPNI object
1361  * @en:		Set to '1' to enable; '0' to disable
1362  *
1363  * Return:	'0' on Success; Error code otherwise.
1364  */
1365 int dpni_enable_vlan_filter(struct fsl_mc_io *mc_io,
1366 			    uint32_t cmd_flags,
1367 			    uint16_t token,
1368 			    int en)
1369 {
1370 	struct dpni_cmd_enable_vlan_filter *cmd_params;
1371 	struct mc_command cmd = { 0 };
1372 
1373 	/* prepare command */
1374 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE_VLAN_FILTER,
1375 					  cmd_flags,
1376 					  token);
1377 	cmd_params = (struct dpni_cmd_enable_vlan_filter *)cmd.params;
1378 	dpni_set_field(cmd_params->en, ENABLE, en);
1379 
1380 	/* send command to mc*/
1381 	return mc_send_command(mc_io, &cmd);
1382 }
1383 
1384 /**
1385  * dpni_add_vlan_id() - Add VLAN ID filter
1386  * @mc_io:	Pointer to MC portal's I/O object
1387  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1388  * @token:	Token of DPNI object
1389  * @vlan_id:	VLAN ID to add
1390  * @flags:	0 - tc_id and flow_id will be ignored.
1391  *		  Pkt with this vlan_id will be passed to the next
1392  *		  classification stages
1393  *		DPNI_VLAN_SET_QUEUE_ACTION
1394  *		  Pkt with this vlan_id will be forward directly to
1395  *		  queue defined by the tc_id and flow_id
1396  *
1397  * @tc_id: Traffic class selection (0-7)
1398  * @flow_id: Selects the specific queue out of the set allocated for the
1399  *           same as tc_id. Value must be in range 0 to NUM_QUEUES - 1
1400  *
1401  * Return:	'0' on Success; Error code otherwise.
1402  */
1403 int dpni_add_vlan_id(struct fsl_mc_io *mc_io,
1404 		     uint32_t cmd_flags,
1405 		     uint16_t token,
1406 		     uint16_t vlan_id,
1407 			 uint8_t flags,
1408 			 uint8_t tc_id,
1409 			 uint8_t flow_id)
1410 {
1411 	struct dpni_cmd_vlan_id *cmd_params;
1412 	struct mc_command cmd = { 0 };
1413 
1414 	/* prepare command */
1415 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_VLAN_ID,
1416 					  cmd_flags,
1417 					  token);
1418 	cmd_params = (struct dpni_cmd_vlan_id *)cmd.params;
1419 	cmd_params->flags = flags;
1420 	cmd_params->tc_id = tc_id;
1421 	cmd_params->flow_id =  flow_id;
1422 	cmd_params->vlan_id = cpu_to_le16(vlan_id);
1423 
1424 	/* send command to mc*/
1425 	return mc_send_command(mc_io, &cmd);
1426 }
1427 
1428 /**
1429  * dpni_remove_vlan_id() - Remove VLAN ID filter
1430  * @mc_io:	Pointer to MC portal's I/O object
1431  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1432  * @token:	Token of DPNI object
1433  * @vlan_id:	VLAN ID to remove
1434  *
1435  * Return:	'0' on Success; Error code otherwise.
1436  */
1437 int dpni_remove_vlan_id(struct fsl_mc_io *mc_io,
1438 			uint32_t cmd_flags,
1439 			uint16_t token,
1440 			uint16_t vlan_id)
1441 {
1442 	struct dpni_cmd_vlan_id *cmd_params;
1443 	struct mc_command cmd = { 0 };
1444 
1445 	/* prepare command */
1446 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_VLAN_ID,
1447 					  cmd_flags,
1448 					  token);
1449 	cmd_params = (struct dpni_cmd_vlan_id *)cmd.params;
1450 	cmd_params->vlan_id = cpu_to_le16(vlan_id);
1451 
1452 	/* send command to mc*/
1453 	return mc_send_command(mc_io, &cmd);
1454 }
1455 
1456 /**
1457  * dpni_clear_vlan_filters() - Clear all VLAN filters
1458  * @mc_io:	Pointer to MC portal's I/O object
1459  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1460  * @token:	Token of DPNI object
1461  *
1462  * Return:	'0' on Success; Error code otherwise.
1463  */
1464 int dpni_clear_vlan_filters(struct fsl_mc_io *mc_io,
1465 			    uint32_t cmd_flags,
1466 			    uint16_t token)
1467 {
1468 	struct mc_command cmd = { 0 };
1469 
1470 	/* prepare command */
1471 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_VLAN_FILTERS,
1472 					  cmd_flags,
1473 					  token);
1474 
1475 	/* send command to mc*/
1476 	return mc_send_command(mc_io, &cmd);
1477 }
1478 
1479 /**
1480  * dpni_set_rx_tc_dist() - Set Rx traffic class distribution configuration
1481  * @mc_io:	Pointer to MC portal's I/O object
1482  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1483  * @token:	Token of DPNI object
1484  * @tc_id:	Traffic class selection (0-7)
1485  * @cfg:	Traffic class distribution configuration
1486  *
1487  * warning: if 'dist_mode != DPNI_DIST_MODE_NONE', call dpkg_prepare_key_cfg()
1488  *			first to prepare the key_cfg_iova parameter
1489  *
1490  * Return:	'0' on Success; error code otherwise.
1491  */
1492 int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
1493 			uint32_t cmd_flags,
1494 			uint16_t token,
1495 			uint8_t tc_id,
1496 			const struct dpni_rx_tc_dist_cfg *cfg)
1497 {
1498 	struct mc_command cmd = { 0 };
1499 	struct dpni_cmd_set_rx_tc_dist *cmd_params;
1500 
1501 	/* prepare command */
1502 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_TC_DIST,
1503 					  cmd_flags,
1504 					  token);
1505 	cmd_params = (struct dpni_cmd_set_rx_tc_dist *)cmd.params;
1506 	cmd_params->dist_size = cpu_to_le16(cfg->dist_size);
1507 	cmd_params->tc_id = tc_id;
1508 	cmd_params->default_flow_id = cpu_to_le16(cfg->fs_cfg.default_flow_id);
1509 	cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova);
1510 	dpni_set_field(cmd_params->flags,
1511 		       DIST_MODE,
1512 		       cfg->dist_mode);
1513 	dpni_set_field(cmd_params->flags,
1514 		       MISS_ACTION,
1515 		       cfg->fs_cfg.miss_action);
1516 	dpni_set_field(cmd_params->keep_hash_key,
1517 		       KEEP_HASH_KEY,
1518 		       cfg->fs_cfg.keep_hash_key);
1519 	dpni_set_field(cmd_params->keep_hash_key,
1520 		       KEEP_ENTRIES,
1521 		       cfg->fs_cfg.keep_entries);
1522 
1523 	/* send command to mc*/
1524 	return mc_send_command(mc_io, &cmd);
1525 }
1526 
1527 /**
1528  * dpni_set_tx_confirmation_mode() - Tx confirmation mode
1529  * @mc_io:	Pointer to MC portal's I/O object
1530  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1531  * @token:	Token of DPNI object
1532  * @mode:	Tx confirmation mode
1533  *
1534  * This function is useful only when 'DPNI_OPT_TX_CONF_DISABLED' is not
1535  * selected at DPNI creation.
1536  * Calling this function with 'mode' set to DPNI_CONF_DISABLE disables all
1537  * transmit confirmation (including the private confirmation queues), regardless
1538  * of previous settings; Note that in this case, Tx error frames are still
1539  * enqueued to the general transmit errors queue.
1540  * Calling this function with 'mode' set to DPNI_CONF_SINGLE switches all
1541  * Tx confirmations to a shared Tx conf queue. 'index' field in dpni_get_queue
1542  * command will be ignored.
1543  *
1544  * Return:	'0' on Success; Error code otherwise.
1545  */
1546 int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io,
1547 				  uint32_t cmd_flags,
1548 				  uint16_t token,
1549 				  enum dpni_confirmation_mode mode)
1550 {
1551 	struct dpni_tx_confirmation_mode *cmd_params;
1552 	struct mc_command cmd = { 0 };
1553 
1554 	/* prepare command */
1555 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_CONFIRMATION_MODE,
1556 					  cmd_flags,
1557 					  token);
1558 	cmd_params = (struct dpni_tx_confirmation_mode *)cmd.params;
1559 	cmd_params->confirmation_mode = mode;
1560 
1561 	/* send command to mc*/
1562 	return mc_send_command(mc_io, &cmd);
1563 }
1564 
1565 /**
1566  * dpni_set_qos_table() - Set QoS mapping table
1567  * @mc_io:	Pointer to MC portal's I/O object
1568  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1569  * @token:	Token of DPNI object
1570  * @cfg:	QoS table configuration
1571  *
1572  * This function and all QoS-related functions require that
1573  *'max_tcs > 1' was set at DPNI creation.
1574  *
1575  * warning: Before calling this function, call dpkg_prepare_key_cfg() to
1576  *			prepare the key_cfg_iova parameter
1577  *
1578  * Return:	'0' on Success; Error code otherwise.
1579  */
1580 int dpni_set_qos_table(struct fsl_mc_io *mc_io,
1581 		       uint32_t cmd_flags,
1582 		       uint16_t token,
1583 		       const struct dpni_qos_tbl_cfg *cfg)
1584 {
1585 	struct dpni_cmd_set_qos_table *cmd_params;
1586 	struct mc_command cmd = { 0 };
1587 
1588 	/* prepare command */
1589 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QOS_TBL,
1590 					  cmd_flags,
1591 					  token);
1592 	cmd_params = (struct dpni_cmd_set_qos_table *)cmd.params;
1593 	cmd_params->default_tc = cfg->default_tc;
1594 	cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova);
1595 	dpni_set_field(cmd_params->discard_on_miss,
1596 		       ENABLE,
1597 		       cfg->discard_on_miss);
1598 	dpni_set_field(cmd_params->discard_on_miss,
1599 					KEEP_QOS_ENTRIES,
1600 			       cfg->keep_entries);
1601 
1602 	/* send command to mc*/
1603 	return mc_send_command(mc_io, &cmd);
1604 }
1605 
1606 /**
1607  * dpni_add_qos_entry() - Add QoS mapping entry (to select a traffic class)
1608  * @mc_io:	Pointer to MC portal's I/O object
1609  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1610  * @token:	Token of DPNI object
1611  * @cfg:	QoS rule to add
1612  * @tc_id:	Traffic class selection (0-7)
1613  * @index:	Location in the QoS table where to insert the entry.
1614  *		Only relevant if MASKING is enabled for QoS classification on
1615  *		this DPNI, it is ignored for exact match.
1616  *
1617  * Return:	'0' on Success; Error code otherwise.
1618  */
1619 int dpni_add_qos_entry(struct fsl_mc_io *mc_io,
1620 		       uint32_t cmd_flags,
1621 		       uint16_t token,
1622 		       const struct dpni_rule_cfg *cfg,
1623 		       uint8_t tc_id,
1624 		       uint16_t index,
1625 			   uint8_t flags,
1626 			   uint8_t flow_id)
1627 {
1628 	struct dpni_cmd_add_qos_entry *cmd_params;
1629 	struct mc_command cmd = { 0 };
1630 
1631 	/* prepare command */
1632 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_QOS_ENT,
1633 					  cmd_flags,
1634 					  token);
1635 	cmd_params = (struct dpni_cmd_add_qos_entry *)cmd.params;
1636 	cmd_params->flags = flags;
1637 	cmd_params->flow_id = flow_id;
1638 	cmd_params->tc_id = tc_id;
1639 	cmd_params->key_size = cfg->key_size;
1640 	cmd_params->index = cpu_to_le16(index);
1641 	cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
1642 	cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova);
1643 
1644 	/* send command to mc*/
1645 	return mc_send_command(mc_io, &cmd);
1646 }
1647 
1648 /**
1649  * dpni_remove_qos_entry() - Remove QoS mapping entry
1650  * @mc_io:	Pointer to MC portal's I/O object
1651  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1652  * @token:	Token of DPNI object
1653  * @cfg:	QoS rule to remove
1654  *
1655  * Return:	'0' on Success; Error code otherwise.
1656  */
1657 int dpni_remove_qos_entry(struct fsl_mc_io *mc_io,
1658 			  uint32_t cmd_flags,
1659 			  uint16_t token,
1660 			  const struct dpni_rule_cfg *cfg)
1661 {
1662 	struct dpni_cmd_remove_qos_entry *cmd_params;
1663 	struct mc_command cmd = { 0 };
1664 
1665 	/* prepare command */
1666 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_QOS_ENT,
1667 					  cmd_flags,
1668 					  token);
1669 	cmd_params = (struct dpni_cmd_remove_qos_entry *)cmd.params;
1670 	cmd_params->key_size = cfg->key_size;
1671 	cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
1672 	cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova);
1673 
1674 	/* send command to mc*/
1675 	return mc_send_command(mc_io, &cmd);
1676 }
1677 
1678 /**
1679  * dpni_clear_qos_table() - Clear all QoS mapping entries
1680  * @mc_io:	Pointer to MC portal's I/O object
1681  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1682  * @token:	Token of DPNI object
1683  *
1684  * Following this function call, all frames are directed to
1685  * the default traffic class (0)
1686  *
1687  * Return:	'0' on Success; Error code otherwise.
1688  */
1689 int dpni_clear_qos_table(struct fsl_mc_io *mc_io,
1690 			 uint32_t cmd_flags,
1691 			 uint16_t token)
1692 {
1693 	struct mc_command cmd = { 0 };
1694 
1695 	/* prepare command */
1696 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_QOS_TBL,
1697 					  cmd_flags,
1698 					  token);
1699 
1700 	/* send command to mc*/
1701 	return mc_send_command(mc_io, &cmd);
1702 }
1703 
1704 /**
1705  * dpni_add_fs_entry() - Add Flow Steering entry for a specific traffic class
1706  *			(to select a flow ID)
1707  * @mc_io:	Pointer to MC portal's I/O object
1708  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1709  * @token:	Token of DPNI object
1710  * @tc_id:	Traffic class selection (0-7)
1711  * @index:	Location in the QoS table where to insert the entry.
1712  *		Only relevant if MASKING is enabled for QoS classification
1713  *		on this DPNI, it is ignored for exact match.
1714  * @cfg:	Flow steering rule to add
1715  * @action:	Action to be taken as result of a classification hit
1716  *
1717  * Return:	'0' on Success; Error code otherwise.
1718  */
1719 int dpni_add_fs_entry(struct fsl_mc_io *mc_io,
1720 		      uint32_t cmd_flags,
1721 		      uint16_t token,
1722 		      uint8_t tc_id,
1723 		      uint16_t index,
1724 		      const struct dpni_rule_cfg *cfg,
1725 		      const struct dpni_fs_action_cfg *action)
1726 {
1727 	struct dpni_cmd_add_fs_entry *cmd_params;
1728 	struct mc_command cmd = { 0 };
1729 
1730 	/* prepare command */
1731 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_FS_ENT,
1732 					  cmd_flags,
1733 					  token);
1734 	cmd_params = (struct dpni_cmd_add_fs_entry *)cmd.params;
1735 	cmd_params->tc_id = tc_id;
1736 	cmd_params->key_size = cfg->key_size;
1737 	cmd_params->index = cpu_to_le16(index);
1738 	cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
1739 	cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova);
1740 	cmd_params->options = cpu_to_le16(action->options);
1741 	cmd_params->flow_id = cpu_to_le16(action->flow_id);
1742 	cmd_params->flc = cpu_to_le64(action->flc);
1743 
1744 	/* send command to mc*/
1745 	return mc_send_command(mc_io, &cmd);
1746 }
1747 
1748 /**
1749  * dpni_remove_fs_entry() - Remove Flow Steering entry from a specific
1750  *			traffic class
1751  * @mc_io:	Pointer to MC portal's I/O object
1752  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1753  * @token:	Token of DPNI object
1754  * @tc_id:	Traffic class selection (0-7)
1755  * @cfg:	Flow steering rule to remove
1756  *
1757  * Return:	'0' on Success; Error code otherwise.
1758  */
1759 int dpni_remove_fs_entry(struct fsl_mc_io *mc_io,
1760 			 uint32_t cmd_flags,
1761 			 uint16_t token,
1762 			 uint8_t tc_id,
1763 			 const struct dpni_rule_cfg *cfg)
1764 {
1765 	struct dpni_cmd_remove_fs_entry *cmd_params;
1766 	struct mc_command cmd = { 0 };
1767 
1768 	/* prepare command */
1769 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_FS_ENT,
1770 					  cmd_flags,
1771 					  token);
1772 	cmd_params = (struct dpni_cmd_remove_fs_entry *)cmd.params;
1773 	cmd_params->tc_id = tc_id;
1774 	cmd_params->key_size = cfg->key_size;
1775 	cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
1776 	cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova);
1777 
1778 	/* send command to mc*/
1779 	return mc_send_command(mc_io, &cmd);
1780 }
1781 
1782 /**
1783  * dpni_clear_fs_entries() - Clear all Flow Steering entries of a specific
1784  *			traffic class
1785  * @mc_io:	Pointer to MC portal's I/O object
1786  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1787  * @token:	Token of DPNI object
1788  * @tc_id:	Traffic class selection (0-7)
1789  *
1790  * Return:	'0' on Success; Error code otherwise.
1791  */
1792 int dpni_clear_fs_entries(struct fsl_mc_io *mc_io,
1793 			  uint32_t cmd_flags,
1794 			  uint16_t token,
1795 			  uint8_t tc_id)
1796 {
1797 	struct dpni_cmd_clear_fs_entries *cmd_params;
1798 	struct mc_command cmd = { 0 };
1799 
1800 	/* prepare command */
1801 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_FS_ENT,
1802 					  cmd_flags,
1803 					  token);
1804 	cmd_params = (struct dpni_cmd_clear_fs_entries *)cmd.params;
1805 	cmd_params->tc_id = tc_id;
1806 
1807 	/* send command to mc*/
1808 	return mc_send_command(mc_io, &cmd);
1809 }
1810 
1811 /**
1812  * dpni_set_congestion_notification() - Set traffic class congestion
1813  *	notification configuration
1814  * @mc_io:	Pointer to MC portal's I/O object
1815  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1816  * @token:	Token of DPNI object
1817  * @qtype:	Type of queue - Rx, Tx and Tx confirm types are supported
1818  * @tc_id:	Traffic class selection (0-7)
1819  * @cfg:	congestion notification configuration
1820  *
1821  * Return:	'0' on Success; error code otherwise.
1822  */
1823 int dpni_set_congestion_notification(struct fsl_mc_io *mc_io,
1824 				     uint32_t cmd_flags,
1825 				     uint16_t token,
1826 				     enum dpni_queue_type qtype,
1827 				     uint8_t tc_id,
1828 			const struct dpni_congestion_notification_cfg *cfg)
1829 {
1830 	struct dpni_cmd_set_congestion_notification *cmd_params;
1831 	struct mc_command cmd = { 0 };
1832 
1833 	/* prepare command */
1834 	cmd.header = mc_encode_cmd_header(
1835 					DPNI_CMDID_SET_CONGESTION_NOTIFICATION,
1836 					cmd_flags,
1837 					token);
1838 	cmd_params = (struct dpni_cmd_set_congestion_notification *)cmd.params;
1839 	cmd_params->qtype = qtype;
1840 	cmd_params->tc = tc_id;
1841 	cmd_params->congestion_point = cfg->cg_point;
1842 	cmd_params->cgid = (uint8_t)cfg->cgid;
1843 	cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
1844 	cmd_params->notification_mode = cpu_to_le16(cfg->notification_mode);
1845 	cmd_params->dest_priority = cfg->dest_cfg.priority;
1846 	cmd_params->message_iova = cpu_to_le64(cfg->message_iova);
1847 	cmd_params->message_ctx = cpu_to_le64(cfg->message_ctx);
1848 	cmd_params->threshold_entry = cpu_to_le32(cfg->threshold_entry);
1849 	cmd_params->threshold_exit = cpu_to_le32(cfg->threshold_exit);
1850 	dpni_set_field(cmd_params->type_units,
1851 		       DEST_TYPE,
1852 		       cfg->dest_cfg.dest_type);
1853 	dpni_set_field(cmd_params->type_units,
1854 		       CONG_UNITS,
1855 		       cfg->units);
1856 
1857 	/* send command to mc*/
1858 	return mc_send_command(mc_io, &cmd);
1859 }
1860 
1861 /**
1862  * dpni_get_congestion_notification() - Get traffic class congestion
1863  *	notification configuration
1864  * @mc_io:	Pointer to MC portal's I/O object
1865  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1866  * @token:	Token of DPNI object
1867  * @qtype:	Type of queue - Rx, Tx and Tx confirm types are supported
1868  * @tc_id:	Traffic class selection (0-7)
1869  * @cfg:	congestion notification configuration
1870  *
1871  * Return:	'0' on Success; error code otherwise.
1872  */
1873 int dpni_get_congestion_notification(struct fsl_mc_io *mc_io,
1874 				     uint32_t cmd_flags,
1875 				     uint16_t token,
1876 				     enum dpni_queue_type qtype,
1877 				     uint8_t tc_id,
1878 				struct dpni_congestion_notification_cfg *cfg)
1879 {
1880 	struct dpni_rsp_get_congestion_notification *rsp_params;
1881 	struct dpni_cmd_get_congestion_notification *cmd_params;
1882 	struct mc_command cmd = { 0 };
1883 	int err;
1884 
1885 	/* prepare command */
1886 	cmd.header = mc_encode_cmd_header(
1887 					DPNI_CMDID_GET_CONGESTION_NOTIFICATION,
1888 					cmd_flags,
1889 					token);
1890 	cmd_params = (struct dpni_cmd_get_congestion_notification *)cmd.params;
1891 	cmd_params->qtype = qtype;
1892 	cmd_params->tc = tc_id;
1893 	cmd_params->congestion_point = cfg->cg_point;
1894 	cmd_params->cgid = cfg->cgid;
1895 
1896 	/* send command to mc*/
1897 	err = mc_send_command(mc_io, &cmd);
1898 	if (err)
1899 		return err;
1900 
1901 	rsp_params = (struct dpni_rsp_get_congestion_notification *)cmd.params;
1902 	cfg->units = dpni_get_field(rsp_params->type_units, CONG_UNITS);
1903 	cfg->threshold_entry = le32_to_cpu(rsp_params->threshold_entry);
1904 	cfg->threshold_exit = le32_to_cpu(rsp_params->threshold_exit);
1905 	cfg->message_ctx = le64_to_cpu(rsp_params->message_ctx);
1906 	cfg->message_iova = le64_to_cpu(rsp_params->message_iova);
1907 	cfg->notification_mode = le16_to_cpu(rsp_params->notification_mode);
1908 	cfg->dest_cfg.dest_id = le32_to_cpu(rsp_params->dest_id);
1909 	cfg->dest_cfg.priority = rsp_params->dest_priority;
1910 	cfg->dest_cfg.dest_type = dpni_get_field(rsp_params->type_units,
1911 						 DEST_TYPE);
1912 
1913 	return 0;
1914 }
1915 
1916 /**
1917  * dpni_get_api_version() - Get Data Path Network Interface API version
1918  * @mc_io:  Pointer to MC portal's I/O object
1919  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1920  * @major_ver:	Major version of data path network interface API
1921  * @minor_ver:	Minor version of data path network interface API
1922  *
1923  * Return:  '0' on Success; Error code otherwise.
1924  */
1925 int dpni_get_api_version(struct fsl_mc_io *mc_io,
1926 			 uint32_t cmd_flags,
1927 			 uint16_t *major_ver,
1928 			 uint16_t *minor_ver)
1929 {
1930 	struct dpni_rsp_get_api_version *rsp_params;
1931 	struct mc_command cmd = { 0 };
1932 	int err;
1933 
1934 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_API_VERSION,
1935 					cmd_flags,
1936 					0);
1937 
1938 	err = mc_send_command(mc_io, &cmd);
1939 	if (err)
1940 		return err;
1941 
1942 	rsp_params = (struct dpni_rsp_get_api_version *)cmd.params;
1943 	*major_ver = le16_to_cpu(rsp_params->major);
1944 	*minor_ver = le16_to_cpu(rsp_params->minor);
1945 
1946 	return 0;
1947 }
1948 
1949 /**
1950  * dpni_set_queue() - Set queue parameters
1951  * @mc_io:	Pointer to MC portal's I/O object
1952  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1953  * @token:	Token of DPNI object
1954  * @qtype:	Type of queue - all queue types are supported, although
1955  *		the command is ignored for Tx
1956  * @tc:		Traffic class, in range 0 to NUM_TCS - 1
1957  * @index:	Selects the specific queue out of the set allocated for the
1958  *		same TC. Value must be in range 0 to NUM_QUEUES - 1
1959  * @options:	A combination of DPNI_QUEUE_OPT_ values that control what
1960  *		configuration options are set on the queue
1961  * @queue:	Queue structure
1962  *
1963  * Return:	'0' on Success; Error code otherwise.
1964  */
1965 int dpni_set_queue(struct fsl_mc_io *mc_io,
1966 		   uint32_t cmd_flags,
1967 		   uint16_t token,
1968 		   enum dpni_queue_type qtype,
1969 		   uint8_t tc,
1970 		   uint8_t index,
1971 		   uint8_t options,
1972 		   const struct dpni_queue *queue)
1973 {
1974 	struct mc_command cmd = { 0 };
1975 	struct dpni_cmd_set_queue *cmd_params;
1976 
1977 	/* prepare command */
1978 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QUEUE,
1979 					  cmd_flags,
1980 					  token);
1981 	cmd_params = (struct dpni_cmd_set_queue *)cmd.params;
1982 	cmd_params->qtype = qtype;
1983 	cmd_params->tc = tc;
1984 	cmd_params->index = index;
1985 	cmd_params->options = options;
1986 	cmd_params->dest_id = cpu_to_le32(queue->destination.id);
1987 	cmd_params->dest_prio = queue->destination.priority;
1988 	dpni_set_field(cmd_params->flags, DEST_TYPE, queue->destination.type);
1989 	dpni_set_field(cmd_params->flags, STASH_CTRL, queue->flc.stash_control);
1990 	dpni_set_field(cmd_params->flags, HOLD_ACTIVE,
1991 		       queue->destination.hold_active);
1992 	cmd_params->flc = cpu_to_le64(queue->flc.value);
1993 	cmd_params->user_context = cpu_to_le64(queue->user_context);
1994 	cmd_params->cgid = queue->cgid;
1995 
1996 	/* send command to mc */
1997 	return mc_send_command(mc_io, &cmd);
1998 }
1999 
2000 /**
2001  * dpni_get_queue() - Get queue parameters
2002  * @mc_io:	Pointer to MC portal's I/O object
2003  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
2004  * @token:	Token of DPNI object
2005  * @qtype:	Type of queue - all queue types are supported
2006  * @tc:		Traffic class, in range 0 to NUM_TCS - 1
2007  * @index:	Selects the specific queue out of the set allocated for the
2008  *		same TC. Value must be in range 0 to NUM_QUEUES - 1
2009  * @queue:	Queue configuration structure
2010  * @qid:	Queue identification
2011  *
2012  * Return:	'0' on Success; Error code otherwise.
2013  */
2014 int dpni_get_queue(struct fsl_mc_io *mc_io,
2015 		   uint32_t cmd_flags,
2016 		   uint16_t token,
2017 		   enum dpni_queue_type qtype,
2018 		   uint8_t tc,
2019 		   uint8_t index,
2020 		   struct dpni_queue *queue,
2021 		   struct dpni_queue_id *qid)
2022 {
2023 	struct mc_command cmd = { 0 };
2024 	struct dpni_cmd_get_queue *cmd_params;
2025 	struct dpni_rsp_get_queue *rsp_params;
2026 	int err;
2027 
2028 	/* prepare command */
2029 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QUEUE,
2030 					  cmd_flags,
2031 					  token);
2032 	cmd_params = (struct dpni_cmd_get_queue *)cmd.params;
2033 	cmd_params->qtype = qtype;
2034 	cmd_params->tc = tc;
2035 	cmd_params->index = index;
2036 
2037 	/* send command to mc */
2038 	err = mc_send_command(mc_io, &cmd);
2039 	if (err)
2040 		return err;
2041 
2042 	/* retrieve response parameters */
2043 	rsp_params = (struct dpni_rsp_get_queue *)cmd.params;
2044 	queue->destination.id = le32_to_cpu(rsp_params->dest_id);
2045 	queue->destination.priority = rsp_params->dest_prio;
2046 	queue->destination.type = dpni_get_field(rsp_params->flags,
2047 						     DEST_TYPE);
2048 	queue->flc.stash_control = dpni_get_field(rsp_params->flags,
2049 						  STASH_CTRL);
2050 	queue->destination.hold_active = dpni_get_field(rsp_params->flags,
2051 							HOLD_ACTIVE);
2052 	queue->flc.value = le64_to_cpu(rsp_params->flc);
2053 	queue->user_context = le64_to_cpu(rsp_params->user_context);
2054 	qid->fqid = le32_to_cpu(rsp_params->fqid);
2055 	qid->qdbin = le16_to_cpu(rsp_params->qdbin);
2056 	if (dpni_get_field(rsp_params->flags, CGID_VALID))
2057 		queue->cgid = rsp_params->cgid;
2058 	else
2059 		queue->cgid = -1;
2060 
2061 	return 0;
2062 }
2063 
2064 /**
2065  * dpni_get_statistics() - Get DPNI statistics
2066  * @mc_io:	Pointer to MC portal's I/O object
2067  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
2068  * @token:	Token of DPNI object
2069  * @page:	Selects the statistics page to retrieve, see
2070  *		DPNI_GET_STATISTICS output. Pages are numbered 0 to 6.
2071  * @param:	Custom parameter for some pages used to select
2072  *		a certain statistic source, for example the TC.
2073  * @stat:	Structure containing the statistics
2074  *
2075  * Return:	'0' on Success; Error code otherwise.
2076  */
2077 int dpni_get_statistics(struct fsl_mc_io *mc_io,
2078 			uint32_t cmd_flags,
2079 			uint16_t token,
2080 			uint8_t page,
2081 			uint16_t param,
2082 			union dpni_statistics *stat)
2083 {
2084 	struct mc_command cmd = { 0 };
2085 	struct dpni_cmd_get_statistics *cmd_params;
2086 	struct dpni_rsp_get_statistics *rsp_params;
2087 	int i, err;
2088 
2089 	/* prepare command */
2090 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_STATISTICS,
2091 					  cmd_flags,
2092 					  token);
2093 	cmd_params = (struct dpni_cmd_get_statistics *)cmd.params;
2094 	cmd_params->page_number = page;
2095 	cmd_params->param = param;
2096 
2097 	/* send command to mc */
2098 	err = mc_send_command(mc_io, &cmd);
2099 	if (err)
2100 		return err;
2101 
2102 	/* retrieve response parameters */
2103 	rsp_params = (struct dpni_rsp_get_statistics *)cmd.params;
2104 	for (i = 0; i < DPNI_STATISTICS_CNT; i++)
2105 		stat->raw.counter[i] = le64_to_cpu(rsp_params->counter[i]);
2106 
2107 	return 0;
2108 }
2109 
2110 /**
2111  * dpni_reset_statistics() - Clears DPNI statistics
2112  * @mc_io:		Pointer to MC portal's I/O object
2113  * @cmd_flags:		Command flags; one or more of 'MC_CMD_FLAG_'
2114  * @token:		Token of DPNI object
2115  *
2116  * Return:  '0' on Success; Error code otherwise.
2117  */
2118 int dpni_reset_statistics(struct fsl_mc_io *mc_io,
2119 			  uint32_t cmd_flags,
2120 		     uint16_t token)
2121 {
2122 	struct mc_command cmd = { 0 };
2123 
2124 	/* prepare command */
2125 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET_STATISTICS,
2126 					  cmd_flags,
2127 					  token);
2128 
2129 	/* send command to mc*/
2130 	return mc_send_command(mc_io, &cmd);
2131 }
2132 
2133 /**
2134  * dpni_set_taildrop() - Set taildrop per queue or TC
2135  *
2136  * Setting a per-TC taildrop (cg_point = DPNI_CP_GROUP) will reset any current
2137  * congestion notification or early drop (WRED) configuration previously applied
2138  * to the same TC.
2139  *
2140  * @mc_io:	Pointer to MC portal's I/O object
2141  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
2142  * @token:	Token of DPNI object
2143  * @cg_point:	Congestion point, DPNI_CP_QUEUE is only supported in
2144  *		combination with DPNI_QUEUE_RX.
2145  * @q_type:	Queue type, can be DPNI_QUEUE_RX or DPNI_QUEUE_TX.
2146  * @tc:		Traffic class to apply this taildrop to
2147  * @q_index:	Index of the queue if the DPNI supports multiple queues for
2148  *		traffic distribution.
2149  *		Ignored if CONGESTION_POINT is not DPNI_CP_QUEUE.
2150  * @taildrop:	Taildrop structure
2151  *
2152  * Return:	'0' on Success; Error code otherwise.
2153  */
2154 int dpni_set_taildrop(struct fsl_mc_io *mc_io,
2155 		      uint32_t cmd_flags,
2156 		      uint16_t token,
2157 		      enum dpni_congestion_point cg_point,
2158 		      enum dpni_queue_type qtype,
2159 		      uint8_t tc,
2160 		      uint8_t index,
2161 		      struct dpni_taildrop *taildrop)
2162 {
2163 	struct mc_command cmd = { 0 };
2164 	struct dpni_cmd_set_taildrop *cmd_params;
2165 
2166 	/* prepare command */
2167 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TAILDROP,
2168 					  cmd_flags,
2169 					  token);
2170 	cmd_params = (struct dpni_cmd_set_taildrop *)cmd.params;
2171 	cmd_params->congestion_point = cg_point;
2172 	cmd_params->qtype = qtype;
2173 	cmd_params->tc = tc;
2174 	cmd_params->index = index;
2175 	cmd_params->units = taildrop->units;
2176 	cmd_params->threshold = cpu_to_le32(taildrop->threshold);
2177 	dpni_set_field(cmd_params->enable_oal_lo, ENABLE, taildrop->enable);
2178 	dpni_set_field(cmd_params->enable_oal_lo, OAL_LO, taildrop->oal);
2179 	dpni_set_field(cmd_params->oal_hi,
2180 		       OAL_HI,
2181 		       taildrop->oal >> DPNI_OAL_LO_SIZE);
2182 
2183 	/* send command to mc */
2184 	return mc_send_command(mc_io, &cmd);
2185 }
2186 
2187 /**
2188  * dpni_get_taildrop() - Get taildrop information
2189  * @mc_io:	Pointer to MC portal's I/O object
2190  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
2191  * @token:	Token of DPNI object
2192  * @cg_point:	Congestion point
2193  * @q_type:	Queue type on which the taildrop is configured.
2194  *		Only Rx queues are supported for now
2195  * @tc:		Traffic class to apply this taildrop to
2196  * @q_index:	Index of the queue if the DPNI supports multiple queues for
2197  *		traffic distribution. Ignored if CONGESTION_POINT is not 0.
2198  * @taildrop:	Taildrop structure
2199  *
2200  * Return:	'0' on Success; Error code otherwise.
2201  */
2202 int dpni_get_taildrop(struct fsl_mc_io *mc_io,
2203 		      uint32_t cmd_flags,
2204 		      uint16_t token,
2205 		      enum dpni_congestion_point cg_point,
2206 		      enum dpni_queue_type qtype,
2207 		      uint8_t tc,
2208 		      uint8_t index,
2209 		      struct dpni_taildrop *taildrop)
2210 {
2211 	struct mc_command cmd = { 0 };
2212 	struct dpni_cmd_get_taildrop *cmd_params;
2213 	struct dpni_rsp_get_taildrop *rsp_params;
2214 	uint8_t oal_lo, oal_hi;
2215 	int err;
2216 
2217 	/* prepare command */
2218 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TAILDROP,
2219 					  cmd_flags,
2220 					  token);
2221 	cmd_params = (struct dpni_cmd_get_taildrop *)cmd.params;
2222 	cmd_params->congestion_point = cg_point;
2223 	cmd_params->qtype = qtype;
2224 	cmd_params->tc = tc;
2225 	cmd_params->index = index;
2226 
2227 	/* send command to mc */
2228 	err = mc_send_command(mc_io, &cmd);
2229 	if (err)
2230 		return err;
2231 
2232 	/* retrieve response parameters */
2233 	rsp_params = (struct dpni_rsp_get_taildrop *)cmd.params;
2234 	taildrop->enable = dpni_get_field(rsp_params->enable_oal_lo, ENABLE);
2235 	taildrop->units = rsp_params->units;
2236 	taildrop->threshold = le32_to_cpu(rsp_params->threshold);
2237 	oal_lo = dpni_get_field(rsp_params->enable_oal_lo, OAL_LO);
2238 	oal_hi = dpni_get_field(rsp_params->oal_hi, OAL_HI);
2239 	taildrop->oal = oal_hi << DPNI_OAL_LO_SIZE | oal_lo;
2240 
2241 	/* Fill the first 4 bits, 'oal' is a 2's complement value of 12 bits */
2242 	if (taildrop->oal >= 0x0800)
2243 		taildrop->oal |= 0xF000;
2244 
2245 	return 0;
2246 }
2247 
2248 /**
2249  * dpni_set_opr() - Set Order Restoration configuration.
2250  * @mc_io:	Pointer to MC portal's I/O object
2251  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
2252  * @token:	Token of DPNI object
2253  * @tc:		Traffic class, in range 0 to NUM_TCS - 1
2254  * @index:	Selects the specific queue out of the set allocated
2255  *			for the same TC. Value must be in range 0 to
2256  *			NUM_QUEUES - 1
2257  * @options:	Configuration mode options
2258  *			can be OPR_OPT_CREATE or OPR_OPT_RETIRE
2259  * @cfg:	Configuration options for the OPR
2260  *
2261  * Return:	'0' on Success; Error code otherwise.
2262  */
2263 int dpni_set_opr(struct fsl_mc_io *mc_io,
2264 		 uint32_t cmd_flags,
2265 		 uint16_t token,
2266 		 uint8_t tc,
2267 		 uint8_t index,
2268 		 uint8_t options,
2269 		 struct opr_cfg *cfg)
2270 {
2271 	struct dpni_cmd_set_opr *cmd_params;
2272 	struct mc_command cmd = { 0 };
2273 
2274 	/* prepare command */
2275 	cmd.header = mc_encode_cmd_header(
2276 			DPNI_CMDID_SET_OPR,
2277 			cmd_flags,
2278 			token);
2279 	cmd_params = (struct dpni_cmd_set_opr *)cmd.params;
2280 	cmd_params->tc_id = tc;
2281 	cmd_params->index = index;
2282 	cmd_params->options = options;
2283 	cmd_params->oloe = cfg->oloe;
2284 	cmd_params->oeane = cfg->oeane;
2285 	cmd_params->olws = cfg->olws;
2286 	cmd_params->oa = cfg->oa;
2287 	cmd_params->oprrws = cfg->oprrws;
2288 
2289 	/* send command to mc*/
2290 	return mc_send_command(mc_io, &cmd);
2291 }
2292 
2293 /**
2294  * dpni_get_opr() - Retrieve Order Restoration config and query.
2295  * @mc_io:	Pointer to MC portal's I/O object
2296  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
2297  * @token:	Token of DPNI object
2298  * @tc:		Traffic class, in range 0 to NUM_TCS - 1
2299  * @index:	Selects the specific queue out of the set allocated
2300  *			for the same TC. Value must be in range 0 to
2301  *			NUM_QUEUES - 1
2302  * @cfg:	Returned OPR configuration
2303  * @qry:	Returned OPR query
2304  *
2305  * Return:	'0' on Success; Error code otherwise.
2306  */
2307 int dpni_get_opr(struct fsl_mc_io *mc_io,
2308 		 uint32_t cmd_flags,
2309 		 uint16_t token,
2310 		 uint8_t tc,
2311 		 uint8_t index,
2312 		 struct opr_cfg *cfg,
2313 		 struct opr_qry *qry)
2314 {
2315 	struct dpni_rsp_get_opr *rsp_params;
2316 	struct dpni_cmd_get_opr *cmd_params;
2317 	struct mc_command cmd = { 0 };
2318 	int err;
2319 
2320 	/* prepare command */
2321 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_OPR,
2322 					  cmd_flags,
2323 					  token);
2324 	cmd_params = (struct dpni_cmd_get_opr *)cmd.params;
2325 	cmd_params->index = index;
2326 	cmd_params->tc_id = tc;
2327 
2328 	/* send command to mc*/
2329 	err = mc_send_command(mc_io, &cmd);
2330 	if (err)
2331 		return err;
2332 
2333 	/* retrieve response parameters */
2334 	rsp_params = (struct dpni_rsp_get_opr *)cmd.params;
2335 	cfg->oloe = rsp_params->oloe;
2336 	cfg->oeane = rsp_params->oeane;
2337 	cfg->olws = rsp_params->olws;
2338 	cfg->oa = rsp_params->oa;
2339 	cfg->oprrws = rsp_params->oprrws;
2340 	qry->rip = dpni_get_field(rsp_params->flags, RIP);
2341 	qry->enable = dpni_get_field(rsp_params->flags, OPR_ENABLE);
2342 	qry->nesn = le16_to_cpu(rsp_params->nesn);
2343 	qry->ndsn = le16_to_cpu(rsp_params->ndsn);
2344 	qry->ea_tseq = le16_to_cpu(rsp_params->ea_tseq);
2345 	qry->tseq_nlis = dpni_get_field(rsp_params->tseq_nlis, TSEQ_NLIS);
2346 	qry->ea_hseq = le16_to_cpu(rsp_params->ea_hseq);
2347 	qry->hseq_nlis = dpni_get_field(rsp_params->hseq_nlis, HSEQ_NLIS);
2348 	qry->ea_hptr = le16_to_cpu(rsp_params->ea_hptr);
2349 	qry->ea_tptr = le16_to_cpu(rsp_params->ea_tptr);
2350 	qry->opr_vid = le16_to_cpu(rsp_params->opr_vid);
2351 	qry->opr_id = le16_to_cpu(rsp_params->opr_id);
2352 
2353 	return 0;
2354 }
2355 
2356 /**
2357  * dpni_set_rx_fs_dist() - Set Rx traffic class FS distribution
2358  * @mc_io:	Pointer to MC portal's I/O object
2359  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
2360  * @token:	Token of DPNI object
2361  * @cfg: Distribution configuration
2362  * If the FS is already enabled with a previous call the classification
2363  *		key will be changed but all the table rules are kept. If the
2364  *		existing rules do not match the key the results will not be
2365  *		predictable. It is the user responsibility to keep key integrity
2366  * If cfg.enable is set to 1 the command will create a flow steering table
2367  *		and will classify packets according to this table. The packets
2368  *		that miss all the table rules will be classified according to
2369  *		settings made in dpni_set_rx_hash_dist()
2370  * If cfg.enable is set to 0 the command will clear flow steering table. The
2371  *		packets will be classified according to settings made in
2372  *		dpni_set_rx_hash_dist()
2373  */
2374 int dpni_set_rx_fs_dist(struct fsl_mc_io *mc_io, uint32_t cmd_flags,
2375 		uint16_t token, const struct dpni_rx_dist_cfg *cfg)
2376 {
2377 	struct dpni_cmd_set_rx_fs_dist *cmd_params;
2378 	struct mc_command cmd = { 0 };
2379 
2380 	/* prepare command */
2381 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_FS_DIST,
2382 					  cmd_flags,
2383 					  token);
2384 	cmd_params = (struct dpni_cmd_set_rx_fs_dist *)cmd.params;
2385 	cmd_params->dist_size	= cpu_to_le16(cfg->dist_size);
2386 	dpni_set_field(cmd_params->enable, RX_FS_DIST_ENABLE, cfg->enable);
2387 	cmd_params->tc = cfg->tc;
2388 	cmd_params->miss_flow_id = cpu_to_le16(cfg->fs_miss_flow_id);
2389 	cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova);
2390 
2391 	/* send command to mc*/
2392 	return mc_send_command(mc_io, &cmd);
2393 }
2394 
2395 /**
2396  * dpni_set_rx_hash_dist() - Set Rx traffic class HASH distribution
2397  * @mc_io:	Pointer to MC portal's I/O object
2398  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
2399  * @token:	Token of DPNI object
2400  * @cfg: Distribution configuration
2401  * If cfg.enable is set to 1 the packets will be classified using a hash
2402  *		function based on the key received in cfg.key_cfg_iova parameter
2403  * If cfg.enable is set to 0 the packets will be sent to the queue configured in
2404  *		dpni_set_rx_dist_default_queue() call
2405  */
2406 int dpni_set_rx_hash_dist(struct fsl_mc_io *mc_io, uint32_t cmd_flags,
2407 		uint16_t token, const struct dpni_rx_dist_cfg *cfg)
2408 {
2409 	struct dpni_cmd_set_rx_hash_dist *cmd_params;
2410 	struct mc_command cmd = { 0 };
2411 
2412 	/* prepare command */
2413 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_HASH_DIST,
2414 					  cmd_flags,
2415 					  token);
2416 	cmd_params = (struct dpni_cmd_set_rx_hash_dist *)cmd.params;
2417 	cmd_params->dist_size	= cpu_to_le16(cfg->dist_size);
2418 	dpni_set_field(cmd_params->enable, RX_FS_DIST_ENABLE, cfg->enable);
2419 	cmd_params->tc_id		= cfg->tc;
2420 	cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova);
2421 
2422 	/* send command to mc*/
2423 	return mc_send_command(mc_io, &cmd);
2424 }
2425 
2426 /**
2427  * dpni_add_custom_tpid() - Configures a distinct Ethertype value
2428  *		(or TPID value) to indicate VLAN tag in addition to the common
2429  *		TPID values 0x8100 and 0x88A8
2430  * @mc_io:	Pointer to MC portal's I/O object
2431  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
2432  * @token:	Token of DPNI object
2433  * @tpid:	New value for TPID
2434  *
2435  * Only two custom values are accepted. If the function is called for the third
2436  * time it will return error.
2437  * To replace an existing value use dpni_remove_custom_tpid() to remove
2438  * a previous TPID and after that use again the function.
2439  *
2440  * Return:	'0' on Success; Error code otherwise.
2441  */
2442 int dpni_add_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags,
2443 		uint16_t token, uint16_t tpid)
2444 {
2445 	struct dpni_cmd_add_custom_tpid *cmd_params;
2446 	struct mc_command cmd = { 0 };
2447 
2448 	/* prepare command */
2449 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_CUSTOM_TPID,
2450 					  cmd_flags,
2451 					  token);
2452 	cmd_params = (struct dpni_cmd_add_custom_tpid *)cmd.params;
2453 	cmd_params->tpid = cpu_to_le16(tpid);
2454 
2455 	/* send command to mc*/
2456 	return mc_send_command(mc_io, &cmd);
2457 }
2458 
2459 /**
2460  * dpni_remove_custom_tpid() - Removes a distinct Ethertype value added
2461  *		previously with dpni_add_custom_tpid()
2462  * @mc_io:	Pointer to MC portal's I/O object
2463  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
2464  * @token:	Token of DPNI object
2465  * @tpid:	New value for TPID
2466  *
2467  * Use this function when a TPID value added with dpni_add_custom_tpid() needs
2468  * to be replaced.
2469  *
2470  * Return:	'0' on Success; Error code otherwise.
2471  */
2472 int dpni_remove_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags,
2473 		uint16_t token, uint16_t tpid)
2474 {
2475 	struct dpni_cmd_remove_custom_tpid *cmd_params;
2476 	struct mc_command cmd = { 0 };
2477 
2478 	/* prepare command */
2479 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_CUSTOM_TPID,
2480 					  cmd_flags,
2481 					  token);
2482 	cmd_params = (struct dpni_cmd_remove_custom_tpid *)cmd.params;
2483 	cmd_params->tpid = cpu_to_le16(tpid);
2484 
2485 	/* send command to mc*/
2486 	return mc_send_command(mc_io, &cmd);
2487 }
2488 
2489 /**
2490  * dpni_get_custom_tpid() - Returns custom TPID (vlan tags) values configured
2491  *				to detect 802.1q frames
2492  * @mc_io:	Pointer to MC portal's I/O object
2493  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
2494  * @token:	Token of DPNI object
2495  * @tpid:	TPID values. Only nonzero members of the structure are valid.
2496  *
2497  * Return:	'0' on Success; Error code otherwise.
2498  */
2499 int dpni_get_custom_tpid(struct fsl_mc_io *mc_io, uint32_t cmd_flags,
2500 		uint16_t token, struct dpni_custom_tpid_cfg *tpid)
2501 {
2502 	struct dpni_rsp_get_custom_tpid *rsp_params;
2503 	struct mc_command cmd = { 0 };
2504 	int err;
2505 
2506 	/* prepare command */
2507 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_CUSTOM_TPID,
2508 					  cmd_flags,
2509 					  token);
2510 
2511 	/* send command to mc*/
2512 	err = mc_send_command(mc_io, &cmd);
2513 	if (err)
2514 		return err;
2515 
2516 	/* read command response */
2517 	rsp_params = (struct dpni_rsp_get_custom_tpid *)cmd.params;
2518 	tpid->tpid1 = le16_to_cpu(rsp_params->tpid1);
2519 	tpid->tpid2 = le16_to_cpu(rsp_params->tpid2);
2520 
2521 	return err;
2522 }
2523 
2524 int dpni_load_sw_sequence(struct fsl_mc_io *mc_io,
2525 	      uint32_t cmd_flags,
2526 	      uint16_t token,
2527 		  struct dpni_load_ss_cfg *cfg)
2528 {
2529 	struct dpni_load_sw_sequence *cmd_params;
2530 	struct mc_command cmd = { 0 };
2531 
2532 	/* prepare command */
2533 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_LOAD_SW_SEQUENCE,
2534 					  cmd_flags,
2535 					  token);
2536 	cmd_params = (struct dpni_load_sw_sequence *)cmd.params;
2537 	cmd_params->dest = cfg->dest;
2538 	cmd_params->ss_offset = cpu_to_le16(cfg->ss_offset);
2539 	cmd_params->ss_size = cpu_to_le16(cfg->ss_size);
2540 	cmd_params->ss_iova = cpu_to_le64(cfg->ss_iova);
2541 
2542 	/* send command to mc*/
2543 	return mc_send_command(mc_io, &cmd);
2544 }
2545 
2546 int dpni_enable_sw_sequence(struct fsl_mc_io *mc_io,
2547 	      uint32_t cmd_flags,
2548 	      uint16_t token,
2549 		  struct dpni_enable_ss_cfg *cfg)
2550 {
2551 	struct dpni_enable_sw_sequence *cmd_params;
2552 	struct mc_command cmd = { 0 };
2553 
2554 	/* prepare command */
2555 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE_SW_SEQUENCE,
2556 					  cmd_flags,
2557 					  token);
2558 	cmd_params = (struct dpni_enable_sw_sequence *)cmd.params;
2559 	cmd_params->dest = cfg->dest;
2560 	cmd_params->set_start = cfg->set_start;
2561 	cmd_params->hxs = cpu_to_le16(cfg->hxs);
2562 	cmd_params->ss_offset = cpu_to_le16(cfg->ss_offset);
2563 	cmd_params->param_offset = cfg->param_offset;
2564 	cmd_params->param_size = cfg->param_size;
2565 	cmd_params->param_iova = cpu_to_le64(cfg->param_iova);
2566 
2567 	/* send command to mc*/
2568 	return mc_send_command(mc_io, &cmd);
2569 }
2570 
2571 /**
2572  * dpni_get_sw_sequence_layout() - Get the soft sequence layout
2573  * @mc_io:	Pointer to MC portal's I/O object
2574  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
2575  * @token:	Token of DPNI object
2576  * @src:	Source of the layout (WRIOP Rx or Tx)
2577  * @ss_layout_iova:  I/O virtual address of 264 bytes DMA-able memory
2578  *
2579  * warning: After calling this function, call dpni_extract_sw_sequence_layout()
2580  *		to get the layout.
2581  *
2582  * Return:	'0' on Success; error code otherwise.
2583  */
2584 int dpni_get_sw_sequence_layout(struct fsl_mc_io *mc_io,
2585 	      uint32_t cmd_flags,
2586 	      uint16_t token,
2587 		  enum dpni_soft_sequence_dest src,
2588 		  uint64_t ss_layout_iova)
2589 {
2590 	struct dpni_get_sw_sequence_layout *cmd_params;
2591 	struct mc_command cmd = { 0 };
2592 
2593 	/* prepare command */
2594 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_SW_SEQUENCE_LAYOUT,
2595 					  cmd_flags,
2596 					  token);
2597 
2598 	cmd_params = (struct dpni_get_sw_sequence_layout *)cmd.params;
2599 	cmd_params->src = src;
2600 	cmd_params->layout_iova = cpu_to_le64(ss_layout_iova);
2601 
2602 	/* send command to mc*/
2603 	return mc_send_command(mc_io, &cmd);
2604 }
2605 
2606 /**
2607  * dpni_extract_sw_sequence_layout() - extract the software sequence layout
2608  * @layout:		software sequence layout
2609  * @sw_sequence_layout_buf:	Zeroed 264 bytes of memory before mapping it
2610  *				to DMA
2611  *
2612  * This function has to be called after dpni_get_sw_sequence_layout
2613  *
2614  */
2615 void dpni_extract_sw_sequence_layout(struct dpni_sw_sequence_layout *layout,
2616 			     const uint8_t *sw_sequence_layout_buf)
2617 {
2618 	const struct dpni_sw_sequence_layout_entry *ext_params;
2619 	int i;
2620 	uint16_t ss_size, ss_offset;
2621 
2622 	ext_params = (const struct dpni_sw_sequence_layout_entry *)
2623 						sw_sequence_layout_buf;
2624 
2625 	for (i = 0; i < DPNI_SW_SEQUENCE_LAYOUT_SIZE; i++) {
2626 		ss_offset = le16_to_cpu(ext_params[i].ss_offset);
2627 		ss_size = le16_to_cpu(ext_params[i].ss_size);
2628 
2629 		if (ss_offset == 0 && ss_size == 0) {
2630 			layout->num_ss = i;
2631 			return;
2632 		}
2633 
2634 		layout->ss[i].ss_offset = ss_offset;
2635 		layout->ss[i].ss_size = ss_size;
2636 		layout->ss[i].param_offset = ext_params[i].param_offset;
2637 		layout->ss[i].param_size = ext_params[i].param_size;
2638 	}
2639 }
2640