Hi Codrin, On Tue, Jun 23, 2015 at 11:48 AM, Codrin Ciubotariu <codrin.ciubota...@freescale.com> wrote: > 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
Why does this need to be defined outside of the #ifdef already at the bottom of the file? > +/* Set PVID for a VSC9953 port */ > +static int vsc9953_port_vlan_pvid_get(int port_nr, int *pvid) > +{ > + u32 val; Use a single space. > + struct vsc9953_analyzer *l2ana_reg; > + > + /* Administrative down */ > + if ((!vsc9953_l2sw.port[port_nr].enabled)) { Why do you have double "((" and "))"? > + 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 Why does this need to be defined outside of the #ifdef already at the bottom of the file? > +/* 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)) { Why do you have double "((" and "))"? > + 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 */ Shiw -> Show > +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)))) There is no need for "!!" in an if statement. Drop it and the extra parenthesis. > + 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; Use a single space. > + > + 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; Please use: + return CMD_RET_SUCCESS; > +} > + > +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; Please use: + return CMD_RET_FAILURE; > + 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; Please use: + return CMD_RET_SUCCESS; > +} > + > +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; Please use: + return CMD_RET_USAGE; > + } > + > + 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; Please use: + return CMD_RET_SUCCESS; > +} > + > +#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; Please use: + return CMD_RET_SUCCESS; > +} > + > +static int vsc9953_vlan_show_key_func(struct command_def *parsed_cmd) > +{ > + int i; Use a single space. > + > + 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; Please use: + return CMD_RET_SUCCESS; > +} > + > +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; Please use: + return CMD_RET_USAGE; > + } > + > + /* 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; Please use: + return CMD_RET_USAGE; > + > + 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; Please use: + return CMD_RET_SUCCESS; > +} > + > +#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; Please use: + return CMD_RET_SUCCESS; > +} > + > +static int vsc9953_port_untag_show_key_func(struct command_def *parsed_cmd) > +{ > + int i; Use a single space. > + > + 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; Please use: + return CMD_RET_SUCCESS; > +} > + > +static int vsc9953_port_untag_set_key_func(struct command_def *parsed_cmd) > +{ > + int i; > + enum egress_untag_mode mode; Use a single space. > + > + /* 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; Please use: + return CMD_RET_USAGE; > + > + 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; Please use: + return CMD_RET_SUCCESS; > +} > + > +#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; Please use: + return CMD_RET_SUCCESS; > +} > + > +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; Please use: + return CMD_RET_SUCCESS; > +} > + > +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; Please use: + return CMD_RET_USAGE; > + > + 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; Please use: + return CMD_RET_SUCCESS; > +} > + > #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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot