xref: /linux/drivers/net/ethernet/freescale/dpaa2/dpni.c (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
2 /* Copyright 2013-2016 Freescale Semiconductor Inc.
3  * Copyright 2016 NXP
4  * Copyright 2020 NXP
5  */
6 #include <linux/kernel.h>
7 #include <linux/errno.h>
8 #include <linux/fsl/mc.h>
9 #include "dpni.h"
10 #include "dpni-cmd.h"
11 
12 /**
13  * dpni_prepare_key_cfg() - function prepare extract parameters
14  * @cfg: defining a full Key Generation profile (rule)
15  * @key_cfg_buf: Zeroed 256 bytes of memory before mapping it to DMA
16  *
17  * This function has to be called before the following functions:
18  *	- dpni_set_rx_tc_dist()
19  *	- dpni_set_qos_table()
20  *
21  * Return:	'0' on Success; Error code otherwise.
22  */
23 int dpni_prepare_key_cfg(const struct dpkg_profile_cfg *cfg, u8 *key_cfg_buf)
24 {
25 	int i, j;
26 	struct dpni_ext_set_rx_tc_dist *dpni_ext;
27 	struct dpni_dist_extract *extr;
28 
29 	if (cfg->num_extracts > DPKG_MAX_NUM_OF_EXTRACTS)
30 		return -EINVAL;
31 
32 	dpni_ext = (struct dpni_ext_set_rx_tc_dist *)key_cfg_buf;
33 	dpni_ext->num_extracts = cfg->num_extracts;
34 
35 	for (i = 0; i < cfg->num_extracts; i++) {
36 		extr = &dpni_ext->extracts[i];
37 
38 		switch (cfg->extracts[i].type) {
39 		case DPKG_EXTRACT_FROM_HDR:
40 			extr->prot = cfg->extracts[i].extract.from_hdr.prot;
41 			dpni_set_field(extr->efh_type, EFH_TYPE,
42 				       cfg->extracts[i].extract.from_hdr.type);
43 			extr->size = cfg->extracts[i].extract.from_hdr.size;
44 			extr->offset = cfg->extracts[i].extract.from_hdr.offset;
45 			extr->field = cpu_to_le32(
46 				cfg->extracts[i].extract.from_hdr.field);
47 			extr->hdr_index =
48 				cfg->extracts[i].extract.from_hdr.hdr_index;
49 			break;
50 		case DPKG_EXTRACT_FROM_DATA:
51 			extr->size = cfg->extracts[i].extract.from_data.size;
52 			extr->offset =
53 				cfg->extracts[i].extract.from_data.offset;
54 			break;
55 		case DPKG_EXTRACT_FROM_PARSE:
56 			extr->size = cfg->extracts[i].extract.from_parse.size;
57 			extr->offset =
58 				cfg->extracts[i].extract.from_parse.offset;
59 			break;
60 		default:
61 			return -EINVAL;
62 		}
63 
64 		extr->num_of_byte_masks = cfg->extracts[i].num_of_byte_masks;
65 		dpni_set_field(extr->extract_type, EXTRACT_TYPE,
66 			       cfg->extracts[i].type);
67 
68 		for (j = 0; j < DPKG_NUM_OF_MASKS; j++) {
69 			extr->masks[j].mask = cfg->extracts[i].masks[j].mask;
70 			extr->masks[j].offset =
71 				cfg->extracts[i].masks[j].offset;
72 		}
73 	}
74 
75 	return 0;
76 }
77 
78 /**
79  * dpni_open() - Open a control session for the specified object
80  * @mc_io:	Pointer to MC portal's I/O object
81  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
82  * @dpni_id:	DPNI unique ID
83  * @token:	Returned token; use in subsequent API calls
84  *
85  * This function can be used to open a control session for an
86  * already created object; an object may have been declared in
87  * the DPL or by calling the dpni_create() function.
88  * This function returns a unique authentication token,
89  * associated with the specific object ID and the specific MC
90  * portal; this token must be used in all subsequent commands for
91  * this specific object.
92  *
93  * Return:	'0' on Success; Error code otherwise.
94  */
95 int dpni_open(struct fsl_mc_io *mc_io,
96 	      u32 cmd_flags,
97 	      int dpni_id,
98 	      u16 *token)
99 {
100 	struct fsl_mc_command cmd = { 0 };
101 	struct dpni_cmd_open *cmd_params;
102 
103 	int err;
104 
105 	/* prepare command */
106 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_OPEN,
107 					  cmd_flags,
108 					  0);
109 	cmd_params = (struct dpni_cmd_open *)cmd.params;
110 	cmd_params->dpni_id = cpu_to_le32(dpni_id);
111 
112 	/* send command to mc*/
113 	err = mc_send_command(mc_io, &cmd);
114 	if (err)
115 		return err;
116 
117 	/* retrieve response parameters */
118 	*token = mc_cmd_hdr_read_token(&cmd);
119 
120 	return 0;
121 }
122 
123 /**
124  * dpni_close() - Close the control session of the object
125  * @mc_io:	Pointer to MC portal's I/O object
126  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
127  * @token:	Token of DPNI object
128  *
129  * After this function is called, no further operations are
130  * allowed on the object without opening a new control session.
131  *
132  * Return:	'0' on Success; Error code otherwise.
133  */
134 int dpni_close(struct fsl_mc_io *mc_io,
135 	       u32 cmd_flags,
136 	       u16 token)
137 {
138 	struct fsl_mc_command cmd = { 0 };
139 
140 	/* prepare command */
141 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLOSE,
142 					  cmd_flags,
143 					  token);
144 
145 	/* send command to mc*/
146 	return mc_send_command(mc_io, &cmd);
147 }
148 
149 /**
150  * dpni_set_pools() - Set buffer pools configuration
151  * @mc_io:	Pointer to MC portal's I/O object
152  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
153  * @token:	Token of DPNI object
154  * @cfg:	Buffer pools configuration
155  *
156  * mandatory for DPNI operation
157  * warning:Allowed only when DPNI is disabled
158  *
159  * Return:	'0' on Success; Error code otherwise.
160  */
161 int dpni_set_pools(struct fsl_mc_io *mc_io,
162 		   u32 cmd_flags,
163 		   u16 token,
164 		   const struct dpni_pools_cfg *cfg)
165 {
166 	struct fsl_mc_command cmd = { 0 };
167 	struct dpni_cmd_set_pools *cmd_params;
168 	int i;
169 
170 	/* prepare command */
171 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_POOLS,
172 					  cmd_flags,
173 					  token);
174 	cmd_params = (struct dpni_cmd_set_pools *)cmd.params;
175 	cmd_params->num_dpbp = cfg->num_dpbp;
176 	cmd_params->pool_options = cfg->pool_options;
177 	for (i = 0; i < DPNI_MAX_DPBP; i++) {
178 		cmd_params->pool[i].dpbp_id =
179 			cpu_to_le16(cfg->pools[i].dpbp_id);
180 		cmd_params->pool[i].priority_mask =
181 			cfg->pools[i].priority_mask;
182 		cmd_params->buffer_size[i] =
183 			cpu_to_le16(cfg->pools[i].buffer_size);
184 		cmd_params->backup_pool_mask |=
185 			DPNI_BACKUP_POOL(cfg->pools[i].backup_pool, i);
186 	}
187 
188 	/* send command to mc*/
189 	return mc_send_command(mc_io, &cmd);
190 }
191 
192 /**
193  * dpni_enable() - Enable the DPNI, allow sending and receiving frames.
194  * @mc_io:	Pointer to MC portal's I/O object
195  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
196  * @token:		Token of DPNI object
197  *
198  * Return:	'0' on Success; Error code otherwise.
199  */
200 int dpni_enable(struct fsl_mc_io *mc_io,
201 		u32 cmd_flags,
202 		u16 token)
203 {
204 	struct fsl_mc_command cmd = { 0 };
205 
206 	/* prepare command */
207 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE,
208 					  cmd_flags,
209 					  token);
210 
211 	/* send command to mc*/
212 	return mc_send_command(mc_io, &cmd);
213 }
214 
215 /**
216  * dpni_disable() - Disable the DPNI, stop sending and receiving frames.
217  * @mc_io:	Pointer to MC portal's I/O object
218  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
219  * @token:	Token of DPNI object
220  *
221  * Return:	'0' on Success; Error code otherwise.
222  */
223 int dpni_disable(struct fsl_mc_io *mc_io,
224 		 u32 cmd_flags,
225 		 u16 token)
226 {
227 	struct fsl_mc_command cmd = { 0 };
228 
229 	/* prepare command */
230 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_DISABLE,
231 					  cmd_flags,
232 					  token);
233 
234 	/* send command to mc*/
235 	return mc_send_command(mc_io, &cmd);
236 }
237 
238 /**
239  * dpni_is_enabled() - Check if the DPNI is enabled.
240  * @mc_io:	Pointer to MC portal's I/O object
241  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
242  * @token:	Token of DPNI object
243  * @en:		Returns '1' if object is enabled; '0' otherwise
244  *
245  * Return:	'0' on Success; Error code otherwise.
246  */
247 int dpni_is_enabled(struct fsl_mc_io *mc_io,
248 		    u32 cmd_flags,
249 		    u16 token,
250 		    int *en)
251 {
252 	struct fsl_mc_command cmd = { 0 };
253 	struct dpni_rsp_is_enabled *rsp_params;
254 	int err;
255 
256 	/* prepare command */
257 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_IS_ENABLED,
258 					  cmd_flags,
259 					  token);
260 
261 	/* send command to mc*/
262 	err = mc_send_command(mc_io, &cmd);
263 	if (err)
264 		return err;
265 
266 	/* retrieve response parameters */
267 	rsp_params = (struct dpni_rsp_is_enabled *)cmd.params;
268 	*en = dpni_get_field(rsp_params->enabled, ENABLE);
269 
270 	return 0;
271 }
272 
273 /**
274  * dpni_reset() - Reset the DPNI, returns the object to initial state.
275  * @mc_io:	Pointer to MC portal's I/O object
276  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
277  * @token:	Token of DPNI object
278  *
279  * Return:	'0' on Success; Error code otherwise.
280  */
281 int dpni_reset(struct fsl_mc_io *mc_io,
282 	       u32 cmd_flags,
283 	       u16 token)
284 {
285 	struct fsl_mc_command cmd = { 0 };
286 
287 	/* prepare command */
288 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET,
289 					  cmd_flags,
290 					  token);
291 
292 	/* send command to mc*/
293 	return mc_send_command(mc_io, &cmd);
294 }
295 
296 /**
297  * dpni_set_irq_enable() - Set overall interrupt state.
298  * @mc_io:	Pointer to MC portal's I/O object
299  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
300  * @token:	Token of DPNI object
301  * @irq_index:	The interrupt index to configure
302  * @en:		Interrupt state: - enable = 1, disable = 0
303  *
304  * Allows GPP software to control when interrupts are generated.
305  * Each interrupt can have up to 32 causes.  The enable/disable control's the
306  * overall interrupt state. if the interrupt is disabled no causes will cause
307  * an interrupt.
308  *
309  * Return:	'0' on Success; Error code otherwise.
310  */
311 int dpni_set_irq_enable(struct fsl_mc_io *mc_io,
312 			u32 cmd_flags,
313 			u16 token,
314 			u8 irq_index,
315 			u8 en)
316 {
317 	struct fsl_mc_command cmd = { 0 };
318 	struct dpni_cmd_set_irq_enable *cmd_params;
319 
320 	/* prepare command */
321 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_IRQ_ENABLE,
322 					  cmd_flags,
323 					  token);
324 	cmd_params = (struct dpni_cmd_set_irq_enable *)cmd.params;
325 	dpni_set_field(cmd_params->enable, ENABLE, en);
326 	cmd_params->irq_index = irq_index;
327 
328 	/* send command to mc*/
329 	return mc_send_command(mc_io, &cmd);
330 }
331 
332 /**
333  * dpni_get_irq_enable() - Get overall interrupt state
334  * @mc_io:	Pointer to MC portal's I/O object
335  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
336  * @token:	Token of DPNI object
337  * @irq_index:	The interrupt index to configure
338  * @en:		Returned interrupt state - enable = 1, disable = 0
339  *
340  * Return:	'0' on Success; Error code otherwise.
341  */
342 int dpni_get_irq_enable(struct fsl_mc_io *mc_io,
343 			u32 cmd_flags,
344 			u16 token,
345 			u8 irq_index,
346 			u8 *en)
347 {
348 	struct fsl_mc_command cmd = { 0 };
349 	struct dpni_cmd_get_irq_enable *cmd_params;
350 	struct dpni_rsp_get_irq_enable *rsp_params;
351 
352 	int err;
353 
354 	/* prepare command */
355 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_IRQ_ENABLE,
356 					  cmd_flags,
357 					  token);
358 	cmd_params = (struct dpni_cmd_get_irq_enable *)cmd.params;
359 	cmd_params->irq_index = irq_index;
360 
361 	/* send command to mc*/
362 	err = mc_send_command(mc_io, &cmd);
363 	if (err)
364 		return err;
365 
366 	/* retrieve response parameters */
367 	rsp_params = (struct dpni_rsp_get_irq_enable *)cmd.params;
368 	*en = dpni_get_field(rsp_params->enabled, ENABLE);
369 
370 	return 0;
371 }
372 
373 /**
374  * dpni_set_irq_mask() - Set interrupt mask.
375  * @mc_io:	Pointer to MC portal's I/O object
376  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
377  * @token:	Token of DPNI object
378  * @irq_index:	The interrupt index to configure
379  * @mask:	event mask to trigger interrupt;
380  *			each bit:
381  *				0 = ignore event
382  *				1 = consider event for asserting IRQ
383  *
384  * Every interrupt can have up to 32 causes and the interrupt model supports
385  * masking/unmasking each cause independently
386  *
387  * Return:	'0' on Success; Error code otherwise.
388  */
389 int dpni_set_irq_mask(struct fsl_mc_io *mc_io,
390 		      u32 cmd_flags,
391 		      u16 token,
392 		      u8 irq_index,
393 		      u32 mask)
394 {
395 	struct fsl_mc_command cmd = { 0 };
396 	struct dpni_cmd_set_irq_mask *cmd_params;
397 
398 	/* prepare command */
399 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_IRQ_MASK,
400 					  cmd_flags,
401 					  token);
402 	cmd_params = (struct dpni_cmd_set_irq_mask *)cmd.params;
403 	cmd_params->mask = cpu_to_le32(mask);
404 	cmd_params->irq_index = irq_index;
405 
406 	/* send command to mc*/
407 	return mc_send_command(mc_io, &cmd);
408 }
409 
410 /**
411  * dpni_get_irq_mask() - Get interrupt mask.
412  * @mc_io:	Pointer to MC portal's I/O object
413  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
414  * @token:	Token of DPNI object
415  * @irq_index:	The interrupt index to configure
416  * @mask:	Returned event mask to trigger interrupt
417  *
418  * Every interrupt can have up to 32 causes and the interrupt model supports
419  * masking/unmasking each cause independently
420  *
421  * Return:	'0' on Success; Error code otherwise.
422  */
423 int dpni_get_irq_mask(struct fsl_mc_io *mc_io,
424 		      u32 cmd_flags,
425 		      u16 token,
426 		      u8 irq_index,
427 		      u32 *mask)
428 {
429 	struct fsl_mc_command cmd = { 0 };
430 	struct dpni_cmd_get_irq_mask *cmd_params;
431 	struct dpni_rsp_get_irq_mask *rsp_params;
432 	int err;
433 
434 	/* prepare command */
435 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_IRQ_MASK,
436 					  cmd_flags,
437 					  token);
438 	cmd_params = (struct dpni_cmd_get_irq_mask *)cmd.params;
439 	cmd_params->irq_index = irq_index;
440 
441 	/* send command to mc*/
442 	err = mc_send_command(mc_io, &cmd);
443 	if (err)
444 		return err;
445 
446 	/* retrieve response parameters */
447 	rsp_params = (struct dpni_rsp_get_irq_mask *)cmd.params;
448 	*mask = le32_to_cpu(rsp_params->mask);
449 
450 	return 0;
451 }
452 
453 /**
454  * dpni_get_irq_status() - Get the current status of any pending interrupts.
455  * @mc_io:	Pointer to MC portal's I/O object
456  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
457  * @token:	Token of DPNI object
458  * @irq_index:	The interrupt index to configure
459  * @status:	Returned interrupts status - one bit per cause:
460  *			0 = no interrupt pending
461  *			1 = interrupt pending
462  *
463  * Return:	'0' on Success; Error code otherwise.
464  */
465 int dpni_get_irq_status(struct fsl_mc_io *mc_io,
466 			u32 cmd_flags,
467 			u16 token,
468 			u8 irq_index,
469 			u32 *status)
470 {
471 	struct fsl_mc_command cmd = { 0 };
472 	struct dpni_cmd_get_irq_status *cmd_params;
473 	struct dpni_rsp_get_irq_status *rsp_params;
474 	int err;
475 
476 	/* prepare command */
477 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_IRQ_STATUS,
478 					  cmd_flags,
479 					  token);
480 	cmd_params = (struct dpni_cmd_get_irq_status *)cmd.params;
481 	cmd_params->status = cpu_to_le32(*status);
482 	cmd_params->irq_index = irq_index;
483 
484 	/* send command to mc*/
485 	err = mc_send_command(mc_io, &cmd);
486 	if (err)
487 		return err;
488 
489 	/* retrieve response parameters */
490 	rsp_params = (struct dpni_rsp_get_irq_status *)cmd.params;
491 	*status = le32_to_cpu(rsp_params->status);
492 
493 	return 0;
494 }
495 
496 /**
497  * dpni_clear_irq_status() - Clear a pending interrupt's status
498  * @mc_io:	Pointer to MC portal's I/O object
499  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
500  * @token:	Token of DPNI object
501  * @irq_index:	The interrupt index to configure
502  * @status:	bits to clear (W1C) - one bit per cause:
503  *			0 = don't change
504  *			1 = clear status bit
505  *
506  * Return:	'0' on Success; Error code otherwise.
507  */
508 int dpni_clear_irq_status(struct fsl_mc_io *mc_io,
509 			  u32 cmd_flags,
510 			  u16 token,
511 			  u8 irq_index,
512 			  u32 status)
513 {
514 	struct fsl_mc_command cmd = { 0 };
515 	struct dpni_cmd_clear_irq_status *cmd_params;
516 
517 	/* prepare command */
518 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLEAR_IRQ_STATUS,
519 					  cmd_flags,
520 					  token);
521 	cmd_params = (struct dpni_cmd_clear_irq_status *)cmd.params;
522 	cmd_params->irq_index = irq_index;
523 	cmd_params->status = cpu_to_le32(status);
524 
525 	/* send command to mc*/
526 	return mc_send_command(mc_io, &cmd);
527 }
528 
529 /**
530  * dpni_get_attributes() - Retrieve DPNI attributes.
531  * @mc_io:	Pointer to MC portal's I/O object
532  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
533  * @token:	Token of DPNI object
534  * @attr:	Object's attributes
535  *
536  * Return:	'0' on Success; Error code otherwise.
537  */
538 int dpni_get_attributes(struct fsl_mc_io *mc_io,
539 			u32 cmd_flags,
540 			u16 token,
541 			struct dpni_attr *attr)
542 {
543 	struct fsl_mc_command cmd = { 0 };
544 	struct dpni_rsp_get_attr *rsp_params;
545 
546 	int err;
547 
548 	/* prepare command */
549 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_ATTR,
550 					  cmd_flags,
551 					  token);
552 
553 	/* send command to mc*/
554 	err = mc_send_command(mc_io, &cmd);
555 	if (err)
556 		return err;
557 
558 	/* retrieve response parameters */
559 	rsp_params = (struct dpni_rsp_get_attr *)cmd.params;
560 	attr->options = le32_to_cpu(rsp_params->options);
561 	attr->num_queues = rsp_params->num_queues;
562 	attr->num_tcs = rsp_params->num_tcs;
563 	attr->mac_filter_entries = rsp_params->mac_filter_entries;
564 	attr->vlan_filter_entries = rsp_params->vlan_filter_entries;
565 	attr->qos_entries = rsp_params->qos_entries;
566 	attr->fs_entries = le16_to_cpu(rsp_params->fs_entries);
567 	attr->qos_key_size = rsp_params->qos_key_size;
568 	attr->fs_key_size = rsp_params->fs_key_size;
569 	attr->wriop_version = le16_to_cpu(rsp_params->wriop_version);
570 
571 	return 0;
572 }
573 
574 /**
575  * dpni_set_errors_behavior() - Set errors behavior
576  * @mc_io:	Pointer to MC portal's I/O object
577  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
578  * @token:	Token of DPNI object
579  * @cfg:	Errors configuration
580  *
581  * this function may be called numerous times with different
582  * error masks
583  *
584  * Return:	'0' on Success; Error code otherwise.
585  */
586 int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
587 			     u32 cmd_flags,
588 			     u16 token,
589 			     struct dpni_error_cfg *cfg)
590 {
591 	struct fsl_mc_command cmd = { 0 };
592 	struct dpni_cmd_set_errors_behavior *cmd_params;
593 
594 	/* prepare command */
595 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_ERRORS_BEHAVIOR,
596 					  cmd_flags,
597 					  token);
598 	cmd_params = (struct dpni_cmd_set_errors_behavior *)cmd.params;
599 	cmd_params->errors = cpu_to_le32(cfg->errors);
600 	dpni_set_field(cmd_params->flags, ERROR_ACTION, cfg->error_action);
601 	dpni_set_field(cmd_params->flags, FRAME_ANN, cfg->set_frame_annotation);
602 
603 	/* send command to mc*/
604 	return mc_send_command(mc_io, &cmd);
605 }
606 
607 /**
608  * dpni_get_buffer_layout() - Retrieve buffer layout attributes.
609  * @mc_io:	Pointer to MC portal's I/O object
610  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
611  * @token:	Token of DPNI object
612  * @qtype:	Type of queue to retrieve configuration for
613  * @layout:	Returns buffer layout attributes
614  *
615  * Return:	'0' on Success; Error code otherwise.
616  */
617 int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
618 			   u32 cmd_flags,
619 			   u16 token,
620 			   enum dpni_queue_type qtype,
621 			   struct dpni_buffer_layout *layout)
622 {
623 	struct fsl_mc_command cmd = { 0 };
624 	struct dpni_cmd_get_buffer_layout *cmd_params;
625 	struct dpni_rsp_get_buffer_layout *rsp_params;
626 	int err;
627 
628 	/* prepare command */
629 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_BUFFER_LAYOUT,
630 					  cmd_flags,
631 					  token);
632 	cmd_params = (struct dpni_cmd_get_buffer_layout *)cmd.params;
633 	cmd_params->qtype = qtype;
634 
635 	/* send command to mc*/
636 	err = mc_send_command(mc_io, &cmd);
637 	if (err)
638 		return err;
639 
640 	/* retrieve response parameters */
641 	rsp_params = (struct dpni_rsp_get_buffer_layout *)cmd.params;
642 	layout->pass_timestamp = dpni_get_field(rsp_params->flags, PASS_TS);
643 	layout->pass_parser_result = dpni_get_field(rsp_params->flags, PASS_PR);
644 	layout->pass_frame_status = dpni_get_field(rsp_params->flags, PASS_FS);
645 	layout->private_data_size = le16_to_cpu(rsp_params->private_data_size);
646 	layout->data_align = le16_to_cpu(rsp_params->data_align);
647 	layout->data_head_room = le16_to_cpu(rsp_params->head_room);
648 	layout->data_tail_room = le16_to_cpu(rsp_params->tail_room);
649 
650 	return 0;
651 }
652 
653 /**
654  * dpni_set_buffer_layout() - Set buffer layout configuration.
655  * @mc_io:	Pointer to MC portal's I/O object
656  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
657  * @token:	Token of DPNI object
658  * @qtype:	Type of queue this configuration applies to
659  * @layout:	Buffer layout configuration
660  *
661  * Return:	'0' on Success; Error code otherwise.
662  *
663  * @warning	Allowed only when DPNI is disabled
664  */
665 int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
666 			   u32 cmd_flags,
667 			   u16 token,
668 			   enum dpni_queue_type qtype,
669 			   const struct dpni_buffer_layout *layout)
670 {
671 	struct fsl_mc_command cmd = { 0 };
672 	struct dpni_cmd_set_buffer_layout *cmd_params;
673 
674 	/* prepare command */
675 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_BUFFER_LAYOUT,
676 					  cmd_flags,
677 					  token);
678 	cmd_params = (struct dpni_cmd_set_buffer_layout *)cmd.params;
679 	cmd_params->qtype = qtype;
680 	cmd_params->options = cpu_to_le16(layout->options);
681 	dpni_set_field(cmd_params->flags, PASS_TS, layout->pass_timestamp);
682 	dpni_set_field(cmd_params->flags, PASS_PR, layout->pass_parser_result);
683 	dpni_set_field(cmd_params->flags, PASS_FS, layout->pass_frame_status);
684 	cmd_params->private_data_size = cpu_to_le16(layout->private_data_size);
685 	cmd_params->data_align = cpu_to_le16(layout->data_align);
686 	cmd_params->head_room = cpu_to_le16(layout->data_head_room);
687 	cmd_params->tail_room = cpu_to_le16(layout->data_tail_room);
688 
689 	/* send command to mc*/
690 	return mc_send_command(mc_io, &cmd);
691 }
692 
693 /**
694  * dpni_set_offload() - Set DPNI offload configuration.
695  * @mc_io:	Pointer to MC portal's I/O object
696  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
697  * @token:	Token of DPNI object
698  * @type:	Type of DPNI offload
699  * @config:	Offload configuration.
700  *		For checksum offloads, non-zero value enables the offload
701  *
702  * Return:     '0' on Success; Error code otherwise.
703  *
704  * @warning    Allowed only when DPNI is disabled
705  */
706 
707 int dpni_set_offload(struct fsl_mc_io *mc_io,
708 		     u32 cmd_flags,
709 		     u16 token,
710 		     enum dpni_offload type,
711 		     u32 config)
712 {
713 	struct fsl_mc_command cmd = { 0 };
714 	struct dpni_cmd_set_offload *cmd_params;
715 
716 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_OFFLOAD,
717 					  cmd_flags,
718 					  token);
719 	cmd_params = (struct dpni_cmd_set_offload *)cmd.params;
720 	cmd_params->dpni_offload = type;
721 	cmd_params->config = cpu_to_le32(config);
722 
723 	return mc_send_command(mc_io, &cmd);
724 }
725 
726 int dpni_get_offload(struct fsl_mc_io *mc_io,
727 		     u32 cmd_flags,
728 		     u16 token,
729 		     enum dpni_offload type,
730 		     u32 *config)
731 {
732 	struct fsl_mc_command cmd = { 0 };
733 	struct dpni_cmd_get_offload *cmd_params;
734 	struct dpni_rsp_get_offload *rsp_params;
735 	int err;
736 
737 	/* prepare command */
738 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_OFFLOAD,
739 					  cmd_flags,
740 					  token);
741 	cmd_params = (struct dpni_cmd_get_offload *)cmd.params;
742 	cmd_params->dpni_offload = type;
743 
744 	/* send command to mc*/
745 	err = mc_send_command(mc_io, &cmd);
746 	if (err)
747 		return err;
748 
749 	/* retrieve response parameters */
750 	rsp_params = (struct dpni_rsp_get_offload *)cmd.params;
751 	*config = le32_to_cpu(rsp_params->config);
752 
753 	return 0;
754 }
755 
756 /**
757  * dpni_get_qdid() - Get the Queuing Destination ID (QDID) that should be used
758  *			for enqueue operations
759  * @mc_io:	Pointer to MC portal's I/O object
760  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
761  * @token:	Token of DPNI object
762  * @qtype:	Type of queue to receive QDID for
763  * @qdid:	Returned virtual QDID value that should be used as an argument
764  *			in all enqueue operations
765  *
766  * Return:	'0' on Success; Error code otherwise.
767  */
768 int dpni_get_qdid(struct fsl_mc_io *mc_io,
769 		  u32 cmd_flags,
770 		  u16 token,
771 		  enum dpni_queue_type qtype,
772 		  u16 *qdid)
773 {
774 	struct fsl_mc_command cmd = { 0 };
775 	struct dpni_cmd_get_qdid *cmd_params;
776 	struct dpni_rsp_get_qdid *rsp_params;
777 	int err;
778 
779 	/* prepare command */
780 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QDID,
781 					  cmd_flags,
782 					  token);
783 	cmd_params = (struct dpni_cmd_get_qdid *)cmd.params;
784 	cmd_params->qtype = qtype;
785 
786 	/* send command to mc*/
787 	err = mc_send_command(mc_io, &cmd);
788 	if (err)
789 		return err;
790 
791 	/* retrieve response parameters */
792 	rsp_params = (struct dpni_rsp_get_qdid *)cmd.params;
793 	*qdid = le16_to_cpu(rsp_params->qdid);
794 
795 	return 0;
796 }
797 
798 /**
799  * dpni_get_tx_data_offset() - Get the Tx data offset (from start of buffer)
800  * @mc_io:	Pointer to MC portal's I/O object
801  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
802  * @token:	Token of DPNI object
803  * @data_offset: Tx data offset (from start of buffer)
804  *
805  * Return:	'0' on Success; Error code otherwise.
806  */
807 int dpni_get_tx_data_offset(struct fsl_mc_io *mc_io,
808 			    u32 cmd_flags,
809 			    u16 token,
810 			    u16 *data_offset)
811 {
812 	struct fsl_mc_command cmd = { 0 };
813 	struct dpni_rsp_get_tx_data_offset *rsp_params;
814 	int err;
815 
816 	/* prepare command */
817 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_DATA_OFFSET,
818 					  cmd_flags,
819 					  token);
820 
821 	/* send command to mc*/
822 	err = mc_send_command(mc_io, &cmd);
823 	if (err)
824 		return err;
825 
826 	/* retrieve response parameters */
827 	rsp_params = (struct dpni_rsp_get_tx_data_offset *)cmd.params;
828 	*data_offset = le16_to_cpu(rsp_params->data_offset);
829 
830 	return 0;
831 }
832 
833 /**
834  * dpni_set_link_cfg() - set the link configuration.
835  * @mc_io:	Pointer to MC portal's I/O object
836  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
837  * @token:	Token of DPNI object
838  * @cfg:	Link configuration
839  *
840  * Return:	'0' on Success; Error code otherwise.
841  */
842 int dpni_set_link_cfg(struct fsl_mc_io *mc_io,
843 		      u32 cmd_flags,
844 		      u16 token,
845 		      const struct dpni_link_cfg *cfg)
846 {
847 	struct fsl_mc_command cmd = { 0 };
848 	struct dpni_cmd_link_cfg *cmd_params;
849 
850 	/* prepare command */
851 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_LINK_CFG,
852 					  cmd_flags,
853 					  token);
854 	cmd_params = (struct dpni_cmd_link_cfg *)cmd.params;
855 	cmd_params->rate = cpu_to_le32(cfg->rate);
856 	cmd_params->options = cpu_to_le64(cfg->options);
857 
858 	/* send command to mc*/
859 	return mc_send_command(mc_io, &cmd);
860 }
861 
862 /**
863  * dpni_get_link_cfg() - return the link configuration
864  * @mc_io:	Pointer to MC portal's I/O object
865  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
866  * @token:	Token of DPNI object
867  * @cfg:	Link configuration from dpni object
868  *
869  * Return:	'0' on Success; Error code otherwise.
870  */
871 int dpni_get_link_cfg(struct fsl_mc_io *mc_io,
872 		      u32 cmd_flags,
873 		      u16 token,
874 		      struct dpni_link_cfg *cfg)
875 {
876 	struct fsl_mc_command cmd = { 0 };
877 	struct dpni_cmd_link_cfg *rsp_params;
878 	int err;
879 
880 	/* prepare command */
881 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_CFG,
882 					  cmd_flags,
883 					  token);
884 
885 	/* send command to mc*/
886 	err = mc_send_command(mc_io, &cmd);
887 	if (err)
888 		return err;
889 
890 	/* retrieve response parameters */
891 	rsp_params = (struct dpni_cmd_link_cfg *)cmd.params;
892 	cfg->rate = le32_to_cpu(rsp_params->rate);
893 	cfg->options = le64_to_cpu(rsp_params->options);
894 
895 	return err;
896 }
897 
898 /**
899  * dpni_get_link_state() - Return the link state (either up or down)
900  * @mc_io:	Pointer to MC portal's I/O object
901  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
902  * @token:	Token of DPNI object
903  * @state:	Returned link state;
904  *
905  * Return:	'0' on Success; Error code otherwise.
906  */
907 int dpni_get_link_state(struct fsl_mc_io *mc_io,
908 			u32 cmd_flags,
909 			u16 token,
910 			struct dpni_link_state *state)
911 {
912 	struct fsl_mc_command cmd = { 0 };
913 	struct dpni_rsp_get_link_state *rsp_params;
914 	int err;
915 
916 	/* prepare command */
917 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_STATE,
918 					  cmd_flags,
919 					  token);
920 
921 	/* send command to mc*/
922 	err = mc_send_command(mc_io, &cmd);
923 	if (err)
924 		return err;
925 
926 	/* retrieve response parameters */
927 	rsp_params = (struct dpni_rsp_get_link_state *)cmd.params;
928 	state->up = dpni_get_field(rsp_params->flags, LINK_STATE);
929 	state->rate = le32_to_cpu(rsp_params->rate);
930 	state->options = le64_to_cpu(rsp_params->options);
931 
932 	return 0;
933 }
934 
935 /**
936  * dpni_set_max_frame_length() - Set the maximum received frame length.
937  * @mc_io:	Pointer to MC portal's I/O object
938  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
939  * @token:	Token of DPNI object
940  * @max_frame_length:	Maximum received frame length (in
941  *				bytes); frame is discarded if its
942  *				length exceeds this value
943  *
944  * Return:	'0' on Success; Error code otherwise.
945  */
946 int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
947 			      u32 cmd_flags,
948 			      u16 token,
949 			      u16 max_frame_length)
950 {
951 	struct fsl_mc_command cmd = { 0 };
952 	struct dpni_cmd_set_max_frame_length *cmd_params;
953 
954 	/* prepare command */
955 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MAX_FRAME_LENGTH,
956 					  cmd_flags,
957 					  token);
958 	cmd_params = (struct dpni_cmd_set_max_frame_length *)cmd.params;
959 	cmd_params->max_frame_length = cpu_to_le16(max_frame_length);
960 
961 	/* send command to mc*/
962 	return mc_send_command(mc_io, &cmd);
963 }
964 
965 /**
966  * dpni_get_max_frame_length() - Get the maximum received frame length.
967  * @mc_io:	Pointer to MC portal's I/O object
968  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
969  * @token:	Token of DPNI object
970  * @max_frame_length:	Maximum received frame length (in
971  *				bytes); frame is discarded if its
972  *				length exceeds this value
973  *
974  * Return:	'0' on Success; Error code otherwise.
975  */
976 int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
977 			      u32 cmd_flags,
978 			      u16 token,
979 			      u16 *max_frame_length)
980 {
981 	struct fsl_mc_command cmd = { 0 };
982 	struct dpni_rsp_get_max_frame_length *rsp_params;
983 	int err;
984 
985 	/* prepare command */
986 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MAX_FRAME_LENGTH,
987 					  cmd_flags,
988 					  token);
989 
990 	/* send command to mc*/
991 	err = mc_send_command(mc_io, &cmd);
992 	if (err)
993 		return err;
994 
995 	/* retrieve response parameters */
996 	rsp_params = (struct dpni_rsp_get_max_frame_length *)cmd.params;
997 	*max_frame_length = le16_to_cpu(rsp_params->max_frame_length);
998 
999 	return 0;
1000 }
1001 
1002 /**
1003  * dpni_set_multicast_promisc() - Enable/disable multicast promiscuous mode
1004  * @mc_io:	Pointer to MC portal's I/O object
1005  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1006  * @token:	Token of DPNI object
1007  * @en:		Set to '1' to enable; '0' to disable
1008  *
1009  * Return:	'0' on Success; Error code otherwise.
1010  */
1011 int dpni_set_multicast_promisc(struct fsl_mc_io *mc_io,
1012 			       u32 cmd_flags,
1013 			       u16 token,
1014 			       int en)
1015 {
1016 	struct fsl_mc_command cmd = { 0 };
1017 	struct dpni_cmd_set_multicast_promisc *cmd_params;
1018 
1019 	/* prepare command */
1020 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MCAST_PROMISC,
1021 					  cmd_flags,
1022 					  token);
1023 	cmd_params = (struct dpni_cmd_set_multicast_promisc *)cmd.params;
1024 	dpni_set_field(cmd_params->enable, ENABLE, en);
1025 
1026 	/* send command to mc*/
1027 	return mc_send_command(mc_io, &cmd);
1028 }
1029 
1030 /**
1031  * dpni_get_multicast_promisc() - Get multicast promiscuous mode
1032  * @mc_io:	Pointer to MC portal's I/O object
1033  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1034  * @token:	Token of DPNI object
1035  * @en:		Returns '1' if enabled; '0' otherwise
1036  *
1037  * Return:	'0' on Success; Error code otherwise.
1038  */
1039 int dpni_get_multicast_promisc(struct fsl_mc_io *mc_io,
1040 			       u32 cmd_flags,
1041 			       u16 token,
1042 			       int *en)
1043 {
1044 	struct fsl_mc_command cmd = { 0 };
1045 	struct dpni_rsp_get_multicast_promisc *rsp_params;
1046 	int err;
1047 
1048 	/* prepare command */
1049 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MCAST_PROMISC,
1050 					  cmd_flags,
1051 					  token);
1052 
1053 	/* send command to mc*/
1054 	err = mc_send_command(mc_io, &cmd);
1055 	if (err)
1056 		return err;
1057 
1058 	/* retrieve response parameters */
1059 	rsp_params = (struct dpni_rsp_get_multicast_promisc *)cmd.params;
1060 	*en = dpni_get_field(rsp_params->enabled, ENABLE);
1061 
1062 	return 0;
1063 }
1064 
1065 /**
1066  * dpni_set_unicast_promisc() - Enable/disable unicast promiscuous mode
1067  * @mc_io:	Pointer to MC portal's I/O object
1068  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1069  * @token:	Token of DPNI object
1070  * @en:		Set to '1' to enable; '0' to disable
1071  *
1072  * Return:	'0' on Success; Error code otherwise.
1073  */
1074 int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
1075 			     u32 cmd_flags,
1076 			     u16 token,
1077 			     int en)
1078 {
1079 	struct fsl_mc_command cmd = { 0 };
1080 	struct dpni_cmd_set_unicast_promisc *cmd_params;
1081 
1082 	/* prepare command */
1083 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_UNICAST_PROMISC,
1084 					  cmd_flags,
1085 					  token);
1086 	cmd_params = (struct dpni_cmd_set_unicast_promisc *)cmd.params;
1087 	dpni_set_field(cmd_params->enable, ENABLE, en);
1088 
1089 	/* send command to mc*/
1090 	return mc_send_command(mc_io, &cmd);
1091 }
1092 
1093 /**
1094  * dpni_get_unicast_promisc() - Get unicast promiscuous mode
1095  * @mc_io:	Pointer to MC portal's I/O object
1096  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1097  * @token:	Token of DPNI object
1098  * @en:		Returns '1' if enabled; '0' otherwise
1099  *
1100  * Return:	'0' on Success; Error code otherwise.
1101  */
1102 int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
1103 			     u32 cmd_flags,
1104 			     u16 token,
1105 			     int *en)
1106 {
1107 	struct fsl_mc_command cmd = { 0 };
1108 	struct dpni_rsp_get_unicast_promisc *rsp_params;
1109 	int err;
1110 
1111 	/* prepare command */
1112 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_UNICAST_PROMISC,
1113 					  cmd_flags,
1114 					  token);
1115 
1116 	/* send command to mc*/
1117 	err = mc_send_command(mc_io, &cmd);
1118 	if (err)
1119 		return err;
1120 
1121 	/* retrieve response parameters */
1122 	rsp_params = (struct dpni_rsp_get_unicast_promisc *)cmd.params;
1123 	*en = dpni_get_field(rsp_params->enabled, ENABLE);
1124 
1125 	return 0;
1126 }
1127 
1128 /**
1129  * dpni_set_primary_mac_addr() - Set the primary MAC address
1130  * @mc_io:	Pointer to MC portal's I/O object
1131  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1132  * @token:	Token of DPNI object
1133  * @mac_addr:	MAC address to set as primary address
1134  *
1135  * Return:	'0' on Success; Error code otherwise.
1136  */
1137 int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
1138 			      u32 cmd_flags,
1139 			      u16 token,
1140 			      const u8 mac_addr[6])
1141 {
1142 	struct fsl_mc_command cmd = { 0 };
1143 	struct dpni_cmd_set_primary_mac_addr *cmd_params;
1144 	int i;
1145 
1146 	/* prepare command */
1147 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_PRIM_MAC,
1148 					  cmd_flags,
1149 					  token);
1150 	cmd_params = (struct dpni_cmd_set_primary_mac_addr *)cmd.params;
1151 	for (i = 0; i < 6; i++)
1152 		cmd_params->mac_addr[i] = mac_addr[5 - i];
1153 
1154 	/* send command to mc*/
1155 	return mc_send_command(mc_io, &cmd);
1156 }
1157 
1158 /**
1159  * dpni_get_primary_mac_addr() - Get the primary MAC address
1160  * @mc_io:	Pointer to MC portal's I/O object
1161  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1162  * @token:	Token of DPNI object
1163  * @mac_addr:	Returned MAC address
1164  *
1165  * Return:	'0' on Success; Error code otherwise.
1166  */
1167 int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
1168 			      u32 cmd_flags,
1169 			      u16 token,
1170 			      u8 mac_addr[6])
1171 {
1172 	struct fsl_mc_command cmd = { 0 };
1173 	struct dpni_rsp_get_primary_mac_addr *rsp_params;
1174 	int i, err;
1175 
1176 	/* prepare command */
1177 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PRIM_MAC,
1178 					  cmd_flags,
1179 					  token);
1180 
1181 	/* send command to mc*/
1182 	err = mc_send_command(mc_io, &cmd);
1183 	if (err)
1184 		return err;
1185 
1186 	/* retrieve response parameters */
1187 	rsp_params = (struct dpni_rsp_get_primary_mac_addr *)cmd.params;
1188 	for (i = 0; i < 6; i++)
1189 		mac_addr[5 - i] = rsp_params->mac_addr[i];
1190 
1191 	return 0;
1192 }
1193 
1194 /**
1195  * dpni_get_port_mac_addr() - Retrieve MAC address associated to the physical
1196  *			port the DPNI is attached to
1197  * @mc_io:	Pointer to MC portal's I/O object
1198  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1199  * @token:	Token of DPNI object
1200  * @mac_addr:	MAC address of the physical port, if any, otherwise 0
1201  *
1202  * The primary MAC address is not cleared by this operation.
1203  *
1204  * Return:	'0' on Success; Error code otherwise.
1205  */
1206 int dpni_get_port_mac_addr(struct fsl_mc_io *mc_io,
1207 			   u32 cmd_flags,
1208 			   u16 token,
1209 			   u8 mac_addr[6])
1210 {
1211 	struct fsl_mc_command cmd = { 0 };
1212 	struct dpni_rsp_get_port_mac_addr *rsp_params;
1213 	int i, err;
1214 
1215 	/* prepare command */
1216 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PORT_MAC_ADDR,
1217 					  cmd_flags,
1218 					  token);
1219 
1220 	/* send command to mc*/
1221 	err = mc_send_command(mc_io, &cmd);
1222 	if (err)
1223 		return err;
1224 
1225 	/* retrieve response parameters */
1226 	rsp_params = (struct dpni_rsp_get_port_mac_addr *)cmd.params;
1227 	for (i = 0; i < 6; i++)
1228 		mac_addr[5 - i] = rsp_params->mac_addr[i];
1229 
1230 	return 0;
1231 }
1232 
1233 /**
1234  * dpni_enable_vlan_filter() - Enable/disable VLAN filtering mode
1235  * @mc_io:	Pointer to MC portal's I/O object
1236  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1237  * @token:	Token of DPNI object
1238  * @en:		Set to '1' to enable; '0' to disable
1239  *
1240  * Return:	'0' on Success; Error code otherwise.
1241  */
1242 int dpni_enable_vlan_filter(struct fsl_mc_io *mc_io,
1243 			    u32 cmd_flags,
1244 			    u16 token,
1245 			    u32 en)
1246 {
1247 	struct dpni_cmd_enable_vlan_filter *cmd_params;
1248 	struct fsl_mc_command cmd = { 0 };
1249 
1250 	/* prepare command */
1251 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE_VLAN_FILTER,
1252 					  cmd_flags,
1253 					  token);
1254 	cmd_params = (struct dpni_cmd_enable_vlan_filter *)cmd.params;
1255 	dpni_set_field(cmd_params->en, ENABLE, en);
1256 
1257 	/* send command to mc*/
1258 	return mc_send_command(mc_io, &cmd);
1259 }
1260 
1261 /**
1262  * dpni_add_vlan_id() - Add VLAN ID filter
1263  * @mc_io:	Pointer to MC portal's I/O object
1264  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1265  * @token:	Token of DPNI object
1266  * @vlan_id:	VLAN ID to add
1267  * @flags:   0 - tc_id and flow_id will be ignored.
1268  * Pkt with this vlan_id will be passed to the next
1269  * classification stages
1270  * DPNI_VLAN_SET_QUEUE_ACTION
1271  * Pkt with this vlan_id will be forward directly to
1272  * queue defined by the tc_id and flow_id
1273  *
1274  * @tc_id: Traffic class selection (0-7)
1275  * @flow_id: Selects the specific queue out of the set allocated for the
1276  *           same as tc_id. Value must be in range 0 to NUM_QUEUES - 1
1277  *
1278  * Return:	'0' on Success; Error code otherwise.
1279  */
1280 int dpni_add_vlan_id(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
1281 		     u16 vlan_id, u8 flags, u8 tc_id, u8 flow_id)
1282 {
1283 	struct dpni_cmd_vlan_id *cmd_params;
1284 	struct fsl_mc_command cmd = { 0 };
1285 
1286 	/* prepare command */
1287 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_VLAN_ID,
1288 					  cmd_flags,
1289 					  token);
1290 	cmd_params = (struct dpni_cmd_vlan_id *)cmd.params;
1291 	cmd_params->flags = flags;
1292 	cmd_params->tc_id = tc_id;
1293 	cmd_params->flow_id =  flow_id;
1294 	cmd_params->vlan_id = cpu_to_le16(vlan_id);
1295 
1296 	/* send command to mc*/
1297 	return mc_send_command(mc_io, &cmd);
1298 }
1299 
1300 /**
1301  * dpni_remove_vlan_id() - Remove VLAN ID filter
1302  * @mc_io:	Pointer to MC portal's I/O object
1303  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1304  * @token:	Token of DPNI object
1305  * @vlan_id:	VLAN ID to remove
1306  *
1307  * Return:	'0' on Success; Error code otherwise.
1308  */
1309 int dpni_remove_vlan_id(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
1310 			u16 vlan_id)
1311 {
1312 	struct dpni_cmd_vlan_id *cmd_params;
1313 	struct fsl_mc_command cmd = { 0 };
1314 
1315 	/* prepare command */
1316 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_VLAN_ID,
1317 					  cmd_flags,
1318 					  token);
1319 	cmd_params = (struct dpni_cmd_vlan_id *)cmd.params;
1320 	cmd_params->vlan_id = cpu_to_le16(vlan_id);
1321 
1322 	/* send command to mc*/
1323 	return mc_send_command(mc_io, &cmd);
1324 }
1325 
1326 /**
1327  * dpni_add_mac_addr() - Add MAC address filter
1328  * @mc_io:	Pointer to MC portal's I/O object
1329  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1330  * @token:	Token of DPNI object
1331  * @mac_addr:	MAC address to add
1332  *
1333  * Return:	'0' on Success; Error code otherwise.
1334  */
1335 int dpni_add_mac_addr(struct fsl_mc_io *mc_io,
1336 		      u32 cmd_flags,
1337 		      u16 token,
1338 		      const u8 mac_addr[6])
1339 {
1340 	struct fsl_mc_command cmd = { 0 };
1341 	struct dpni_cmd_add_mac_addr *cmd_params;
1342 	int i;
1343 
1344 	/* prepare command */
1345 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_MAC_ADDR,
1346 					  cmd_flags,
1347 					  token);
1348 	cmd_params = (struct dpni_cmd_add_mac_addr *)cmd.params;
1349 	for (i = 0; i < 6; i++)
1350 		cmd_params->mac_addr[i] = mac_addr[5 - i];
1351 
1352 	/* send command to mc*/
1353 	return mc_send_command(mc_io, &cmd);
1354 }
1355 
1356 /**
1357  * dpni_remove_mac_addr() - Remove MAC address filter
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  * @mac_addr:	MAC address to remove
1362  *
1363  * Return:	'0' on Success; Error code otherwise.
1364  */
1365 int dpni_remove_mac_addr(struct fsl_mc_io *mc_io,
1366 			 u32 cmd_flags,
1367 			 u16 token,
1368 			 const u8 mac_addr[6])
1369 {
1370 	struct fsl_mc_command cmd = { 0 };
1371 	struct dpni_cmd_remove_mac_addr *cmd_params;
1372 	int i;
1373 
1374 	/* prepare command */
1375 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_MAC_ADDR,
1376 					  cmd_flags,
1377 					  token);
1378 	cmd_params = (struct dpni_cmd_remove_mac_addr *)cmd.params;
1379 	for (i = 0; i < 6; i++)
1380 		cmd_params->mac_addr[i] = mac_addr[5 - i];
1381 
1382 	/* send command to mc*/
1383 	return mc_send_command(mc_io, &cmd);
1384 }
1385 
1386 /**
1387  * dpni_clear_mac_filters() - Clear all unicast and/or multicast MAC filters
1388  * @mc_io:	Pointer to MC portal's I/O object
1389  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1390  * @token:	Token of DPNI object
1391  * @unicast:	Set to '1' to clear unicast addresses
1392  * @multicast:	Set to '1' to clear multicast addresses
1393  *
1394  * The primary MAC address is not cleared by this operation.
1395  *
1396  * Return:	'0' on Success; Error code otherwise.
1397  */
1398 int dpni_clear_mac_filters(struct fsl_mc_io *mc_io,
1399 			   u32 cmd_flags,
1400 			   u16 token,
1401 			   int unicast,
1402 			   int multicast)
1403 {
1404 	struct fsl_mc_command cmd = { 0 };
1405 	struct dpni_cmd_clear_mac_filters *cmd_params;
1406 
1407 	/* prepare command */
1408 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_MAC_FILTERS,
1409 					  cmd_flags,
1410 					  token);
1411 	cmd_params = (struct dpni_cmd_clear_mac_filters *)cmd.params;
1412 	dpni_set_field(cmd_params->flags, UNICAST_FILTERS, unicast);
1413 	dpni_set_field(cmd_params->flags, MULTICAST_FILTERS, multicast);
1414 
1415 	/* send command to mc*/
1416 	return mc_send_command(mc_io, &cmd);
1417 }
1418 
1419 /**
1420  * dpni_set_rx_tc_dist() - Set Rx traffic class distribution configuration
1421  * @mc_io:	Pointer to MC portal's I/O object
1422  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1423  * @token:	Token of DPNI object
1424  * @tc_id:	Traffic class selection (0-7)
1425  * @cfg:	Traffic class distribution configuration
1426  *
1427  * warning: if 'dist_mode != DPNI_DIST_MODE_NONE', call dpni_prepare_key_cfg()
1428  *			first to prepare the key_cfg_iova parameter
1429  *
1430  * Return:	'0' on Success; error code otherwise.
1431  */
1432 int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
1433 			u32 cmd_flags,
1434 			u16 token,
1435 			u8 tc_id,
1436 			const struct dpni_rx_tc_dist_cfg *cfg)
1437 {
1438 	struct fsl_mc_command cmd = { 0 };
1439 	struct dpni_cmd_set_rx_tc_dist *cmd_params;
1440 
1441 	/* prepare command */
1442 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_TC_DIST,
1443 					  cmd_flags,
1444 					  token);
1445 	cmd_params = (struct dpni_cmd_set_rx_tc_dist *)cmd.params;
1446 	cmd_params->dist_size = cpu_to_le16(cfg->dist_size);
1447 	cmd_params->tc_id = tc_id;
1448 	dpni_set_field(cmd_params->flags, DIST_MODE, cfg->dist_mode);
1449 	dpni_set_field(cmd_params->flags, MISS_ACTION, cfg->fs_cfg.miss_action);
1450 	cmd_params->default_flow_id = cpu_to_le16(cfg->fs_cfg.default_flow_id);
1451 	cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova);
1452 
1453 	/* send command to mc*/
1454 	return mc_send_command(mc_io, &cmd);
1455 }
1456 
1457 /**
1458  * dpni_set_congestion_notification() - Set traffic class congestion
1459  *					notification configuration
1460  * @mc_io:	Pointer to MC portal's I/O object
1461  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1462  * @token:	Token of DPNI object
1463  * @qtype:	Type of queue - Rx, Tx and Tx confirm types are supported
1464  * @tc_id:	Traffic class selection (0-7)
1465  * @cfg:	Congestion notification configuration
1466  *
1467  * Return:	'0' on Success; error code otherwise.
1468  */
1469 int dpni_set_congestion_notification(
1470 			struct fsl_mc_io *mc_io,
1471 			u32 cmd_flags,
1472 			u16 token,
1473 			enum dpni_queue_type qtype,
1474 			u8 tc_id,
1475 			const struct dpni_congestion_notification_cfg *cfg)
1476 {
1477 	struct dpni_cmd_set_congestion_notification *cmd_params;
1478 	struct fsl_mc_command cmd = { 0 };
1479 
1480 	/* prepare command */
1481 	cmd.header =
1482 		mc_encode_cmd_header(DPNI_CMDID_SET_CONGESTION_NOTIFICATION,
1483 				     cmd_flags,
1484 				     token);
1485 	cmd_params = (struct dpni_cmd_set_congestion_notification *)cmd.params;
1486 	cmd_params->qtype = qtype;
1487 	cmd_params->tc = tc_id;
1488 	cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
1489 	cmd_params->notification_mode = cpu_to_le16(cfg->notification_mode);
1490 	cmd_params->dest_priority = cfg->dest_cfg.priority;
1491 	dpni_set_field(cmd_params->type_units, DEST_TYPE,
1492 		       cfg->dest_cfg.dest_type);
1493 	dpni_set_field(cmd_params->type_units, CONG_UNITS, cfg->units);
1494 	cmd_params->message_iova = cpu_to_le64(cfg->message_iova);
1495 	cmd_params->message_ctx = cpu_to_le64(cfg->message_ctx);
1496 	cmd_params->threshold_entry = cpu_to_le32(cfg->threshold_entry);
1497 	cmd_params->threshold_exit = cpu_to_le32(cfg->threshold_exit);
1498 
1499 	/* send command to mc*/
1500 	return mc_send_command(mc_io, &cmd);
1501 }
1502 
1503 /**
1504  * dpni_set_queue() - Set queue parameters
1505  * @mc_io:	Pointer to MC portal's I/O object
1506  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1507  * @token:	Token of DPNI object
1508  * @qtype:	Type of queue - all queue types are supported, although
1509  *		the command is ignored for Tx
1510  * @tc:		Traffic class, in range 0 to NUM_TCS - 1
1511  * @index:	Selects the specific queue out of the set allocated for the
1512  *		same TC. Value must be in range 0 to NUM_QUEUES - 1
1513  * @options:	A combination of DPNI_QUEUE_OPT_ values that control what
1514  *		configuration options are set on the queue
1515  * @queue:	Queue structure
1516  *
1517  * Return:	'0' on Success; Error code otherwise.
1518  */
1519 int dpni_set_queue(struct fsl_mc_io *mc_io,
1520 		   u32 cmd_flags,
1521 		   u16 token,
1522 		   enum dpni_queue_type qtype,
1523 		   u8 tc,
1524 		   u8 index,
1525 		   u8 options,
1526 		   const struct dpni_queue *queue)
1527 {
1528 	struct fsl_mc_command cmd = { 0 };
1529 	struct dpni_cmd_set_queue *cmd_params;
1530 
1531 	/* prepare command */
1532 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QUEUE,
1533 					  cmd_flags,
1534 					  token);
1535 	cmd_params = (struct dpni_cmd_set_queue *)cmd.params;
1536 	cmd_params->qtype = qtype;
1537 	cmd_params->tc = tc;
1538 	cmd_params->index = index;
1539 	cmd_params->options = options;
1540 	cmd_params->dest_id = cpu_to_le32(queue->destination.id);
1541 	cmd_params->dest_prio = queue->destination.priority;
1542 	dpni_set_field(cmd_params->flags, DEST_TYPE, queue->destination.type);
1543 	dpni_set_field(cmd_params->flags, STASH_CTRL, queue->flc.stash_control);
1544 	dpni_set_field(cmd_params->flags, HOLD_ACTIVE,
1545 		       queue->destination.hold_active);
1546 	cmd_params->flc = cpu_to_le64(queue->flc.value);
1547 	cmd_params->user_context = cpu_to_le64(queue->user_context);
1548 
1549 	/* send command to mc */
1550 	return mc_send_command(mc_io, &cmd);
1551 }
1552 
1553 /**
1554  * dpni_get_queue() - Get queue parameters
1555  * @mc_io:	Pointer to MC portal's I/O object
1556  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1557  * @token:	Token of DPNI object
1558  * @qtype:	Type of queue - all queue types are supported
1559  * @tc:		Traffic class, in range 0 to NUM_TCS - 1
1560  * @index:	Selects the specific queue out of the set allocated for the
1561  *		same TC. Value must be in range 0 to NUM_QUEUES - 1
1562  * @queue:	Queue configuration structure
1563  * @qid:	Queue identification
1564  *
1565  * Return:	'0' on Success; Error code otherwise.
1566  */
1567 int dpni_get_queue(struct fsl_mc_io *mc_io,
1568 		   u32 cmd_flags,
1569 		   u16 token,
1570 		   enum dpni_queue_type qtype,
1571 		   u8 tc,
1572 		   u8 index,
1573 		   struct dpni_queue *queue,
1574 		   struct dpni_queue_id *qid)
1575 {
1576 	struct fsl_mc_command cmd = { 0 };
1577 	struct dpni_cmd_get_queue *cmd_params;
1578 	struct dpni_rsp_get_queue *rsp_params;
1579 	int err;
1580 
1581 	/* prepare command */
1582 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QUEUE,
1583 					  cmd_flags,
1584 					  token);
1585 	cmd_params = (struct dpni_cmd_get_queue *)cmd.params;
1586 	cmd_params->qtype = qtype;
1587 	cmd_params->tc = tc;
1588 	cmd_params->index = index;
1589 
1590 	/* send command to mc */
1591 	err = mc_send_command(mc_io, &cmd);
1592 	if (err)
1593 		return err;
1594 
1595 	/* retrieve response parameters */
1596 	rsp_params = (struct dpni_rsp_get_queue *)cmd.params;
1597 	queue->destination.id = le32_to_cpu(rsp_params->dest_id);
1598 	queue->destination.priority = rsp_params->dest_prio;
1599 	queue->destination.type = dpni_get_field(rsp_params->flags,
1600 						 DEST_TYPE);
1601 	queue->flc.stash_control = dpni_get_field(rsp_params->flags,
1602 						  STASH_CTRL);
1603 	queue->destination.hold_active = dpni_get_field(rsp_params->flags,
1604 							HOLD_ACTIVE);
1605 	queue->flc.value = le64_to_cpu(rsp_params->flc);
1606 	queue->user_context = le64_to_cpu(rsp_params->user_context);
1607 	qid->fqid = le32_to_cpu(rsp_params->fqid);
1608 	qid->qdbin = le16_to_cpu(rsp_params->qdbin);
1609 
1610 	return 0;
1611 }
1612 
1613 /**
1614  * dpni_get_statistics() - Get DPNI statistics
1615  * @mc_io:	Pointer to MC portal's I/O object
1616  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1617  * @token:	Token of DPNI object
1618  * @page:	Selects the statistics page to retrieve, see
1619  *		DPNI_GET_STATISTICS output. Pages are numbered 0 to 6.
1620  * @stat:	Structure containing the statistics
1621  *
1622  * Return:	'0' on Success; Error code otherwise.
1623  */
1624 int dpni_get_statistics(struct fsl_mc_io *mc_io,
1625 			u32 cmd_flags,
1626 			u16 token,
1627 			u8 page,
1628 			union dpni_statistics *stat)
1629 {
1630 	struct fsl_mc_command cmd = { 0 };
1631 	struct dpni_cmd_get_statistics *cmd_params;
1632 	struct dpni_rsp_get_statistics *rsp_params;
1633 	int i, err;
1634 
1635 	/* prepare command */
1636 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_STATISTICS,
1637 					  cmd_flags,
1638 					  token);
1639 	cmd_params = (struct dpni_cmd_get_statistics *)cmd.params;
1640 	cmd_params->page_number = page;
1641 
1642 	/* send command to mc */
1643 	err = mc_send_command(mc_io, &cmd);
1644 	if (err)
1645 		return err;
1646 
1647 	/* retrieve response parameters */
1648 	rsp_params = (struct dpni_rsp_get_statistics *)cmd.params;
1649 	for (i = 0; i < DPNI_STATISTICS_CNT; i++)
1650 		stat->raw.counter[i] = le64_to_cpu(rsp_params->counter[i]);
1651 
1652 	return 0;
1653 }
1654 
1655 /**
1656  * dpni_set_taildrop() - Set taildrop per queue or TC
1657  * @mc_io:	Pointer to MC portal's I/O object
1658  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1659  * @token:	Token of DPNI object
1660  * @cg_point:	Congestion point
1661  * @qtype:	Queue type on which the taildrop is configured.
1662  *		Only Rx queues are supported for now
1663  * @tc:		Traffic class to apply this taildrop to
1664  * @index:	Index of the queue if the DPNI supports multiple queues for
1665  *		traffic distribution. Ignored if CONGESTION_POINT is not 0.
1666  * @taildrop:	Taildrop structure
1667  *
1668  * Return:	'0' on Success; Error code otherwise.
1669  */
1670 int dpni_set_taildrop(struct fsl_mc_io *mc_io,
1671 		      u32 cmd_flags,
1672 		      u16 token,
1673 		      enum dpni_congestion_point cg_point,
1674 		      enum dpni_queue_type qtype,
1675 		      u8 tc,
1676 		      u8 index,
1677 		      struct dpni_taildrop *taildrop)
1678 {
1679 	struct fsl_mc_command cmd = { 0 };
1680 	struct dpni_cmd_set_taildrop *cmd_params;
1681 
1682 	/* prepare command */
1683 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TAILDROP,
1684 					  cmd_flags,
1685 					  token);
1686 	cmd_params = (struct dpni_cmd_set_taildrop *)cmd.params;
1687 	cmd_params->congestion_point = cg_point;
1688 	cmd_params->qtype = qtype;
1689 	cmd_params->tc = tc;
1690 	cmd_params->index = index;
1691 	dpni_set_field(cmd_params->enable, ENABLE, taildrop->enable);
1692 	cmd_params->units = taildrop->units;
1693 	cmd_params->threshold = cpu_to_le32(taildrop->threshold);
1694 
1695 	/* send command to mc */
1696 	return mc_send_command(mc_io, &cmd);
1697 }
1698 
1699 /**
1700  * dpni_get_taildrop() - Get taildrop information
1701  * @mc_io:	Pointer to MC portal's I/O object
1702  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1703  * @token:	Token of DPNI object
1704  * @cg_point:	Congestion point
1705  * @qtype:	Queue type on which the taildrop is configured.
1706  *		Only Rx queues are supported for now
1707  * @tc:		Traffic class to apply this taildrop to
1708  * @index:	Index of the queue if the DPNI supports multiple queues for
1709  *		traffic distribution. Ignored if CONGESTION_POINT is not 0.
1710  * @taildrop:	Taildrop structure
1711  *
1712  * Return:	'0' on Success; Error code otherwise.
1713  */
1714 int dpni_get_taildrop(struct fsl_mc_io *mc_io,
1715 		      u32 cmd_flags,
1716 		      u16 token,
1717 		      enum dpni_congestion_point cg_point,
1718 		      enum dpni_queue_type qtype,
1719 		      u8 tc,
1720 		      u8 index,
1721 		      struct dpni_taildrop *taildrop)
1722 {
1723 	struct fsl_mc_command cmd = { 0 };
1724 	struct dpni_cmd_get_taildrop *cmd_params;
1725 	struct dpni_rsp_get_taildrop *rsp_params;
1726 	int err;
1727 
1728 	/* prepare command */
1729 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TAILDROP,
1730 					  cmd_flags,
1731 					  token);
1732 	cmd_params = (struct dpni_cmd_get_taildrop *)cmd.params;
1733 	cmd_params->congestion_point = cg_point;
1734 	cmd_params->qtype = qtype;
1735 	cmd_params->tc = tc;
1736 	cmd_params->index = index;
1737 
1738 	/* send command to mc */
1739 	err = mc_send_command(mc_io, &cmd);
1740 	if (err)
1741 		return err;
1742 
1743 	/* retrieve response parameters */
1744 	rsp_params = (struct dpni_rsp_get_taildrop *)cmd.params;
1745 	taildrop->enable = dpni_get_field(rsp_params->enable, ENABLE);
1746 	taildrop->units = rsp_params->units;
1747 	taildrop->threshold = le32_to_cpu(rsp_params->threshold);
1748 
1749 	return 0;
1750 }
1751 
1752 /**
1753  * dpni_get_api_version() - Get Data Path Network Interface API version
1754  * @mc_io:	Pointer to MC portal's I/O object
1755  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1756  * @major_ver:	Major version of data path network interface API
1757  * @minor_ver:	Minor version of data path network interface API
1758  *
1759  * Return:	'0' on Success; Error code otherwise.
1760  */
1761 int dpni_get_api_version(struct fsl_mc_io *mc_io,
1762 			 u32 cmd_flags,
1763 			 u16 *major_ver,
1764 			 u16 *minor_ver)
1765 {
1766 	struct dpni_rsp_get_api_version *rsp_params;
1767 	struct fsl_mc_command cmd = { 0 };
1768 	int err;
1769 
1770 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_API_VERSION,
1771 					  cmd_flags, 0);
1772 
1773 	err = mc_send_command(mc_io, &cmd);
1774 	if (err)
1775 		return err;
1776 
1777 	rsp_params = (struct dpni_rsp_get_api_version *)cmd.params;
1778 	*major_ver = le16_to_cpu(rsp_params->major);
1779 	*minor_ver = le16_to_cpu(rsp_params->minor);
1780 
1781 	return 0;
1782 }
1783 
1784 /**
1785  * dpni_set_rx_fs_dist() - Set Rx flow steering distribution
1786  * @mc_io:	Pointer to MC portal's I/O object
1787  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1788  * @token:	Token of DPNI object
1789  * @cfg: Distribution configuration
1790  *
1791  * If the FS is already enabled with a previous call the classification
1792  * key will be changed but all the table rules are kept. If the
1793  * existing rules do not match the key the results will not be
1794  * predictable. It is the user responsibility to keep key integrity.
1795  * If cfg.enable is set to 1 the command will create a flow steering table
1796  * and will classify packets according to this table. The packets that
1797  * miss all the table rules will be classified according to settings
1798  * made in dpni_set_rx_hash_dist()
1799  * If cfg.enable is set to 0 the command will clear flow steering table.
1800  * The packets will be classified according to settings made in
1801  * dpni_set_rx_hash_dist()
1802  *
1803  * Return:	'0' on Success; Error code otherwise.
1804  */
1805 int dpni_set_rx_fs_dist(struct fsl_mc_io *mc_io,
1806 			u32 cmd_flags,
1807 			u16 token,
1808 			const struct dpni_rx_dist_cfg *cfg)
1809 {
1810 	struct dpni_cmd_set_rx_fs_dist *cmd_params;
1811 	struct fsl_mc_command cmd = { 0 };
1812 
1813 	/* prepare command */
1814 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_FS_DIST,
1815 					  cmd_flags,
1816 					  token);
1817 	cmd_params = (struct dpni_cmd_set_rx_fs_dist *)cmd.params;
1818 	cmd_params->dist_size = cpu_to_le16(cfg->dist_size);
1819 	dpni_set_field(cmd_params->enable, RX_FS_DIST_ENABLE, cfg->enable);
1820 	cmd_params->tc = cfg->tc;
1821 	cmd_params->miss_flow_id = cpu_to_le16(cfg->fs_miss_flow_id);
1822 	cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova);
1823 
1824 	/* send command to mc*/
1825 	return mc_send_command(mc_io, &cmd);
1826 }
1827 
1828 /**
1829  * dpni_set_rx_hash_dist() - Set Rx hash distribution
1830  * @mc_io:	Pointer to MC portal's I/O object
1831  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1832  * @token:	Token of DPNI object
1833  * @cfg: Distribution configuration
1834  * If cfg.enable is set to 1 the packets will be classified using a hash
1835  * function based on the key received in cfg.key_cfg_iova parameter.
1836  * If cfg.enable is set to 0 the packets will be sent to the default queue
1837  *
1838  * Return:	'0' on Success; Error code otherwise.
1839  */
1840 int dpni_set_rx_hash_dist(struct fsl_mc_io *mc_io,
1841 			  u32 cmd_flags,
1842 			  u16 token,
1843 			  const struct dpni_rx_dist_cfg *cfg)
1844 {
1845 	struct dpni_cmd_set_rx_hash_dist *cmd_params;
1846 	struct fsl_mc_command cmd = { 0 };
1847 
1848 	/* prepare command */
1849 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_HASH_DIST,
1850 					  cmd_flags,
1851 					  token);
1852 	cmd_params = (struct dpni_cmd_set_rx_hash_dist *)cmd.params;
1853 	cmd_params->dist_size = cpu_to_le16(cfg->dist_size);
1854 	dpni_set_field(cmd_params->enable, RX_HASH_DIST_ENABLE, cfg->enable);
1855 	cmd_params->tc = cfg->tc;
1856 	cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova);
1857 
1858 	/* send command to mc*/
1859 	return mc_send_command(mc_io, &cmd);
1860 }
1861 
1862 /**
1863  * dpni_add_fs_entry() - Add Flow Steering entry for a specific traffic class
1864  *			(to select a flow ID)
1865  * @mc_io:	Pointer to MC portal's I/O object
1866  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1867  * @token:	Token of DPNI object
1868  * @tc_id:	Traffic class selection (0-7)
1869  * @index:	Location in the FS table where to insert the entry.
1870  *		Only relevant if MASKING is enabled for FS
1871  *		classification on this DPNI, it is ignored for exact match.
1872  * @cfg:	Flow steering rule to add
1873  * @action:	Action to be taken as result of a classification hit
1874  *
1875  * Return:	'0' on Success; Error code otherwise.
1876  */
1877 int dpni_add_fs_entry(struct fsl_mc_io *mc_io,
1878 		      u32 cmd_flags,
1879 		      u16 token,
1880 		      u8 tc_id,
1881 		      u16 index,
1882 		      const struct dpni_rule_cfg *cfg,
1883 		      const struct dpni_fs_action_cfg *action)
1884 {
1885 	struct dpni_cmd_add_fs_entry *cmd_params;
1886 	struct fsl_mc_command cmd = { 0 };
1887 
1888 	/* prepare command */
1889 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_FS_ENT,
1890 					  cmd_flags,
1891 					  token);
1892 	cmd_params = (struct dpni_cmd_add_fs_entry *)cmd.params;
1893 	cmd_params->tc_id = tc_id;
1894 	cmd_params->key_size = cfg->key_size;
1895 	cmd_params->index = cpu_to_le16(index);
1896 	cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
1897 	cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova);
1898 	cmd_params->options = cpu_to_le16(action->options);
1899 	cmd_params->flow_id = cpu_to_le16(action->flow_id);
1900 	cmd_params->flc = cpu_to_le64(action->flc);
1901 
1902 	/* send command to mc*/
1903 	return mc_send_command(mc_io, &cmd);
1904 }
1905 
1906 /**
1907  * dpni_remove_fs_entry() - Remove Flow Steering entry from a specific
1908  *			    traffic class
1909  * @mc_io:	Pointer to MC portal's I/O object
1910  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1911  * @token:	Token of DPNI object
1912  * @tc_id:	Traffic class selection (0-7)
1913  * @cfg:	Flow steering rule to remove
1914  *
1915  * Return:	'0' on Success; Error code otherwise.
1916  */
1917 int dpni_remove_fs_entry(struct fsl_mc_io *mc_io,
1918 			 u32 cmd_flags,
1919 			 u16 token,
1920 			 u8 tc_id,
1921 			 const struct dpni_rule_cfg *cfg)
1922 {
1923 	struct dpni_cmd_remove_fs_entry *cmd_params;
1924 	struct fsl_mc_command cmd = { 0 };
1925 
1926 	/* prepare command */
1927 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_FS_ENT,
1928 					  cmd_flags,
1929 					  token);
1930 	cmd_params = (struct dpni_cmd_remove_fs_entry *)cmd.params;
1931 	cmd_params->tc_id = tc_id;
1932 	cmd_params->key_size = cfg->key_size;
1933 	cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
1934 	cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova);
1935 
1936 	/* send command to mc*/
1937 	return mc_send_command(mc_io, &cmd);
1938 }
1939 
1940 /**
1941  * dpni_set_qos_table() - Set QoS mapping table
1942  * @mc_io:	Pointer to MC portal's I/O object
1943  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1944  * @token:	Token of DPNI object
1945  * @cfg:	QoS table configuration
1946  *
1947  * This function and all QoS-related functions require that
1948  *'max_tcs > 1' was set at DPNI creation.
1949  *
1950  * warning: Before calling this function, call dpkg_prepare_key_cfg() to
1951  *			prepare the key_cfg_iova parameter
1952  *
1953  * Return:	'0' on Success; Error code otherwise.
1954  */
1955 int dpni_set_qos_table(struct fsl_mc_io *mc_io,
1956 		       u32 cmd_flags,
1957 		       u16 token,
1958 		       const struct dpni_qos_tbl_cfg *cfg)
1959 {
1960 	struct dpni_cmd_set_qos_table *cmd_params;
1961 	struct fsl_mc_command cmd = { 0 };
1962 
1963 	/* prepare command */
1964 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QOS_TBL,
1965 					  cmd_flags,
1966 					  token);
1967 	cmd_params = (struct dpni_cmd_set_qos_table *)cmd.params;
1968 	cmd_params->default_tc = cfg->default_tc;
1969 	cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova);
1970 	dpni_set_field(cmd_params->discard_on_miss, DISCARD_ON_MISS,
1971 		       cfg->discard_on_miss);
1972 
1973 	/* send command to mc*/
1974 	return mc_send_command(mc_io, &cmd);
1975 }
1976 
1977 /**
1978  * dpni_add_qos_entry() - Add QoS mapping entry (to select a traffic class)
1979  * @mc_io:	Pointer to MC portal's I/O object
1980  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1981  * @token:	Token of DPNI object
1982  * @cfg:	QoS rule to add
1983  * @tc_id:	Traffic class selection (0-7)
1984  * @index:	Location in the QoS table where to insert the entry.
1985  *		Only relevant if MASKING is enabled for QoS classification on
1986  *		this DPNI, it is ignored for exact match.
1987  *
1988  * Return:	'0' on Success; Error code otherwise.
1989  */
1990 int dpni_add_qos_entry(struct fsl_mc_io *mc_io,
1991 		       u32 cmd_flags,
1992 		       u16 token,
1993 		       const struct dpni_rule_cfg *cfg,
1994 		       u8 tc_id,
1995 		       u16 index)
1996 {
1997 	struct dpni_cmd_add_qos_entry *cmd_params;
1998 	struct fsl_mc_command cmd = { 0 };
1999 
2000 	/* prepare command */
2001 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_QOS_ENT,
2002 					  cmd_flags,
2003 					  token);
2004 	cmd_params = (struct dpni_cmd_add_qos_entry *)cmd.params;
2005 	cmd_params->tc_id = tc_id;
2006 	cmd_params->key_size = cfg->key_size;
2007 	cmd_params->index = cpu_to_le16(index);
2008 	cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
2009 	cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova);
2010 
2011 	/* send command to mc*/
2012 	return mc_send_command(mc_io, &cmd);
2013 }
2014 
2015 /**
2016  * dpni_remove_qos_entry() - Remove QoS mapping entry
2017  * @mc_io:	Pointer to MC portal's I/O object
2018  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
2019  * @token:	Token of DPNI object
2020  * @cfg:	QoS rule to remove
2021  *
2022  * Return:	'0' on Success; Error code otherwise.
2023  */
2024 int dpni_remove_qos_entry(struct fsl_mc_io *mc_io,
2025 			  u32 cmd_flags,
2026 			  u16 token,
2027 			  const struct dpni_rule_cfg *cfg)
2028 {
2029 	struct dpni_cmd_remove_qos_entry *cmd_params;
2030 	struct fsl_mc_command cmd = { 0 };
2031 
2032 	/* prepare command */
2033 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_QOS_ENT,
2034 					  cmd_flags,
2035 					  token);
2036 	cmd_params = (struct dpni_cmd_remove_qos_entry *)cmd.params;
2037 	cmd_params->key_size = cfg->key_size;
2038 	cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
2039 	cmd_params->mask_iova = cpu_to_le64(cfg->mask_iova);
2040 
2041 	/* send command to mc*/
2042 	return mc_send_command(mc_io, &cmd);
2043 }
2044 
2045 /**
2046  * dpni_clear_qos_table() - Clear all QoS mapping entries
2047  * @mc_io:	Pointer to MC portal's I/O object
2048  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
2049  * @token:	Token of DPNI object
2050  *
2051  * Following this function call, all frames are directed to
2052  * the default traffic class (0)
2053  *
2054  * Return:	'0' on Success; Error code otherwise.
2055  */
2056 int dpni_clear_qos_table(struct fsl_mc_io *mc_io,
2057 			 u32 cmd_flags,
2058 			 u16 token)
2059 {
2060 	struct fsl_mc_command cmd = { 0 };
2061 
2062 	/* prepare command */
2063 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_QOS_TBL,
2064 					  cmd_flags,
2065 					  token);
2066 
2067 	/* send command to mc*/
2068 	return mc_send_command(mc_io, &cmd);
2069 }
2070 
2071 /**
2072  * dpni_set_tx_shaping() - Set the transmit shaping
2073  * @mc_io:		Pointer to MC portal's I/O object
2074  * @cmd_flags:		Command flags; one or more of 'MC_CMD_FLAG_'
2075  * @token:		Token of DPNI object
2076  * @tx_cr_shaper:	TX committed rate shaping configuration
2077  * @tx_er_shaper:	TX excess rate shaping configuration
2078  * @coupled:		Committed and excess rate shapers are coupled
2079  *
2080  * Return:	'0' on Success; Error code otherwise.
2081  */
2082 int dpni_set_tx_shaping(struct fsl_mc_io *mc_io,
2083 			u32 cmd_flags,
2084 			u16 token,
2085 			const struct dpni_tx_shaping_cfg *tx_cr_shaper,
2086 			const struct dpni_tx_shaping_cfg *tx_er_shaper,
2087 			int coupled)
2088 {
2089 	struct dpni_cmd_set_tx_shaping *cmd_params;
2090 	struct fsl_mc_command cmd = { 0 };
2091 
2092 	/* prepare command */
2093 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_SHAPING,
2094 					  cmd_flags,
2095 					  token);
2096 	cmd_params = (struct dpni_cmd_set_tx_shaping *)cmd.params;
2097 	cmd_params->tx_cr_max_burst_size = cpu_to_le16(tx_cr_shaper->max_burst_size);
2098 	cmd_params->tx_er_max_burst_size = cpu_to_le16(tx_er_shaper->max_burst_size);
2099 	cmd_params->tx_cr_rate_limit = cpu_to_le32(tx_cr_shaper->rate_limit);
2100 	cmd_params->tx_er_rate_limit = cpu_to_le32(tx_er_shaper->rate_limit);
2101 	dpni_set_field(cmd_params->coupled, COUPLED, coupled);
2102 
2103 	/* send command to mc*/
2104 	return mc_send_command(mc_io, &cmd);
2105 }
2106 
2107 /**
2108  * dpni_get_single_step_cfg() - return current configuration for
2109  *                              single step PTP
2110  * @mc_io:	Pointer to MC portal's I/O object
2111  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
2112  * @token:	Token of DPNI object
2113  * @ptp_cfg:	ptp single step configuration
2114  *
2115  * Return:	'0' on Success; Error code otherwise.
2116  *
2117  */
2118 int dpni_get_single_step_cfg(struct fsl_mc_io *mc_io,
2119 			     u32 cmd_flags,
2120 			     u16 token,
2121 			     struct dpni_single_step_cfg *ptp_cfg)
2122 {
2123 	struct dpni_rsp_single_step_cfg *rsp_params;
2124 	struct fsl_mc_command cmd = { 0 };
2125 	int err;
2126 
2127 	/* prepare command */
2128 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_SINGLE_STEP_CFG,
2129 					  cmd_flags, token);
2130 	/* send command to mc*/
2131 	err =  mc_send_command(mc_io, &cmd);
2132 	if (err)
2133 		return err;
2134 
2135 	/* read command response */
2136 	rsp_params = (struct dpni_rsp_single_step_cfg *)cmd.params;
2137 	ptp_cfg->offset = le16_to_cpu(rsp_params->offset);
2138 	ptp_cfg->en = dpni_get_field(le16_to_cpu(rsp_params->flags),
2139 				     PTP_ENABLE) ? 1 : 0;
2140 	ptp_cfg->ch_update = dpni_get_field(le16_to_cpu(rsp_params->flags),
2141 					    PTP_CH_UPDATE) ? 1 : 0;
2142 	ptp_cfg->peer_delay = le32_to_cpu(rsp_params->peer_delay);
2143 	ptp_cfg->ptp_onestep_reg_base =
2144 				  le32_to_cpu(rsp_params->ptp_onestep_reg_base);
2145 
2146 	return err;
2147 }
2148 
2149 /**
2150  * dpni_set_single_step_cfg() - enable/disable and configure single step PTP
2151  * @mc_io:	Pointer to MC portal's I/O object
2152  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
2153  * @token:	Token of DPNI object
2154  * @ptp_cfg:	ptp single step configuration
2155  *
2156  * Return:	'0' on Success; Error code otherwise.
2157  *
2158  * The function has effect only when dpni object is connected to a dpmac
2159  * object. If the dpni is not connected to a dpmac the configuration will
2160  * be stored inside and applied when connection is made.
2161  */
2162 int dpni_set_single_step_cfg(struct fsl_mc_io *mc_io,
2163 			     u32 cmd_flags,
2164 			     u16 token,
2165 			     struct dpni_single_step_cfg *ptp_cfg)
2166 {
2167 	struct dpni_cmd_single_step_cfg *cmd_params;
2168 	struct fsl_mc_command cmd = { 0 };
2169 	u16 flags;
2170 
2171 	/* prepare command */
2172 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_SINGLE_STEP_CFG,
2173 					  cmd_flags, token);
2174 	cmd_params = (struct dpni_cmd_single_step_cfg *)cmd.params;
2175 	cmd_params->offset = cpu_to_le16(ptp_cfg->offset);
2176 	cmd_params->peer_delay = cpu_to_le32(ptp_cfg->peer_delay);
2177 
2178 	flags = le16_to_cpu(cmd_params->flags);
2179 	dpni_set_field(flags, PTP_ENABLE, !!ptp_cfg->en);
2180 	dpni_set_field(flags, PTP_CH_UPDATE, !!ptp_cfg->ch_update);
2181 	cmd_params->flags = cpu_to_le16(flags);
2182 
2183 	/* send command to mc*/
2184 	return mc_send_command(mc_io, &cmd);
2185 }
2186