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