The new added commands can be used to configure VLANs for a port on both ingress and egress.
The new commands are: ethsw [port <port_no>] pvid { [help] | show | <pvid> } - set/show PVID (ingress and egress VLAN tagging) for a port; ethsw [port <port_no>] vlan { [help] | show | add <vid> | del <vid> } - add a VLAN to a port (VLAN members); ethsw [port <port_no>] untagged { [help] | show | all | none | pvid } - set egress tagging mod for a port" ethsw [port <port_no>] egress tag { [help] | show | pvid | classified } - Configure VID source for egress tag. Tag's VID could be the frame's classified VID or the PVID of the port Signed-off-by: Johnson Leung <johnson.le...@freescale.com> Signed-off-by: Codrin Ciubotariu <codrin.ciubota...@freescale.com> --- Changes for v2: - removed Change-id field; drivers/net/vsc9953.c | 678 +++++++++++++++++++++++++++++++++++++++++++++++++- include/vsc9953.h | 3 + 2 files changed, 680 insertions(+), 1 deletion(-) diff --git a/drivers/net/vsc9953.c b/drivers/net/vsc9953.c index ef7b50c..b78a941 100644 --- a/drivers/net/vsc9953.c +++ b/drivers/net/vsc9953.c @@ -270,6 +270,31 @@ static void vsc9953_port_vlan_pvid_set(int port_no, int pvid) field_set(pvid, CONFIG_VSC9953_PORT_VLAN_CFG_VID_MASK)); } +#ifdef CONFIG_VSC9953_CMD +/* Set PVID for a VSC9953 port */ +static int vsc9953_port_vlan_pvid_get(int port_nr, int *pvid) +{ + u32 val; + struct vsc9953_analyzer *l2ana_reg; + + /* Administrative down */ + if ((!vsc9953_l2sw.port[port_nr].enabled)) { + printf("Port %d is administrative down\n", port_nr); + return -1; + } + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + /* Get ingress PVID */ + val = in_le32(&l2ana_reg->port[port_nr].vlan_cfg); + *pvid = field_get(val & CONFIG_VSC9953_VLAN_CFG_VID_MASK, + CONFIG_VSC9953_VLAN_CFG_VID_MASK); + + return 0; +} +#endif + static void vsc9953_port_all_vlan_pvid_set(int pvid) { int i; @@ -407,6 +432,75 @@ static void vsc9953_port_vlan_egr_untag_set(int port_no, } } +#ifdef CONFIG_VSC9953_CMD +/* Get egress tagging configuration for a VSC9953 port */ +static int vsc9953_port_vlan_egr_untag_get(int port_no, + enum egress_untag_mode *mode) +{ + u32 val; + struct vsc9953_rew_reg *l2rew_reg; + + /* Administrative down */ + if ((!vsc9953_l2sw.port[port_no].enabled)) { + printf("Port %d is administrative down\n", port_no); + return -1; + } + + l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET + + VSC9953_REW_OFFSET); + + val = in_le32(&l2rew_reg->port[port_no].port_tag_cfg); + + switch (val & CONFIG_VSC9953_TAG_CFG_MASK) { + case CONFIG_VSC9953_TAG_CFG_NONE: + *mode = EGRESS_UNTAG_ALL; + return 0; + case CONFIG_VSC9953_TAG_CFG_ALL_PVID_ZERO: + *mode = EGRESS_UNTAG_PVID_AND_ZERO; + return 0; + case CONFIG_VSC9953_TAG_CFG_ALL_ZERO: + *mode = EGRESS_UNTAG_ZERO; + return 0; + case CONFIG_VSC9953_TAG_CFG_ALL: + *mode = EGRESS_UNTAG_NONE; + return 0; + default: + printf("Unknown egress tagging configuration for port %d\n", + port_no); + return -1; + } +} + +/* Shiw egress tagging configuration for a VSC9953 port */ +static void vsc9953_port_vlan_egr_untag_show(int port_no) +{ + enum egress_untag_mode mode; + + if (vsc9953_port_vlan_egr_untag_get(port_no, &mode)) { + printf("%7d\t%17s\n", port_no, "-"); + return; + } + + printf("%7d\t", port_no); + switch (mode) { + case EGRESS_UNTAG_ALL: + printf("%17s\n", "none"); + break; + case EGRESS_UNTAG_NONE: + printf("%17s\n", "all"); + break; + case EGRESS_UNTAG_PVID_AND_ZERO: + printf("%17s\n", "all but PVID and 0"); + break; + case EGRESS_UNTAG_ZERO: + printf("%17s\n", "all but 0"); + break; + default: + printf("%17s\n", "-"); + } +} +#endif + static void vsc9953_port_all_vlan_egress_untagged_set( enum egress_untag_mode mode) { @@ -954,6 +1048,102 @@ static void vsc9953_port_statistics_clear(int port_no) CONFIG_VSC9953_STAT_CLEAR_DR); } +/* Add/remove a port to/from a VLAN */ +static void vsc9953_vlan_table_membership_set(int vid, u32 port_no, u8 add) +{ + struct vsc9953_analyzer *l2ana_reg; + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + if (!vsc9953_vlan_table_poll_idle()) { + debug("VLAN table timeout\n"); + return; + } + + clrsetbits_le32(&l2ana_reg->ana_tables.vlan_tidx, + CONFIG_VSC9953_ANA_TBL_VID_MASK, + field_set(vid, CONFIG_VSC9953_ANA_TBL_VID_MASK)); + clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access, + CONFIG_VSC9953_VLAN_CMD_MASK, + field_set(CONFIG_VSC9953_VLAN_CMD_READ, + CONFIG_VSC9953_VLAN_CMD_MASK)); + + if (!vsc9953_vlan_table_poll_idle()) { + debug("VLAN table timeout\n"); + return; + } + + clrsetbits_le32(&l2ana_reg->ana_tables.vlan_tidx, + CONFIG_VSC9953_ANA_TBL_VID_MASK, + field_set(vid, CONFIG_VSC9953_ANA_TBL_VID_MASK)); + + if (!add) { + clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access, + CONFIG_VSC9953_VLAN_CMD_MASK | + (field_set((1 << port_no), + CONFIG_VSC9953_VLAN_PORT_MASK) & + CONFIG_VSC9953_VLAN_PORT_MASK), + field_set(CONFIG_VSC9953_VLAN_CMD_WRITE, + CONFIG_VSC9953_VLAN_CMD_MASK)); + } else { + clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access, + CONFIG_VSC9953_VLAN_CMD_MASK, + field_set(CONFIG_VSC9953_VLAN_CMD_WRITE, + CONFIG_VSC9953_VLAN_CMD_MASK) | + (field_set((1 << port_no), + CONFIG_VSC9953_VLAN_PORT_MASK) & + CONFIG_VSC9953_VLAN_PORT_MASK)); + } + + /* wait for VLAN table command to flush */ + if (!vsc9953_vlan_table_poll_idle()) { + debug("VLAN table timeout\n"); + return; + } +} + +/* show VLAN membership for a port */ +static void vsc9953_vlan_membership_show(int port_no) +{ + u32 val; + struct vsc9953_analyzer *l2ana_reg; + u32 vid; + + l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET + + VSC9953_ANA_OFFSET); + + printf("Port %d VLAN membership: ", port_no); + + for (vid = 0; vid < VSC9953_MAX_VLAN; vid++) { + if (!vsc9953_vlan_table_poll_idle()) { + debug("VLAN table timeout\n"); + return; + } + + clrsetbits_le32(&l2ana_reg->ana_tables.vlan_tidx, + CONFIG_VSC9953_ANA_TBL_VID_MASK, + field_set(vid, + CONFIG_VSC9953_ANA_TBL_VID_MASK)); + clrsetbits_le32(&l2ana_reg->ana_tables.vlan_access, + CONFIG_VSC9953_VLAN_CMD_MASK, + field_set(CONFIG_VSC9953_VLAN_CMD_READ, + CONFIG_VSC9953_VLAN_CMD_MASK)); + + if (!vsc9953_vlan_table_poll_idle()) { + debug("VLAN table timeout\n"); + return; + } + + val = in_le32(&l2ana_reg->ana_tables.vlan_access); + + if (!!(val & (field_set((1 << port_no), + CONFIG_VSC9953_VLAN_PORT_MASK)))) + printf("%d ", vid); + } + printf("\n"); +} + /* wait for FDB to become available */ static int vsc9953_mac_table_poll_idle(void) { @@ -965,7 +1155,7 @@ static int vsc9953_mac_table_poll_idle(void) timeout = 50000; while (((in_le32(&l2ana_reg->ana_tables.mac_access) & - CONFIG_VSC9953_MAC_CMD_MASK) != + CONFIG_VSC9953_MAC_CMD_MASK) != CONFIG_VSC9953_MAC_CMD_IDLE) && --timeout) udelay(1); @@ -1313,6 +1503,51 @@ static void vsc9953_mac_table_flush(int port, int vid) vsc9953_mac_table_age(port, vid); } +enum egress_vlan_tag { + EGR_TAG_CLASS = 0, + EGR_TAG_PVID, +}; + +/* Set egress tag mode for a VSC9953 port */ +static void vsc9953_port_vlan_egress_tag_set(int port_no, + enum egress_vlan_tag mode) +{ + struct vsc9953_rew_reg *l2rew_reg; + + l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET + + VSC9953_REW_OFFSET); + + switch (mode) { + case EGR_TAG_CLASS: + clrbits_le32(&l2rew_reg->port[port_no].port_tag_cfg, + CONFIG_VSC9953_TAG_VID_PVID); + break; + case EGR_TAG_PVID: + setbits_le32(&l2rew_reg->port[port_no].port_tag_cfg, + CONFIG_VSC9953_TAG_VID_PVID); + break; + default: + printf("Unknown egress VLAN tag mode for port %d\n", port_no); + } +} + +/* Get egress tag mode for a VSC9953 port */ +static void vsc9953_port_vlan_egress_tag_get(int port_no, + enum egress_vlan_tag *mode) +{ + u32 val; + struct vsc9953_rew_reg *l2rew_reg; + + l2rew_reg = (struct vsc9953_rew_reg *)(VSC9953_OFFSET + + VSC9953_REW_OFFSET); + + val = in_le32(&l2rew_reg->port[port_no].port_tag_cfg); + if (val & CONFIG_VSC9953_TAG_VID_PVID) + *mode = EGR_TAG_PVID; + else + *mode = EGR_TAG_CLASS; +} + /* IDs used to track keywords in a command */ enum keyword_id { id_key_end = -1, @@ -1330,12 +1565,20 @@ enum keyword_id { id_add, id_del, id_flush, + id_pvid, + id_untagged, + id_all, + id_none, + id_egress, + id_tag, + id_classified, id_count, /* keep last */ }; enum keyword_opt_id { id_port_no = id_count + 1, id_vlan_no, + id_pvid_no, id_add_del_no, id_add_del_mac, id_count_all, /* keep last */ @@ -1520,6 +1763,241 @@ static int vsc9953_learn_set_key_func(struct command_def *parsed_cmd) return 0; } +#define VSC9953_PVID_HELP "ethsw [port <port_no>] " \ +"pvid { [help] | show | <pvid> } " \ +"- set/show PVID (ingress and egress VLAN tagging) for a port" + +static int vsc9953_pvid_help_key_func(struct command_def *parsed_cmd) +{ + printf(VSC9953_PVID_HELP"\n"); + + return 0; +} + +static int vsc9953_pvid_show_key_func(struct command_def *parsed_cmd) +{ + int i, pvid; + + if (parsed_cmd->port != VSC9953_CMD_PORT_ALL) { + if (vsc9953_port_vlan_pvid_get(parsed_cmd->port, &pvid)) + return -1; + printf("%7s %7s\n", "Port", "PVID"); + printf("%7d %7d\n", parsed_cmd->port, pvid); + } else { + printf("%7s %7s\n", "Port", "PVID"); + for (i = 0; i < VSC9953_MAX_PORTS; i++) { + if (vsc9953_port_vlan_pvid_get(i, &pvid)) + continue; + printf("%7d %7d\n", i, pvid); + } + } + + return 0; +} + +static int vsc9953_pvid_set_key_func(struct command_def *parsed_cmd) +{ + /* PVID number should be set in parsed_cmd->vid */ + if (parsed_cmd->vid == VSC9953_CMD_VLAN_ALL) { + printf("Please set a vlan value\n"); + return -1; + } + + if (parsed_cmd->port != VSC9953_CMD_PORT_ALL) + vsc9953_port_vlan_pvid_set(parsed_cmd->port, parsed_cmd->vid); + else + vsc9953_port_all_vlan_pvid_set(parsed_cmd->vid); + + return 0; +} + +#define VSC9953_VLAN_HELP "ethsw [port <port_no>] vlan " \ +"{ [help] | show | add <vid> | del <vid> } " \ +"- add a VLAN to a port (VLAN members)" + +static int vsc9953_vlan_help_key_func(struct command_def *parsed_cmd) +{ + printf(VSC9953_VLAN_HELP"\n"); + + return 0; +} + +static int vsc9953_vlan_show_key_func(struct command_def *parsed_cmd) +{ + int i; + + if (parsed_cmd->port != VSC9953_CMD_PORT_ALL) { + vsc9953_vlan_membership_show(parsed_cmd->port); + } else { + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_vlan_membership_show(i); + } + + return 0; +} + +static int vsc9953_vlan_set_key_func(struct command_def *parsed_cmd) +{ + int i, add; + + /* VLAN should be set in parsed_cmd->vid */ + if (parsed_cmd->vid == VSC9953_CMD_VLAN_ALL) { + printf("Please set a vlan value\n"); + return -1; + } + + /* keywords add/delete should be the last but one in array */ + if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 2] == + id_add) + add = 1; + else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 2] == + id_del) + add = 0; + else + return -1; + + if (parsed_cmd->port != VSC9953_CMD_PORT_ALL) { + vsc9953_vlan_table_membership_set(parsed_cmd->vid, + parsed_cmd->port, add); + } else { + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_vlan_table_membership_set(parsed_cmd->vid, i, + add); + } + + return 0; +} + +#define VSC9953_PORT_UNTAG_HELP "ethsw [port <port_no>] untagged " \ +"{ [help] | show | all | none | pvid } " \ +" - set egress tagging mod for a port" + +static int vsc9953_port_untag_help_key_func(struct command_def *parsed_cmd) +{ + printf(VSC9953_PORT_UNTAG_HELP"\n"); + + return 0; +} + +static int vsc9953_port_untag_show_key_func(struct command_def *parsed_cmd) +{ + int i; + + printf("%7s\t%17s\n", "Port", "Egress VLAN tag"); + if (parsed_cmd->port != VSC9953_CMD_PORT_ALL) { + vsc9953_port_vlan_egr_untag_show(parsed_cmd->port); + } else { + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_port_vlan_egr_untag_show(i); + } + + return 0; +} + +static int vsc9953_port_untag_set_key_func(struct command_def *parsed_cmd) +{ + int i; + enum egress_untag_mode mode; + + /* keywords for the untagged mode are the last in the array */ + if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == + id_all) + mode = EGRESS_UNTAG_ALL; + else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == + id_none) + mode = EGRESS_UNTAG_NONE; + else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == + id_pvid) + mode = EGRESS_UNTAG_PVID_AND_ZERO; + else + return -1; + + if (parsed_cmd->port != VSC9953_CMD_PORT_ALL) { + vsc9953_port_vlan_egr_untag_set(parsed_cmd->port, mode); + } else { + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_port_vlan_egr_untag_set(i, mode); + } + + return 0; +} + +#define VSC9953_EGR_VLAN_TAG_HELP "ethsw [port <port_no>] egress tag " \ +"{ [help] | show | pvid | classified } " \ +"- Configure VID source for egress tag. " \ +"Tag's VID could be the frame's classified VID or the PVID of the port" + +static int vsc9953_egr_tag_help_key_func(struct command_def *parsed_cmd) +{ + printf(VSC9953_EGR_VLAN_TAG_HELP"\n"); + + return 0; +} + +static int vsc9953_egr_vlan_tag_show_key_func(struct command_def *parsed_cmd) +{ + int i; + enum egress_vlan_tag mode; + + if (parsed_cmd->port != VSC9953_CMD_PORT_ALL) { + vsc9953_port_vlan_egress_tag_get(parsed_cmd->port, &mode); + printf("%7s\t%12s\n", "Port", "Egress VID"); + printf("%7d\t", parsed_cmd->port); + switch (mode) { + case EGR_TAG_CLASS: + printf("%12s\n", "classified"); + break; + case EGR_TAG_PVID: + printf("%12s\n", "pvid"); + break; + default: + printf("%12s\n", "-"); + } + } else { + printf("%7s\t%12s\n", "Port", "Egress VID"); + for (i = 0; i < VSC9953_MAX_PORTS; i++) { + vsc9953_port_vlan_egress_tag_get(i, &mode); + switch (mode) { + case EGR_TAG_CLASS: + printf("%7d\t%12s\n", i, "classified"); + break; + case EGR_TAG_PVID: + printf("%7d\t%12s\n", i, "pvid"); + break; + default: + printf("%7d\t%12s\n", i, "-"); + } + } + } + + return 0; +} + +static int vsc9953_egr_vlan_tag_set_key_func(struct command_def *parsed_cmd) +{ + int i; + enum egress_vlan_tag mode; + + /* keywords for the egress vlan tag mode are the last in the array */ + if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == + id_pvid) + mode = EGR_TAG_PVID; + else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] == + id_classified) + mode = EGR_TAG_CLASS; + else + return -1; + + if (parsed_cmd->port != VSC9953_CMD_PORT_ALL) { + vsc9953_port_vlan_egress_tag_set(parsed_cmd->port, mode); + } else { + for (i = 0; i < VSC9953_MAX_PORTS; i++) + vsc9953_port_vlan_egress_tag_set(i, mode); + } + + return 0; +} + #define VSC9953_FDB_HELP "ethsw [port <port_no>] [vlan <vid>] fdb " \ "{ [help] | show | flush | { add | del } <mac> } " \ "- Add/delete a mac entry in FDB; use show to see FDB entries; " \ @@ -1669,6 +2147,149 @@ struct keywords_to_function { .keyword_function = &vsc9953_learn_set_key_func, }, { .cmd_keyword = { + id_pvid, + id_key_end, + }, + .keyword_function = &vsc9953_pvid_help_key_func, + }, { + .cmd_keyword = { + id_pvid, + id_help, + id_key_end, + }, + .keyword_function = &vsc9953_pvid_help_key_func, + }, { + .cmd_keyword = { + id_pvid, + id_show, + id_key_end, + }, + .keyword_function = &vsc9953_pvid_show_key_func, + }, { + .cmd_keyword = { + id_pvid, + id_pvid_no, + id_key_end, + }, + .keyword_function = &vsc9953_pvid_set_key_func, + }, { + .cmd_keyword = { + id_vlan, + id_key_end, + }, + .keyword_function = &vsc9953_vlan_help_key_func, + }, { + .cmd_keyword = { + id_vlan, + id_help, + id_key_end, + }, + .keyword_function = &vsc9953_vlan_help_key_func, + }, { + .cmd_keyword = { + id_vlan, + id_show, + id_key_end, + }, + .keyword_function = &vsc9953_vlan_show_key_func, + }, { + .cmd_keyword = { + id_vlan, + id_add, + id_add_del_no, + id_key_end, + }, + .keyword_function = &vsc9953_vlan_set_key_func, + }, { + .cmd_keyword = { + id_vlan, + id_del, + id_add_del_no, + id_key_end, + }, + .keyword_function = &vsc9953_vlan_set_key_func, + }, { + .cmd_keyword = { + id_untagged, + id_key_end, + }, + .keyword_function = &vsc9953_port_untag_help_key_func, + }, { + .cmd_keyword = { + id_untagged, + id_help, + id_key_end, + }, + .keyword_function = &vsc9953_port_untag_help_key_func, + }, { + .cmd_keyword = { + id_untagged, + id_show, + id_key_end, + }, + .keyword_function = &vsc9953_port_untag_show_key_func, + }, { + .cmd_keyword = { + id_untagged, + id_all, + id_key_end, + }, + .keyword_function = &vsc9953_port_untag_set_key_func, + }, { + .cmd_keyword = { + id_untagged, + id_none, + id_key_end, + }, + .keyword_function = &vsc9953_port_untag_set_key_func, + }, { + .cmd_keyword = { + id_untagged, + id_pvid, + id_key_end, + }, + .keyword_function = &vsc9953_port_untag_set_key_func, + }, { + .cmd_keyword = { + id_egress, + id_tag, + id_key_end, + }, + .keyword_function = &vsc9953_egr_tag_help_key_func, + }, { + .cmd_keyword = { + id_egress, + id_tag, + id_help, + id_key_end, + }, + .keyword_function = &vsc9953_egr_tag_help_key_func, + }, { + .cmd_keyword = { + id_egress, + id_tag, + id_show, + id_key_end, + }, + .keyword_function = &vsc9953_egr_vlan_tag_show_key_func, + }, { + .cmd_keyword = { + id_egress, + id_tag, + id_pvid, + id_key_end, + }, + .keyword_function = &vsc9953_egr_vlan_tag_set_key_func, + }, { + .cmd_keyword = { + id_egress, + id_tag, + id_classified, + id_key_end, + }, + .keyword_function = &vsc9953_egr_vlan_tag_set_key_func, + }, { + .cmd_keyword = { id_fdb, id_key_end, }, @@ -1748,6 +2369,9 @@ static int keyword_match_port(enum keyword_id key_id, int argc, static int keyword_match_vlan(enum keyword_id key_id, int argc, char *const argv[], int *argc_nr, struct command_def *parsed_cmd); +static int keyword_match_pvid(enum keyword_id key_id, int argc, + char *const argv[], int *argc_nr, + struct command_def *parsed_cmd); static int keyword_match_mac_addr(enum keyword_id key_id, int argc, char *const argv[], int *argc_nr, struct command_def *parsed_cmd); @@ -1802,6 +2426,27 @@ struct keyword_def { }, { .keyword_name = "flush", .match = &keyword_match_gen, + }, { + .keyword_name = "pvid", + .match = &keyword_match_pvid, + }, { + .keyword_name = "untagged", + .match = &keyword_match_gen, + }, { + .keyword_name = "all", + .match = &keyword_match_gen, + }, { + .keyword_name = "none", + .match = &keyword_match_gen, + }, { + .keyword_name = "egress", + .match = &keyword_match_gen, + }, { + .keyword_name = "tag", + .match = &keyword_match_gen, + }, { + .keyword_name = "classified", + .match = &keyword_match_gen, }, }; @@ -1896,6 +2541,33 @@ static int keyword_match_vlan(enum keyword_id key_id, int argc, return 0; } +/* Function used to match the command's pvid */ +static int keyword_match_pvid(enum keyword_id key_id, int argc, + char *const argv[], int *argc_nr, + struct 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) { + if (!VSC9953_VLAN_CHECK(val)) { + printf("Invalid pvid number: %lu\n", val); + return 0; + } + parsed_cmd->vid = val; + (*argc_nr)++; + parsed_cmd->cmd_to_keywords[*argc_nr] = id_pvid_no; + return 1; + } + + return 1; +} + /* check if the string has the format for a MAC address */ static int string_is_mac_addr(const char *mac) { @@ -2094,6 +2766,10 @@ U_BOOT_CMD(ethsw, VSC9953_MAX_CMD_PARAMS, 0, do_ethsw, VSC9953_PORT_STATS_HELP"\n" VSC9953_LEARN_HELP"\n" VSC9953_FDB_HELP"\n" + VSC9953_VLAN_HELP"\n" + VSC9953_PVID_HELP"\n" + VSC9953_PORT_UNTAG_HELP"\n" + VSC9953_EGR_VLAN_TAG_HELP"\n" ); #endif /* CONFIG_VSC9953_CMD */ diff --git a/include/vsc9953.h b/include/vsc9953.h index 051c24e..6eb22a9 100644 --- a/include/vsc9953.h +++ b/include/vsc9953.h @@ -115,6 +115,8 @@ /* Macros for vsc9953_ana_port.vlan_cfg register */ #define CONFIG_VSC9953_VLAN_CFG_AWARE_ENA 0x00100000 #define CONFIG_VSC9953_VLAN_CFG_POP_CNT_MASK 0x000c0000 +#define CONFIG_VSC9953_VLAN_CFG_POP_CNT_NONE 0x00000000 +#define CONFIG_VSC9953_VLAN_CFG_POP_CNT_ONE 0x00040000 #define CONFIG_VSC9953_VLAN_CFG_VID_MASK 0x00000fff /* Macros for vsc9953_rew_port.port_vlan_cfg register */ @@ -149,6 +151,7 @@ #define CONFIG_VSC9953_TAG_CFG_ALL_PVID_ZERO 0x00000080 #define CONFIG_VSC9953_TAG_CFG_ALL_ZERO 0x00000100 #define CONFIG_VSC9953_TAG_CFG_ALL 0x00000180 +#define CONFIG_VSC9953_TAG_VID_PVID 0x00000010 /* Macros for vsc9953_ana_ana.anag_efil register */ #define CONFIG_VSC9953_AGE_PORT_EN 0x00080000 -- 1.9.3 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot