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

dpsw.c (53219B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright 2014-2016 Freescale Semiconductor Inc.
      4 * Copyright 2017-2021 NXP
      5 *
      6 */
      7
      8#include <linux/fsl/mc.h>
      9#include "dpsw.h"
     10#include "dpsw-cmd.h"
     11
     12static void build_if_id_bitmap(__le64 *bmap, const u16 *id, const u16 num_ifs)
     13{
     14	int i;
     15
     16	for (i = 0; (i < num_ifs) && (i < DPSW_MAX_IF); i++) {
     17		if (id[i] < DPSW_MAX_IF)
     18			bmap[id[i] / 64] |= cpu_to_le64(BIT_MASK(id[i] % 64));
     19	}
     20}
     21
     22/**
     23 * dpsw_open() - Open a control session for the specified object
     24 * @mc_io:	Pointer to MC portal's I/O object
     25 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
     26 * @dpsw_id:	DPSW unique ID
     27 * @token:	Returned token; use in subsequent API calls
     28 *
     29 * This function can be used to open a control session for an
     30 * already created object; an object may have been declared in
     31 * the DPL or by calling the dpsw_create() function.
     32 * This function returns a unique authentication token,
     33 * associated with the specific object ID and the specific MC
     34 * portal; this token must be used in all subsequent commands for
     35 * this specific object
     36 *
     37 * Return:	'0' on Success; Error code otherwise.
     38 */
     39int dpsw_open(struct fsl_mc_io *mc_io, u32 cmd_flags, int dpsw_id, u16 *token)
     40{
     41	struct fsl_mc_command cmd = { 0 };
     42	struct dpsw_cmd_open *cmd_params;
     43	int err;
     44
     45	/* prepare command */
     46	cmd.header = mc_encode_cmd_header(DPSW_CMDID_OPEN,
     47					  cmd_flags,
     48					  0);
     49	cmd_params = (struct dpsw_cmd_open *)cmd.params;
     50	cmd_params->dpsw_id = cpu_to_le32(dpsw_id);
     51
     52	/* send command to mc*/
     53	err = mc_send_command(mc_io, &cmd);
     54	if (err)
     55		return err;
     56
     57	/* retrieve response parameters */
     58	*token = mc_cmd_hdr_read_token(&cmd);
     59
     60	return 0;
     61}
     62
     63/**
     64 * dpsw_close() - Close the control session of the object
     65 * @mc_io:	Pointer to MC portal's I/O object
     66 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
     67 * @token:	Token of DPSW object
     68 *
     69 * After this function is called, no further operations are
     70 * allowed on the object without opening a new control session.
     71 *
     72 * Return:	'0' on Success; Error code otherwise.
     73 */
     74int dpsw_close(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)
     75{
     76	struct fsl_mc_command cmd = { 0 };
     77
     78	/* prepare command */
     79	cmd.header = mc_encode_cmd_header(DPSW_CMDID_CLOSE,
     80					  cmd_flags,
     81					  token);
     82
     83	/* send command to mc*/
     84	return mc_send_command(mc_io, &cmd);
     85}
     86
     87/**
     88 * dpsw_enable() - Enable DPSW functionality
     89 * @mc_io:	Pointer to MC portal's I/O object
     90 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
     91 * @token:	Token of DPSW object
     92 *
     93 * Return:	Completion status. '0' on Success; Error code otherwise.
     94 */
     95int dpsw_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)
     96{
     97	struct fsl_mc_command cmd = { 0 };
     98
     99	/* prepare command */
    100	cmd.header = mc_encode_cmd_header(DPSW_CMDID_ENABLE,
    101					  cmd_flags,
    102					  token);
    103
    104	/* send command to mc*/
    105	return mc_send_command(mc_io, &cmd);
    106}
    107
    108/**
    109 * dpsw_disable() - Disable DPSW functionality
    110 * @mc_io:	Pointer to MC portal's I/O object
    111 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    112 * @token:	Token of DPSW object
    113 *
    114 * Return:	Completion status. '0' on Success; Error code otherwise.
    115 */
    116int dpsw_disable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)
    117{
    118	struct fsl_mc_command cmd = { 0 };
    119
    120	/* prepare command */
    121	cmd.header = mc_encode_cmd_header(DPSW_CMDID_DISABLE,
    122					  cmd_flags,
    123					  token);
    124
    125	/* send command to mc*/
    126	return mc_send_command(mc_io, &cmd);
    127}
    128
    129/**
    130 * dpsw_reset() - Reset the DPSW, returns the object to initial state.
    131 * @mc_io:	Pointer to MC portal's I/O object
    132 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    133 * @token:	Token of DPSW object
    134 *
    135 * Return:	'0' on Success; Error code otherwise.
    136 */
    137int dpsw_reset(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)
    138{
    139	struct fsl_mc_command cmd = { 0 };
    140
    141	/* prepare command */
    142	cmd.header = mc_encode_cmd_header(DPSW_CMDID_RESET,
    143					  cmd_flags,
    144					  token);
    145
    146	/* send command to mc*/
    147	return mc_send_command(mc_io, &cmd);
    148}
    149
    150/**
    151 * dpsw_set_irq_enable() - Set overall interrupt state.
    152 * @mc_io:	Pointer to MC portal's I/O object
    153 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    154 * @token:	Token of DPCI object
    155 * @irq_index:	The interrupt index to configure
    156 * @en:		Interrupt state - enable = 1, disable = 0
    157 *
    158 * Allows GPP software to control when interrupts are generated.
    159 * Each interrupt can have up to 32 causes.  The enable/disable control's the
    160 * overall interrupt state. if the interrupt is disabled no causes will cause
    161 * an interrupt
    162 *
    163 * Return:	'0' on Success; Error code otherwise.
    164 */
    165int dpsw_set_irq_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
    166			u8 irq_index, u8 en)
    167{
    168	struct fsl_mc_command cmd = { 0 };
    169	struct dpsw_cmd_set_irq_enable *cmd_params;
    170
    171	/* prepare command */
    172	cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_IRQ_ENABLE,
    173					  cmd_flags,
    174					  token);
    175	cmd_params = (struct dpsw_cmd_set_irq_enable *)cmd.params;
    176	dpsw_set_field(cmd_params->enable_state, ENABLE, en);
    177	cmd_params->irq_index = irq_index;
    178
    179	/* send command to mc*/
    180	return mc_send_command(mc_io, &cmd);
    181}
    182
    183/**
    184 * dpsw_set_irq_mask() - Set interrupt mask.
    185 * @mc_io:	Pointer to MC portal's I/O object
    186 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    187 * @token:	Token of DPCI object
    188 * @irq_index:	The interrupt index to configure
    189 * @mask:	Event mask to trigger interrupt;
    190 *		each bit:
    191 *			0 = ignore event
    192 *			1 = consider event for asserting IRQ
    193 *
    194 * Every interrupt can have up to 32 causes and the interrupt model supports
    195 * masking/unmasking each cause independently
    196 *
    197 * Return:	'0' on Success; Error code otherwise.
    198 */
    199int dpsw_set_irq_mask(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
    200		      u8 irq_index, u32 mask)
    201{
    202	struct fsl_mc_command cmd = { 0 };
    203	struct dpsw_cmd_set_irq_mask *cmd_params;
    204
    205	/* prepare command */
    206	cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_IRQ_MASK,
    207					  cmd_flags,
    208					  token);
    209	cmd_params = (struct dpsw_cmd_set_irq_mask *)cmd.params;
    210	cmd_params->mask = cpu_to_le32(mask);
    211	cmd_params->irq_index = irq_index;
    212
    213	/* send command to mc*/
    214	return mc_send_command(mc_io, &cmd);
    215}
    216
    217/**
    218 * dpsw_get_irq_status() - Get the current status of any pending interrupts
    219 * @mc_io:	Pointer to MC portal's I/O object
    220 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    221 * @token:	Token of DPSW object
    222 * @irq_index:	The interrupt index to configure
    223 * @status:	Returned interrupts status - one bit per cause:
    224 *			0 = no interrupt pending
    225 *			1 = interrupt pending
    226 *
    227 * Return:	'0' on Success; Error code otherwise.
    228 */
    229int dpsw_get_irq_status(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
    230			u8 irq_index, u32 *status)
    231{
    232	struct fsl_mc_command cmd = { 0 };
    233	struct dpsw_cmd_get_irq_status *cmd_params;
    234	struct dpsw_rsp_get_irq_status *rsp_params;
    235	int err;
    236
    237	/* prepare command */
    238	cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_IRQ_STATUS,
    239					  cmd_flags,
    240					  token);
    241	cmd_params = (struct dpsw_cmd_get_irq_status *)cmd.params;
    242	cmd_params->status = cpu_to_le32(*status);
    243	cmd_params->irq_index = irq_index;
    244
    245	/* send command to mc*/
    246	err = mc_send_command(mc_io, &cmd);
    247	if (err)
    248		return err;
    249
    250	/* retrieve response parameters */
    251	rsp_params = (struct dpsw_rsp_get_irq_status *)cmd.params;
    252	*status = le32_to_cpu(rsp_params->status);
    253
    254	return 0;
    255}
    256
    257/**
    258 * dpsw_clear_irq_status() - Clear a pending interrupt's status
    259 * @mc_io:	Pointer to MC portal's I/O object
    260 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    261 * @token:	Token of DPCI object
    262 * @irq_index:	The interrupt index to configure
    263 * @status:	bits to clear (W1C) - one bit per cause:
    264 *			0 = don't change
    265 *			1 = clear status bit
    266 *
    267 * Return:	'0' on Success; Error code otherwise.
    268 */
    269int dpsw_clear_irq_status(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
    270			  u8 irq_index, u32 status)
    271{
    272	struct fsl_mc_command cmd = { 0 };
    273	struct dpsw_cmd_clear_irq_status *cmd_params;
    274
    275	/* prepare command */
    276	cmd.header = mc_encode_cmd_header(DPSW_CMDID_CLEAR_IRQ_STATUS,
    277					  cmd_flags,
    278					  token);
    279	cmd_params = (struct dpsw_cmd_clear_irq_status *)cmd.params;
    280	cmd_params->status = cpu_to_le32(status);
    281	cmd_params->irq_index = irq_index;
    282
    283	/* send command to mc*/
    284	return mc_send_command(mc_io, &cmd);
    285}
    286
    287/**
    288 * dpsw_get_attributes() - Retrieve DPSW attributes
    289 * @mc_io:	Pointer to MC portal's I/O object
    290 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    291 * @token:	Token of DPSW object
    292 * @attr:	Returned DPSW attributes
    293 *
    294 * Return:	Completion status. '0' on Success; Error code otherwise.
    295 */
    296int dpsw_get_attributes(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
    297			struct dpsw_attr *attr)
    298{
    299	struct fsl_mc_command cmd = { 0 };
    300	struct dpsw_rsp_get_attr *rsp_params;
    301	int err;
    302
    303	/* prepare command */
    304	cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_ATTR,
    305					  cmd_flags,
    306					  token);
    307
    308	/* send command to mc*/
    309	err = mc_send_command(mc_io, &cmd);
    310	if (err)
    311		return err;
    312
    313	/* retrieve response parameters */
    314	rsp_params = (struct dpsw_rsp_get_attr *)cmd.params;
    315	attr->num_ifs = le16_to_cpu(rsp_params->num_ifs);
    316	attr->max_fdbs = rsp_params->max_fdbs;
    317	attr->num_fdbs = rsp_params->num_fdbs;
    318	attr->max_vlans = le16_to_cpu(rsp_params->max_vlans);
    319	attr->num_vlans = le16_to_cpu(rsp_params->num_vlans);
    320	attr->max_fdb_entries = le16_to_cpu(rsp_params->max_fdb_entries);
    321	attr->fdb_aging_time = le16_to_cpu(rsp_params->fdb_aging_time);
    322	attr->id = le32_to_cpu(rsp_params->dpsw_id);
    323	attr->mem_size = le16_to_cpu(rsp_params->mem_size);
    324	attr->max_fdb_mc_groups = le16_to_cpu(rsp_params->max_fdb_mc_groups);
    325	attr->max_meters_per_if = rsp_params->max_meters_per_if;
    326	attr->options = le64_to_cpu(rsp_params->options);
    327	attr->component_type = dpsw_get_field(rsp_params->component_type, COMPONENT_TYPE);
    328	attr->flooding_cfg = dpsw_get_field(rsp_params->repl_cfg, FLOODING_CFG);
    329	attr->broadcast_cfg = dpsw_get_field(rsp_params->repl_cfg, BROADCAST_CFG);
    330	return 0;
    331}
    332
    333/**
    334 * dpsw_if_set_link_cfg() - Set the link configuration.
    335 * @mc_io:	Pointer to MC portal's I/O object
    336 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    337 * @token:	Token of DPSW object
    338 * @if_id:	Interface id
    339 * @cfg:	Link configuration
    340 *
    341 * Return:	'0' on Success; Error code otherwise.
    342 */
    343int dpsw_if_set_link_cfg(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 if_id,
    344			 struct dpsw_link_cfg *cfg)
    345{
    346	struct fsl_mc_command cmd = { 0 };
    347	struct dpsw_cmd_if_set_link_cfg *cmd_params;
    348
    349	/* prepare command */
    350	cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_LINK_CFG,
    351					  cmd_flags,
    352					  token);
    353	cmd_params = (struct dpsw_cmd_if_set_link_cfg *)cmd.params;
    354	cmd_params->if_id = cpu_to_le16(if_id);
    355	cmd_params->rate = cpu_to_le32(cfg->rate);
    356	cmd_params->options = cpu_to_le64(cfg->options);
    357
    358	/* send command to mc*/
    359	return mc_send_command(mc_io, &cmd);
    360}
    361
    362/**
    363 * dpsw_if_get_link_state - Return the link state
    364 * @mc_io:	Pointer to MC portal's I/O object
    365 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    366 * @token:	Token of DPSW object
    367 * @if_id:	Interface id
    368 * @state:	Link state	1 - linkup, 0 - link down or disconnected
    369 *
    370 * Return:	'0' on Success; Error code otherwise.
    371 */
    372int dpsw_if_get_link_state(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
    373			   u16 if_id, struct dpsw_link_state *state)
    374{
    375	struct fsl_mc_command cmd = { 0 };
    376	struct dpsw_cmd_if_get_link_state *cmd_params;
    377	struct dpsw_rsp_if_get_link_state *rsp_params;
    378	int err;
    379
    380	/* prepare command */
    381	cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_LINK_STATE,
    382					  cmd_flags,
    383					  token);
    384	cmd_params = (struct dpsw_cmd_if_get_link_state *)cmd.params;
    385	cmd_params->if_id = cpu_to_le16(if_id);
    386
    387	/* send command to mc*/
    388	err = mc_send_command(mc_io, &cmd);
    389	if (err)
    390		return err;
    391
    392	/* retrieve response parameters */
    393	rsp_params = (struct dpsw_rsp_if_get_link_state *)cmd.params;
    394	state->rate = le32_to_cpu(rsp_params->rate);
    395	state->options = le64_to_cpu(rsp_params->options);
    396	state->up = dpsw_get_field(rsp_params->up, UP);
    397
    398	return 0;
    399}
    400
    401/**
    402 * dpsw_if_set_tci() - Set default VLAN Tag Control Information (TCI)
    403 * @mc_io:	Pointer to MC portal's I/O object
    404 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    405 * @token:	Token of DPSW object
    406 * @if_id:	Interface Identifier
    407 * @cfg:	Tag Control Information Configuration
    408 *
    409 * Return:	Completion status. '0' on Success; Error code otherwise.
    410 */
    411int dpsw_if_set_tci(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 if_id,
    412		    const struct dpsw_tci_cfg *cfg)
    413{
    414	struct fsl_mc_command cmd = { 0 };
    415	struct dpsw_cmd_if_set_tci *cmd_params;
    416	u16 tmp_conf = 0;
    417
    418	/* prepare command */
    419	cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_TCI,
    420					  cmd_flags,
    421					  token);
    422	cmd_params = (struct dpsw_cmd_if_set_tci *)cmd.params;
    423	cmd_params->if_id = cpu_to_le16(if_id);
    424	dpsw_set_field(tmp_conf, VLAN_ID, cfg->vlan_id);
    425	dpsw_set_field(tmp_conf, DEI, cfg->dei);
    426	dpsw_set_field(tmp_conf, PCP, cfg->pcp);
    427	cmd_params->conf = cpu_to_le16(tmp_conf);
    428
    429	/* send command to mc*/
    430	return mc_send_command(mc_io, &cmd);
    431}
    432
    433/**
    434 * dpsw_if_get_tci() - Get default VLAN Tag Control Information (TCI)
    435 * @mc_io:	Pointer to MC portal's I/O object
    436 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    437 * @token:	Token of DPSW object
    438 * @if_id:	Interface Identifier
    439 * @cfg:	Tag Control Information Configuration
    440 *
    441 * Return:	Completion status. '0' on Success; Error code otherwise.
    442 */
    443int dpsw_if_get_tci(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 if_id,
    444		    struct dpsw_tci_cfg *cfg)
    445{
    446	struct fsl_mc_command cmd = { 0 };
    447	struct dpsw_cmd_if_get_tci *cmd_params;
    448	struct dpsw_rsp_if_get_tci *rsp_params;
    449	int err;
    450
    451	/* prepare command */
    452	cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_TCI,
    453					  cmd_flags,
    454					  token);
    455	cmd_params = (struct dpsw_cmd_if_get_tci *)cmd.params;
    456	cmd_params->if_id = cpu_to_le16(if_id);
    457
    458	/* send command to mc*/
    459	err = mc_send_command(mc_io, &cmd);
    460	if (err)
    461		return err;
    462
    463	/* retrieve response parameters */
    464	rsp_params = (struct dpsw_rsp_if_get_tci *)cmd.params;
    465	cfg->pcp = rsp_params->pcp;
    466	cfg->dei = rsp_params->dei;
    467	cfg->vlan_id = le16_to_cpu(rsp_params->vlan_id);
    468
    469	return 0;
    470}
    471
    472/**
    473 * dpsw_if_set_stp() - Function sets Spanning Tree Protocol (STP) state.
    474 * @mc_io:	Pointer to MC portal's I/O object
    475 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    476 * @token:	Token of DPSW object
    477 * @if_id:	Interface Identifier
    478 * @cfg:	STP State configuration parameters
    479 *
    480 * The following STP states are supported -
    481 * blocking, listening, learning, forwarding and disabled.
    482 *
    483 * Return:	Completion status. '0' on Success; Error code otherwise.
    484 */
    485int dpsw_if_set_stp(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 if_id,
    486		    const struct dpsw_stp_cfg *cfg)
    487{
    488	struct fsl_mc_command cmd = { 0 };
    489	struct dpsw_cmd_if_set_stp *cmd_params;
    490
    491	/* prepare command */
    492	cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_STP,
    493					  cmd_flags,
    494					  token);
    495	cmd_params = (struct dpsw_cmd_if_set_stp *)cmd.params;
    496	cmd_params->if_id = cpu_to_le16(if_id);
    497	cmd_params->vlan_id = cpu_to_le16(cfg->vlan_id);
    498	dpsw_set_field(cmd_params->state, STATE, cfg->state);
    499
    500	/* send command to mc*/
    501	return mc_send_command(mc_io, &cmd);
    502}
    503
    504/**
    505 * dpsw_if_get_counter() - Get specific counter of particular interface
    506 * @mc_io:	Pointer to MC portal's I/O object
    507 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    508 * @token:	Token of DPSW object
    509 * @if_id:	Interface Identifier
    510 * @type:	Counter type
    511 * @counter:	return value
    512 *
    513 * Return:	Completion status. '0' on Success; Error code otherwise.
    514 */
    515int dpsw_if_get_counter(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
    516			u16 if_id, enum dpsw_counter type, u64 *counter)
    517{
    518	struct fsl_mc_command cmd = { 0 };
    519	struct dpsw_cmd_if_get_counter *cmd_params;
    520	struct dpsw_rsp_if_get_counter *rsp_params;
    521	int err;
    522
    523	/* prepare command */
    524	cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_COUNTER,
    525					  cmd_flags,
    526					  token);
    527	cmd_params = (struct dpsw_cmd_if_get_counter *)cmd.params;
    528	cmd_params->if_id = cpu_to_le16(if_id);
    529	dpsw_set_field(cmd_params->type, COUNTER_TYPE, type);
    530
    531	/* send command to mc*/
    532	err = mc_send_command(mc_io, &cmd);
    533	if (err)
    534		return err;
    535
    536	/* retrieve response parameters */
    537	rsp_params = (struct dpsw_rsp_if_get_counter *)cmd.params;
    538	*counter = le64_to_cpu(rsp_params->counter);
    539
    540	return 0;
    541}
    542
    543/**
    544 * dpsw_if_enable() - Enable Interface
    545 * @mc_io:	Pointer to MC portal's I/O object
    546 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    547 * @token:	Token of DPSW object
    548 * @if_id:	Interface Identifier
    549 *
    550 * Return:	Completion status. '0' on Success; Error code otherwise.
    551 */
    552int dpsw_if_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 if_id)
    553{
    554	struct fsl_mc_command cmd = { 0 };
    555	struct dpsw_cmd_if *cmd_params;
    556
    557	/* prepare command */
    558	cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_ENABLE,
    559					  cmd_flags,
    560					  token);
    561	cmd_params = (struct dpsw_cmd_if *)cmd.params;
    562	cmd_params->if_id = cpu_to_le16(if_id);
    563
    564	/* send command to mc*/
    565	return mc_send_command(mc_io, &cmd);
    566}
    567
    568/**
    569 * dpsw_if_disable() - Disable Interface
    570 * @mc_io:	Pointer to MC portal's I/O object
    571 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    572 * @token:	Token of DPSW object
    573 * @if_id:	Interface Identifier
    574 *
    575 * Return:	Completion status. '0' on Success; Error code otherwise.
    576 */
    577int dpsw_if_disable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 if_id)
    578{
    579	struct fsl_mc_command cmd = { 0 };
    580	struct dpsw_cmd_if *cmd_params;
    581
    582	/* prepare command */
    583	cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_DISABLE,
    584					  cmd_flags,
    585					  token);
    586	cmd_params = (struct dpsw_cmd_if *)cmd.params;
    587	cmd_params->if_id = cpu_to_le16(if_id);
    588
    589	/* send command to mc*/
    590	return mc_send_command(mc_io, &cmd);
    591}
    592
    593/**
    594 * dpsw_if_get_attributes() - Function obtains attributes of interface
    595 * @mc_io:	Pointer to MC portal's I/O object
    596 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    597 * @token:	Token of DPSW object
    598 * @if_id:	Interface Identifier
    599 * @attr:	Returned interface attributes
    600 *
    601 * Return:	Completion status. '0' on Success; Error code otherwise.
    602 */
    603int dpsw_if_get_attributes(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
    604			   u16 if_id, struct dpsw_if_attr *attr)
    605{
    606	struct dpsw_rsp_if_get_attr *rsp_params;
    607	struct fsl_mc_command cmd = { 0 };
    608	struct dpsw_cmd_if *cmd_params;
    609	int err;
    610
    611	cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_ATTR, cmd_flags,
    612					  token);
    613	cmd_params = (struct dpsw_cmd_if *)cmd.params;
    614	cmd_params->if_id = cpu_to_le16(if_id);
    615
    616	err = mc_send_command(mc_io, &cmd);
    617	if (err)
    618		return err;
    619
    620	rsp_params = (struct dpsw_rsp_if_get_attr *)cmd.params;
    621	attr->num_tcs = rsp_params->num_tcs;
    622	attr->rate = le32_to_cpu(rsp_params->rate);
    623	attr->options = le32_to_cpu(rsp_params->options);
    624	attr->qdid = le16_to_cpu(rsp_params->qdid);
    625	attr->enabled = dpsw_get_field(rsp_params->conf, ENABLED);
    626	attr->accept_all_vlan = dpsw_get_field(rsp_params->conf,
    627					       ACCEPT_ALL_VLAN);
    628	attr->admit_untagged = dpsw_get_field(rsp_params->conf,
    629					      ADMIT_UNTAGGED);
    630
    631	return 0;
    632}
    633
    634/**
    635 * dpsw_if_set_max_frame_length() - Set Maximum Receive frame length.
    636 * @mc_io:		Pointer to MC portal's I/O object
    637 * @cmd_flags:		Command flags; one or more of 'MC_CMD_FLAG_'
    638 * @token:		Token of DPSW object
    639 * @if_id:		Interface Identifier
    640 * @frame_length:	Maximum Frame Length
    641 *
    642 * Return:	Completion status. '0' on Success; Error code otherwise.
    643 */
    644int dpsw_if_set_max_frame_length(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
    645				 u16 if_id, u16 frame_length)
    646{
    647	struct fsl_mc_command cmd = { 0 };
    648	struct dpsw_cmd_if_set_max_frame_length *cmd_params;
    649
    650	/* prepare command */
    651	cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_MAX_FRAME_LENGTH,
    652					  cmd_flags,
    653					  token);
    654	cmd_params = (struct dpsw_cmd_if_set_max_frame_length *)cmd.params;
    655	cmd_params->if_id = cpu_to_le16(if_id);
    656	cmd_params->frame_length = cpu_to_le16(frame_length);
    657
    658	/* send command to mc*/
    659	return mc_send_command(mc_io, &cmd);
    660}
    661
    662/**
    663 * dpsw_vlan_add() - Adding new VLAN to DPSW.
    664 * @mc_io:	Pointer to MC portal's I/O object
    665 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    666 * @token:	Token of DPSW object
    667 * @vlan_id:	VLAN Identifier
    668 * @cfg:	VLAN configuration
    669 *
    670 * Only VLAN ID and FDB ID are required parameters here.
    671 * 12 bit VLAN ID is defined in IEEE802.1Q.
    672 * Adding a duplicate VLAN ID is not allowed.
    673 * FDB ID can be shared across multiple VLANs. Shared learning
    674 * is obtained by calling dpsw_vlan_add for multiple VLAN IDs
    675 * with same fdb_id
    676 *
    677 * Return:	Completion status. '0' on Success; Error code otherwise.
    678 */
    679int dpsw_vlan_add(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
    680		  u16 vlan_id, const struct dpsw_vlan_cfg *cfg)
    681{
    682	struct fsl_mc_command cmd = { 0 };
    683	struct dpsw_vlan_add *cmd_params;
    684
    685	/* prepare command */
    686	cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD,
    687					  cmd_flags,
    688					  token);
    689	cmd_params = (struct dpsw_vlan_add *)cmd.params;
    690	cmd_params->fdb_id = cpu_to_le16(cfg->fdb_id);
    691	cmd_params->vlan_id = cpu_to_le16(vlan_id);
    692
    693	/* send command to mc*/
    694	return mc_send_command(mc_io, &cmd);
    695}
    696
    697/**
    698 * dpsw_vlan_add_if() - Adding a set of interfaces to an existing VLAN.
    699 * @mc_io:	Pointer to MC portal's I/O object
    700 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    701 * @token:	Token of DPSW object
    702 * @vlan_id:	VLAN Identifier
    703 * @cfg:	Set of interfaces to add
    704 *
    705 * It adds only interfaces not belonging to this VLAN yet,
    706 * otherwise an error is generated and an entire command is
    707 * ignored. This function can be called numerous times always
    708 * providing required interfaces delta.
    709 *
    710 * Return:	Completion status. '0' on Success; Error code otherwise.
    711 */
    712int dpsw_vlan_add_if(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
    713		     u16 vlan_id, const struct dpsw_vlan_if_cfg *cfg)
    714{
    715	struct dpsw_cmd_vlan_add_if *cmd_params;
    716	struct fsl_mc_command cmd = { 0 };
    717
    718	/* prepare command */
    719	cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD_IF,
    720					  cmd_flags,
    721					  token);
    722	cmd_params = (struct dpsw_cmd_vlan_add_if *)cmd.params;
    723	cmd_params->vlan_id = cpu_to_le16(vlan_id);
    724	cmd_params->options = cpu_to_le16(cfg->options);
    725	cmd_params->fdb_id = cpu_to_le16(cfg->fdb_id);
    726	build_if_id_bitmap(&cmd_params->if_id, cfg->if_id, cfg->num_ifs);
    727
    728	/* send command to mc*/
    729	return mc_send_command(mc_io, &cmd);
    730}
    731
    732/**
    733 * dpsw_vlan_add_if_untagged() - Defining a set of interfaces that should be
    734 *				transmitted as untagged.
    735 * @mc_io:	Pointer to MC portal's I/O object
    736 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    737 * @token:	Token of DPSW object
    738 * @vlan_id:	VLAN Identifier
    739 * @cfg:	Set of interfaces that should be transmitted as untagged
    740 *
    741 * These interfaces should already belong to this VLAN.
    742 * By default all interfaces are transmitted as tagged.
    743 * Providing un-existing interface or untagged interface that is
    744 * configured untagged already generates an error and the entire
    745 * command is ignored.
    746 *
    747 * Return:	Completion status. '0' on Success; Error code otherwise.
    748 */
    749int dpsw_vlan_add_if_untagged(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
    750			      u16 vlan_id, const struct dpsw_vlan_if_cfg *cfg)
    751{
    752	struct fsl_mc_command cmd = { 0 };
    753	struct dpsw_cmd_vlan_manage_if *cmd_params;
    754
    755	/* prepare command */
    756	cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD_IF_UNTAGGED,
    757					  cmd_flags,
    758					  token);
    759	cmd_params = (struct dpsw_cmd_vlan_manage_if *)cmd.params;
    760	cmd_params->vlan_id = cpu_to_le16(vlan_id);
    761	build_if_id_bitmap(&cmd_params->if_id, cfg->if_id, cfg->num_ifs);
    762
    763	/* send command to mc*/
    764	return mc_send_command(mc_io, &cmd);
    765}
    766
    767/**
    768 * dpsw_vlan_remove_if() - Remove interfaces from an existing VLAN.
    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 DPSW object
    772 * @vlan_id:	VLAN Identifier
    773 * @cfg:	Set of interfaces that should be removed
    774 *
    775 * Interfaces must belong to this VLAN, otherwise an error
    776 * is returned and an the command is ignored
    777 *
    778 * Return:	Completion status. '0' on Success; Error code otherwise.
    779 */
    780int dpsw_vlan_remove_if(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
    781			u16 vlan_id, const struct dpsw_vlan_if_cfg *cfg)
    782{
    783	struct fsl_mc_command cmd = { 0 };
    784	struct dpsw_cmd_vlan_manage_if *cmd_params;
    785
    786	/* prepare command */
    787	cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE_IF,
    788					  cmd_flags,
    789					  token);
    790	cmd_params = (struct dpsw_cmd_vlan_manage_if *)cmd.params;
    791	cmd_params->vlan_id = cpu_to_le16(vlan_id);
    792	build_if_id_bitmap(&cmd_params->if_id, cfg->if_id, cfg->num_ifs);
    793
    794	/* send command to mc*/
    795	return mc_send_command(mc_io, &cmd);
    796}
    797
    798/**
    799 * dpsw_vlan_remove_if_untagged() - Define a set of interfaces that should be
    800 *		converted from transmitted as untagged to transmit as tagged.
    801 * @mc_io:	Pointer to MC portal's I/O object
    802 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    803 * @token:	Token of DPSW object
    804 * @vlan_id:	VLAN Identifier
    805 * @cfg:	Set of interfaces that should be removed
    806 *
    807 * Interfaces provided by API have to belong to this VLAN and
    808 * configured untagged, otherwise an error is returned and the
    809 * command is ignored
    810 *
    811 * Return:	Completion status. '0' on Success; Error code otherwise.
    812 */
    813int dpsw_vlan_remove_if_untagged(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
    814				 u16 vlan_id, const struct dpsw_vlan_if_cfg *cfg)
    815{
    816	struct fsl_mc_command cmd = { 0 };
    817	struct dpsw_cmd_vlan_manage_if *cmd_params;
    818
    819	/* prepare command */
    820	cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE_IF_UNTAGGED,
    821					  cmd_flags,
    822					  token);
    823	cmd_params = (struct dpsw_cmd_vlan_manage_if *)cmd.params;
    824	cmd_params->vlan_id = cpu_to_le16(vlan_id);
    825	build_if_id_bitmap(&cmd_params->if_id, cfg->if_id, cfg->num_ifs);
    826
    827	/* send command to mc*/
    828	return mc_send_command(mc_io, &cmd);
    829}
    830
    831/**
    832 * dpsw_vlan_remove() - Remove an entire VLAN
    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 DPSW object
    836 * @vlan_id:	VLAN Identifier
    837 *
    838 * Return:	Completion status. '0' on Success; Error code otherwise.
    839 */
    840int dpsw_vlan_remove(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
    841		     u16 vlan_id)
    842{
    843	struct fsl_mc_command cmd = { 0 };
    844	struct dpsw_cmd_vlan_remove *cmd_params;
    845
    846	/* prepare command */
    847	cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE,
    848					  cmd_flags,
    849					  token);
    850	cmd_params = (struct dpsw_cmd_vlan_remove *)cmd.params;
    851	cmd_params->vlan_id = cpu_to_le16(vlan_id);
    852
    853	/* send command to mc*/
    854	return mc_send_command(mc_io, &cmd);
    855}
    856
    857/**
    858 * dpsw_fdb_add() - Add FDB to switch and Returns handle to FDB table for
    859 *		the reference
    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 DPSW object
    863 * @fdb_id:	Returned Forwarding Database Identifier
    864 * @cfg:	FDB Configuration
    865 *
    866 * Return:	Completion status. '0' on Success; Error code otherwise.
    867 */
    868int dpsw_fdb_add(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 *fdb_id,
    869		 const struct dpsw_fdb_cfg *cfg)
    870{
    871	struct dpsw_cmd_fdb_add *cmd_params;
    872	struct dpsw_rsp_fdb_add *rsp_params;
    873	struct fsl_mc_command cmd = { 0 };
    874	int err;
    875
    876	cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD,
    877					  cmd_flags,
    878					  token);
    879	cmd_params = (struct dpsw_cmd_fdb_add *)cmd.params;
    880	cmd_params->fdb_ageing_time = cpu_to_le16(cfg->fdb_ageing_time);
    881	cmd_params->num_fdb_entries = cpu_to_le16(cfg->num_fdb_entries);
    882
    883	err = mc_send_command(mc_io, &cmd);
    884	if (err)
    885		return err;
    886
    887	rsp_params = (struct dpsw_rsp_fdb_add *)cmd.params;
    888	*fdb_id = le16_to_cpu(rsp_params->fdb_id);
    889
    890	return 0;
    891}
    892
    893/**
    894 * dpsw_fdb_remove() - Remove FDB from switch
    895 * @mc_io:	Pointer to MC portal's I/O object
    896 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    897 * @token:	Token of DPSW object
    898 * @fdb_id:	Forwarding Database Identifier
    899 *
    900 * Return:	Completion status. '0' on Success; Error code otherwise.
    901 */
    902int dpsw_fdb_remove(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 fdb_id)
    903{
    904	struct dpsw_cmd_fdb_remove *cmd_params;
    905	struct fsl_mc_command cmd = { 0 };
    906
    907	/* prepare command */
    908	cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE,
    909					  cmd_flags,
    910					  token);
    911	cmd_params = (struct dpsw_cmd_fdb_remove *)cmd.params;
    912	cmd_params->fdb_id = cpu_to_le16(fdb_id);
    913
    914	return mc_send_command(mc_io, &cmd);
    915}
    916
    917/**
    918 * dpsw_fdb_add_unicast() - Function adds an unicast entry into MAC lookup table
    919 * @mc_io:	Pointer to MC portal's I/O object
    920 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    921 * @token:	Token of DPSW object
    922 * @fdb_id:	Forwarding Database Identifier
    923 * @cfg:	Unicast entry configuration
    924 *
    925 * Return:	Completion status. '0' on Success; Error code otherwise.
    926 */
    927int dpsw_fdb_add_unicast(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
    928			 u16 fdb_id, const struct dpsw_fdb_unicast_cfg *cfg)
    929{
    930	struct fsl_mc_command cmd = { 0 };
    931	struct dpsw_cmd_fdb_unicast_op *cmd_params;
    932	int i;
    933
    934	/* prepare command */
    935	cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD_UNICAST,
    936					  cmd_flags,
    937					  token);
    938	cmd_params = (struct dpsw_cmd_fdb_unicast_op *)cmd.params;
    939	cmd_params->fdb_id = cpu_to_le16(fdb_id);
    940	cmd_params->if_egress = cpu_to_le16(cfg->if_egress);
    941	for (i = 0; i < 6; i++)
    942		cmd_params->mac_addr[i] = cfg->mac_addr[5 - i];
    943	dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type);
    944
    945	/* send command to mc*/
    946	return mc_send_command(mc_io, &cmd);
    947}
    948
    949/**
    950 * dpsw_fdb_dump() - Dump the content of FDB table into memory.
    951 * @mc_io:	Pointer to MC portal's I/O object
    952 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
    953 * @token:	Token of DPSW object
    954 * @fdb_id:	Forwarding Database Identifier
    955 * @iova_addr:	Data will be stored here as an array of struct fdb_dump_entry
    956 * @iova_size:	Memory size allocated at iova_addr
    957 * @num_entries:Number of entries written at iova_addr
    958 *
    959 * Return:	Completion status. '0' on Success; Error code otherwise.
    960 *
    961 * The memory allocated at iova_addr must be initialized with zero before
    962 * command execution. If the FDB table does not fit into memory MC will stop
    963 * after the memory is filled up.
    964 * The struct fdb_dump_entry array must be parsed until the end of memory
    965 * area or until an entry with mac_addr set to zero is found.
    966 */
    967int dpsw_fdb_dump(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 fdb_id,
    968		  u64 iova_addr, u32 iova_size, u16 *num_entries)
    969{
    970	struct dpsw_cmd_fdb_dump *cmd_params;
    971	struct dpsw_rsp_fdb_dump *rsp_params;
    972	struct fsl_mc_command cmd = { 0 };
    973	int err;
    974
    975	/* prepare command */
    976	cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_DUMP,
    977					  cmd_flags,
    978					  token);
    979	cmd_params = (struct dpsw_cmd_fdb_dump *)cmd.params;
    980	cmd_params->fdb_id = cpu_to_le16(fdb_id);
    981	cmd_params->iova_addr = cpu_to_le64(iova_addr);
    982	cmd_params->iova_size = cpu_to_le32(iova_size);
    983
    984	/* send command to mc */
    985	err = mc_send_command(mc_io, &cmd);
    986	if (err)
    987		return err;
    988
    989	rsp_params = (struct dpsw_rsp_fdb_dump *)cmd.params;
    990	*num_entries = le16_to_cpu(rsp_params->num_entries);
    991
    992	return 0;
    993}
    994
    995/**
    996 * dpsw_fdb_remove_unicast() - removes an entry from MAC lookup table
    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 DPSW object
   1000 * @fdb_id:	Forwarding Database Identifier
   1001 * @cfg:	Unicast entry configuration
   1002 *
   1003 * Return:	Completion status. '0' on Success; Error code otherwise.
   1004 */
   1005int dpsw_fdb_remove_unicast(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
   1006			    u16 fdb_id, const struct dpsw_fdb_unicast_cfg *cfg)
   1007{
   1008	struct fsl_mc_command cmd = { 0 };
   1009	struct dpsw_cmd_fdb_unicast_op *cmd_params;
   1010	int i;
   1011
   1012	/* prepare command */
   1013	cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE_UNICAST,
   1014					  cmd_flags,
   1015					  token);
   1016	cmd_params = (struct dpsw_cmd_fdb_unicast_op *)cmd.params;
   1017	cmd_params->fdb_id = cpu_to_le16(fdb_id);
   1018	for (i = 0; i < 6; i++)
   1019		cmd_params->mac_addr[i] = cfg->mac_addr[5 - i];
   1020	cmd_params->if_egress = cpu_to_le16(cfg->if_egress);
   1021	dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type);
   1022
   1023	/* send command to mc*/
   1024	return mc_send_command(mc_io, &cmd);
   1025}
   1026
   1027/**
   1028 * dpsw_fdb_add_multicast() - Add a set of egress interfaces to multi-cast group
   1029 * @mc_io:	Pointer to MC portal's I/O object
   1030 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
   1031 * @token:	Token of DPSW object
   1032 * @fdb_id:	Forwarding Database Identifier
   1033 * @cfg:	Multicast entry configuration
   1034 *
   1035 * If group doesn't exist, it will be created.
   1036 * It adds only interfaces not belonging to this multicast group
   1037 * yet, otherwise error will be generated and the command is
   1038 * ignored.
   1039 * This function may be called numerous times always providing
   1040 * required interfaces delta.
   1041 *
   1042 * Return:	Completion status. '0' on Success; Error code otherwise.
   1043 */
   1044int dpsw_fdb_add_multicast(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
   1045			   u16 fdb_id, const struct dpsw_fdb_multicast_cfg *cfg)
   1046{
   1047	struct fsl_mc_command cmd = { 0 };
   1048	struct dpsw_cmd_fdb_multicast_op *cmd_params;
   1049	int i;
   1050
   1051	/* prepare command */
   1052	cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD_MULTICAST,
   1053					  cmd_flags,
   1054					  token);
   1055	cmd_params = (struct dpsw_cmd_fdb_multicast_op *)cmd.params;
   1056	cmd_params->fdb_id = cpu_to_le16(fdb_id);
   1057	cmd_params->num_ifs = cpu_to_le16(cfg->num_ifs);
   1058	dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type);
   1059	build_if_id_bitmap(&cmd_params->if_id, cfg->if_id, cfg->num_ifs);
   1060	for (i = 0; i < 6; i++)
   1061		cmd_params->mac_addr[i] = cfg->mac_addr[5 - i];
   1062
   1063	/* send command to mc*/
   1064	return mc_send_command(mc_io, &cmd);
   1065}
   1066
   1067/**
   1068 * dpsw_fdb_remove_multicast() - Removing interfaces from an existing multicast
   1069 *				group.
   1070 * @mc_io:	Pointer to MC portal's I/O object
   1071 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
   1072 * @token:	Token of DPSW object
   1073 * @fdb_id:	Forwarding Database Identifier
   1074 * @cfg:	Multicast entry configuration
   1075 *
   1076 * Interfaces provided by this API have to exist in the group,
   1077 * otherwise an error will be returned and an entire command
   1078 * ignored. If there is no interface left in the group,
   1079 * an entire group is deleted
   1080 *
   1081 * Return:	Completion status. '0' on Success; Error code otherwise.
   1082 */
   1083int dpsw_fdb_remove_multicast(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
   1084			      u16 fdb_id, const struct dpsw_fdb_multicast_cfg *cfg)
   1085{
   1086	struct fsl_mc_command cmd = { 0 };
   1087	struct dpsw_cmd_fdb_multicast_op *cmd_params;
   1088	int i;
   1089
   1090	/* prepare command */
   1091	cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE_MULTICAST,
   1092					  cmd_flags,
   1093					  token);
   1094	cmd_params = (struct dpsw_cmd_fdb_multicast_op *)cmd.params;
   1095	cmd_params->fdb_id = cpu_to_le16(fdb_id);
   1096	cmd_params->num_ifs = cpu_to_le16(cfg->num_ifs);
   1097	dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type);
   1098	build_if_id_bitmap(&cmd_params->if_id, cfg->if_id, cfg->num_ifs);
   1099	for (i = 0; i < 6; i++)
   1100		cmd_params->mac_addr[i] = cfg->mac_addr[5 - i];
   1101
   1102	/* send command to mc*/
   1103	return mc_send_command(mc_io, &cmd);
   1104}
   1105
   1106/**
   1107 * dpsw_ctrl_if_get_attributes() - Obtain control interface attributes
   1108 * @mc_io:	Pointer to MC portal's I/O object
   1109 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
   1110 * @token:	Token of DPSW object
   1111 * @attr:	Returned control interface attributes
   1112 *
   1113 * Return:	'0' on Success; Error code otherwise.
   1114 */
   1115int dpsw_ctrl_if_get_attributes(struct fsl_mc_io *mc_io, u32 cmd_flags,
   1116				u16 token, struct dpsw_ctrl_if_attr *attr)
   1117{
   1118	struct dpsw_rsp_ctrl_if_get_attr *rsp_params;
   1119	struct fsl_mc_command cmd = { 0 };
   1120	int err;
   1121
   1122	cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_GET_ATTR,
   1123					  cmd_flags, token);
   1124
   1125	err = mc_send_command(mc_io, &cmd);
   1126	if (err)
   1127		return err;
   1128
   1129	rsp_params = (struct dpsw_rsp_ctrl_if_get_attr *)cmd.params;
   1130	attr->rx_fqid = le32_to_cpu(rsp_params->rx_fqid);
   1131	attr->rx_err_fqid = le32_to_cpu(rsp_params->rx_err_fqid);
   1132	attr->tx_err_conf_fqid = le32_to_cpu(rsp_params->tx_err_conf_fqid);
   1133
   1134	return 0;
   1135}
   1136
   1137/**
   1138 * dpsw_ctrl_if_set_pools() - Set control interface buffer pools
   1139 * @mc_io:	Pointer to MC portal's I/O object
   1140 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
   1141 * @token:	Token of DPSW object
   1142 * @cfg:	Buffer pools configuration
   1143 *
   1144 * Return:	'0' on Success; Error code otherwise.
   1145 */
   1146int dpsw_ctrl_if_set_pools(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
   1147			   const struct dpsw_ctrl_if_pools_cfg *cfg)
   1148{
   1149	struct dpsw_cmd_ctrl_if_set_pools *cmd_params;
   1150	struct fsl_mc_command cmd = { 0 };
   1151	int i;
   1152
   1153	cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_SET_POOLS,
   1154					  cmd_flags, token);
   1155	cmd_params = (struct dpsw_cmd_ctrl_if_set_pools *)cmd.params;
   1156	cmd_params->num_dpbp = cfg->num_dpbp;
   1157	for (i = 0; i < DPSW_MAX_DPBP; i++) {
   1158		cmd_params->dpbp_id[i] = cpu_to_le32(cfg->pools[i].dpbp_id);
   1159		cmd_params->buffer_size[i] =
   1160			cpu_to_le16(cfg->pools[i].buffer_size);
   1161		cmd_params->backup_pool_mask |=
   1162			DPSW_BACKUP_POOL(cfg->pools[i].backup_pool, i);
   1163	}
   1164
   1165	return mc_send_command(mc_io, &cmd);
   1166}
   1167
   1168/**
   1169 * dpsw_ctrl_if_set_queue() - Set Rx queue configuration
   1170 * @mc_io:	Pointer to MC portal's I/O object
   1171 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
   1172 * @token:	Token of dpsw object
   1173 * @qtype:	dpsw_queue_type of the targeted queue
   1174 * @cfg:	Rx queue configuration
   1175 *
   1176 * Return:	'0' on Success; Error code otherwise.
   1177 */
   1178int dpsw_ctrl_if_set_queue(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
   1179			   enum dpsw_queue_type qtype,
   1180			   const struct dpsw_ctrl_if_queue_cfg *cfg)
   1181{
   1182	struct dpsw_cmd_ctrl_if_set_queue *cmd_params;
   1183	struct fsl_mc_command cmd = { 0 };
   1184
   1185	cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_SET_QUEUE,
   1186					  cmd_flags,
   1187					  token);
   1188	cmd_params = (struct dpsw_cmd_ctrl_if_set_queue *)cmd.params;
   1189	cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id);
   1190	cmd_params->dest_priority = cfg->dest_cfg.priority;
   1191	cmd_params->qtype = qtype;
   1192	cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx);
   1193	cmd_params->options = cpu_to_le32(cfg->options);
   1194	dpsw_set_field(cmd_params->dest_type,
   1195		       DEST_TYPE,
   1196		       cfg->dest_cfg.dest_type);
   1197
   1198	return mc_send_command(mc_io, &cmd);
   1199}
   1200
   1201/**
   1202 * dpsw_get_api_version() - Get Data Path Switch API version
   1203 * @mc_io:	Pointer to MC portal's I/O object
   1204 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
   1205 * @major_ver:	Major version of data path switch API
   1206 * @minor_ver:	Minor version of data path switch API
   1207 *
   1208 * Return:  '0' on Success; Error code otherwise.
   1209 */
   1210int dpsw_get_api_version(struct fsl_mc_io *mc_io, u32 cmd_flags,
   1211			 u16 *major_ver, u16 *minor_ver)
   1212{
   1213	struct fsl_mc_command cmd = { 0 };
   1214	struct dpsw_rsp_get_api_version *rsp_params;
   1215	int err;
   1216
   1217	cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_API_VERSION,
   1218					  cmd_flags,
   1219					  0);
   1220
   1221	err = mc_send_command(mc_io, &cmd);
   1222	if (err)
   1223		return err;
   1224
   1225	rsp_params = (struct dpsw_rsp_get_api_version *)cmd.params;
   1226	*major_ver = le16_to_cpu(rsp_params->version_major);
   1227	*minor_ver = le16_to_cpu(rsp_params->version_minor);
   1228
   1229	return 0;
   1230}
   1231
   1232/**
   1233 * dpsw_if_get_port_mac_addr() - Retrieve MAC address associated to the physical port
   1234 * @mc_io:	Pointer to MC portal's I/O object
   1235 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
   1236 * @token:	Token of DPSW object
   1237 * @if_id:	Interface Identifier
   1238 * @mac_addr:	MAC address of the physical port, if any, otherwise 0
   1239 *
   1240 * Return:	Completion status. '0' on Success; Error code otherwise.
   1241 */
   1242int dpsw_if_get_port_mac_addr(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
   1243			      u16 if_id, u8 mac_addr[6])
   1244{
   1245	struct dpsw_rsp_if_get_mac_addr *rsp_params;
   1246	struct fsl_mc_command cmd = { 0 };
   1247	struct dpsw_cmd_if *cmd_params;
   1248	int err, i;
   1249
   1250	/* prepare command */
   1251	cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_PORT_MAC_ADDR,
   1252					  cmd_flags,
   1253					  token);
   1254	cmd_params = (struct dpsw_cmd_if *)cmd.params;
   1255	cmd_params->if_id = cpu_to_le16(if_id);
   1256
   1257	/* send command to mc*/
   1258	err = mc_send_command(mc_io, &cmd);
   1259	if (err)
   1260		return err;
   1261
   1262	/* retrieve response parameters */
   1263	rsp_params = (struct dpsw_rsp_if_get_mac_addr *)cmd.params;
   1264	for (i = 0; i < 6; i++)
   1265		mac_addr[5 - i] = rsp_params->mac_addr[i];
   1266
   1267	return 0;
   1268}
   1269
   1270/**
   1271 * dpsw_ctrl_if_enable() - Enable control interface
   1272 * @mc_io:	Pointer to MC portal's I/O object
   1273 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
   1274 * @token:	Token of DPSW object
   1275 *
   1276 * Return:	'0' on Success; Error code otherwise.
   1277 */
   1278int dpsw_ctrl_if_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)
   1279{
   1280	struct fsl_mc_command cmd = { 0 };
   1281
   1282	cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_ENABLE, cmd_flags,
   1283					  token);
   1284
   1285	return mc_send_command(mc_io, &cmd);
   1286}
   1287
   1288/**
   1289 * dpsw_ctrl_if_disable() - Function disables control interface
   1290 * @mc_io:	Pointer to MC portal's I/O object
   1291 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
   1292 * @token:	Token of DPSW object
   1293 *
   1294 * Return:	'0' on Success; Error code otherwise.
   1295 */
   1296int dpsw_ctrl_if_disable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)
   1297{
   1298	struct fsl_mc_command cmd = { 0 };
   1299
   1300	cmd.header = mc_encode_cmd_header(DPSW_CMDID_CTRL_IF_DISABLE,
   1301					  cmd_flags,
   1302					  token);
   1303
   1304	return mc_send_command(mc_io, &cmd);
   1305}
   1306
   1307/**
   1308 * dpsw_set_egress_flood() - Set egress parameters associated with an FDB ID
   1309 * @mc_io:	Pointer to MC portal's I/O object
   1310 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
   1311 * @token:	Token of DPSW object
   1312 * @cfg:	Egress flooding configuration
   1313 *
   1314 * Return:	'0' on Success; Error code otherwise.
   1315 */
   1316int dpsw_set_egress_flood(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
   1317			  const struct dpsw_egress_flood_cfg *cfg)
   1318{
   1319	struct dpsw_cmd_set_egress_flood *cmd_params;
   1320	struct fsl_mc_command cmd = { 0 };
   1321
   1322	cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_EGRESS_FLOOD, cmd_flags, token);
   1323	cmd_params = (struct dpsw_cmd_set_egress_flood *)cmd.params;
   1324	cmd_params->fdb_id = cpu_to_le16(cfg->fdb_id);
   1325	cmd_params->flood_type = cfg->flood_type;
   1326	build_if_id_bitmap(&cmd_params->if_id, cfg->if_id, cfg->num_ifs);
   1327
   1328	return mc_send_command(mc_io, &cmd);
   1329}
   1330
   1331/**
   1332 * dpsw_if_set_learning_mode() - Configure the learning mode on an interface.
   1333 * If this API is used, it will take precedence over the FDB configuration.
   1334 * @mc_io:	Pointer to MC portal's I/O object
   1335 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
   1336 * @token:	Token of DPSW object
   1337 * @if_id:	InterfaceID
   1338 * @mode:	Learning mode
   1339 *
   1340 * Return:	Completion status. '0' on Success; Error code otherwise.
   1341 */
   1342int dpsw_if_set_learning_mode(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
   1343			      u16 if_id, enum dpsw_learning_mode mode)
   1344{
   1345	struct dpsw_cmd_if_set_learning_mode *cmd_params;
   1346	struct fsl_mc_command cmd = { 0 };
   1347
   1348	cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_LEARNING_MODE,
   1349					  cmd_flags,
   1350					  token);
   1351	cmd_params = (struct dpsw_cmd_if_set_learning_mode *)cmd.params;
   1352	cmd_params->if_id = cpu_to_le16(if_id);
   1353	dpsw_set_field(cmd_params->mode, LEARNING_MODE, mode);
   1354
   1355	return mc_send_command(mc_io, &cmd);
   1356}
   1357
   1358/**
   1359 * dpsw_acl_add() - Create an ACL table
   1360 * @mc_io:	Pointer to MC portal's I/O object
   1361 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
   1362 * @token:	Token of DPSW object
   1363 * @acl_id:	Returned ACL ID, for future references
   1364 * @cfg:	ACL configuration
   1365 *
   1366 * Create Access Control List table. Multiple ACLs can be created and
   1367 * co-exist in L2 switch
   1368 *
   1369 * Return:	'0' on Success; Error code otherwise.
   1370 */
   1371int dpsw_acl_add(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 *acl_id,
   1372		 const struct dpsw_acl_cfg *cfg)
   1373{
   1374	struct dpsw_cmd_acl_add *cmd_params;
   1375	struct dpsw_rsp_acl_add *rsp_params;
   1376	struct fsl_mc_command cmd = { 0 };
   1377	int err;
   1378
   1379	cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_ADD, cmd_flags, token);
   1380	cmd_params = (struct dpsw_cmd_acl_add *)cmd.params;
   1381	cmd_params->max_entries = cpu_to_le16(cfg->max_entries);
   1382
   1383	err = mc_send_command(mc_io, &cmd);
   1384	if (err)
   1385		return err;
   1386
   1387	rsp_params = (struct dpsw_rsp_acl_add *)cmd.params;
   1388	*acl_id = le16_to_cpu(rsp_params->acl_id);
   1389
   1390	return 0;
   1391}
   1392
   1393/**
   1394 * dpsw_acl_remove() - Remove an ACL table from L2 switch.
   1395 * @mc_io:	Pointer to MC portal's I/O object
   1396 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
   1397 * @token:	Token of DPSW object
   1398 * @acl_id:	ACL ID
   1399 *
   1400 * Return:	'0' on Success; Error code otherwise.
   1401 */
   1402int dpsw_acl_remove(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
   1403		    u16 acl_id)
   1404{
   1405	struct dpsw_cmd_acl_remove *cmd_params;
   1406	struct fsl_mc_command cmd = { 0 };
   1407
   1408	cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_REMOVE, cmd_flags,
   1409					  token);
   1410	cmd_params = (struct dpsw_cmd_acl_remove *)cmd.params;
   1411	cmd_params->acl_id = cpu_to_le16(acl_id);
   1412
   1413	return mc_send_command(mc_io, &cmd);
   1414}
   1415
   1416/**
   1417 * dpsw_acl_add_if() - Associate interface/interfaces with an ACL table.
   1418 * @mc_io:	Pointer to MC portal's I/O object
   1419 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
   1420 * @token:	Token of DPSW object
   1421 * @acl_id:	ACL ID
   1422 * @cfg:	Interfaces list
   1423 *
   1424 * Return:	'0' on Success; Error code otherwise.
   1425 */
   1426int dpsw_acl_add_if(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
   1427		    u16 acl_id, const struct dpsw_acl_if_cfg *cfg)
   1428{
   1429	struct dpsw_cmd_acl_if *cmd_params;
   1430	struct fsl_mc_command cmd = { 0 };
   1431
   1432	cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_ADD_IF, cmd_flags,
   1433					  token);
   1434	cmd_params = (struct dpsw_cmd_acl_if *)cmd.params;
   1435	cmd_params->acl_id = cpu_to_le16(acl_id);
   1436	cmd_params->num_ifs = cpu_to_le16(cfg->num_ifs);
   1437	build_if_id_bitmap(&cmd_params->if_id, cfg->if_id, cfg->num_ifs);
   1438
   1439	return mc_send_command(mc_io, &cmd);
   1440}
   1441
   1442/**
   1443 * dpsw_acl_remove_if() - De-associate interface/interfaces from an ACL table
   1444 * @mc_io:	Pointer to MC portal's I/O object
   1445 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
   1446 * @token:	Token of DPSW object
   1447 * @acl_id:	ACL ID
   1448 * @cfg:	Interfaces list
   1449 *
   1450 * Return:	'0' on Success; Error code otherwise.
   1451 */
   1452int dpsw_acl_remove_if(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
   1453		       u16 acl_id, const struct dpsw_acl_if_cfg *cfg)
   1454{
   1455	struct dpsw_cmd_acl_if *cmd_params;
   1456	struct fsl_mc_command cmd = { 0 };
   1457
   1458	/* prepare command */
   1459	cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_REMOVE_IF, cmd_flags,
   1460					  token);
   1461	cmd_params = (struct dpsw_cmd_acl_if *)cmd.params;
   1462	cmd_params->acl_id = cpu_to_le16(acl_id);
   1463	cmd_params->num_ifs = cpu_to_le16(cfg->num_ifs);
   1464	build_if_id_bitmap(&cmd_params->if_id, cfg->if_id, cfg->num_ifs);
   1465
   1466	/* send command to mc*/
   1467	return mc_send_command(mc_io, &cmd);
   1468}
   1469
   1470/**
   1471 * dpsw_acl_prepare_entry_cfg() - Setup an ACL entry
   1472 * @key:		Key
   1473 * @entry_cfg_buf:	Zeroed 256 bytes of memory before mapping it to DMA
   1474 *
   1475 * This function has to be called before adding or removing acl_entry
   1476 *
   1477 */
   1478void dpsw_acl_prepare_entry_cfg(const struct dpsw_acl_key *key,
   1479				u8 *entry_cfg_buf)
   1480{
   1481	struct dpsw_prep_acl_entry *ext_params;
   1482	int i;
   1483
   1484	ext_params = (struct dpsw_prep_acl_entry *)entry_cfg_buf;
   1485
   1486	for (i = 0; i < 6; i++) {
   1487		ext_params->match_l2_dest_mac[i] = key->match.l2_dest_mac[5 - i];
   1488		ext_params->match_l2_source_mac[i] = key->match.l2_source_mac[5 - i];
   1489		ext_params->mask_l2_dest_mac[i] = key->mask.l2_dest_mac[5 - i];
   1490		ext_params->mask_l2_source_mac[i] = key->mask.l2_source_mac[5 - i];
   1491	}
   1492
   1493	ext_params->match_l2_tpid = cpu_to_le16(key->match.l2_tpid);
   1494	ext_params->match_l2_vlan_id = cpu_to_le16(key->match.l2_vlan_id);
   1495	ext_params->match_l3_dest_ip = cpu_to_le32(key->match.l3_dest_ip);
   1496	ext_params->match_l3_source_ip = cpu_to_le32(key->match.l3_source_ip);
   1497	ext_params->match_l4_dest_port = cpu_to_le16(key->match.l4_dest_port);
   1498	ext_params->match_l4_source_port = cpu_to_le16(key->match.l4_source_port);
   1499	ext_params->match_l2_ether_type = cpu_to_le16(key->match.l2_ether_type);
   1500	ext_params->match_l2_pcp_dei = key->match.l2_pcp_dei;
   1501	ext_params->match_l3_dscp = key->match.l3_dscp;
   1502
   1503	ext_params->mask_l2_tpid = cpu_to_le16(key->mask.l2_tpid);
   1504	ext_params->mask_l2_vlan_id = cpu_to_le16(key->mask.l2_vlan_id);
   1505	ext_params->mask_l3_dest_ip = cpu_to_le32(key->mask.l3_dest_ip);
   1506	ext_params->mask_l3_source_ip = cpu_to_le32(key->mask.l3_source_ip);
   1507	ext_params->mask_l4_dest_port = cpu_to_le16(key->mask.l4_dest_port);
   1508	ext_params->mask_l4_source_port = cpu_to_le16(key->mask.l4_source_port);
   1509	ext_params->mask_l2_ether_type = cpu_to_le16(key->mask.l2_ether_type);
   1510	ext_params->mask_l2_pcp_dei = key->mask.l2_pcp_dei;
   1511	ext_params->mask_l3_dscp = key->mask.l3_dscp;
   1512	ext_params->match_l3_protocol = key->match.l3_protocol;
   1513	ext_params->mask_l3_protocol = key->mask.l3_protocol;
   1514}
   1515
   1516/**
   1517 * dpsw_acl_add_entry() - Add a rule to the ACL table.
   1518 * @mc_io:	Pointer to MC portal's I/O object
   1519 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
   1520 * @token:	Token of DPSW object
   1521 * @acl_id:	ACL ID
   1522 * @cfg:	Entry configuration
   1523 *
   1524 * warning: This function has to be called after dpsw_acl_prepare_entry_cfg()
   1525 *
   1526 * Return:	'0' on Success; Error code otherwise.
   1527 */
   1528int dpsw_acl_add_entry(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
   1529		       u16 acl_id, const struct dpsw_acl_entry_cfg *cfg)
   1530{
   1531	struct dpsw_cmd_acl_entry *cmd_params;
   1532	struct fsl_mc_command cmd = { 0 };
   1533
   1534	cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_ADD_ENTRY, cmd_flags,
   1535					  token);
   1536	cmd_params = (struct dpsw_cmd_acl_entry *)cmd.params;
   1537	cmd_params->acl_id = cpu_to_le16(acl_id);
   1538	cmd_params->result_if_id = cpu_to_le16(cfg->result.if_id);
   1539	cmd_params->precedence = cpu_to_le32(cfg->precedence);
   1540	cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
   1541	dpsw_set_field(cmd_params->result_action,
   1542		       RESULT_ACTION,
   1543		       cfg->result.action);
   1544
   1545	return mc_send_command(mc_io, &cmd);
   1546}
   1547
   1548/**
   1549 * dpsw_acl_remove_entry() - Removes an entry from ACL.
   1550 * @mc_io:	Pointer to MC portal's I/O object
   1551 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
   1552 * @token:	Token of DPSW object
   1553 * @acl_id:	ACL ID
   1554 * @cfg:	Entry configuration
   1555 *
   1556 * warning: This function has to be called after dpsw_acl_set_entry_cfg()
   1557 *
   1558 * Return:	'0' on Success; Error code otherwise.
   1559 */
   1560int dpsw_acl_remove_entry(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
   1561			  u16 acl_id, const struct dpsw_acl_entry_cfg *cfg)
   1562{
   1563	struct dpsw_cmd_acl_entry *cmd_params;
   1564	struct fsl_mc_command cmd = { 0 };
   1565
   1566	/* prepare command */
   1567	cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_REMOVE_ENTRY,
   1568					  cmd_flags,
   1569					  token);
   1570	cmd_params = (struct dpsw_cmd_acl_entry *)cmd.params;
   1571	cmd_params->acl_id = cpu_to_le16(acl_id);
   1572	cmd_params->result_if_id = cpu_to_le16(cfg->result.if_id);
   1573	cmd_params->precedence = cpu_to_le32(cfg->precedence);
   1574	cmd_params->key_iova = cpu_to_le64(cfg->key_iova);
   1575	dpsw_set_field(cmd_params->result_action,
   1576		       RESULT_ACTION,
   1577		       cfg->result.action);
   1578
   1579	/* send command to mc*/
   1580	return mc_send_command(mc_io, &cmd);
   1581}
   1582
   1583/**
   1584 * dpsw_set_reflection_if() - Set target interface for traffic mirrored
   1585 * @mc_io:	Pointer to MC portal's I/O object
   1586 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
   1587 * @token:	Token of DPSW object
   1588 * @if_id:	Interface Id
   1589 *
   1590 * Only one mirroring destination is allowed per switch
   1591 *
   1592 * Return:	Completion status. '0' on Success; Error code otherwise.
   1593 */
   1594int dpsw_set_reflection_if(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
   1595			   u16 if_id)
   1596{
   1597	struct dpsw_cmd_set_reflection_if *cmd_params;
   1598	struct fsl_mc_command cmd = { 0 };
   1599
   1600	cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_REFLECTION_IF,
   1601					  cmd_flags,
   1602					  token);
   1603	cmd_params = (struct dpsw_cmd_set_reflection_if *)cmd.params;
   1604	cmd_params->if_id = cpu_to_le16(if_id);
   1605
   1606	return mc_send_command(mc_io, &cmd);
   1607}
   1608
   1609/**
   1610 * dpsw_if_add_reflection() - Setup mirroring rule
   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 DPSW object
   1614 * @if_id:	Interface Identifier
   1615 * @cfg:	Reflection configuration
   1616 *
   1617 * Return:	Completion status. '0' on Success; Error code otherwise.
   1618 */
   1619int dpsw_if_add_reflection(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
   1620			   u16 if_id, const struct dpsw_reflection_cfg *cfg)
   1621{
   1622	struct dpsw_cmd_if_reflection *cmd_params;
   1623	struct fsl_mc_command cmd = { 0 };
   1624
   1625	cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_ADD_REFLECTION,
   1626					  cmd_flags,
   1627					  token);
   1628	cmd_params = (struct dpsw_cmd_if_reflection *)cmd.params;
   1629	cmd_params->if_id = cpu_to_le16(if_id);
   1630	cmd_params->vlan_id = cpu_to_le16(cfg->vlan_id);
   1631	dpsw_set_field(cmd_params->filter, FILTER, cfg->filter);
   1632
   1633	return mc_send_command(mc_io, &cmd);
   1634}
   1635
   1636/**
   1637 * dpsw_if_remove_reflection() - Remove mirroring rule
   1638 * @mc_io:	Pointer to MC portal's I/O object
   1639 * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
   1640 * @token:	Token of DPSW object
   1641 * @if_id:	Interface Identifier
   1642 * @cfg:	Reflection configuration
   1643 *
   1644 * Return:	Completion status. '0' on Success; Error code otherwise.
   1645 */
   1646int dpsw_if_remove_reflection(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
   1647			      u16 if_id, const struct dpsw_reflection_cfg *cfg)
   1648{
   1649	struct dpsw_cmd_if_reflection *cmd_params;
   1650	struct fsl_mc_command cmd = { 0 };
   1651
   1652	cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_REMOVE_REFLECTION,
   1653					  cmd_flags,
   1654					  token);
   1655	cmd_params = (struct dpsw_cmd_if_reflection *)cmd.params;
   1656	cmd_params->if_id = cpu_to_le16(if_id);
   1657	cmd_params->vlan_id = cpu_to_le16(cfg->vlan_id);
   1658	dpsw_set_field(cmd_params->filter, FILTER, cfg->filter);
   1659
   1660	return mc_send_command(mc_io, &cmd);
   1661}