cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dpni.c (64855B)


      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 */
     23int 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 */
     95int 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 */
    134int 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 */
    161int 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 */
    196int 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 */
    219int 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 */
    243int 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 */
    277int 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 */
    307int 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 */
    338int 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 */
    385int 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 */
    419int 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 */
    461int 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 */
    504int 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 */
    534int 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 */
    582int 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 */
    613int 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 */
    661int 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
    703int 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
    722int 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 */
    764int 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 */
    803int 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 */
    838int 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 */
    867int 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 */
    903int 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 */
    942int 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 */
    972int 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 */
   1007int 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 */
   1035int 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 */
   1070int 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 */
   1098int 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 */
   1133int 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 */
   1163int 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 */
   1202int 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 */
   1238int 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 */
   1276int 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 */
   1305int 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 */
   1331int 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 */
   1361int 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 */
   1394int 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 */
   1428int 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 */
   1465int 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 */
   1515int 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 */
   1563int 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 */
   1620int 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 */
   1666int 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 */
   1710int 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 */
   1757int 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 */
   1801int 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 */
   1836int 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 */
   1873int 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 */
   1913int 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 */
   1951int 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 */
   1986int 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 */
   2020int 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 */
   2052int 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 */
   2078int 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 */
   2114int 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	ptp_cfg->ptp_onestep_reg_base =
   2140				  le32_to_cpu(rsp_params->ptp_onestep_reg_base);
   2141
   2142	return err;
   2143}
   2144
   2145/**
   2146 * dpni_set_single_step_cfg() - enable/disable and configure single step PTP
   2147 * @mc_io:	Pointer to MC portal's I/O object
   2148 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
   2149 * @token:	Token of DPNI object
   2150 * @ptp_cfg:	ptp single step configuration
   2151 *
   2152 * Return:	'0' on Success; Error code otherwise.
   2153 *
   2154 * The function has effect only when dpni object is connected to a dpmac
   2155 * object. If the dpni is not connected to a dpmac the configuration will
   2156 * be stored inside and applied when connection is made.
   2157 */
   2158int dpni_set_single_step_cfg(struct fsl_mc_io *mc_io,
   2159			     u32 cmd_flags,
   2160			     u16 token,
   2161			     struct dpni_single_step_cfg *ptp_cfg)
   2162{
   2163	struct dpni_cmd_single_step_cfg *cmd_params;
   2164	struct fsl_mc_command cmd = { 0 };
   2165	u16 flags;
   2166
   2167	/* prepare command */
   2168	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_SINGLE_STEP_CFG,
   2169					  cmd_flags, token);
   2170	cmd_params = (struct dpni_cmd_single_step_cfg *)cmd.params;
   2171	cmd_params->offset = cpu_to_le16(ptp_cfg->offset);
   2172	cmd_params->peer_delay = cpu_to_le32(ptp_cfg->peer_delay);
   2173
   2174	flags = le16_to_cpu(cmd_params->flags);
   2175	dpni_set_field(flags, PTP_ENABLE, !!ptp_cfg->en);
   2176	dpni_set_field(flags, PTP_CH_UPDATE, !!ptp_cfg->ch_update);
   2177	cmd_params->flags = cpu_to_le16(flags);
   2178
   2179	/* send command to mc*/
   2180	return mc_send_command(mc_io, &cmd);
   2181}