xref: /dpdk/drivers/net/dpaa2/mc/dpni.c (revision 5a4806d304e084573eb2193341add736ef0af50f)
1 /*-
2  * This file is provided under a dual BSD/GPLv2 license. When using or
3  * redistributing this file, you may do so under either license.
4  *
5  *   BSD LICENSE
6  *
7  * Copyright 2013-2016 Freescale Semiconductor Inc.
8  * Copyright 2016 NXP.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  * * Neither the name of the above-listed copyright holders nor the
18  * names of any contributors may be used to endorse or promote products
19  * derived from this software without specific prior written permission.
20  *
21  *   GPL LICENSE SUMMARY
22  *
23  * ALTERNATIVELY, this software may be distributed under the terms of the
24  * GNU General Public License ("GPL") as published by the Free Software
25  * Foundation, either version 2 of that License or (at your option) any
26  * later version.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
32  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40 #include <fsl_mc_sys.h>
41 #include <fsl_mc_cmd.h>
42 #include <fsl_dpni.h>
43 #include <fsl_dpni_cmd.h>
44 
45 /**
46  * dpni_open() - Open a control session for the specified object
47  * @mc_io:	Pointer to MC portal's I/O object
48  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
49  * @dpni_id:	DPNI unique ID
50  * @token:	Returned token; use in subsequent API calls
51  *
52  * This function can be used to open a control session for an
53  * already created object; an object may have been declared in
54  * the DPL or by calling the dpni_create() function.
55  * This function returns a unique authentication token,
56  * associated with the specific object ID and the specific MC
57  * portal; this token must be used in all subsequent commands for
58  * this specific object.
59  *
60  * Return:	'0' on Success; Error code otherwise.
61  */
62 int dpni_open(struct fsl_mc_io *mc_io,
63 	      uint32_t cmd_flags,
64 	      int dpni_id,
65 	      uint16_t *token)
66 {
67 	struct mc_command cmd = { 0 };
68 	struct dpni_cmd_open *cmd_params;
69 
70 	int err;
71 
72 	/* prepare command */
73 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_OPEN,
74 					  cmd_flags,
75 					  0);
76 	cmd_params = (struct dpni_cmd_open *)cmd.params;
77 	cmd_params->dpni_id = cpu_to_le32(dpni_id);
78 
79 	/* send command to mc*/
80 	err = mc_send_command(mc_io, &cmd);
81 	if (err)
82 		return err;
83 
84 	/* retrieve response parameters */
85 	*token = mc_cmd_hdr_read_token(&cmd);
86 
87 	return 0;
88 }
89 
90 /**
91  * dpni_close() - Close the control session of the object
92  * @mc_io:	Pointer to MC portal's I/O object
93  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
94  * @token:	Token of DPNI object
95  *
96  * After this function is called, no further operations are
97  * allowed on the object without opening a new control session.
98  *
99  * Return:	'0' on Success; Error code otherwise.
100  */
101 int dpni_close(struct fsl_mc_io *mc_io,
102 	       uint32_t cmd_flags,
103 	       uint16_t token)
104 {
105 	struct mc_command cmd = { 0 };
106 
107 	/* prepare command */
108 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLOSE,
109 					  cmd_flags,
110 					  token);
111 
112 	/* send command to mc*/
113 	return mc_send_command(mc_io, &cmd);
114 }
115 
116 /**
117  * dpni_create() - Create the DPNI object
118  * @mc_io:	Pointer to MC portal's I/O object
119  * @dprc_token:	Parent container token; '0' for default container
120  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
121  * @cfg:	Configuration structure
122  * @obj_id:	Returned object id
123  *
124  * Create the DPNI object, allocate required resources and
125  * perform required initialization.
126  *
127  * The object can be created either by declaring it in the
128  * DPL file, or by calling this function.
129  *
130  * The function accepts an authentication token of a parent
131  * container that this object should be assigned to. The token
132  * can be '0' so the object will be assigned to the default container.
133  * The newly created object can be opened with the returned
134  * object id and using the container's associated tokens and MC portals.
135  *
136  * Return:	'0' on Success; Error code otherwise.
137  */
138 int dpni_create(struct fsl_mc_io *mc_io,
139 		uint16_t dprc_token,
140 		uint32_t cmd_flags,
141 		const struct dpni_cfg *cfg,
142 		uint32_t *obj_id)
143 {
144 	struct dpni_cmd_create *cmd_params;
145 	struct mc_command cmd = { 0 };
146 	int err;
147 
148 	/* prepare command */
149 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_CREATE,
150 					  cmd_flags,
151 					  dprc_token);
152 	cmd_params = (struct dpni_cmd_create *)cmd.params;
153 	cmd_params->options = cpu_to_le32(cfg->options);
154 	cmd_params->num_queues = cfg->num_queues;
155 	cmd_params->num_tcs = cfg->num_tcs;
156 	cmd_params->mac_filter_entries = cfg->mac_filter_entries;
157 	cmd_params->vlan_filter_entries =  cfg->vlan_filter_entries;
158 	cmd_params->qos_entries = cfg->qos_entries;
159 	cmd_params->fs_entries = cpu_to_le16(cfg->fs_entries);
160 
161 	/* send command to mc*/
162 	err = mc_send_command(mc_io, &cmd);
163 	if (err)
164 		return err;
165 
166 	/* retrieve response parameters */
167 	*obj_id = mc_cmd_read_object_id(&cmd);
168 
169 	return 0;
170 }
171 
172 /**
173  * dpni_destroy() - Destroy the DPNI object and release all its resources.
174  * @mc_io:	Pointer to MC portal's I/O object
175  * @dprc_token: Parent container token; '0' for default container
176  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
177  * @object_id:	The object id; it must be a valid id within the container that
178  * created this object;
179  *
180  * The function accepts the authentication token of the parent container that
181  * created the object (not the one that currently owns the object). The object
182  * is searched within parent using the provided 'object_id'.
183  * All tokens to the object must be closed before calling destroy.
184  *
185  * Return:	'0' on Success; error code otherwise.
186  */
187 int dpni_destroy(struct fsl_mc_io *mc_io,
188 		 uint16_t dprc_token,
189 		 uint32_t cmd_flags,
190 		 uint32_t object_id)
191 {
192 	struct dpni_cmd_destroy *cmd_params;
193 	struct mc_command cmd = { 0 };
194 
195 	/* prepare command */
196 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_DESTROY,
197 					  cmd_flags,
198 					  dprc_token);
199 	/* set object id to destroy */
200 	cmd_params = (struct dpni_cmd_destroy *)cmd.params;
201 	cmd_params->dpsw_id = cpu_to_le32(object_id);
202 
203 	/* send command to mc*/
204 	return mc_send_command(mc_io, &cmd);
205 }
206 
207 /**
208  * dpni_set_pools() - Set buffer pools configuration
209  * @mc_io:	Pointer to MC portal's I/O object
210  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
211  * @token:	Token of DPNI object
212  * @cfg:	Buffer pools configuration
213  *
214  * mandatory for DPNI operation
215  * warning:Allowed only when DPNI is disabled
216  *
217  * Return:	'0' on Success; Error code otherwise.
218  */
219 int dpni_set_pools(struct fsl_mc_io *mc_io,
220 		   uint32_t cmd_flags,
221 		   uint16_t token,
222 		   const struct dpni_pools_cfg *cfg)
223 {
224 	struct mc_command cmd = { 0 };
225 	struct dpni_cmd_set_pools *cmd_params;
226 	int i;
227 
228 	/* prepare command */
229 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_POOLS,
230 					  cmd_flags,
231 					  token);
232 	cmd_params = (struct dpni_cmd_set_pools *)cmd.params;
233 	cmd_params->num_dpbp = cfg->num_dpbp;
234 	for (i = 0; i < DPNI_MAX_DPBP; i++) {
235 		cmd_params->pool[i].dpbp_id =
236 			cpu_to_le16(cfg->pools[i].dpbp_id);
237 		cmd_params->pool[i].priority_mask =
238 			cfg->pools[i].priority_mask;
239 		cmd_params->buffer_size[i] =
240 			cpu_to_le16(cfg->pools[i].buffer_size);
241 		cmd_params->backup_pool_mask |=
242 			DPNI_BACKUP_POOL(cfg->pools[i].backup_pool, i);
243 	}
244 
245 	/* send command to mc*/
246 	return mc_send_command(mc_io, &cmd);
247 }
248 
249 /**
250  * dpni_enable() - Enable the DPNI, allow sending and receiving frames.
251  * @mc_io:	Pointer to MC portal's I/O object
252  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
253  * @token:	Token of DPNI object
254  *
255  * Return:	'0' on Success; Error code otherwise.
256  */
257 int dpni_enable(struct fsl_mc_io *mc_io,
258 		uint32_t cmd_flags,
259 		uint16_t token)
260 {
261 	struct mc_command cmd = { 0 };
262 
263 	/* prepare command */
264 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE,
265 					  cmd_flags,
266 					  token);
267 
268 	/* send command to mc*/
269 	return mc_send_command(mc_io, &cmd);
270 }
271 
272 /**
273  * dpni_disable() - Disable the DPNI, stop sending and receiving frames.
274  * @mc_io:	Pointer to MC portal's I/O object
275  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
276  * @token:	Token of DPNI object
277  *
278  * Return:	'0' on Success; Error code otherwise.
279  */
280 int dpni_disable(struct fsl_mc_io *mc_io,
281 		 uint32_t cmd_flags,
282 		 uint16_t token)
283 {
284 	struct mc_command cmd = { 0 };
285 
286 	/* prepare command */
287 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_DISABLE,
288 					  cmd_flags,
289 					  token);
290 
291 	/* send command to mc*/
292 	return mc_send_command(mc_io, &cmd);
293 }
294 
295 /**
296  * dpni_is_enabled() - Check if the DPNI is enabled.
297  * @mc_io:	Pointer to MC portal's I/O object
298  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
299  * @token:	Token of DPNI object
300  * @en:		Returns '1' if object is enabled; '0' otherwise
301  *
302  * Return:	'0' on Success; Error code otherwise.
303  */
304 int dpni_is_enabled(struct fsl_mc_io *mc_io,
305 		    uint32_t cmd_flags,
306 		    uint16_t token,
307 		    int *en)
308 {
309 	struct mc_command cmd = { 0 };
310 	struct dpni_rsp_is_enabled *rsp_params;
311 	int err;
312 
313 	/* prepare command */
314 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_IS_ENABLED,
315 					  cmd_flags,
316 					  token);
317 
318 	/* send command to mc*/
319 	err = mc_send_command(mc_io, &cmd);
320 	if (err)
321 		return err;
322 
323 	/* retrieve response parameters */
324 	rsp_params = (struct dpni_rsp_is_enabled *)cmd.params;
325 	*en = dpni_get_field(rsp_params->enabled, ENABLE);
326 
327 	return 0;
328 }
329 
330 /**
331  * dpni_reset() - Reset the DPNI, returns the object to initial state.
332  * @mc_io:	Pointer to MC portal's I/O object
333  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
334  * @token:	Token of DPNI object
335  *
336  * Return:	'0' on Success; Error code otherwise.
337  */
338 int dpni_reset(struct fsl_mc_io *mc_io,
339 	       uint32_t cmd_flags,
340 	       uint16_t token)
341 {
342 	struct mc_command cmd = { 0 };
343 
344 	/* prepare command */
345 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET,
346 					  cmd_flags,
347 					  token);
348 
349 	/* send command to mc*/
350 	return mc_send_command(mc_io, &cmd);
351 }
352 
353 /**
354  * dpni_get_attributes() - Retrieve DPNI attributes.
355  * @mc_io:	Pointer to MC portal's I/O object
356  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
357  * @token:	Token of DPNI object
358  * @attr:	Object's attributes
359  *
360  * Return:	'0' on Success; Error code otherwise.
361  */
362 int dpni_get_attributes(struct fsl_mc_io *mc_io,
363 			uint32_t cmd_flags,
364 			uint16_t token,
365 			struct dpni_attr *attr)
366 {
367 	struct mc_command cmd = { 0 };
368 	struct dpni_rsp_get_attr *rsp_params;
369 
370 	int err;
371 
372 	/* prepare command */
373 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_ATTR,
374 					  cmd_flags,
375 					  token);
376 
377 	/* send command to mc*/
378 	err = mc_send_command(mc_io, &cmd);
379 	if (err)
380 		return err;
381 
382 	/* retrieve response parameters */
383 	rsp_params = (struct dpni_rsp_get_attr *)cmd.params;
384 	attr->options = le32_to_cpu(rsp_params->options);
385 	attr->num_queues = rsp_params->num_queues;
386 	attr->num_rx_tcs = rsp_params->num_rx_tcs;
387 	attr->num_tx_tcs = rsp_params->num_tx_tcs;
388 	attr->mac_filter_entries = rsp_params->mac_filter_entries;
389 	attr->vlan_filter_entries = rsp_params->vlan_filter_entries;
390 	attr->qos_entries = rsp_params->qos_entries;
391 	attr->fs_entries = le16_to_cpu(rsp_params->fs_entries);
392 	attr->qos_key_size = rsp_params->qos_key_size;
393 	attr->fs_key_size = rsp_params->fs_key_size;
394 	attr->wriop_version = le16_to_cpu(rsp_params->wriop_version);
395 
396 	return 0;
397 }
398 
399 /**
400  * dpni_set_errors_behavior() - Set errors behavior
401  * @mc_io:	Pointer to MC portal's I/O object
402  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
403  * @token:	Token of DPNI object
404  * @cfg:	Errors configuration
405  *
406  * This function may be called numerous times with different
407  * error masks
408  *
409  * Return:	'0' on Success; Error code otherwise.
410  */
411 int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
412 			     uint32_t cmd_flags,
413 			     uint16_t token,
414 			     struct dpni_error_cfg *cfg)
415 {
416 	struct mc_command cmd = { 0 };
417 	struct dpni_cmd_set_errors_behavior *cmd_params;
418 
419 	/* prepare command */
420 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_ERRORS_BEHAVIOR,
421 					  cmd_flags,
422 					  token);
423 	cmd_params = (struct dpni_cmd_set_errors_behavior *)cmd.params;
424 	cmd_params->errors = cpu_to_le32(cfg->errors);
425 	dpni_set_field(cmd_params->flags, ERROR_ACTION, cfg->error_action);
426 	dpni_set_field(cmd_params->flags, FRAME_ANN, cfg->set_frame_annotation);
427 
428 	/* send command to mc*/
429 	return mc_send_command(mc_io, &cmd);
430 }
431 
432 /**
433  * dpni_get_buffer_layout() - Retrieve buffer layout attributes.
434  * @mc_io:	Pointer to MC portal's I/O object
435  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
436  * @token:	Token of DPNI object
437  * @qtype:	Type of queue to retrieve configuration for
438  * @layout:	Returns buffer layout attributes
439  *
440  * Return:	'0' on Success; Error code otherwise.
441  */
442 int dpni_get_buffer_layout(struct fsl_mc_io *mc_io,
443 			   uint32_t cmd_flags,
444 			   uint16_t token,
445 			   enum dpni_queue_type qtype,
446 			   struct dpni_buffer_layout *layout)
447 {
448 	struct mc_command cmd = { 0 };
449 	struct dpni_cmd_get_buffer_layout *cmd_params;
450 	struct dpni_rsp_get_buffer_layout *rsp_params;
451 	int err;
452 
453 	/* prepare command */
454 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_BUFFER_LAYOUT,
455 					  cmd_flags,
456 					  token);
457 	cmd_params = (struct dpni_cmd_get_buffer_layout *)cmd.params;
458 	cmd_params->qtype = qtype;
459 
460 	/* send command to mc*/
461 	err = mc_send_command(mc_io, &cmd);
462 	if (err)
463 		return err;
464 
465 	/* retrieve response parameters */
466 	rsp_params = (struct dpni_rsp_get_buffer_layout *)cmd.params;
467 	layout->pass_timestamp = dpni_get_field(rsp_params->flags, PASS_TS);
468 	layout->pass_parser_result = dpni_get_field(rsp_params->flags, PASS_PR);
469 	layout->pass_frame_status = dpni_get_field(rsp_params->flags, PASS_FS);
470 	layout->private_data_size = le16_to_cpu(rsp_params->private_data_size);
471 	layout->data_align = le16_to_cpu(rsp_params->data_align);
472 	layout->data_head_room = le16_to_cpu(rsp_params->head_room);
473 	layout->data_tail_room = le16_to_cpu(rsp_params->tail_room);
474 
475 	return 0;
476 }
477 
478 /**
479  * dpni_set_buffer_layout() - Set buffer layout configuration.
480  * @mc_io:	Pointer to MC portal's I/O object
481  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
482  * @token:	Token of DPNI object
483  * @qtype:	Type of queue this configuration applies to
484  * @layout:	Buffer layout configuration
485  *
486  * Return:	'0' on Success; Error code otherwise.
487  *
488  * @warning	Allowed only when DPNI is disabled
489  */
490 int dpni_set_buffer_layout(struct fsl_mc_io *mc_io,
491 			   uint32_t cmd_flags,
492 			   uint16_t token,
493 			   enum dpni_queue_type qtype,
494 			   const struct dpni_buffer_layout *layout)
495 {
496 	struct mc_command cmd = { 0 };
497 	struct dpni_cmd_set_buffer_layout *cmd_params;
498 
499 	/* prepare command */
500 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_BUFFER_LAYOUT,
501 					  cmd_flags,
502 					  token);
503 	cmd_params = (struct dpni_cmd_set_buffer_layout *)cmd.params;
504 	cmd_params->qtype = qtype;
505 	cmd_params->options = cpu_to_le16(layout->options);
506 	dpni_set_field(cmd_params->flags, PASS_TS, layout->pass_timestamp);
507 	dpni_set_field(cmd_params->flags, PASS_PR, layout->pass_parser_result);
508 	dpni_set_field(cmd_params->flags, PASS_FS, layout->pass_frame_status);
509 	cmd_params->private_data_size = cpu_to_le16(layout->private_data_size);
510 	cmd_params->data_align = cpu_to_le16(layout->data_align);
511 	cmd_params->head_room = cpu_to_le16(layout->data_head_room);
512 	cmd_params->tail_room = cpu_to_le16(layout->data_tail_room);
513 
514 	/* send command to mc*/
515 	return mc_send_command(mc_io, &cmd);
516 }
517 
518 /**
519  * dpni_set_offload() - Set DPNI offload configuration.
520  * @mc_io:	Pointer to MC portal's I/O object
521  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
522  * @token:	Token of DPNI object
523  * @type:	Type of DPNI offload
524  * @config:	Offload configuration.
525  *		For checksum offloads, non-zero value enables the offload
526  *
527  * Return:     '0' on Success; Error code otherwise.
528  *
529  * @warning    Allowed only when DPNI is disabled
530  */
531 
532 int dpni_set_offload(struct fsl_mc_io *mc_io,
533 		     uint32_t cmd_flags,
534 		     uint16_t token,
535 		     enum dpni_offload type,
536 		     uint32_t config)
537 {
538 	struct mc_command cmd = { 0 };
539 	struct dpni_cmd_set_offload *cmd_params;
540 
541 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_OFFLOAD,
542 					  cmd_flags,
543 					  token);
544 	cmd_params = (struct dpni_cmd_set_offload *)cmd.params;
545 	cmd_params->dpni_offload = type;
546 	cmd_params->config = cpu_to_le32(config);
547 
548 	return mc_send_command(mc_io, &cmd);
549 }
550 
551 /**
552  * dpni_get_offload() - Get DPNI offload configuration.
553  * @mc_io:	Pointer to MC portal's I/O object
554  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
555  * @token:	Token of DPNI object
556  * @type:	Type of DPNI offload
557  * @config:	Offload configuration.
558  *			For checksum offloads, a value of 1 indicates that the
559  *			offload is enabled.
560  *
561  * Return:	'0' on Success; Error code otherwise.
562  *
563  * @warning	Allowed only when DPNI is disabled
564  */
565 int dpni_get_offload(struct fsl_mc_io *mc_io,
566 		     uint32_t cmd_flags,
567 		     uint16_t token,
568 		     enum dpni_offload type,
569 		     uint32_t *config)
570 {
571 	struct mc_command cmd = { 0 };
572 	struct dpni_cmd_get_offload *cmd_params;
573 	struct dpni_rsp_get_offload *rsp_params;
574 	int err;
575 
576 	/* prepare command */
577 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_OFFLOAD,
578 					  cmd_flags,
579 					  token);
580 	cmd_params = (struct dpni_cmd_get_offload *)cmd.params;
581 	cmd_params->dpni_offload = type;
582 
583 	/* send command to mc*/
584 	err = mc_send_command(mc_io, &cmd);
585 	if (err)
586 		return err;
587 
588 	/* retrieve response parameters */
589 	rsp_params = (struct dpni_rsp_get_offload *)cmd.params;
590 	*config = le32_to_cpu(rsp_params->config);
591 
592 	return 0;
593 }
594 
595 /**
596  * dpni_get_qdid() - Get the Queuing Destination ID (QDID) that should be used
597  *			for enqueue operations
598  * @mc_io:	Pointer to MC portal's I/O object
599  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
600  * @token:	Token of DPNI object
601  * @qtype:	Type of queue to receive QDID for
602  * @qdid:	Returned virtual QDID value that should be used as an argument
603  *			in all enqueue operations
604  *
605  * Return:	'0' on Success; Error code otherwise.
606  */
607 int dpni_get_qdid(struct fsl_mc_io *mc_io,
608 		  uint32_t cmd_flags,
609 		  uint16_t token,
610 		  enum dpni_queue_type qtype,
611 		  uint16_t *qdid)
612 {
613 	struct mc_command cmd = { 0 };
614 	struct dpni_cmd_get_qdid *cmd_params;
615 	struct dpni_rsp_get_qdid *rsp_params;
616 	int err;
617 
618 	/* prepare command */
619 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QDID,
620 					  cmd_flags,
621 					  token);
622 	cmd_params = (struct dpni_cmd_get_qdid *)cmd.params;
623 	cmd_params->qtype = qtype;
624 
625 	/* send command to mc*/
626 	err = mc_send_command(mc_io, &cmd);
627 	if (err)
628 		return err;
629 
630 	/* retrieve response parameters */
631 	rsp_params = (struct dpni_rsp_get_qdid *)cmd.params;
632 	*qdid = le16_to_cpu(rsp_params->qdid);
633 
634 	return 0;
635 }
636 
637 /**
638  * dpni_get_tx_data_offset() - Get the Tx data offset (from start of buffer)
639  * @mc_io:	Pointer to MC portal's I/O object
640  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
641  * @token:	Token of DPNI object
642  * @data_offset: Tx data offset (from start of buffer)
643  *
644  * Return:	'0' on Success; Error code otherwise.
645  */
646 int dpni_get_tx_data_offset(struct fsl_mc_io *mc_io,
647 			    uint32_t cmd_flags,
648 			    uint16_t token,
649 			    uint16_t *data_offset)
650 {
651 	struct mc_command cmd = { 0 };
652 	struct dpni_rsp_get_tx_data_offset *rsp_params;
653 	int err;
654 
655 	/* prepare command */
656 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_DATA_OFFSET,
657 					  cmd_flags,
658 					  token);
659 
660 	/* send command to mc*/
661 	err = mc_send_command(mc_io, &cmd);
662 	if (err)
663 		return err;
664 
665 	/* retrieve response parameters */
666 	rsp_params = (struct dpni_rsp_get_tx_data_offset *)cmd.params;
667 	*data_offset = le16_to_cpu(rsp_params->data_offset);
668 
669 	return 0;
670 }
671 
672 /**
673  * dpni_set_link_cfg() - set the link configuration.
674  * @mc_io:	Pointer to MC portal's I/O object
675  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
676  * @token:	Token of DPNI object
677  * @cfg:	Link configuration
678  *
679  * Return:	'0' on Success; Error code otherwise.
680  */
681 int dpni_set_link_cfg(struct fsl_mc_io *mc_io,
682 		      uint32_t cmd_flags,
683 		      uint16_t token,
684 		      const struct dpni_link_cfg *cfg)
685 {
686 	struct mc_command cmd = { 0 };
687 	struct dpni_cmd_set_link_cfg *cmd_params;
688 
689 	/* prepare command */
690 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_LINK_CFG,
691 					  cmd_flags,
692 					  token);
693 	cmd_params = (struct dpni_cmd_set_link_cfg *)cmd.params;
694 	cmd_params->rate = cpu_to_le32(cfg->rate);
695 	cmd_params->options = cpu_to_le64(cfg->options);
696 
697 	/* send command to mc*/
698 	return mc_send_command(mc_io, &cmd);
699 }
700 
701 /**
702  * dpni_get_link_state() - Return the link state (either up or down)
703  * @mc_io:	Pointer to MC portal's I/O object
704  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
705  * @token:	Token of DPNI object
706  * @state:	Returned link state;
707  *
708  * Return:	'0' on Success; Error code otherwise.
709  */
710 int dpni_get_link_state(struct fsl_mc_io *mc_io,
711 			uint32_t cmd_flags,
712 			uint16_t token,
713 			struct dpni_link_state *state)
714 {
715 	struct mc_command cmd = { 0 };
716 	struct dpni_rsp_get_link_state *rsp_params;
717 	int err;
718 
719 	/* prepare command */
720 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_STATE,
721 					  cmd_flags,
722 					  token);
723 
724 	/* send command to mc*/
725 	err = mc_send_command(mc_io, &cmd);
726 	if (err)
727 		return err;
728 
729 	/* retrieve response parameters */
730 	rsp_params = (struct dpni_rsp_get_link_state *)cmd.params;
731 	state->up = dpni_get_field(rsp_params->flags, LINK_STATE);
732 	state->rate = le32_to_cpu(rsp_params->rate);
733 	state->options = le64_to_cpu(rsp_params->options);
734 
735 	return 0;
736 }
737 
738 /**
739  * dpni_set_max_frame_length() - Set the maximum received frame length.
740  * @mc_io:		Pointer to MC portal's I/O object
741  * @cmd_flags:		Command flags; one or more of 'MC_CMD_FLAG_'
742  * @token:		Token of DPNI object
743  * @max_frame_length:	Maximum received frame length (in bytes);
744  *			frame is discarded if its length exceeds this value
745  *
746  * Return:	'0' on Success; Error code otherwise.
747  */
748 int dpni_set_max_frame_length(struct fsl_mc_io *mc_io,
749 			      uint32_t cmd_flags,
750 			      uint16_t token,
751 			      uint16_t max_frame_length)
752 {
753 	struct mc_command cmd = { 0 };
754 	struct dpni_cmd_set_max_frame_length *cmd_params;
755 
756 	/* prepare command */
757 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MAX_FRAME_LENGTH,
758 					  cmd_flags,
759 					  token);
760 	cmd_params = (struct dpni_cmd_set_max_frame_length *)cmd.params;
761 	cmd_params->max_frame_length = cpu_to_le16(max_frame_length);
762 
763 	/* send command to mc*/
764 	return mc_send_command(mc_io, &cmd);
765 }
766 
767 /**
768  * dpni_get_max_frame_length() - Get the maximum received frame length.
769  * @mc_io:		Pointer to MC portal's I/O object
770  * @cmd_flags:		Command flags; one or more of 'MC_CMD_FLAG_'
771  * @token:		Token of DPNI object
772  * @max_frame_length:	Maximum received frame length (in bytes);
773  *			frame is discarded if its length exceeds this value
774  *
775  * Return:	'0' on Success; Error code otherwise.
776  */
777 int dpni_get_max_frame_length(struct fsl_mc_io *mc_io,
778 			      uint32_t cmd_flags,
779 			      uint16_t token,
780 			      uint16_t *max_frame_length)
781 {
782 	struct mc_command cmd = { 0 };
783 	struct dpni_rsp_get_max_frame_length *rsp_params;
784 	int err;
785 
786 	/* prepare command */
787 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MAX_FRAME_LENGTH,
788 					  cmd_flags,
789 					  token);
790 
791 	/* send command to mc*/
792 	err = mc_send_command(mc_io, &cmd);
793 	if (err)
794 		return err;
795 
796 	/* retrieve response parameters */
797 	rsp_params = (struct dpni_rsp_get_max_frame_length *)cmd.params;
798 	*max_frame_length = le16_to_cpu(rsp_params->max_frame_length);
799 
800 	return 0;
801 }
802 
803 /**
804  * dpni_set_multicast_promisc() - Enable/disable multicast promiscuous mode
805  * @mc_io:	Pointer to MC portal's I/O object
806  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
807  * @token:	Token of DPNI object
808  * @en:		Set to '1' to enable; '0' to disable
809  *
810  * Return:	'0' on Success; Error code otherwise.
811  */
812 int dpni_set_multicast_promisc(struct fsl_mc_io *mc_io,
813 			       uint32_t cmd_flags,
814 			       uint16_t token,
815 			       int en)
816 {
817 	struct mc_command cmd = { 0 };
818 	struct dpni_cmd_set_multicast_promisc *cmd_params;
819 
820 	/* prepare command */
821 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_MCAST_PROMISC,
822 					  cmd_flags,
823 					  token);
824 	cmd_params = (struct dpni_cmd_set_multicast_promisc *)cmd.params;
825 	dpni_set_field(cmd_params->enable, ENABLE, en);
826 
827 	/* send command to mc*/
828 	return mc_send_command(mc_io, &cmd);
829 }
830 
831 /**
832  * dpni_get_multicast_promisc() - Get multicast promiscuous mode
833  * @mc_io:	Pointer to MC portal's I/O object
834  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
835  * @token:	Token of DPNI object
836  * @en:		Returns '1' if enabled; '0' otherwise
837  *
838  * Return:	'0' on Success; Error code otherwise.
839  */
840 int dpni_get_multicast_promisc(struct fsl_mc_io *mc_io,
841 			       uint32_t cmd_flags,
842 			       uint16_t token,
843 			       int *en)
844 {
845 	struct mc_command cmd = { 0 };
846 	struct dpni_rsp_get_multicast_promisc *rsp_params;
847 	int err;
848 
849 	/* prepare command */
850 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_MCAST_PROMISC,
851 					  cmd_flags,
852 					  token);
853 
854 	/* send command to mc*/
855 	err = mc_send_command(mc_io, &cmd);
856 	if (err)
857 		return err;
858 
859 	/* retrieve response parameters */
860 	rsp_params = (struct dpni_rsp_get_multicast_promisc *)cmd.params;
861 	*en = dpni_get_field(rsp_params->enabled, ENABLE);
862 
863 	return 0;
864 }
865 
866 /**
867  * dpni_set_unicast_promisc() - Enable/disable unicast promiscuous mode
868  * @mc_io:	Pointer to MC portal's I/O object
869  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
870  * @token:	Token of DPNI object
871  * @en:		Set to '1' to enable; '0' to disable
872  *
873  * Return:	'0' on Success; Error code otherwise.
874  */
875 int dpni_set_unicast_promisc(struct fsl_mc_io *mc_io,
876 			     uint32_t cmd_flags,
877 			     uint16_t token,
878 			     int en)
879 {
880 	struct mc_command cmd = { 0 };
881 	struct dpni_cmd_set_unicast_promisc *cmd_params;
882 
883 	/* prepare command */
884 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_UNICAST_PROMISC,
885 					  cmd_flags,
886 					  token);
887 	cmd_params = (struct dpni_cmd_set_unicast_promisc *)cmd.params;
888 	dpni_set_field(cmd_params->enable, ENABLE, en);
889 
890 	/* send command to mc*/
891 	return mc_send_command(mc_io, &cmd);
892 }
893 
894 /**
895  * dpni_get_unicast_promisc() - Get unicast promiscuous mode
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  * @en:		Returns '1' if enabled; '0' otherwise
900  *
901  * Return:	'0' on Success; Error code otherwise.
902  */
903 int dpni_get_unicast_promisc(struct fsl_mc_io *mc_io,
904 			     uint32_t cmd_flags,
905 			     uint16_t token,
906 			     int *en)
907 {
908 	struct mc_command cmd = { 0 };
909 	struct dpni_rsp_get_unicast_promisc *rsp_params;
910 	int err;
911 
912 	/* prepare command */
913 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_UNICAST_PROMISC,
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_unicast_promisc *)cmd.params;
924 	*en = dpni_get_field(rsp_params->enabled, ENABLE);
925 
926 	return 0;
927 }
928 
929 /**
930  * dpni_set_primary_mac_addr() - Set the primary MAC address
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  * @mac_addr:	MAC address to set as primary address
935  *
936  * Return:	'0' on Success; Error code otherwise.
937  */
938 int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
939 			      uint32_t cmd_flags,
940 			      uint16_t token,
941 			      const uint8_t mac_addr[6])
942 {
943 	struct mc_command cmd = { 0 };
944 	struct dpni_cmd_set_primary_mac_addr *cmd_params;
945 	int i;
946 
947 	/* prepare command */
948 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_PRIM_MAC,
949 					  cmd_flags,
950 					  token);
951 	cmd_params = (struct dpni_cmd_set_primary_mac_addr *)cmd.params;
952 	for (i = 0; i < 6; i++)
953 		cmd_params->mac_addr[i] = mac_addr[5 - i];
954 
955 	/* send command to mc*/
956 	return mc_send_command(mc_io, &cmd);
957 }
958 
959 /**
960  * dpni_get_primary_mac_addr() - Get the primary MAC address
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  * @mac_addr:	Returned MAC address
965  *
966  * Return:	'0' on Success; Error code otherwise.
967  */
968 int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
969 			      uint32_t cmd_flags,
970 			      uint16_t token,
971 			      uint8_t mac_addr[6])
972 {
973 	struct mc_command cmd = { 0 };
974 	struct dpni_rsp_get_primary_mac_addr *rsp_params;
975 	int i, err;
976 
977 	/* prepare command */
978 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PRIM_MAC,
979 					  cmd_flags,
980 					  token);
981 
982 	/* send command to mc*/
983 	err = mc_send_command(mc_io, &cmd);
984 	if (err)
985 		return err;
986 
987 	/* retrieve response parameters */
988 	rsp_params = (struct dpni_rsp_get_primary_mac_addr *)cmd.params;
989 	for (i = 0; i < 6; i++)
990 		mac_addr[5 - i] = rsp_params->mac_addr[i];
991 
992 	return 0;
993 }
994 
995 /**
996  * dpni_add_mac_addr() - Add MAC address filter
997  * @mc_io:	Pointer to MC portal's I/O object
998  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
999  * @token:	Token of DPNI object
1000  * @mac_addr:	MAC address to add
1001  *
1002  * Return:	'0' on Success; Error code otherwise.
1003  */
1004 int dpni_add_mac_addr(struct fsl_mc_io *mc_io,
1005 		      uint32_t cmd_flags,
1006 		      uint16_t token,
1007 		      const uint8_t mac_addr[6])
1008 {
1009 	struct mc_command cmd = { 0 };
1010 	struct dpni_cmd_add_mac_addr *cmd_params;
1011 	int i;
1012 
1013 	/* prepare command */
1014 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_MAC_ADDR,
1015 					  cmd_flags,
1016 					  token);
1017 	cmd_params = (struct dpni_cmd_add_mac_addr *)cmd.params;
1018 	for (i = 0; i < 6; i++)
1019 		cmd_params->mac_addr[i] = mac_addr[5 - i];
1020 
1021 	/* send command to mc*/
1022 	return mc_send_command(mc_io, &cmd);
1023 }
1024 
1025 /**
1026  * dpni_remove_mac_addr() - Remove MAC address filter
1027  * @mc_io:	Pointer to MC portal's I/O object
1028  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1029  * @token:	Token of DPNI object
1030  * @mac_addr:	MAC address to remove
1031  *
1032  * Return:	'0' on Success; Error code otherwise.
1033  */
1034 int dpni_remove_mac_addr(struct fsl_mc_io *mc_io,
1035 			 uint32_t cmd_flags,
1036 			 uint16_t token,
1037 			 const uint8_t mac_addr[6])
1038 {
1039 	struct mc_command cmd = { 0 };
1040 	struct dpni_cmd_remove_mac_addr *cmd_params;
1041 	int i;
1042 
1043 	/* prepare command */
1044 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_MAC_ADDR,
1045 					  cmd_flags,
1046 					  token);
1047 	cmd_params = (struct dpni_cmd_remove_mac_addr *)cmd.params;
1048 	for (i = 0; i < 6; i++)
1049 		cmd_params->mac_addr[i] = mac_addr[5 - i];
1050 
1051 	/* send command to mc*/
1052 	return mc_send_command(mc_io, &cmd);
1053 }
1054 
1055 /**
1056  * dpni_clear_mac_filters() - Clear all unicast and/or multicast MAC filters
1057  * @mc_io:	Pointer to MC portal's I/O object
1058  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1059  * @token:	Token of DPNI object
1060  * @unicast:	Set to '1' to clear unicast addresses
1061  * @multicast:	Set to '1' to clear multicast addresses
1062  *
1063  * The primary MAC address is not cleared by this operation.
1064  *
1065  * Return:	'0' on Success; Error code otherwise.
1066  */
1067 int dpni_clear_mac_filters(struct fsl_mc_io *mc_io,
1068 			   uint32_t cmd_flags,
1069 			   uint16_t token,
1070 			   int unicast,
1071 			   int multicast)
1072 {
1073 	struct mc_command cmd = { 0 };
1074 	struct dpni_cmd_clear_mac_filters *cmd_params;
1075 
1076 	/* prepare command */
1077 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_MAC_FILTERS,
1078 					  cmd_flags,
1079 					  token);
1080 	cmd_params = (struct dpni_cmd_clear_mac_filters *)cmd.params;
1081 	dpni_set_field(cmd_params->flags, UNICAST_FILTERS, unicast);
1082 	dpni_set_field(cmd_params->flags, MULTICAST_FILTERS, multicast);
1083 
1084 	/* send command to mc*/
1085 	return mc_send_command(mc_io, &cmd);
1086 }
1087 
1088 /**
1089  * dpni_get_port_mac_addr() - Retrieve MAC address associated to the physical
1090  *			port the DPNI is attached to
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  * @mac_addr:	MAC address of the physical port, if any, otherwise 0
1095  *
1096  * The primary MAC address is not cleared by this operation.
1097  *
1098  * Return:	'0' on Success; Error code otherwise.
1099  */
1100 int dpni_get_port_mac_addr(struct fsl_mc_io *mc_io,
1101 			   uint32_t cmd_flags,
1102 			   uint16_t token,
1103 			   uint8_t mac_addr[6])
1104 {
1105 	struct mc_command cmd = { 0 };
1106 	struct dpni_rsp_get_port_mac_addr *rsp_params;
1107 	int i, err;
1108 
1109 	/* prepare command */
1110 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PORT_MAC_ADDR,
1111 					  cmd_flags,
1112 					  token);
1113 
1114 	/* send command to mc*/
1115 	err = mc_send_command(mc_io, &cmd);
1116 	if (err)
1117 		return err;
1118 
1119 	/* retrieve response parameters */
1120 	rsp_params = (struct dpni_rsp_get_port_mac_addr *)cmd.params;
1121 	for (i = 0; i < 6; i++)
1122 		mac_addr[5 - i] = rsp_params->mac_addr[i];
1123 
1124 	return 0;
1125 }
1126 
1127 /**
1128  * dpni_enable_vlan_filter() - Enable/disable VLAN filtering mode
1129  * @mc_io:	Pointer to MC portal's I/O object
1130  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1131  * @token:	Token of DPNI object
1132  * @en:		Set to '1' to enable; '0' to disable
1133  *
1134  * Return:	'0' on Success; Error code otherwise.
1135  */
1136 int dpni_enable_vlan_filter(struct fsl_mc_io *mc_io,
1137 			    uint32_t cmd_flags,
1138 			    uint16_t token,
1139 			    int en)
1140 {
1141 	struct dpni_cmd_enable_vlan_filter *cmd_params;
1142 	struct mc_command cmd = { 0 };
1143 
1144 	/* prepare command */
1145 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE_VLAN_FILTER,
1146 					  cmd_flags,
1147 					  token);
1148 	cmd_params = (struct dpni_cmd_enable_vlan_filter *)cmd.params;
1149 	dpni_set_field(cmd_params->en, ENABLE, en);
1150 
1151 	/* send command to mc*/
1152 	return mc_send_command(mc_io, &cmd);
1153 }
1154 
1155 /**
1156  * dpni_add_vlan_id() - Add VLAN ID filter
1157  * @mc_io:	Pointer to MC portal's I/O object
1158  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1159  * @token:	Token of DPNI object
1160  * @vlan_id:	VLAN ID to add
1161  *
1162  * Return:	'0' on Success; Error code otherwise.
1163  */
1164 int dpni_add_vlan_id(struct fsl_mc_io *mc_io,
1165 		     uint32_t cmd_flags,
1166 		     uint16_t token,
1167 		     uint16_t vlan_id)
1168 {
1169 	struct dpni_cmd_vlan_id *cmd_params;
1170 	struct mc_command cmd = { 0 };
1171 
1172 	/* prepare command */
1173 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_VLAN_ID,
1174 					  cmd_flags,
1175 					  token);
1176 	cmd_params = (struct dpni_cmd_vlan_id *)cmd.params;
1177 	cmd_params->vlan_id = cpu_to_le16(vlan_id);
1178 
1179 	/* send command to mc*/
1180 	return mc_send_command(mc_io, &cmd);
1181 }
1182 
1183 /**
1184  * dpni_remove_vlan_id() - Remove VLAN ID filter
1185  * @mc_io:	Pointer to MC portal's I/O object
1186  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1187  * @token:	Token of DPNI object
1188  * @vlan_id:	VLAN ID to remove
1189  *
1190  * Return:	'0' on Success; Error code otherwise.
1191  */
1192 int dpni_remove_vlan_id(struct fsl_mc_io *mc_io,
1193 			uint32_t cmd_flags,
1194 			uint16_t token,
1195 			uint16_t vlan_id)
1196 {
1197 	struct dpni_cmd_vlan_id *cmd_params;
1198 	struct mc_command cmd = { 0 };
1199 
1200 	/* prepare command */
1201 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_VLAN_ID,
1202 					  cmd_flags,
1203 					  token);
1204 	cmd_params = (struct dpni_cmd_vlan_id *)cmd.params;
1205 	cmd_params->vlan_id = cpu_to_le16(vlan_id);
1206 
1207 	/* send command to mc*/
1208 	return mc_send_command(mc_io, &cmd);
1209 }
1210 
1211 /**
1212  * dpni_clear_vlan_filters() - Clear all VLAN filters
1213  * @mc_io:	Pointer to MC portal's I/O object
1214  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1215  * @token:	Token of DPNI object
1216  *
1217  * Return:	'0' on Success; Error code otherwise.
1218  */
1219 int dpni_clear_vlan_filters(struct fsl_mc_io *mc_io,
1220 			    uint32_t cmd_flags,
1221 			    uint16_t token)
1222 {
1223 	struct mc_command cmd = { 0 };
1224 
1225 	/* prepare command */
1226 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLR_VLAN_FILTERS,
1227 					  cmd_flags,
1228 					  token);
1229 
1230 	/* send command to mc*/
1231 	return mc_send_command(mc_io, &cmd);
1232 }
1233 
1234 /**
1235  * dpni_set_rx_tc_dist() - Set Rx traffic class distribution configuration
1236  * @mc_io:	Pointer to MC portal's I/O object
1237  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1238  * @token:	Token of DPNI object
1239  * @tc_id:	Traffic class selection (0-7)
1240  * @cfg:	Traffic class distribution configuration
1241  *
1242  * warning: if 'dist_mode != DPNI_DIST_MODE_NONE', call dpkg_prepare_key_cfg()
1243  *			first to prepare the key_cfg_iova parameter
1244  *
1245  * Return:	'0' on Success; error code otherwise.
1246  */
1247 int dpni_set_rx_tc_dist(struct fsl_mc_io *mc_io,
1248 			uint32_t cmd_flags,
1249 			uint16_t token,
1250 			uint8_t tc_id,
1251 			const struct dpni_rx_tc_dist_cfg *cfg)
1252 {
1253 	struct mc_command cmd = { 0 };
1254 	struct dpni_cmd_set_rx_tc_dist *cmd_params;
1255 
1256 	/* prepare command */
1257 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_TC_DIST,
1258 					  cmd_flags,
1259 					  token);
1260 	cmd_params = (struct dpni_cmd_set_rx_tc_dist *)cmd.params;
1261 	cmd_params->dist_size = cpu_to_le16(cfg->dist_size);
1262 	cmd_params->tc_id = tc_id;
1263 	cmd_params->default_flow_id = cpu_to_le16(cfg->fs_cfg.default_flow_id);
1264 	cmd_params->key_cfg_iova = cpu_to_le64(cfg->key_cfg_iova);
1265 	dpni_set_field(cmd_params->flags,
1266 		       DIST_MODE,
1267 		       cfg->dist_mode);
1268 	dpni_set_field(cmd_params->flags,
1269 		       MISS_ACTION,
1270 		       cfg->fs_cfg.miss_action);
1271 	dpni_set_field(cmd_params->keep_hash_key,
1272 		       KEEP_HASH_KEY,
1273 		       cfg->fs_cfg.keep_hash_key);
1274 
1275 	/* send command to mc*/
1276 	return mc_send_command(mc_io, &cmd);
1277 }
1278 
1279 /**
1280  * dpni_set_tx_confirmation_mode() - Tx confirmation mode
1281  * @mc_io:	Pointer to MC portal's I/O object
1282  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1283  * @token:	Token of DPNI object
1284  * @mode:	Tx confirmation mode
1285  *
1286  * This function is useful only when 'DPNI_OPT_TX_CONF_DISABLED' is not
1287  * selected at DPNI creation.
1288  * Calling this function with 'mode' set to DPNI_CONF_DISABLE disables all
1289  * transmit confirmation (including the private confirmation queues), regardless
1290  * of previous settings; Note that in this case, Tx error frames are still
1291  * enqueued to the general transmit errors queue.
1292  * Calling this function with 'mode' set to DPNI_CONF_SINGLE switches all
1293  * Tx confirmations to a shared Tx conf queue. 'index' field in dpni_get_queue
1294  * command will be ignored.
1295  *
1296  * Return:	'0' on Success; Error code otherwise.
1297  */
1298 int dpni_set_tx_confirmation_mode(struct fsl_mc_io *mc_io,
1299 				  uint32_t cmd_flags,
1300 				  uint16_t token,
1301 				  enum dpni_confirmation_mode mode)
1302 {
1303 	struct dpni_tx_confirmation_mode *cmd_params;
1304 	struct mc_command cmd = { 0 };
1305 
1306 	/* prepare command */
1307 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_CONFIRMATION_MODE,
1308 					  cmd_flags,
1309 					  token);
1310 	cmd_params = (struct dpni_tx_confirmation_mode *)cmd.params;
1311 	cmd_params->confirmation_mode = mode;
1312 
1313 	/* send command to mc*/
1314 	return mc_send_command(mc_io, &cmd);
1315 }
1316 
1317 /**
1318  * dpni_set_congestion_notification() - Set traffic class congestion
1319  *	notification configuration
1320  * @mc_io:	Pointer to MC portal's I/O object
1321  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1322  * @token:	Token of DPNI object
1323  * @qtype:	Type of queue - Rx, Tx and Tx confirm types are supported
1324  * @tc_id:	Traffic class selection (0-7)
1325  * @cfg:	congestion notification configuration
1326  *
1327  * Return:	'0' on Success; error code otherwise.
1328  */
1329 int dpni_set_congestion_notification(struct fsl_mc_io *mc_io,
1330 				     uint32_t cmd_flags,
1331 				     uint16_t token,
1332 				     enum dpni_queue_type qtype,
1333 				     uint8_t tc_id,
1334 			const struct dpni_congestion_notification_cfg *cfg)
1335 {
1336 	struct dpni_cmd_set_congestion_notification *cmd_params;
1337 	struct mc_command cmd = { 0 };
1338 
1339 	/* prepare command */
1340 	cmd.header = mc_encode_cmd_header(
1341 					DPNI_CMDID_SET_CONGESTION_NOTIFICATION,
1342 					cmd_flags,
1343 					token);
1344 	cmd_params = (struct dpni_cmd_set_congestion_notification *)cmd.params;
1345 	cmd_params->qtype = qtype;
1346 	cmd_params->tc = tc_id;
1347 	cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
1348 	cmd_params->notification_mode = cpu_to_le16(cfg->notification_mode);
1349 	cmd_params->dest_priority = cfg->dest_cfg.priority;
1350 	cmd_params->message_iova = cpu_to_le64(cfg->message_iova);
1351 	cmd_params->message_ctx = cpu_to_le64(cfg->message_ctx);
1352 	cmd_params->threshold_entry = cpu_to_le32(cfg->threshold_entry);
1353 	cmd_params->threshold_exit = cpu_to_le32(cfg->threshold_exit);
1354 	dpni_set_field(cmd_params->type_units,
1355 		       DEST_TYPE,
1356 		       cfg->dest_cfg.dest_type);
1357 	dpni_set_field(cmd_params->type_units,
1358 		       CONG_UNITS,
1359 		       cfg->units);
1360 
1361 	/* send command to mc*/
1362 	return mc_send_command(mc_io, &cmd);
1363 }
1364 
1365 /**
1366  * dpni_get_congestion_notification() - Get traffic class congestion
1367  *	notification configuration
1368  * @mc_io:	Pointer to MC portal's I/O object
1369  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1370  * @token:	Token of DPNI object
1371  * @qtype:	Type of queue - Rx, Tx and Tx confirm types are supported
1372  * @tc_id:	Traffic class selection (0-7)
1373  * @cfg:	congestion notification configuration
1374  *
1375  * Return:	'0' on Success; error code otherwise.
1376  */
1377 int dpni_get_congestion_notification(struct fsl_mc_io *mc_io,
1378 				     uint32_t cmd_flags,
1379 				     uint16_t token,
1380 				     enum dpni_queue_type qtype,
1381 				     uint8_t tc_id,
1382 				struct dpni_congestion_notification_cfg *cfg)
1383 {
1384 	struct dpni_rsp_get_congestion_notification *rsp_params;
1385 	struct dpni_cmd_get_congestion_notification *cmd_params;
1386 	struct mc_command cmd = { 0 };
1387 	int err;
1388 
1389 	/* prepare command */
1390 	cmd.header = mc_encode_cmd_header(
1391 					DPNI_CMDID_GET_CONGESTION_NOTIFICATION,
1392 					cmd_flags,
1393 					token);
1394 	cmd_params = (struct dpni_cmd_get_congestion_notification *)cmd.params;
1395 	cmd_params->qtype = qtype;
1396 	cmd_params->tc = tc_id;
1397 
1398 	/* send command to mc*/
1399 	err = mc_send_command(mc_io, &cmd);
1400 	if (err)
1401 		return err;
1402 
1403 	rsp_params = (struct dpni_rsp_get_congestion_notification *)cmd.params;
1404 	cfg->units = dpni_get_field(rsp_params->type_units, CONG_UNITS);
1405 	cfg->threshold_entry = le32_to_cpu(rsp_params->threshold_entry);
1406 	cfg->threshold_exit = le32_to_cpu(rsp_params->threshold_exit);
1407 	cfg->message_ctx = le64_to_cpu(rsp_params->message_ctx);
1408 	cfg->message_iova = le64_to_cpu(rsp_params->message_iova);
1409 	cfg->notification_mode = le16_to_cpu(rsp_params->notification_mode);
1410 	cfg->dest_cfg.dest_id = le32_to_cpu(rsp_params->dest_id);
1411 	cfg->dest_cfg.priority = rsp_params->dest_priority;
1412 	cfg->dest_cfg.dest_type = dpni_get_field(rsp_params->type_units,
1413 						 DEST_TYPE);
1414 
1415 	return 0;
1416 }
1417 
1418 /**
1419  * dpni_get_api_version() - Get Data Path Network Interface API version
1420  * @mc_io:  Pointer to MC portal's I/O object
1421  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1422  * @major_ver:	Major version of data path network interface API
1423  * @minor_ver:	Minor version of data path network interface API
1424  *
1425  * Return:  '0' on Success; Error code otherwise.
1426  */
1427 int dpni_get_api_version(struct fsl_mc_io *mc_io,
1428 			 uint32_t cmd_flags,
1429 			 uint16_t *major_ver,
1430 			 uint16_t *minor_ver)
1431 {
1432 	struct dpni_rsp_get_api_version *rsp_params;
1433 	struct mc_command cmd = { 0 };
1434 	int err;
1435 
1436 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_API_VERSION,
1437 					cmd_flags,
1438 					0);
1439 
1440 	err = mc_send_command(mc_io, &cmd);
1441 	if (err)
1442 		return err;
1443 
1444 	rsp_params = (struct dpni_rsp_get_api_version *)cmd.params;
1445 	*major_ver = le16_to_cpu(rsp_params->major);
1446 	*minor_ver = le16_to_cpu(rsp_params->minor);
1447 
1448 	return 0;
1449 }
1450 
1451 /**
1452  * dpni_set_queue() - Set queue parameters
1453  * @mc_io:	Pointer to MC portal's I/O object
1454  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1455  * @token:	Token of DPNI object
1456  * @qtype:	Type of queue - all queue types are supported, although
1457  *		the command is ignored for Tx
1458  * @tc:		Traffic class, in range 0 to NUM_TCS - 1
1459  * @index:	Selects the specific queue out of the set allocated for the
1460  *		same TC. Value must be in range 0 to NUM_QUEUES - 1
1461  * @options:	A combination of DPNI_QUEUE_OPT_ values that control what
1462  *		configuration options are set on the queue
1463  * @queue:	Queue structure
1464  *
1465  * Return:	'0' on Success; Error code otherwise.
1466  */
1467 int dpni_set_queue(struct fsl_mc_io *mc_io,
1468 		   uint32_t cmd_flags,
1469 		   uint16_t token,
1470 		   enum dpni_queue_type qtype,
1471 		   uint8_t tc,
1472 		   uint8_t index,
1473 		   uint8_t options,
1474 		   const struct dpni_queue *queue)
1475 {
1476 	struct mc_command cmd = { 0 };
1477 	struct dpni_cmd_set_queue *cmd_params;
1478 
1479 	/* prepare command */
1480 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_QUEUE,
1481 					  cmd_flags,
1482 					  token);
1483 	cmd_params = (struct dpni_cmd_set_queue *)cmd.params;
1484 	cmd_params->qtype = qtype;
1485 	cmd_params->tc = tc;
1486 	cmd_params->index = index;
1487 	cmd_params->options = options;
1488 	cmd_params->dest_id = cpu_to_le32(queue->destination.id);
1489 	cmd_params->dest_prio = queue->destination.priority;
1490 	dpni_set_field(cmd_params->flags, DEST_TYPE, queue->destination.type);
1491 	dpni_set_field(cmd_params->flags, STASH_CTRL, queue->flc.stash_control);
1492 	dpni_set_field(cmd_params->flags, HOLD_ACTIVE,
1493 		       queue->destination.hold_active);
1494 	cmd_params->flc = cpu_to_le64(queue->flc.value);
1495 	cmd_params->user_context = cpu_to_le64(queue->user_context);
1496 
1497 	/* send command to mc */
1498 	return mc_send_command(mc_io, &cmd);
1499 }
1500 
1501 /**
1502  * dpni_get_queue() - Get queue parameters
1503  * @mc_io:	Pointer to MC portal's I/O object
1504  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1505  * @token:	Token of DPNI object
1506  * @qtype:	Type of queue - all queue types are supported
1507  * @tc:		Traffic class, in range 0 to NUM_TCS - 1
1508  * @index:	Selects the specific queue out of the set allocated for the
1509  *		same TC. Value must be in range 0 to NUM_QUEUES - 1
1510  * @queue:	Queue configuration structure
1511  * @qid:	Queue identification
1512  *
1513  * Return:	'0' on Success; Error code otherwise.
1514  */
1515 int dpni_get_queue(struct fsl_mc_io *mc_io,
1516 		   uint32_t cmd_flags,
1517 		   uint16_t token,
1518 		   enum dpni_queue_type qtype,
1519 		   uint8_t tc,
1520 		   uint8_t index,
1521 		   struct dpni_queue *queue,
1522 		   struct dpni_queue_id *qid)
1523 {
1524 	struct mc_command cmd = { 0 };
1525 	struct dpni_cmd_get_queue *cmd_params;
1526 	struct dpni_rsp_get_queue *rsp_params;
1527 	int err;
1528 
1529 	/* prepare command */
1530 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QUEUE,
1531 					  cmd_flags,
1532 					  token);
1533 	cmd_params = (struct dpni_cmd_get_queue *)cmd.params;
1534 	cmd_params->qtype = qtype;
1535 	cmd_params->tc = tc;
1536 	cmd_params->index = index;
1537 
1538 	/* send command to mc */
1539 	err = mc_send_command(mc_io, &cmd);
1540 	if (err)
1541 		return err;
1542 
1543 	/* retrieve response parameters */
1544 	rsp_params = (struct dpni_rsp_get_queue *)cmd.params;
1545 	queue->destination.id = le32_to_cpu(rsp_params->dest_id);
1546 	queue->destination.priority = rsp_params->dest_prio;
1547 	queue->destination.type = dpni_get_field(rsp_params->flags,
1548 						     DEST_TYPE);
1549 	queue->flc.stash_control = dpni_get_field(rsp_params->flags,
1550 						  STASH_CTRL);
1551 	queue->destination.hold_active = dpni_get_field(rsp_params->flags,
1552 							HOLD_ACTIVE);
1553 	queue->flc.value = le64_to_cpu(rsp_params->flc);
1554 	queue->user_context = le64_to_cpu(rsp_params->user_context);
1555 	qid->fqid = le32_to_cpu(rsp_params->fqid);
1556 	qid->qdbin = le16_to_cpu(rsp_params->qdbin);
1557 
1558 	return 0;
1559 }
1560 
1561 /**
1562  * dpni_get_statistics() - Get DPNI statistics
1563  * @mc_io:	Pointer to MC portal's I/O object
1564  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1565  * @token:	Token of DPNI object
1566  * @page:	Selects the statistics page to retrieve, see
1567  *		DPNI_GET_STATISTICS output. Pages are numbered 0 to 2.
1568  * @param:  Custom parameter for some pages used to select
1569  *		a certain statistic source, for example the TC.
1570  * @stat:	Structure containing the statistics
1571  *
1572  * Return:	'0' on Success; Error code otherwise.
1573  */
1574 int dpni_get_statistics(struct fsl_mc_io *mc_io,
1575 			uint32_t cmd_flags,
1576 			uint16_t token,
1577 			uint8_t page,
1578 			uint8_t param,
1579 			union dpni_statistics *stat)
1580 {
1581 	struct mc_command cmd = { 0 };
1582 	struct dpni_cmd_get_statistics *cmd_params;
1583 	struct dpni_rsp_get_statistics *rsp_params;
1584 	int i, err;
1585 
1586 	/* prepare command */
1587 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_STATISTICS,
1588 					  cmd_flags,
1589 					  token);
1590 	cmd_params = (struct dpni_cmd_get_statistics *)cmd.params;
1591 	cmd_params->page_number = page;
1592 	cmd_params->param = param;
1593 
1594 	/* send command to mc */
1595 	err = mc_send_command(mc_io, &cmd);
1596 	if (err)
1597 		return err;
1598 
1599 	/* retrieve response parameters */
1600 	rsp_params = (struct dpni_rsp_get_statistics *)cmd.params;
1601 	for (i = 0; i < DPNI_STATISTICS_CNT; i++)
1602 		stat->raw.counter[i] = le64_to_cpu(rsp_params->counter[i]);
1603 
1604 	return 0;
1605 }
1606 
1607 /**
1608  * dpni_reset_statistics() - Clears DPNI statistics
1609  * @mc_io:		Pointer to MC portal's I/O object
1610  * @cmd_flags:		Command flags; one or more of 'MC_CMD_FLAG_'
1611  * @token:		Token of DPNI object
1612  *
1613  * Return:  '0' on Success; Error code otherwise.
1614  */
1615 int dpni_reset_statistics(struct fsl_mc_io *mc_io,
1616 			  uint32_t cmd_flags,
1617 		     uint16_t token)
1618 {
1619 	struct mc_command cmd = { 0 };
1620 
1621 	/* prepare command */
1622 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET_STATISTICS,
1623 					  cmd_flags,
1624 					  token);
1625 
1626 	/* send command to mc*/
1627 	return mc_send_command(mc_io, &cmd);
1628 }
1629 
1630 /**
1631  * dpni_set_taildrop() - Set taildrop per queue or TC
1632  *
1633  * Setting a per-TC taildrop (cg_point = DPNI_CP_GROUP) will reset any current
1634  * congestion notification or early drop (WRED) configuration previously applied
1635  * to the same TC.
1636  *
1637  * @mc_io:	Pointer to MC portal's I/O object
1638  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1639  * @token:	Token of DPNI object
1640  * @cg_point:	Congestion point, DPNI_CP_QUEUE is only supported in
1641  *		combination with DPNI_QUEUE_RX.
1642  * @q_type:	Queue type, can be DPNI_QUEUE_RX or DPNI_QUEUE_TX.
1643  * @tc:		Traffic class to apply this taildrop to
1644  * @q_index:	Index of the queue if the DPNI supports multiple queues for
1645  *		traffic distribution.
1646  *		Ignored if CONGESTION_POINT is not DPNI_CP_QUEUE.
1647  * @taildrop:	Taildrop structure
1648  *
1649  * Return:	'0' on Success; Error code otherwise.
1650  */
1651 int dpni_set_taildrop(struct fsl_mc_io *mc_io,
1652 		      uint32_t cmd_flags,
1653 		      uint16_t token,
1654 		      enum dpni_congestion_point cg_point,
1655 		      enum dpni_queue_type qtype,
1656 		      uint8_t tc,
1657 		      uint8_t index,
1658 		      struct dpni_taildrop *taildrop)
1659 {
1660 	struct mc_command cmd = { 0 };
1661 	struct dpni_cmd_set_taildrop *cmd_params;
1662 
1663 	/* prepare command */
1664 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TAILDROP,
1665 					  cmd_flags,
1666 					  token);
1667 	cmd_params = (struct dpni_cmd_set_taildrop *)cmd.params;
1668 	cmd_params->congestion_point = cg_point;
1669 	cmd_params->qtype = qtype;
1670 	cmd_params->tc = tc;
1671 	cmd_params->index = index;
1672 	cmd_params->units = taildrop->units;
1673 	cmd_params->threshold = cpu_to_le32(taildrop->threshold);
1674 	dpni_set_field(cmd_params->enable_oal_lo, ENABLE, taildrop->enable);
1675 	dpni_set_field(cmd_params->enable_oal_lo, OAL_LO, taildrop->oal);
1676 	dpni_set_field(cmd_params->oal_hi,
1677 		       OAL_HI,
1678 		       taildrop->oal >> DPNI_OAL_LO_SIZE);
1679 
1680 	/* send command to mc */
1681 	return mc_send_command(mc_io, &cmd);
1682 }
1683 
1684 /**
1685  * dpni_get_taildrop() - Get taildrop information
1686  * @mc_io:	Pointer to MC portal's I/O object
1687  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
1688  * @token:	Token of DPNI object
1689  * @cg_point:	Congestion point
1690  * @q_type:	Queue type on which the taildrop is configured.
1691  *		Only Rx queues are supported for now
1692  * @tc:		Traffic class to apply this taildrop to
1693  * @q_index:	Index of the queue if the DPNI supports multiple queues for
1694  *		traffic distribution. Ignored if CONGESTION_POINT is not 0.
1695  * @taildrop:	Taildrop structure
1696  *
1697  * Return:	'0' on Success; Error code otherwise.
1698  */
1699 int dpni_get_taildrop(struct fsl_mc_io *mc_io,
1700 		      uint32_t cmd_flags,
1701 		      uint16_t token,
1702 		      enum dpni_congestion_point cg_point,
1703 		      enum dpni_queue_type qtype,
1704 		      uint8_t tc,
1705 		      uint8_t index,
1706 		      struct dpni_taildrop *taildrop)
1707 {
1708 	struct mc_command cmd = { 0 };
1709 	struct dpni_cmd_get_taildrop *cmd_params;
1710 	struct dpni_rsp_get_taildrop *rsp_params;
1711 	uint8_t oal_lo, oal_hi;
1712 	int err;
1713 
1714 	/* prepare command */
1715 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TAILDROP,
1716 					  cmd_flags,
1717 					  token);
1718 	cmd_params = (struct dpni_cmd_get_taildrop *)cmd.params;
1719 	cmd_params->congestion_point = cg_point;
1720 	cmd_params->qtype = qtype;
1721 	cmd_params->tc = tc;
1722 	cmd_params->index = index;
1723 
1724 	/* send command to mc */
1725 	err = mc_send_command(mc_io, &cmd);
1726 	if (err)
1727 		return err;
1728 
1729 	/* retrieve response parameters */
1730 	rsp_params = (struct dpni_rsp_get_taildrop *)cmd.params;
1731 	taildrop->enable = dpni_get_field(rsp_params->enable_oal_lo, ENABLE);
1732 	taildrop->units = rsp_params->units;
1733 	taildrop->threshold = le32_to_cpu(rsp_params->threshold);
1734 	oal_lo = dpni_get_field(rsp_params->enable_oal_lo, OAL_LO);
1735 	oal_hi = dpni_get_field(rsp_params->oal_hi, OAL_HI);
1736 	taildrop->oal = oal_hi << DPNI_OAL_LO_SIZE | oal_lo;
1737 
1738 	/* Fill the first 4 bits, 'oal' is a 2's complement value of 12 bits */
1739 	if (taildrop->oal >= 0x0800)
1740 		taildrop->oal |= 0xF000;
1741 
1742 	return 0;
1743 }
1744