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: Codrin Ciubotariu <codrin.ciubotariu@freescale.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
master
Codrin Ciubotariu 9 years ago committed by Joe Hershberger
parent bf9f2ed83b
commit aae0e68909
  1. 74
      common/cmd_ethsw.c
  2. 2
      doc/README.t1040-l2switch
  3. 331
      drivers/net/vsc9953.c
  4. 6
      include/ethsw.h
  5. 18
      include/vsc9953.h

@ -114,6 +114,17 @@ static int ethsw_ingr_fltr_help_key_func(struct ethsw_command_def *parsed_cmd)
return CMD_RET_SUCCESS; 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 { static struct keywords_to_function {
enum ethsw_keyword_id cmd_keyword[ETHSW_MAX_CMD_PARAMS]; enum ethsw_keyword_id cmd_keyword[ETHSW_MAX_CMD_PARAMS];
int cmd_func_offset; int cmd_func_offset;
@ -532,6 +543,39 @@ static struct keywords_to_function {
.cmd_func_offset = offsetof(struct ethsw_command_func, .cmd_func_offset = offsetof(struct ethsw_command_func,
port_ingr_filt_set), port_ingr_filt_set),
.keyword_function = NULL, .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, static int keyword_match_mac_addr(enum ethsw_keyword_id key_id, int argc,
char *const argv[], int *argc_nr, char *const argv[], int *argc_nr,
struct ethsw_command_def *parsed_cmd); 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; * Define properties for each keyword;
@ -661,6 +708,9 @@ struct keyword_def {
}, { }, {
.keyword_name = "filtering", .keyword_name = "filtering",
.match = &keyword_match_gen, .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; 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 */ /* Finds optional keywords and modifies *argc_va to skip them */
static void cmd_keywords_opt_check(const struct ethsw_command_def *parsed_cmd, static void cmd_keywords_opt_check(const struct ethsw_command_def *parsed_cmd,
int *argc_val) 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->port = ETHSW_CMD_PORT_ALL;
parsed_cmd->vid = ETHSW_CMD_VLAN_ALL; parsed_cmd->vid = ETHSW_CMD_VLAN_ALL;
parsed_cmd->aggr_grp = ETHSW_CMD_AGGR_GRP_NONE;
parsed_cmd->cmd_function = NULL; parsed_cmd->cmd_function = NULL;
/* We initialize the MAC address with the Broadcast address */ /* 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_EGR_VLAN_TAG_HELP"\n"
ETHSW_VLAN_FDB_HELP"\n" ETHSW_VLAN_FDB_HELP"\n"
ETHSW_PORT_INGR_FLTR_HELP"\n" ETHSW_PORT_INGR_FLTR_HELP"\n"
ETHSW_PORT_AGGR_HELP"\n"
); );

@ -31,6 +31,7 @@ Commands supported
- Port-based VLAN - Port-based VLAN
- Private/Shared VLAN learning - Private/Shared VLAN learning
- VLAN ingress filtering - VLAN ingress filtering
- Port LAG
Commands syntax Commands syntax
ethsw [port <port_no>] { enable | disable | show } - enable/disable a port; show a port's configuration 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 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 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>] 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 => ethsw show
Port Status Link Speed Duplex Port Status Link Speed Duplex

@ -469,6 +469,47 @@ static void vsc9953_vlan_ingr_fltr_learn_drop(int enable)
clrbits_le32(&l2ana_reg->ana.adv_learn, VSC9953_VLAN_CHK); clrbits_le32(&l2ana_reg->ana.adv_learn, VSC9953_VLAN_CHK);
} }
enum aggr_code_mode {
AGGR_CODE_RAND = 0,
AGGR_CODE_ALL, /* S/D MAC, IPv4 S/D IP, IPv6 Flow Label, S/D PORT */
};
/* Set aggregation code generation mode */
static int vsc9953_aggr_code_set(enum aggr_code_mode ac)
{
int rc;
struct vsc9953_analyzer *l2ana_reg;
l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
VSC9953_ANA_OFFSET);
switch (ac) {
case AGGR_CODE_RAND:
clrsetbits_le32(&l2ana_reg->common.aggr_cfg,
VSC9953_AC_DMAC_ENA | VSC9953_AC_SMAC_ENA |
VSC9953_AC_IP6_LBL_ENA |
VSC9953_AC_IP6_TCPUDP_ENA |
VSC9953_AC_IP4_SIPDIP_ENA |
VSC9953_AC_IP4_TCPUDP_ENA, VSC9953_AC_RND_ENA);
rc = 0;
break;
case AGGR_CODE_ALL:
clrsetbits_le32(&l2ana_reg->common.aggr_cfg, VSC9953_AC_RND_ENA,
VSC9953_AC_DMAC_ENA | VSC9953_AC_SMAC_ENA |
VSC9953_AC_IP6_LBL_ENA |
VSC9953_AC_IP6_TCPUDP_ENA |
VSC9953_AC_IP4_SIPDIP_ENA |
VSC9953_AC_IP4_TCPUDP_ENA);
rc = 0;
break;
default:
/* unknown mode for aggregation code */
rc = -EINVAL;
}
return rc;
}
/* Egress untag modes of a VSC9953 port */ /* Egress untag modes of a VSC9953 port */
enum egress_untag_mode { enum egress_untag_mode {
EGRESS_UNTAG_ALL = 0, EGRESS_UNTAG_ALL = 0,
@ -1493,6 +1534,224 @@ static int vsc9953_port_ingress_filtering_get(int port_no)
return !!(val & (1 << port_no)); return !!(val & (1 << port_no));
} }
/* Get the aggregation group of a port */
static int vsc9953_port_aggr_grp_get(int port_no, int *aggr_grp)
{
u32 val;
struct vsc9953_analyzer *l2ana_reg;
if (!VSC9953_PORT_CHECK(port_no))
return -EINVAL;
l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
VSC9953_ANA_OFFSET);
val = in_le32(&l2ana_reg->port[port_no].port_cfg);
*aggr_grp = bitfield_extract_by_mask(val,
VSC9953_PORT_CFG_PORTID_MASK);
return 0;
}
static void vsc9953_aggr_grp_members_get(int aggr_grp,
u8 aggr_membr[VSC9953_MAX_PORTS])
{
int port_no;
int aggr_membr_grp;
for (port_no = 0; port_no < VSC9953_MAX_PORTS; port_no++) {
aggr_membr[port_no] = 0;
if (vsc9953_port_aggr_grp_get(port_no, &aggr_membr_grp))
continue;
if (aggr_grp == aggr_membr_grp)
aggr_membr[port_no] = 1;
}
}
static void vsc9953_update_dest_members_masks(int port_no, u32 membr_bitfld_old,
u32 membr_bitfld_new)
{
int i;
u32 pgid;
struct vsc9953_analyzer *l2ana_reg;
l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
VSC9953_ANA_OFFSET);
/*
* NOTE: Only the unicast destination masks are updated, since
* we do not support for now Layer-2 multicast entries
*/
for (i = 0; i < VSC9953_MAX_PORTS; i++) {
if (i == port_no) {
clrsetbits_le32(&l2ana_reg->port_id_tbl.port_grp_id[i],
VSC9953_PGID_PORT_MASK,
membr_bitfld_new);
continue;
}
pgid = in_le32(&l2ana_reg->port_id_tbl.port_grp_id[i]);
if ((u32)(1 << i) & membr_bitfld_old & VSC9953_PGID_PORT_MASK)
pgid &= ~((u32)(1 << port_no));
if ((u32)(1 << i) & membr_bitfld_new & VSC9953_PGID_PORT_MASK)
pgid |= ((u32)(1 << port_no));
out_le32(&l2ana_reg->port_id_tbl.port_grp_id[i], pgid);
}
}
static void vsc9953_update_source_members_masks(int port_no,
u32 membr_bitfld_old,
u32 membr_bitfld_new)
{
int i;
int index;
u32 pgid;
struct vsc9953_analyzer *l2ana_reg;
l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
VSC9953_ANA_OFFSET);
for (i = 0; i < VSC9953_MAX_PORTS + 1; i++) {
index = PGID_SRC_START + i;
pgid = in_le32(&l2ana_reg->port_id_tbl.port_grp_id[index]);
if (i == port_no) {
pgid = (pgid | VSC9953_PGID_PORT_MASK) &
~membr_bitfld_new;
out_le32(&l2ana_reg->port_id_tbl.port_grp_id[index],
pgid);
continue;
}
if ((u32)(1 << i) & membr_bitfld_old & VSC9953_PGID_PORT_MASK)
pgid |= (u32)(1 << port_no);
if ((u32)(1 << i) & membr_bitfld_new & VSC9953_PGID_PORT_MASK)
pgid &= ~(u32)(1 << port_no);
out_le32(&l2ana_reg->port_id_tbl.port_grp_id[index], pgid);
}
}
static u32 vsc9953_aggr_mask_get_next(u32 aggr_mask, u32 member_bitfield)
{
if (!member_bitfield)
return 0;
if (!(aggr_mask & VSC9953_PGID_PORT_MASK))
aggr_mask = 1;
else
aggr_mask <<= 1;
while (!(aggr_mask & member_bitfield)) {
aggr_mask <<= 1;
if (!(aggr_mask & VSC9953_PGID_PORT_MASK))
aggr_mask = 1;
}
return aggr_mask;
}
static void vsc9953_update_aggr_members_masks(int port_no, u32 membr_bitfld_old,
u32 membr_bitfld_new)
{
int i;
u32 pgid;
u32 aggr_mask_old = 0;
u32 aggr_mask_new = 0;
struct vsc9953_analyzer *l2ana_reg;
l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
VSC9953_ANA_OFFSET);
/* Update all the PGID aggregation masks */
for (i = PGID_AGGR_START; i < PGID_SRC_START; i++) {
pgid = in_le32(&l2ana_reg->port_id_tbl.port_grp_id[i]);
aggr_mask_old = vsc9953_aggr_mask_get_next(aggr_mask_old,
membr_bitfld_old);
pgid = (pgid & ~membr_bitfld_old) | aggr_mask_old;
aggr_mask_new = vsc9953_aggr_mask_get_next(aggr_mask_new,
membr_bitfld_new);
pgid = (pgid & ~membr_bitfld_new) | aggr_mask_new;
out_le32(&l2ana_reg->port_id_tbl.port_grp_id[i], pgid);
}
}
static u32 vsc9953_aggr_membr_bitfield_get(u8 member[VSC9953_MAX_PORTS])
{
int i;
u32 member_bitfield = 0;
for (i = 0; i < VSC9953_MAX_PORTS; i++) {
if (member[i])
member_bitfield |= 1 << i;
}
member_bitfield &= VSC9953_PGID_PORT_MASK;
return member_bitfield;
}
static void vsc9953_update_members_masks(int port_no,
u8 member_old[VSC9953_MAX_PORTS],
u8 member_new[VSC9953_MAX_PORTS])
{
u32 membr_bitfld_old = vsc9953_aggr_membr_bitfield_get(member_old);
u32 membr_bitfld_new = vsc9953_aggr_membr_bitfield_get(member_new);
vsc9953_update_dest_members_masks(port_no, membr_bitfld_old,
membr_bitfld_new);
vsc9953_update_source_members_masks(port_no, membr_bitfld_old,
membr_bitfld_new);
vsc9953_update_aggr_members_masks(port_no, membr_bitfld_old,
membr_bitfld_new);
}
/* Set the aggregation group of a port */
static int vsc9953_port_aggr_grp_set(int port_no, int aggr_grp)
{
u8 aggr_membr_old[VSC9953_MAX_PORTS];
u8 aggr_membr_new[VSC9953_MAX_PORTS];
int rc;
int aggr_grp_old;
u32 val;
struct vsc9953_analyzer *l2ana_reg;
if (!VSC9953_PORT_CHECK(port_no) || !VSC9953_PORT_CHECK(aggr_grp))
return -EINVAL;
l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
VSC9953_ANA_OFFSET);
rc = vsc9953_port_aggr_grp_get(port_no, &aggr_grp_old);
if (rc)
return rc;
/* get all the members of the old aggregation group */
vsc9953_aggr_grp_members_get(aggr_grp_old, aggr_membr_old);
/* get all the members of the same aggregation group */
vsc9953_aggr_grp_members_get(aggr_grp, aggr_membr_new);
/* add current port as member to the new aggregation group */
aggr_membr_old[port_no] = 0;
aggr_membr_new[port_no] = 1;
/* update masks */
vsc9953_update_members_masks(port_no, aggr_membr_old, aggr_membr_new);
/* Change logical port number */
val = in_le32(&l2ana_reg->port[port_no].port_cfg);
val = bitfield_replace_by_mask(val,
VSC9953_PORT_CFG_PORTID_MASK, aggr_grp);
out_le32(&l2ana_reg->port[port_no].port_cfg, val);
return 0;
}
static int vsc9953_port_status_key_func(struct ethsw_command_def *parsed_cmd) static int vsc9953_port_status_key_func(struct ethsw_command_def *parsed_cmd)
{ {
int i; int i;
@ -2083,6 +2342,72 @@ static int vsc9953_ingr_fltr_set_key_func(struct ethsw_command_def *parsed_cmd)
return CMD_RET_SUCCESS; return CMD_RET_SUCCESS;
} }
static int vsc9953_port_aggr_show_key_func(struct ethsw_command_def *parsed_cmd)
{
int i;
int aggr_grp;
if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
printf("Invalid port number: %d\n", parsed_cmd->port);
return CMD_RET_FAILURE;
}
if (vsc9953_port_aggr_grp_get(parsed_cmd->port, &aggr_grp))
return CMD_RET_FAILURE;
printf("%7s %10s\n", "Port", "Aggr grp");
printf("%7d %10d\n", parsed_cmd->port, aggr_grp);
} else {
printf("%7s %10s\n", "Port", "Aggr grp");
for (i = 0; i < VSC9953_MAX_PORTS; i++) {
if (vsc9953_port_aggr_grp_get(i, &aggr_grp))
continue;
printf("%7d %10d\n", i, aggr_grp);
}
}
return CMD_RET_SUCCESS;
}
static int vsc9953_port_aggr_set_key_func(struct ethsw_command_def *parsed_cmd)
{
int i;
/* Aggregation group number should be set in parsed_cmd->aggr_grp */
if (parsed_cmd->aggr_grp == ETHSW_CMD_AGGR_GRP_NONE) {
printf("Please set an aggregation group value\n");
return CMD_RET_FAILURE;
}
if (!VSC9953_PORT_CHECK(parsed_cmd->aggr_grp)) {
printf("Invalid aggregation group number: %d\n",
parsed_cmd->aggr_grp);
return CMD_RET_FAILURE;
}
if (parsed_cmd->port != ETHSW_CMD_PORT_ALL) {
if (!VSC9953_PORT_CHECK(parsed_cmd->port)) {
printf("Invalid port number: %d\n", parsed_cmd->port);
return CMD_RET_FAILURE;
}
if (vsc9953_port_aggr_grp_set(parsed_cmd->port,
parsed_cmd->aggr_grp)) {
printf("Port %d: failed to set aggr group %d\n",
parsed_cmd->port, parsed_cmd->aggr_grp);
}
} else {
for (i = 0; i < VSC9953_MAX_PORTS; i++) {
if (vsc9953_port_aggr_grp_set(i,
parsed_cmd->aggr_grp)) {
printf("Port %d: failed to set aggr group %d\n",
i, parsed_cmd->aggr_grp);
}
}
}
return CMD_RET_SUCCESS;
}
static struct ethsw_command_func vsc9953_cmd_func = { static struct ethsw_command_func vsc9953_cmd_func = {
.ethsw_name = "L2 Switch VSC9953", .ethsw_name = "L2 Switch VSC9953",
.port_enable = &vsc9953_port_status_key_func, .port_enable = &vsc9953_port_status_key_func,
@ -2107,7 +2432,9 @@ static struct ethsw_command_func vsc9953_cmd_func = {
.vlan_learn_show = &vsc9953_vlan_learn_show_key_func, .vlan_learn_show = &vsc9953_vlan_learn_show_key_func,
.vlan_learn_set = &vsc9953_vlan_learn_set_key_func, .vlan_learn_set = &vsc9953_vlan_learn_set_key_func,
.port_ingr_filt_show = &vsc9953_ingr_fltr_show_key_func, .port_ingr_filt_show = &vsc9953_ingr_fltr_show_key_func,
.port_ingr_filt_set = &vsc9953_ingr_fltr_set_key_func .port_ingr_filt_set = &vsc9953_ingr_fltr_set_key_func,
.port_aggr_show = &vsc9953_port_aggr_show_key_func,
.port_aggr_set = &vsc9953_port_aggr_set_key_func,
}; };
#endif /* CONFIG_CMD_ETHSW */ #endif /* CONFIG_CMD_ETHSW */
@ -2138,6 +2465,8 @@ void vsc9953_default_configuration(void)
vsc9953_vlan_table_membership_all_set(1, 1); vsc9953_vlan_table_membership_all_set(1, 1);
vsc9953_vlan_ingr_fltr_learn_drop(1); vsc9953_vlan_ingr_fltr_learn_drop(1);
vsc9953_port_all_vlan_egress_untagged_set(EGRESS_UNTAG_PVID_AND_ZERO); vsc9953_port_all_vlan_egress_untagged_set(EGRESS_UNTAG_PVID_AND_ZERO);
if (vsc9953_aggr_code_set(AGGR_CODE_ALL))
debug("VSC9953: failed to set default aggregation code mode\n");
} }
void vsc9953_init(bd_t *bis) void vsc9953_init(bd_t *bis)

@ -12,6 +12,7 @@
#define ETHSW_MAX_CMD_PARAMS 20 #define ETHSW_MAX_CMD_PARAMS 20
#define ETHSW_CMD_PORT_ALL -1 #define ETHSW_CMD_PORT_ALL -1
#define ETHSW_CMD_VLAN_ALL -1 #define ETHSW_CMD_VLAN_ALL -1
#define ETHSW_CMD_AGGR_GRP_NONE -1
/* IDs used to track keywords in a command */ /* IDs used to track keywords in a command */
enum ethsw_keyword_id { enum ethsw_keyword_id {
@ -41,6 +42,7 @@ enum ethsw_keyword_id {
ethsw_id_private, ethsw_id_private,
ethsw_id_ingress, ethsw_id_ingress,
ethsw_id_filtering, ethsw_id_filtering,
ethsw_id_aggr,
ethsw_id_count, /* keep last */ ethsw_id_count, /* keep last */
}; };
@ -50,6 +52,7 @@ enum ethsw_keyword_opt_id {
ethsw_id_pvid_no, ethsw_id_pvid_no,
ethsw_id_add_del_no, ethsw_id_add_del_no,
ethsw_id_add_del_mac, ethsw_id_add_del_mac,
ethsw_id_aggr_no,
ethsw_id_count_all, /* keep last */ ethsw_id_count_all, /* keep last */
}; };
@ -58,6 +61,7 @@ struct ethsw_command_def {
int cmd_keywords_nr; int cmd_keywords_nr;
int port; int port;
int vid; int vid;
int aggr_grp;
uchar ethaddr[6]; uchar ethaddr[6];
int (*cmd_function)(struct ethsw_command_def *parsed_cmd); 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 (*vlan_learn_set)(struct ethsw_command_def *parsed_cmd);
int (*port_ingr_filt_show)(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_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); 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_AUTO 0x00000100
#define VSC9953_PORT_CFG_LEARN_CPU 0x00000200 #define VSC9953_PORT_CFG_LEARN_CPU 0x00000200
#define VSC9953_PORT_CFG_LEARN_DROP 0x00000400 #define VSC9953_PORT_CFG_LEARN_DROP 0x00000400
#define VSC9953_PORT_CFG_PORTID_MASK 0x0000003c
/* Macros for vsc9953_qsys_sys.switch_port_mode register */ /* Macros for vsc9953_qsys_sys.switch_port_mode register */
#define VSC9953_PORT_ENA 0x00002000 #define VSC9953_PORT_ENA 0x00002000
@ -156,6 +157,19 @@
/* Macros for vsc9953_ana_ana_tables.mach_data register */ /* Macros for vsc9953_ana_ana_tables.mach_data register */
#define VSC9953_MACHDATA_VID_MASK 0x1fff0000 #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_MAX_PORTS 10
#define VSC9953_PORT_CHECK(port) \ #define VSC9953_PORT_CHECK(port) \
(((port) < 0 || (port) >= VSC9953_MAX_PORTS) ? 0 : 1) (((port) < 0 || (port) >= VSC9953_MAX_PORTS) ? 0 : 1)
@ -239,6 +253,10 @@ struct vsc9953_ana_ana {
u32 port_mode[12]; u32 port_mode[12];
}; };
#define PGID_DST_START 0
#define PGID_AGGR_START 64
#define PGID_SRC_START 80
struct vsc9953_ana_pgid { struct vsc9953_ana_pgid {
u32 port_grp_id[91]; u32 port_grp_id[91];
}; };

Loading…
Cancel
Save