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