Commit aae0e689 authored by Codrin Ciubotariu's avatar Codrin Ciubotariu Committed by Joe Hershberger

drivers: net: vsc9953: Add LAG support

You can now configure LAG on VSC9953's ports using the command:
ethsw [port <port_no>] aggr {[help] | show | <lag_group_no>}

A port must belong to a single LAG. By default, a port
belongs to a LAG equal to the port's number.

For each frame, a hash will be calculated based on
Source/Destination MAC addresses, Source/Destination IP(v4/v6)
addresses, Source/Destination ports. This hash will be used to
select a single egress port from LAG. This also assures
that frames from the same flow will always have the
same egress port.
Signed-off-by: default avatarCodrin Ciubotariu <codrin.ciubotariu@freescale.com>
Acked-by: default avatarJoe Hershberger <joe.hershberger@ni.com>
parent bf9f2ed8
......@@ -114,6 +114,17 @@ static int ethsw_ingr_fltr_help_key_func(struct ethsw_command_def *parsed_cmd)
return CMD_RET_SUCCESS;
}
#define ETHSW_PORT_AGGR_HELP "ethsw [port <port_no>] aggr" \
" { [help] | show | <lag_group_no> } " \
"- get/set LAG group for a port"
static int ethsw_port_aggr_help_key_func(struct ethsw_command_def *parsed_cmd)
{
printf(ETHSW_PORT_AGGR_HELP"\n");
return CMD_RET_SUCCESS;
}
static struct keywords_to_function {
enum ethsw_keyword_id cmd_keyword[ETHSW_MAX_CMD_PARAMS];
int cmd_func_offset;
......@@ -532,6 +543,39 @@ static struct keywords_to_function {
.cmd_func_offset = offsetof(struct ethsw_command_func,
port_ingr_filt_set),
.keyword_function = NULL,
}, {
.cmd_keyword = {
ethsw_id_aggr,
ethsw_id_key_end,
},
.cmd_func_offset = -1,
.keyword_function = &ethsw_port_aggr_help_key_func,
}, {
.cmd_keyword = {
ethsw_id_aggr,
ethsw_id_help,
ethsw_id_key_end,
},
.cmd_func_offset = -1,
.keyword_function = &ethsw_port_aggr_help_key_func,
}, {
.cmd_keyword = {
ethsw_id_aggr,
ethsw_id_show,
ethsw_id_key_end,
},
.cmd_func_offset = offsetof(struct ethsw_command_func,
port_aggr_show),
.keyword_function = NULL,
}, {
.cmd_keyword = {
ethsw_id_aggr,
ethsw_id_aggr_no,
ethsw_id_key_end,
},
.cmd_func_offset = offsetof(struct ethsw_command_func,
port_aggr_set),
.keyword_function = NULL,
},
};
......@@ -576,6 +620,9 @@ static int keyword_match_pvid(enum ethsw_keyword_id key_id, int argc,
static int keyword_match_mac_addr(enum ethsw_keyword_id key_id, int argc,
char *const argv[], int *argc_nr,
struct ethsw_command_def *parsed_cmd);
static int keyword_match_aggr(enum ethsw_keyword_id key_id, int argc,
char *const argv[], int *argc_nr,
struct ethsw_command_def *parsed_cmd);
/*
* Define properties for each keyword;
......@@ -661,6 +708,9 @@ struct keyword_def {
}, {
.keyword_name = "filtering",
.match = &keyword_match_gen,
}, {
.keyword_name = "aggr",
.match = &keyword_match_aggr,
},
};
......@@ -826,6 +876,28 @@ static int keyword_match_mac_addr(enum ethsw_keyword_id key_id, int argc,
return 1;
}
/* Function used to match the command's aggregation number */
static int keyword_match_aggr(enum ethsw_keyword_id key_id, int argc,
char *const argv[], int *argc_nr,
struct ethsw_command_def *parsed_cmd)
{
unsigned long val;
if (!keyword_match_gen(key_id, argc, argv, argc_nr, parsed_cmd))
return 0;
if (*argc_nr + 1 >= argc)
return 1;
if (strict_strtoul(argv[*argc_nr + 1], 10, &val) != -EINVAL) {
parsed_cmd->aggr_grp = val;
(*argc_nr)++;
parsed_cmd->cmd_to_keywords[*argc_nr] = ethsw_id_aggr_no;
}
return 1;
}
/* Finds optional keywords and modifies *argc_va to skip them */
static void cmd_keywords_opt_check(const struct ethsw_command_def *parsed_cmd,
int *argc_val)
......@@ -984,6 +1056,7 @@ static void command_def_init(struct ethsw_command_def *parsed_cmd)
parsed_cmd->port = ETHSW_CMD_PORT_ALL;
parsed_cmd->vid = ETHSW_CMD_VLAN_ALL;
parsed_cmd->aggr_grp = ETHSW_CMD_AGGR_GRP_NONE;
parsed_cmd->cmd_function = NULL;
/* We initialize the MAC address with the Broadcast address */
......@@ -1024,4 +1097,5 @@ U_BOOT_CMD(ethsw, ETHSW_MAX_CMD_PARAMS, 0, do_ethsw,
ETHSW_EGR_VLAN_TAG_HELP"\n"
ETHSW_VLAN_FDB_HELP"\n"
ETHSW_PORT_INGR_FLTR_HELP"\n"
ETHSW_PORT_AGGR_HELP"\n"
);
......@@ -31,6 +31,7 @@ Commands supported
- Port-based VLAN
- Private/Shared VLAN learning
- VLAN ingress filtering
- Port LAG
Commands syntax
ethsw [port <port_no>] { enable | disable | show } - enable/disable a port; show a port's configuration
......@@ -45,6 +46,7 @@ ethsw [port <port_no>] egress tag { [help] | show | pvid | classified } - config
Tag's VID could be the frame's classified VID or the PVID of the port
ethsw vlan fdb { [help] | show | shared | private } - make VLAN learning shared or private
ethsw [port <port_no>] ingress filtering { [help] | show | enable | disable } - enable/disable VLAN ingress filtering on port
ethsw [port <port_no>] aggr { [help] | show | <lag_group_no> } - get/set LAG group for a port
=> ethsw show
Port Status Link Speed Duplex
......
This diff is collapsed.
......@@ -12,6 +12,7 @@
#define ETHSW_MAX_CMD_PARAMS 20
#define ETHSW_CMD_PORT_ALL -1
#define ETHSW_CMD_VLAN_ALL -1
#define ETHSW_CMD_AGGR_GRP_NONE -1
/* IDs used to track keywords in a command */
enum ethsw_keyword_id {
......@@ -41,6 +42,7 @@ enum ethsw_keyword_id {
ethsw_id_private,
ethsw_id_ingress,
ethsw_id_filtering,
ethsw_id_aggr,
ethsw_id_count, /* keep last */
};
......@@ -50,6 +52,7 @@ enum ethsw_keyword_opt_id {
ethsw_id_pvid_no,
ethsw_id_add_del_no,
ethsw_id_add_del_mac,
ethsw_id_aggr_no,
ethsw_id_count_all, /* keep last */
};
......@@ -58,6 +61,7 @@ struct ethsw_command_def {
int cmd_keywords_nr;
int port;
int vid;
int aggr_grp;
uchar ethaddr[6];
int (*cmd_function)(struct ethsw_command_def *parsed_cmd);
};
......@@ -88,6 +92,8 @@ struct ethsw_command_func {
int (*vlan_learn_set)(struct ethsw_command_def *parsed_cmd);
int (*port_ingr_filt_show)(struct ethsw_command_def *parsed_cmd);
int (*port_ingr_filt_set)(struct ethsw_command_def *parsed_cmd);
int (*port_aggr_show)(struct ethsw_command_def *parsed_cmd);
int (*port_aggr_set)(struct ethsw_command_def *parsed_cmd);
};
int ethsw_define_functions(const struct ethsw_command_func *cmd_func);
......
......@@ -126,6 +126,7 @@
#define VSC9953_PORT_CFG_LEARN_AUTO 0x00000100
#define VSC9953_PORT_CFG_LEARN_CPU 0x00000200
#define VSC9953_PORT_CFG_LEARN_DROP 0x00000400
#define VSC9953_PORT_CFG_PORTID_MASK 0x0000003c
/* Macros for vsc9953_qsys_sys.switch_port_mode register */
#define VSC9953_PORT_ENA 0x00002000
......@@ -156,6 +157,19 @@
/* Macros for vsc9953_ana_ana_tables.mach_data register */
#define VSC9953_MACHDATA_VID_MASK 0x1fff0000
/* Macros for vsc9953_ana_common.aggr_cfg register */
#define VSC9953_AC_RND_ENA 0x00000080
#define VSC9953_AC_DMAC_ENA 0x00000040
#define VSC9953_AC_SMAC_ENA 0x00000020
#define VSC9953_AC_IP6_LBL_ENA 0x00000010
#define VSC9953_AC_IP6_TCPUDP_ENA 0x00000008
#define VSC9953_AC_IP4_SIPDIP_ENA 0x00000004
#define VSC9953_AC_IP4_TCPUDP_ENA 0x00000002
#define VSC9953_AC_MASK 0x000000fe
/* Macros for vsc9953_ana_pgid.port_grp_id[] registers */
#define VSC9953_PGID_PORT_MASK 0x000003ff
#define VSC9953_MAX_PORTS 10
#define VSC9953_PORT_CHECK(port) \
(((port) < 0 || (port) >= VSC9953_MAX_PORTS) ? 0 : 1)
......@@ -239,6 +253,10 @@ struct vsc9953_ana_ana {
u32 port_mode[12];
};
#define PGID_DST_START 0
#define PGID_AGGR_START 64
#define PGID_SRC_START 80
struct vsc9953_ana_pgid {
u32 port_grp_id[91];
};
......
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