Commit 0006351f authored by Razvan Stefanescu's avatar Razvan Stefanescu Committed by Greg Kroah-Hartman

staging: fsl-dpaa2/ethsw: Add APIs for DPSW object

Add the command build/parse APIs for operating on DPSW objects through
the DPAA2 Management Complex.
Signed-off-by: default avatarRazvan Stefanescu <razvan.stefanescu@nxp.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 70ae9cf0
......@@ -16,3 +16,11 @@ config FSL_DPAA2_ETH
---help---
Ethernet driver for Freescale DPAA2 SoCs, using the
Freescale MC bus driver
config FSL_DPAA2_ETHSW
tristate "Freescale DPAA2 Ethernet Switch"
depends on FSL_DPAA2
depends on NET_SWITCHDEV
---help---
Driver for Freescale DPAA2 Ethernet Switch. Select
BRIDGE to have support for bridge tools.
......@@ -3,3 +3,4 @@
#
obj-$(CONFIG_FSL_DPAA2_ETH) += ethernet/
obj-$(CONFIG_FSL_DPAA2_ETHSW) += ethsw/
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the Freescale DPAA2 Ethernet Switch
#
# Copyright 2014-2017 Freescale Semiconductor Inc.
# Copyright 2017-2018 NXP
obj-$(CONFIG_FSL_DPAA2_ETHSW) += dpaa2-ethsw.o
dpaa2-ethsw-objs := dpsw.o
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2014-2016 Freescale Semiconductor Inc.
* Copyright 2017-2018 NXP
*
*/
#ifndef __FSL_DPSW_CMD_H
#define __FSL_DPSW_CMD_H
/* DPSW Version */
#define DPSW_VER_MAJOR 8
#define DPSW_VER_MINOR 0
#define DPSW_CMD_BASE_VERSION 1
#define DPSW_CMD_ID_OFFSET 4
#define DPSW_CMD_ID(id) (((id) << DPSW_CMD_ID_OFFSET) | DPSW_CMD_BASE_VERSION)
/* Command IDs */
#define DPSW_CMDID_CLOSE DPSW_CMD_ID(0x800)
#define DPSW_CMDID_OPEN DPSW_CMD_ID(0x802)
#define DPSW_CMDID_GET_API_VERSION DPSW_CMD_ID(0xa02)
#define DPSW_CMDID_ENABLE DPSW_CMD_ID(0x002)
#define DPSW_CMDID_DISABLE DPSW_CMD_ID(0x003)
#define DPSW_CMDID_GET_ATTR DPSW_CMD_ID(0x004)
#define DPSW_CMDID_RESET DPSW_CMD_ID(0x005)
#define DPSW_CMDID_SET_IRQ_ENABLE DPSW_CMD_ID(0x012)
#define DPSW_CMDID_SET_IRQ_MASK DPSW_CMD_ID(0x014)
#define DPSW_CMDID_GET_IRQ_STATUS DPSW_CMD_ID(0x016)
#define DPSW_CMDID_CLEAR_IRQ_STATUS DPSW_CMD_ID(0x017)
#define DPSW_CMDID_IF_SET_TCI DPSW_CMD_ID(0x030)
#define DPSW_CMDID_IF_SET_STP DPSW_CMD_ID(0x031)
#define DPSW_CMDID_IF_GET_COUNTER DPSW_CMD_ID(0x034)
#define DPSW_CMDID_IF_ENABLE DPSW_CMD_ID(0x03D)
#define DPSW_CMDID_IF_DISABLE DPSW_CMD_ID(0x03E)
#define DPSW_CMDID_IF_SET_MAX_FRAME_LENGTH DPSW_CMD_ID(0x044)
#define DPSW_CMDID_IF_GET_LINK_STATE DPSW_CMD_ID(0x046)
#define DPSW_CMDID_IF_SET_FLOODING DPSW_CMD_ID(0x047)
#define DPSW_CMDID_IF_SET_BROADCAST DPSW_CMD_ID(0x048)
#define DPSW_CMDID_VLAN_ADD DPSW_CMD_ID(0x060)
#define DPSW_CMDID_VLAN_ADD_IF DPSW_CMD_ID(0x061)
#define DPSW_CMDID_VLAN_ADD_IF_UNTAGGED DPSW_CMD_ID(0x062)
#define DPSW_CMDID_VLAN_REMOVE_IF DPSW_CMD_ID(0x064)
#define DPSW_CMDID_VLAN_REMOVE_IF_UNTAGGED DPSW_CMD_ID(0x065)
#define DPSW_CMDID_VLAN_REMOVE_IF_FLOODING DPSW_CMD_ID(0x066)
#define DPSW_CMDID_VLAN_REMOVE DPSW_CMD_ID(0x067)
#define DPSW_CMDID_FDB_ADD_UNICAST DPSW_CMD_ID(0x084)
#define DPSW_CMDID_FDB_REMOVE_UNICAST DPSW_CMD_ID(0x085)
#define DPSW_CMDID_FDB_ADD_MULTICAST DPSW_CMD_ID(0x086)
#define DPSW_CMDID_FDB_REMOVE_MULTICAST DPSW_CMD_ID(0x087)
#define DPSW_CMDID_FDB_SET_LEARNING_MODE DPSW_CMD_ID(0x088)
/* Macros for accessing command fields smaller than 1byte */
#define DPSW_MASK(field) \
GENMASK(DPSW_##field##_SHIFT + DPSW_##field##_SIZE - 1, \
DPSW_##field##_SHIFT)
#define dpsw_set_field(var, field, val) \
((var) |= (((val) << DPSW_##field##_SHIFT) & DPSW_MASK(field)))
#define dpsw_get_field(var, field) \
(((var) & DPSW_MASK(field)) >> DPSW_##field##_SHIFT)
#define dpsw_get_bit(var, bit) \
(((var) >> (bit)) & GENMASK(0, 0))
struct dpsw_cmd_open {
__le32 dpsw_id;
};
#define DPSW_COMPONENT_TYPE_SHIFT 0
#define DPSW_COMPONENT_TYPE_SIZE 4
struct dpsw_cmd_create {
/* cmd word 0 */
__le16 num_ifs;
u8 max_fdbs;
u8 max_meters_per_if;
/* from LSB: only the first 4 bits */
u8 component_type;
u8 pad[3];
/* cmd word 1 */
__le16 max_vlans;
__le16 max_fdb_entries;
__le16 fdb_aging_time;
__le16 max_fdb_mc_groups;
/* cmd word 2 */
__le64 options;
};
struct dpsw_cmd_destroy {
__le32 dpsw_id;
};
#define DPSW_ENABLE_SHIFT 0
#define DPSW_ENABLE_SIZE 1
struct dpsw_rsp_is_enabled {
/* from LSB: enable:1 */
u8 enabled;
};
struct dpsw_cmd_set_irq_enable {
u8 enable_state;
u8 pad[3];
u8 irq_index;
};
struct dpsw_cmd_get_irq_enable {
__le32 pad;
u8 irq_index;
};
struct dpsw_rsp_get_irq_enable {
u8 enable_state;
};
struct dpsw_cmd_set_irq_mask {
__le32 mask;
u8 irq_index;
};
struct dpsw_cmd_get_irq_mask {
__le32 pad;
u8 irq_index;
};
struct dpsw_rsp_get_irq_mask {
__le32 mask;
};
struct dpsw_cmd_get_irq_status {
__le32 status;
u8 irq_index;
};
struct dpsw_rsp_get_irq_status {
__le32 status;
};
struct dpsw_cmd_clear_irq_status {
__le32 status;
u8 irq_index;
};
#define DPSW_COMPONENT_TYPE_SHIFT 0
#define DPSW_COMPONENT_TYPE_SIZE 4
struct dpsw_rsp_get_attr {
/* cmd word 0 */
__le16 num_ifs;
u8 max_fdbs;
u8 num_fdbs;
__le16 max_vlans;
__le16 num_vlans;
/* cmd word 1 */
__le16 max_fdb_entries;
__le16 fdb_aging_time;
__le32 dpsw_id;
/* cmd word 2 */
__le16 mem_size;
__le16 max_fdb_mc_groups;
u8 max_meters_per_if;
/* from LSB only the first 4 bits */
u8 component_type;
__le16 pad;
/* cmd word 3 */
__le64 options;
};
struct dpsw_cmd_if_set_flooding {
__le16 if_id;
/* from LSB: enable:1 */
u8 enable;
};
struct dpsw_cmd_if_set_broadcast {
__le16 if_id;
/* from LSB: enable:1 */
u8 enable;
};
#define DPSW_VLAN_ID_SHIFT 0
#define DPSW_VLAN_ID_SIZE 12
#define DPSW_DEI_SHIFT 12
#define DPSW_DEI_SIZE 1
#define DPSW_PCP_SHIFT 13
#define DPSW_PCP_SIZE 3
struct dpsw_cmd_if_set_tci {
__le16 if_id;
/* from LSB: VLAN_ID:12 DEI:1 PCP:3 */
__le16 conf;
};
#define DPSW_STATE_SHIFT 0
#define DPSW_STATE_SIZE 4
struct dpsw_cmd_if_set_stp {
__le16 if_id;
__le16 vlan_id;
/* only the first LSB 4 bits */
u8 state;
};
#define DPSW_COUNTER_TYPE_SHIFT 0
#define DPSW_COUNTER_TYPE_SIZE 5
struct dpsw_cmd_if_get_counter {
__le16 if_id;
/* from LSB: type:5 */
u8 type;
};
struct dpsw_rsp_if_get_counter {
__le64 pad;
__le64 counter;
};
struct dpsw_cmd_if {
__le16 if_id;
};
struct dpsw_cmd_if_set_max_frame_length {
__le16 if_id;
__le16 frame_length;
};
struct dpsw_cmd_if_get_link_state {
__le16 if_id;
};
#define DPSW_UP_SHIFT 0
#define DPSW_UP_SIZE 1
struct dpsw_rsp_if_get_link_state {
/* cmd word 0 */
__le32 pad0;
u8 up;
u8 pad1[3];
/* cmd word 1 */
__le32 rate;
__le32 pad2;
/* cmd word 2 */
__le64 options;
};
struct dpsw_vlan_add {
__le16 fdb_id;
__le16 vlan_id;
};
struct dpsw_cmd_vlan_manage_if {
/* cmd word 0 */
__le16 pad0;
__le16 vlan_id;
__le32 pad1;
/* cmd word 1-4 */
__le64 if_id[4];
};
struct dpsw_cmd_vlan_remove {
__le16 pad;
__le16 vlan_id;
};
struct dpsw_cmd_fdb_add {
__le32 pad;
__le16 fdb_aging_time;
__le16 num_fdb_entries;
};
struct dpsw_rsp_fdb_add {
__le16 fdb_id;
};
struct dpsw_cmd_fdb_remove {
__le16 fdb_id;
};
#define DPSW_ENTRY_TYPE_SHIFT 0
#define DPSW_ENTRY_TYPE_SIZE 4
struct dpsw_cmd_fdb_unicast_op {
/* cmd word 0 */
__le16 fdb_id;
u8 mac_addr[6];
/* cmd word 1 */
__le16 if_egress;
/* only the first 4 bits from LSB */
u8 type;
};
struct dpsw_cmd_fdb_multicast_op {
/* cmd word 0 */
__le16 fdb_id;
__le16 num_ifs;
/* only the first 4 bits from LSB */
u8 type;
u8 pad[3];
/* cmd word 1 */
u8 mac_addr[6];
__le16 pad2;
/* cmd word 2-5 */
__le64 if_id[4];
};
#define DPSW_LEARNING_MODE_SHIFT 0
#define DPSW_LEARNING_MODE_SIZE 4
struct dpsw_cmd_fdb_set_learning_mode {
__le16 fdb_id;
/* only the first 4 bits from LSB */
u8 mode;
};
struct dpsw_rsp_get_api_version {
__le16 version_major;
__le16 version_minor;
};
#endif /* __FSL_DPSW_CMD_H */
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2014-2016 Freescale Semiconductor Inc.
* Copyright 2017-2018 NXP
*
*/
#include <linux/fsl/mc.h>
#include "dpsw.h"
#include "dpsw-cmd.h"
static void build_if_id_bitmap(__le64 *bmap,
const u16 *id,
const u16 num_ifs)
{
int i;
for (i = 0; (i < num_ifs) && (i < DPSW_MAX_IF); i++) {
if (id[i] < DPSW_MAX_IF)
bmap[id[i] / 64] |= cpu_to_le64(BIT_MASK(id[i] % 64));
}
}
/**
* dpsw_open() - Open a control session for the specified object
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @dpsw_id: DPSW unique ID
* @token: Returned token; use in subsequent API calls
*
* This function can be used to open a control session for an
* already created object; an object may have been declared in
* the DPL or by calling the dpsw_create() function.
* This function returns a unique authentication token,
* associated with the specific object ID and the specific MC
* portal; this token must be used in all subsequent commands for
* this specific object
*
* Return: '0' on Success; Error code otherwise.
*/
int dpsw_open(struct fsl_mc_io *mc_io,
u32 cmd_flags,
int dpsw_id,
u16 *token)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_open *cmd_params;
int err;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_OPEN,
cmd_flags,
0);
cmd_params = (struct dpsw_cmd_open *)cmd.params;
cmd_params->dpsw_id = cpu_to_le32(dpsw_id);
/* send command to mc*/
err = mc_send_command(mc_io, &cmd);
if (err)
return err;
/* retrieve response parameters */
*token = mc_cmd_hdr_read_token(&cmd);
return 0;
}
/**
* dpsw_close() - Close the control session of the object
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
*
* After this function is called, no further operations are
* allowed on the object without opening a new control session.
*
* Return: '0' on Success; Error code otherwise.
*/
int dpsw_close(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token)
{
struct mc_command cmd = { 0 };
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_CLOSE,
cmd_flags,
token);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_enable() - Enable DPSW functionality
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_enable(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token)
{
struct mc_command cmd = { 0 };
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_ENABLE,
cmd_flags,
token);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_disable() - Disable DPSW functionality
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_disable(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token)
{
struct mc_command cmd = { 0 };
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_DISABLE,
cmd_flags,
token);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_reset() - Reset the DPSW, returns the object to initial state.
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
*
* Return: '0' on Success; Error code otherwise.
*/
int dpsw_reset(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token)
{
struct mc_command cmd = { 0 };
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_RESET,
cmd_flags,
token);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_set_irq_enable() - Set overall interrupt state.
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPCI object
* @irq_index: The interrupt index to configure
* @en: Interrupt state - enable = 1, disable = 0
*
* Allows GPP software to control when interrupts are generated.
* Each interrupt can have up to 32 causes. The enable/disable control's the
* overall interrupt state. if the interrupt is disabled no causes will cause
* an interrupt
*
* Return: '0' on Success; Error code otherwise.
*/
int dpsw_set_irq_enable(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u8 irq_index,
u8 en)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_set_irq_enable *cmd_params;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_IRQ_ENABLE,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_set_irq_enable *)cmd.params;
dpsw_set_field(cmd_params->enable_state, ENABLE, en);
cmd_params->irq_index = irq_index;
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_set_irq_mask() - Set interrupt mask.
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPCI object
* @irq_index: The interrupt index to configure
* @mask: Event mask to trigger interrupt;
* each bit:
* 0 = ignore event
* 1 = consider event for asserting IRQ
*
* Every interrupt can have up to 32 causes and the interrupt model supports
* masking/unmasking each cause independently
*
* Return: '0' on Success; Error code otherwise.
*/
int dpsw_set_irq_mask(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u8 irq_index,
u32 mask)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_set_irq_mask *cmd_params;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_SET_IRQ_MASK,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_set_irq_mask *)cmd.params;
cmd_params->mask = cpu_to_le32(mask);
cmd_params->irq_index = irq_index;
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_get_irq_status() - Get the current status of any pending interrupts
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @irq_index: The interrupt index to configure
* @status: Returned interrupts status - one bit per cause:
* 0 = no interrupt pending
* 1 = interrupt pending
*
* Return: '0' on Success; Error code otherwise.
*/
int dpsw_get_irq_status(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u8 irq_index,
u32 *status)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_get_irq_status *cmd_params;
struct dpsw_rsp_get_irq_status *rsp_params;
int err;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_IRQ_STATUS,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_get_irq_status *)cmd.params;
cmd_params->status = cpu_to_le32(*status);
cmd_params->irq_index = irq_index;
/* send command to mc*/
err = mc_send_command(mc_io, &cmd);
if (err)
return err;
/* retrieve response parameters */
rsp_params = (struct dpsw_rsp_get_irq_status *)cmd.params;
*status = le32_to_cpu(rsp_params->status);
return 0;
}
/**
* dpsw_clear_irq_status() - Clear a pending interrupt's status
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPCI object
* @irq_index: The interrupt index to configure
* @status: bits to clear (W1C) - one bit per cause:
* 0 = don't change
* 1 = clear status bit
*
* Return: '0' on Success; Error code otherwise.
*/
int dpsw_clear_irq_status(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u8 irq_index,
u32 status)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_clear_irq_status *cmd_params;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_CLEAR_IRQ_STATUS,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_clear_irq_status *)cmd.params;
cmd_params->status = cpu_to_le32(status);
cmd_params->irq_index = irq_index;
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_get_attributes() - Retrieve DPSW attributes
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @attr: Returned DPSW attributes
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_get_attributes(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
struct dpsw_attr *attr)
{
struct mc_command cmd = { 0 };
struct dpsw_rsp_get_attr *rsp_params;
int err;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_ATTR,
cmd_flags,
token);
/* send command to mc*/
err = mc_send_command(mc_io, &cmd);
if (err)
return err;
/* retrieve response parameters */
rsp_params = (struct dpsw_rsp_get_attr *)cmd.params;
attr->num_ifs = le16_to_cpu(rsp_params->num_ifs);
attr->max_fdbs = rsp_params->max_fdbs;
attr->num_fdbs = rsp_params->num_fdbs;
attr->max_vlans = le16_to_cpu(rsp_params->max_vlans);
attr->num_vlans = le16_to_cpu(rsp_params->num_vlans);
attr->max_fdb_entries = le16_to_cpu(rsp_params->max_fdb_entries);
attr->fdb_aging_time = le16_to_cpu(rsp_params->fdb_aging_time);
attr->id = le32_to_cpu(rsp_params->dpsw_id);
attr->mem_size = le16_to_cpu(rsp_params->mem_size);
attr->max_fdb_mc_groups = le16_to_cpu(rsp_params->max_fdb_mc_groups);
attr->max_meters_per_if = rsp_params->max_meters_per_if;
attr->options = le64_to_cpu(rsp_params->options);
attr->component_type = dpsw_get_field(rsp_params->component_type,
COMPONENT_TYPE);
return 0;
}
/**
* dpsw_if_get_link_state - Return the link state
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @if_id: Interface id
* @state: Link state 1 - linkup, 0 - link down or disconnected
*
* @Return '0' on Success; Error code otherwise.
*/
int dpsw_if_get_link_state(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 if_id,
struct dpsw_link_state *state)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_if_get_link_state *cmd_params;
struct dpsw_rsp_if_get_link_state *rsp_params;
int err;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_LINK_STATE,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_if_get_link_state *)cmd.params;
cmd_params->if_id = cpu_to_le16(if_id);
/* send command to mc*/
err = mc_send_command(mc_io, &cmd);
if (err)
return err;
/* retrieve response parameters */
rsp_params = (struct dpsw_rsp_if_get_link_state *)cmd.params;
state->rate = le32_to_cpu(rsp_params->rate);
state->options = le64_to_cpu(rsp_params->options);
state->up = dpsw_get_field(rsp_params->up, UP);
return 0;
}
/**
* dpsw_if_set_flooding() - Enable Disable flooding for particular interface
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @if_id: Interface Identifier
* @en: 1 - enable, 0 - disable
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_if_set_flooding(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 if_id,
u8 en)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_if_set_flooding *cmd_params;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_FLOODING,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_if_set_flooding *)cmd.params;
cmd_params->if_id = cpu_to_le16(if_id);
dpsw_set_field(cmd_params->enable, ENABLE, en);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_if_set_broadcast() - Enable/disable broadcast for particular interface
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @if_id: Interface Identifier
* @en: 1 - enable, 0 - disable
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_if_set_broadcast(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 if_id,
u8 en)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_if_set_broadcast *cmd_params;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_BROADCAST,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_if_set_broadcast *)cmd.params;
cmd_params->if_id = cpu_to_le16(if_id);
dpsw_set_field(cmd_params->enable, ENABLE, en);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_if_set_tci() - Set default VLAN Tag Control Information (TCI)
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @if_id: Interface Identifier
* @cfg: Tag Control Information Configuration
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_if_set_tci(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 if_id,
const struct dpsw_tci_cfg *cfg)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_if_set_tci *cmd_params;
u16 tmp_conf = 0;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_TCI,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_if_set_tci *)cmd.params;
cmd_params->if_id = cpu_to_le16(if_id);
dpsw_set_field(tmp_conf, VLAN_ID, cfg->vlan_id);
dpsw_set_field(tmp_conf, DEI, cfg->dei);
dpsw_set_field(tmp_conf, PCP, cfg->pcp);
cmd_params->conf = cpu_to_le16(tmp_conf);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_if_set_stp() - Function sets Spanning Tree Protocol (STP) state.
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @if_id: Interface Identifier
* @cfg: STP State configuration parameters
*
* The following STP states are supported -
* blocking, listening, learning, forwarding and disabled.
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_if_set_stp(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 if_id,
const struct dpsw_stp_cfg *cfg)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_if_set_stp *cmd_params;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_STP,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_if_set_stp *)cmd.params;
cmd_params->if_id = cpu_to_le16(if_id);
cmd_params->vlan_id = cpu_to_le16(cfg->vlan_id);
dpsw_set_field(cmd_params->state, STATE, cfg->state);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_if_get_counter() - Get specific counter of particular interface
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @if_id: Interface Identifier
* @type: Counter type
* @counter: return value
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_if_get_counter(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 if_id,
enum dpsw_counter type,
u64 *counter)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_if_get_counter *cmd_params;
struct dpsw_rsp_if_get_counter *rsp_params;
int err;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_GET_COUNTER,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_if_get_counter *)cmd.params;
cmd_params->if_id = cpu_to_le16(if_id);
dpsw_set_field(cmd_params->type, COUNTER_TYPE, type);
/* send command to mc*/
err = mc_send_command(mc_io, &cmd);
if (err)
return err;
/* retrieve response parameters */
rsp_params = (struct dpsw_rsp_if_get_counter *)cmd.params;
*counter = le64_to_cpu(rsp_params->counter);
return 0;
}
/**
* dpsw_if_enable() - Enable Interface
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @if_id: Interface Identifier
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_if_enable(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 if_id)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_if *cmd_params;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_ENABLE,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_if *)cmd.params;
cmd_params->if_id = cpu_to_le16(if_id);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_if_disable() - Disable Interface
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @if_id: Interface Identifier
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_if_disable(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 if_id)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_if *cmd_params;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_DISABLE,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_if *)cmd.params;
cmd_params->if_id = cpu_to_le16(if_id);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_if_set_max_frame_length() - Set Maximum Receive frame length.
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @if_id: Interface Identifier
* @frame_length: Maximum Frame Length
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_if_set_max_frame_length(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 if_id,
u16 frame_length)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_if_set_max_frame_length *cmd_params;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_IF_SET_MAX_FRAME_LENGTH,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_if_set_max_frame_length *)cmd.params;
cmd_params->if_id = cpu_to_le16(if_id);
cmd_params->frame_length = cpu_to_le16(frame_length);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_vlan_add() - Adding new VLAN to DPSW.
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @vlan_id: VLAN Identifier
* @cfg: VLAN configuration
*
* Only VLAN ID and FDB ID are required parameters here.
* 12 bit VLAN ID is defined in IEEE802.1Q.
* Adding a duplicate VLAN ID is not allowed.
* FDB ID can be shared across multiple VLANs. Shared learning
* is obtained by calling dpsw_vlan_add for multiple VLAN IDs
* with same fdb_id
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_vlan_add(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 vlan_id,
const struct dpsw_vlan_cfg *cfg)
{
struct mc_command cmd = { 0 };
struct dpsw_vlan_add *cmd_params;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD,
cmd_flags,
token);
cmd_params = (struct dpsw_vlan_add *)cmd.params;
cmd_params->fdb_id = cpu_to_le16(cfg->fdb_id);
cmd_params->vlan_id = cpu_to_le16(vlan_id);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_vlan_add_if() - Adding a set of interfaces to an existing VLAN.
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @vlan_id: VLAN Identifier
* @cfg: Set of interfaces to add
*
* It adds only interfaces not belonging to this VLAN yet,
* otherwise an error is generated and an entire command is
* ignored. This function can be called numerous times always
* providing required interfaces delta.
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_vlan_add_if(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 vlan_id,
const struct dpsw_vlan_if_cfg *cfg)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_vlan_manage_if *cmd_params;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD_IF,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_vlan_manage_if *)cmd.params;
cmd_params->vlan_id = cpu_to_le16(vlan_id);
build_if_id_bitmap(cmd_params->if_id, cfg->if_id, cfg->num_ifs);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_vlan_add_if_untagged() - Defining a set of interfaces that should be
* transmitted as untagged.
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @vlan_id: VLAN Identifier
* @cfg: Set of interfaces that should be transmitted as untagged
*
* These interfaces should already belong to this VLAN.
* By default all interfaces are transmitted as tagged.
* Providing un-existing interface or untagged interface that is
* configured untagged already generates an error and the entire
* command is ignored.
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_vlan_add_if_untagged(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 vlan_id,
const struct dpsw_vlan_if_cfg *cfg)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_vlan_manage_if *cmd_params;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_ADD_IF_UNTAGGED,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_vlan_manage_if *)cmd.params;
cmd_params->vlan_id = cpu_to_le16(vlan_id);
build_if_id_bitmap(cmd_params->if_id, cfg->if_id, cfg->num_ifs);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_vlan_remove_if() - Remove interfaces from an existing VLAN.
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @vlan_id: VLAN Identifier
* @cfg: Set of interfaces that should be removed
*
* Interfaces must belong to this VLAN, otherwise an error
* is returned and an the command is ignored
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_vlan_remove_if(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 vlan_id,
const struct dpsw_vlan_if_cfg *cfg)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_vlan_manage_if *cmd_params;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE_IF,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_vlan_manage_if *)cmd.params;
cmd_params->vlan_id = cpu_to_le16(vlan_id);
build_if_id_bitmap(cmd_params->if_id, cfg->if_id, cfg->num_ifs);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_vlan_remove_if_untagged() - Define a set of interfaces that should be
* converted from transmitted as untagged to transmit as tagged.
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @vlan_id: VLAN Identifier
* @cfg: Set of interfaces that should be removed
*
* Interfaces provided by API have to belong to this VLAN and
* configured untagged, otherwise an error is returned and the
* command is ignored
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_vlan_remove_if_untagged(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 vlan_id,
const struct dpsw_vlan_if_cfg *cfg)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_vlan_manage_if *cmd_params;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE_IF_UNTAGGED,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_vlan_manage_if *)cmd.params;
cmd_params->vlan_id = cpu_to_le16(vlan_id);
build_if_id_bitmap(cmd_params->if_id, cfg->if_id, cfg->num_ifs);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_vlan_remove() - Remove an entire VLAN
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @vlan_id: VLAN Identifier
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_vlan_remove(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 vlan_id)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_vlan_remove *cmd_params;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_VLAN_REMOVE,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_vlan_remove *)cmd.params;
cmd_params->vlan_id = cpu_to_le16(vlan_id);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_fdb_add_unicast() - Function adds an unicast entry into MAC lookup table
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @fdb_id: Forwarding Database Identifier
* @cfg: Unicast entry configuration
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_fdb_add_unicast(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 fdb_id,
const struct dpsw_fdb_unicast_cfg *cfg)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_fdb_unicast_op *cmd_params;
int i;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD_UNICAST,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_fdb_unicast_op *)cmd.params;
cmd_params->fdb_id = cpu_to_le16(fdb_id);
cmd_params->if_egress = cpu_to_le16(cfg->if_egress);
for (i = 0; i < 6; i++)
cmd_params->mac_addr[i] = cfg->mac_addr[5 - i];
dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_fdb_remove_unicast() - removes an entry from MAC lookup table
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @fdb_id: Forwarding Database Identifier
* @cfg: Unicast entry configuration
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_fdb_remove_unicast(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 fdb_id,
const struct dpsw_fdb_unicast_cfg *cfg)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_fdb_unicast_op *cmd_params;
int i;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE_UNICAST,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_fdb_unicast_op *)cmd.params;
cmd_params->fdb_id = cpu_to_le16(fdb_id);
for (i = 0; i < 6; i++)
cmd_params->mac_addr[i] = cfg->mac_addr[5 - i];
cmd_params->if_egress = cpu_to_le16(cfg->if_egress);
dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_fdb_add_multicast() - Add a set of egress interfaces to multi-cast group
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @fdb_id: Forwarding Database Identifier
* @cfg: Multicast entry configuration
*
* If group doesn't exist, it will be created.
* It adds only interfaces not belonging to this multicast group
* yet, otherwise error will be generated and the command is
* ignored.
* This function may be called numerous times always providing
* required interfaces delta.
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_fdb_add_multicast(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 fdb_id,
const struct dpsw_fdb_multicast_cfg *cfg)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_fdb_multicast_op *cmd_params;
int i;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_ADD_MULTICAST,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_fdb_multicast_op *)cmd.params;
cmd_params->fdb_id = cpu_to_le16(fdb_id);
cmd_params->num_ifs = cpu_to_le16(cfg->num_ifs);
dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type);
build_if_id_bitmap(cmd_params->if_id, cfg->if_id, cfg->num_ifs);
for (i = 0; i < 6; i++)
cmd_params->mac_addr[i] = cfg->mac_addr[5 - i];
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_fdb_remove_multicast() - Removing interfaces from an existing multicast
* group.
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @fdb_id: Forwarding Database Identifier
* @cfg: Multicast entry configuration
*
* Interfaces provided by this API have to exist in the group,
* otherwise an error will be returned and an entire command
* ignored. If there is no interface left in the group,
* an entire group is deleted
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_fdb_remove_multicast(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 fdb_id,
const struct dpsw_fdb_multicast_cfg *cfg)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_fdb_multicast_op *cmd_params;
int i;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_REMOVE_MULTICAST,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_fdb_multicast_op *)cmd.params;
cmd_params->fdb_id = cpu_to_le16(fdb_id);
cmd_params->num_ifs = cpu_to_le16(cfg->num_ifs);
dpsw_set_field(cmd_params->type, ENTRY_TYPE, cfg->type);
build_if_id_bitmap(cmd_params->if_id, cfg->if_id, cfg->num_ifs);
for (i = 0; i < 6; i++)
cmd_params->mac_addr[i] = cfg->mac_addr[5 - i];
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_fdb_set_learning_mode() - Define FDB learning mode
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @token: Token of DPSW object
* @fdb_id: Forwarding Database Identifier
* @mode: Learning mode
*
* Return: Completion status. '0' on Success; Error code otherwise.
*/
int dpsw_fdb_set_learning_mode(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 fdb_id,
enum dpsw_fdb_learning_mode mode)
{
struct mc_command cmd = { 0 };
struct dpsw_cmd_fdb_set_learning_mode *cmd_params;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPSW_CMDID_FDB_SET_LEARNING_MODE,
cmd_flags,
token);
cmd_params = (struct dpsw_cmd_fdb_set_learning_mode *)cmd.params;
cmd_params->fdb_id = cpu_to_le16(fdb_id);
dpsw_set_field(cmd_params->mode, LEARNING_MODE, mode);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
/**
* dpsw_get_api_version() - Get Data Path Switch API version
* @mc_io: Pointer to MC portal's I/O object
* @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
* @major_ver: Major version of data path switch API
* @minor_ver: Minor version of data path switch API
*
* Return: '0' on Success; Error code otherwise.
*/
int dpsw_get_api_version(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 *major_ver,
u16 *minor_ver)
{
struct mc_command cmd = { 0 };
struct dpsw_rsp_get_api_version *rsp_params;
int err;
cmd.header = mc_encode_cmd_header(DPSW_CMDID_GET_API_VERSION,
cmd_flags,
0);
err = mc_send_command(mc_io, &cmd);
if (err)
return err;
rsp_params = (struct dpsw_rsp_get_api_version *)cmd.params;
*major_ver = le16_to_cpu(rsp_params->version_major);
*minor_ver = le16_to_cpu(rsp_params->version_minor);
return 0;
}
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2014-2016 Freescale Semiconductor Inc.
* Copyright 2017-2018 NXP
*
*/
#ifndef __FSL_DPSW_H
#define __FSL_DPSW_H
/* Data Path L2-Switch API
* Contains API for handling DPSW topology and functionality
*/
struct fsl_mc_io;
/**
* DPSW general definitions
*/
/**
* Maximum number of traffic class priorities
*/
#define DPSW_MAX_PRIORITIES 8
/**
* Maximum number of interfaces
*/
#define DPSW_MAX_IF 64
int dpsw_open(struct fsl_mc_io *mc_io,
u32 cmd_flags,
int dpsw_id,
u16 *token);
int dpsw_close(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token);
/**
* DPSW options
*/
/**
* Disable flooding
*/
#define DPSW_OPT_FLOODING_DIS 0x0000000000000001ULL
/**
* Disable Multicast
*/
#define DPSW_OPT_MULTICAST_DIS 0x0000000000000004ULL
/**
* Support control interface
*/
#define DPSW_OPT_CTRL_IF_DIS 0x0000000000000010ULL
/**
* Disable flooding metering
*/
#define DPSW_OPT_FLOODING_METERING_DIS 0x0000000000000020ULL
/**
* Enable metering
*/
#define DPSW_OPT_METERING_EN 0x0000000000000040ULL
/**
* enum dpsw_component_type - component type of a bridge
* @DPSW_COMPONENT_TYPE_C_VLAN: A C-VLAN component of an
* enterprise VLAN bridge or of a Provider Bridge used
* to process C-tagged frames
* @DPSW_COMPONENT_TYPE_S_VLAN: An S-VLAN component of a
* Provider Bridge
*
*/
enum dpsw_component_type {
DPSW_COMPONENT_TYPE_C_VLAN = 0,
DPSW_COMPONENT_TYPE_S_VLAN
};
/**
* struct dpsw_cfg - DPSW configuration
* @num_ifs: Number of external and internal interfaces
* @adv: Advanced parameters; default is all zeros;
* use this structure to change default settings
*/
struct dpsw_cfg {
u16 num_ifs;
/**
* struct adv - Advanced parameters
* @options: Enable/Disable DPSW features (bitmap)
* @max_vlans: Maximum Number of VLAN's; 0 - indicates default 16
* @max_meters_per_if: Number of meters per interface
* @max_fdbs: Maximum Number of FDB's; 0 - indicates default 16
* @max_fdb_entries: Number of FDB entries for default FDB table;
* 0 - indicates default 1024 entries.
* @fdb_aging_time: Default FDB aging time for default FDB table;
* 0 - indicates default 300 seconds
* @max_fdb_mc_groups: Number of multicast groups in each FDB table;
* 0 - indicates default 32
* @component_type: Indicates the component type of this bridge
*/
struct {
u64 options;
u16 max_vlans;
u8 max_meters_per_if;
u8 max_fdbs;
u16 max_fdb_entries;
u16 fdb_aging_time;
u16 max_fdb_mc_groups;
enum dpsw_component_type component_type;
} adv;
};
int dpsw_enable(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token);
int dpsw_disable(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token);
int dpsw_reset(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token);
/**
* DPSW IRQ Index and Events
*/
#define DPSW_IRQ_INDEX_IF 0x0000
#define DPSW_IRQ_INDEX_L2SW 0x0001
/**
* IRQ event - Indicates that the link state changed
*/
#define DPSW_IRQ_EVENT_LINK_CHANGED 0x0001
/**
* struct dpsw_irq_cfg - IRQ configuration
* @addr: Address that must be written to signal a message-based interrupt
* @val: Value to write into irq_addr address
* @irq_num: A user defined number associated with this IRQ
*/
struct dpsw_irq_cfg {
u64 addr;
u32 val;
int irq_num;
};
int dpsw_set_irq_enable(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u8 irq_index,
u8 en);
int dpsw_set_irq_mask(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u8 irq_index,
u32 mask);
int dpsw_get_irq_status(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u8 irq_index,
u32 *status);
int dpsw_clear_irq_status(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u8 irq_index,
u32 status);
/**
* struct dpsw_attr - Structure representing DPSW attributes
* @id: DPSW object ID
* @options: Enable/Disable DPSW features
* @max_vlans: Maximum Number of VLANs
* @max_meters_per_if: Number of meters per interface
* @max_fdbs: Maximum Number of FDBs
* @max_fdb_entries: Number of FDB entries for default FDB table;
* 0 - indicates default 1024 entries.
* @fdb_aging_time: Default FDB aging time for default FDB table;
* 0 - indicates default 300 seconds
* @max_fdb_mc_groups: Number of multicast groups in each FDB table;
* 0 - indicates default 32
* @mem_size: DPSW frame storage memory size
* @num_ifs: Number of interfaces
* @num_vlans: Current number of VLANs
* @num_fdbs: Current number of FDBs
* @component_type: Component type of this bridge
*/
struct dpsw_attr {
int id;
u64 options;
u16 max_vlans;
u8 max_meters_per_if;
u8 max_fdbs;
u16 max_fdb_entries;
u16 fdb_aging_time;
u16 max_fdb_mc_groups;
u16 num_ifs;
u16 mem_size;
u16 num_vlans;
u8 num_fdbs;
enum dpsw_component_type component_type;
};
int dpsw_get_attributes(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
struct dpsw_attr *attr);
/**
* enum dpsw_action - Action selection for special/control frames
* @DPSW_ACTION_DROP: Drop frame
* @DPSW_ACTION_REDIRECT: Redirect frame to control port
*/
enum dpsw_action {
DPSW_ACTION_DROP = 0,
DPSW_ACTION_REDIRECT = 1
};
/**
* struct dpsw_link_state - Structure representing DPSW link state
* @rate: Rate
* @options: Mask of available options; use 'DPSW_LINK_OPT_<X>' values
* @up: 0 - covers two cases: down and disconnected, 1 - up
*/
struct dpsw_link_state {
u32 rate;
u64 options;
u8 up;
};
int dpsw_if_get_link_state(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 if_id,
struct dpsw_link_state *state);
int dpsw_if_set_flooding(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 if_id,
u8 en);
int dpsw_if_set_broadcast(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 if_id,
u8 en);
/**
* struct dpsw_tci_cfg - Tag Control Information (TCI) configuration
* @pcp: Priority Code Point (PCP): a 3-bit field which refers
* to the IEEE 802.1p priority
* @dei: Drop Eligible Indicator (DEI): a 1-bit field. May be used
* separately or in conjunction with PCP to indicate frames
* eligible to be dropped in the presence of congestion
* @vlan_id: VLAN Identifier (VID): a 12-bit field specifying the VLAN
* to which the frame belongs. The hexadecimal values
* of 0x000 and 0xFFF are reserved;
* all other values may be used as VLAN identifiers,
* allowing up to 4,094 VLANs
*/
struct dpsw_tci_cfg {
u8 pcp;
u8 dei;
u16 vlan_id;
};
int dpsw_if_set_tci(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 if_id,
const struct dpsw_tci_cfg *cfg);
/**
* enum dpsw_stp_state - Spanning Tree Protocol (STP) states
* @DPSW_STP_STATE_BLOCKING: Blocking state
* @DPSW_STP_STATE_LISTENING: Listening state
* @DPSW_STP_STATE_LEARNING: Learning state
* @DPSW_STP_STATE_FORWARDING: Forwarding state
*
*/
enum dpsw_stp_state {
DPSW_STP_STATE_DISABLED = 0,
DPSW_STP_STATE_LISTENING = 1,
DPSW_STP_STATE_LEARNING = 2,
DPSW_STP_STATE_FORWARDING = 3,
DPSW_STP_STATE_BLOCKING = 0
};
/**
* struct dpsw_stp_cfg - Spanning Tree Protocol (STP) Configuration
* @vlan_id: VLAN ID STP state
* @state: STP state
*/
struct dpsw_stp_cfg {
u16 vlan_id;
enum dpsw_stp_state state;
};
int dpsw_if_set_stp(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 if_id,
const struct dpsw_stp_cfg *cfg);
/**
* enum dpsw_accepted_frames - Types of frames to accept
* @DPSW_ADMIT_ALL: The device accepts VLAN tagged, untagged and
* priority tagged frames
* @DPSW_ADMIT_ONLY_VLAN_TAGGED: The device discards untagged frames or
* Priority-Tagged frames received on this interface.
*
*/
enum dpsw_accepted_frames {
DPSW_ADMIT_ALL = 1,
DPSW_ADMIT_ONLY_VLAN_TAGGED = 3
};
/**
* enum dpsw_counter - Counters types
* @DPSW_CNT_ING_FRAME: Counts ingress frames
* @DPSW_CNT_ING_BYTE: Counts ingress bytes
* @DPSW_CNT_ING_FLTR_FRAME: Counts filtered ingress frames
* @DPSW_CNT_ING_FRAME_DISCARD: Counts discarded ingress frame
* @DPSW_CNT_ING_MCAST_FRAME: Counts ingress multicast frames
* @DPSW_CNT_ING_MCAST_BYTE: Counts ingress multicast bytes
* @DPSW_CNT_ING_BCAST_FRAME: Counts ingress broadcast frames
* @DPSW_CNT_ING_BCAST_BYTES: Counts ingress broadcast bytes
* @DPSW_CNT_EGR_FRAME: Counts egress frames
* @DPSW_CNT_EGR_BYTE: Counts eEgress bytes
* @DPSW_CNT_EGR_FRAME_DISCARD: Counts discarded egress frames
* @DPSW_CNT_EGR_STP_FRAME_DISCARD: Counts egress STP discarded frames
*/
enum dpsw_counter {
DPSW_CNT_ING_FRAME = 0x0,
DPSW_CNT_ING_BYTE = 0x1,
DPSW_CNT_ING_FLTR_FRAME = 0x2,
DPSW_CNT_ING_FRAME_DISCARD = 0x3,
DPSW_CNT_ING_MCAST_FRAME = 0x4,
DPSW_CNT_ING_MCAST_BYTE = 0x5,
DPSW_CNT_ING_BCAST_FRAME = 0x6,
DPSW_CNT_ING_BCAST_BYTES = 0x7,
DPSW_CNT_EGR_FRAME = 0x8,
DPSW_CNT_EGR_BYTE = 0x9,
DPSW_CNT_EGR_FRAME_DISCARD = 0xa,
DPSW_CNT_EGR_STP_FRAME_DISCARD = 0xb
};
int dpsw_if_get_counter(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 if_id,
enum dpsw_counter type,
u64 *counter);
int dpsw_if_enable(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 if_id);
int dpsw_if_disable(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 if_id);
int dpsw_if_set_max_frame_length(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 if_id,
u16 frame_length);
/**
* struct dpsw_vlan_cfg - VLAN Configuration
* @fdb_id: Forwarding Data Base
*/
struct dpsw_vlan_cfg {
u16 fdb_id;
};
int dpsw_vlan_add(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 vlan_id,
const struct dpsw_vlan_cfg *cfg);
/**
* struct dpsw_vlan_if_cfg - Set of VLAN Interfaces
* @num_ifs: The number of interfaces that are assigned to the egress
* list for this VLAN
* @if_id: The set of interfaces that are
* assigned to the egress list for this VLAN
*/
struct dpsw_vlan_if_cfg {
u16 num_ifs;
u16 if_id[DPSW_MAX_IF];
};
int dpsw_vlan_add_if(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 vlan_id,
const struct dpsw_vlan_if_cfg *cfg);
int dpsw_vlan_add_if_untagged(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 vlan_id,
const struct dpsw_vlan_if_cfg *cfg);
int dpsw_vlan_remove_if(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 vlan_id,
const struct dpsw_vlan_if_cfg *cfg);
int dpsw_vlan_remove_if_untagged(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 vlan_id,
const struct dpsw_vlan_if_cfg *cfg);
int dpsw_vlan_remove(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 vlan_id);
/**
* enum dpsw_fdb_entry_type - FDB Entry type - Static/Dynamic
* @DPSW_FDB_ENTRY_STATIC: Static entry
* @DPSW_FDB_ENTRY_DINAMIC: Dynamic entry
*/
enum dpsw_fdb_entry_type {
DPSW_FDB_ENTRY_STATIC = 0,
DPSW_FDB_ENTRY_DINAMIC = 1
};
/**
* struct dpsw_fdb_unicast_cfg - Unicast entry configuration
* @type: Select static or dynamic entry
* @mac_addr: MAC address
* @if_egress: Egress interface ID
*/
struct dpsw_fdb_unicast_cfg {
enum dpsw_fdb_entry_type type;
u8 mac_addr[6];
u16 if_egress;
};
int dpsw_fdb_add_unicast(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 fdb_id,
const struct dpsw_fdb_unicast_cfg *cfg);
int dpsw_fdb_remove_unicast(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 fdb_id,
const struct dpsw_fdb_unicast_cfg *cfg);
/**
* struct dpsw_fdb_multicast_cfg - Multi-cast entry configuration
* @type: Select static or dynamic entry
* @mac_addr: MAC address
* @num_ifs: Number of external and internal interfaces
* @if_id: Egress interface IDs
*/
struct dpsw_fdb_multicast_cfg {
enum dpsw_fdb_entry_type type;
u8 mac_addr[6];
u16 num_ifs;
u16 if_id[DPSW_MAX_IF];
};
int dpsw_fdb_add_multicast(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 fdb_id,
const struct dpsw_fdb_multicast_cfg *cfg);
int dpsw_fdb_remove_multicast(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 fdb_id,
const struct dpsw_fdb_multicast_cfg *cfg);
/**
* enum dpsw_fdb_learning_mode - Auto-learning modes
* @DPSW_FDB_LEARNING_MODE_DIS: Disable Auto-learning
* @DPSW_FDB_LEARNING_MODE_HW: Enable HW auto-Learning
* @DPSW_FDB_LEARNING_MODE_NON_SECURE: Enable None secure learning by CPU
* @DPSW_FDB_LEARNING_MODE_SECURE: Enable secure learning by CPU
*
* NONE - SECURE LEARNING
* SMAC found DMAC found CTLU Action
* v v Forward frame to
* 1. DMAC destination
* - v Forward frame to
* 1. DMAC destination
* 2. Control interface
* v - Forward frame to
* 1. Flooding list of interfaces
* - - Forward frame to
* 1. Flooding list of interfaces
* 2. Control interface
* SECURE LEARING
* SMAC found DMAC found CTLU Action
* v v Forward frame to
* 1. DMAC destination
* - v Forward frame to
* 1. Control interface
* v - Forward frame to
* 1. Flooding list of interfaces
* - - Forward frame to
* 1. Control interface
*/
enum dpsw_fdb_learning_mode {
DPSW_FDB_LEARNING_MODE_DIS = 0,
DPSW_FDB_LEARNING_MODE_HW = 1,
DPSW_FDB_LEARNING_MODE_NON_SECURE = 2,
DPSW_FDB_LEARNING_MODE_SECURE = 3
};
int dpsw_fdb_set_learning_mode(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 token,
u16 fdb_id,
enum dpsw_fdb_learning_mode mode);
/**
* struct dpsw_fdb_attr - FDB Attributes
* @max_fdb_entries: Number of FDB entries
* @fdb_aging_time: Aging time in seconds
* @learning_mode: Learning mode
* @num_fdb_mc_groups: Current number of multicast groups
* @max_fdb_mc_groups: Maximum number of multicast groups
*/
struct dpsw_fdb_attr {
u16 max_fdb_entries;
u16 fdb_aging_time;
enum dpsw_fdb_learning_mode learning_mode;
u16 num_fdb_mc_groups;
u16 max_fdb_mc_groups;
};
int dpsw_get_api_version(struct fsl_mc_io *mc_io,
u32 cmd_flags,
u16 *major_ver,
u16 *minor_ver);
#endif /* __FSL_DPSW_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment