diff options
Diffstat (limited to 'common/cmd_ethsw.c')
-rw-r--r-- | common/cmd_ethsw.c | 1027 |
1 files changed, 0 insertions, 1027 deletions
diff --git a/common/cmd_ethsw.c b/common/cmd_ethsw.c deleted file mode 100644 index 8e452e9..0000000 --- a/common/cmd_ethsw.c +++ /dev/null @@ -1,1027 +0,0 @@ -/* - * Copyright 2015 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Ethernet Switch commands - */ - -#include <common.h> -#include <command.h> -#include <errno.h> -#include <env_flags.h> -#include <ethsw.h> - -static const char *ethsw_name; - -#define ETHSW_PORT_STATS_HELP "ethsw [port <port_no>] statistics " \ -"{ [help] | [clear] } - show an l2 switch port's statistics" - -static int ethsw_port_stats_help_key_func(struct ethsw_command_def *parsed_cmd) -{ - printf(ETHSW_PORT_STATS_HELP"\n"); - - return CMD_RET_SUCCESS; -} - -#define ETHSW_LEARN_HELP "ethsw [port <port_no>] learning " \ -"{ [help] | show | auto | disable } " \ -"- enable/disable/show learning configuration on a port" - -static int ethsw_learn_help_key_func(struct ethsw_command_def *parsed_cmd) -{ - printf(ETHSW_LEARN_HELP"\n"); - - return CMD_RET_SUCCESS; -} - -#define ETHSW_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; " \ -"if vlan <vid> is missing, VID 1 will be used" - -static int ethsw_fdb_help_key_func(struct ethsw_command_def *parsed_cmd) -{ - printf(ETHSW_FDB_HELP"\n"); - - return CMD_RET_SUCCESS; -} - -#define ETHSW_PVID_HELP "ethsw [port <port_no>] " \ -"pvid { [help] | show | <pvid> } " \ -"- set/show PVID (ingress and egress VLAN tagging) for a port" - -static int ethsw_pvid_help_key_func(struct ethsw_command_def *parsed_cmd) -{ - printf(ETHSW_PVID_HELP"\n"); - - return CMD_RET_SUCCESS; -} - -#define ETHSW_VLAN_HELP "ethsw [port <port_no>] vlan " \ -"{ [help] | show | add <vid> | del <vid> } " \ -"- add a VLAN to a port (VLAN members)" - -static int ethsw_vlan_help_key_func(struct ethsw_command_def *parsed_cmd) -{ - printf(ETHSW_VLAN_HELP"\n"); - - return CMD_RET_SUCCESS; -} - -#define ETHSW_PORT_UNTAG_HELP "ethsw [port <port_no>] untagged " \ -"{ [help] | show | all | none | pvid } " \ -" - set egress tagging mod for a port" - -static int ethsw_port_untag_help_key_func(struct ethsw_command_def *parsed_cmd) -{ - printf(ETHSW_PORT_UNTAG_HELP"\n"); - - return CMD_RET_SUCCESS; -} - -#define ETHSW_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 ethsw_egr_tag_help_key_func(struct ethsw_command_def *parsed_cmd) -{ - printf(ETHSW_EGR_VLAN_TAG_HELP"\n"); - - return CMD_RET_SUCCESS; -} - -#define ETHSW_VLAN_FDB_HELP "ethsw vlan fdb " \ -"{ [help] | show | shared | private } " \ -"- make VLAN learning shared or private" - -static int ethsw_vlan_learn_help_key_func(struct ethsw_command_def *parsed_cmd) -{ - printf(ETHSW_VLAN_FDB_HELP"\n"); - - return CMD_RET_SUCCESS; -} - -#define ETHSW_PORT_INGR_FLTR_HELP "ethsw [port <port_no>] ingress filtering" \ -" { [help] | show | enable | disable } " \ -"- enable/disable VLAN ingress filtering on port" - -static int ethsw_ingr_fltr_help_key_func(struct ethsw_command_def *parsed_cmd) -{ - printf(ETHSW_PORT_INGR_FLTR_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; - int (*keyword_function)(struct ethsw_command_def *parsed_cmd); -} ethsw_cmd_def[] = { - { - .cmd_keyword = { - ethsw_id_enable, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - port_enable), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_disable, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - port_disable), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_show, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - port_show), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_statistics, - ethsw_id_help, - ethsw_id_key_end, - }, - .cmd_func_offset = -1, - .keyword_function = ðsw_port_stats_help_key_func, - }, { - .cmd_keyword = { - ethsw_id_statistics, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - port_stats), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_statistics, - ethsw_id_clear, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - port_stats_clear), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_learning, - ethsw_id_key_end, - }, - .cmd_func_offset = -1, - .keyword_function = ðsw_learn_help_key_func, - }, { - .cmd_keyword = { - ethsw_id_learning, - ethsw_id_help, - ethsw_id_key_end, - }, - .cmd_func_offset = -1, - .keyword_function = ðsw_learn_help_key_func, - }, { - .cmd_keyword = { - ethsw_id_learning, - ethsw_id_show, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - port_learn_show), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_learning, - ethsw_id_auto, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - port_learn), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_learning, - ethsw_id_disable, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - port_learn), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_fdb, - ethsw_id_key_end, - }, - .cmd_func_offset = -1, - .keyword_function = ðsw_fdb_help_key_func, - }, { - .cmd_keyword = { - ethsw_id_fdb, - ethsw_id_help, - ethsw_id_key_end, - }, - .cmd_func_offset = -1, - .keyword_function = ðsw_fdb_help_key_func, - }, { - .cmd_keyword = { - ethsw_id_fdb, - ethsw_id_show, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - fdb_show), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_fdb, - ethsw_id_flush, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - fdb_flush), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_fdb, - ethsw_id_add, - ethsw_id_add_del_mac, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - fdb_entry_add), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_fdb, - ethsw_id_del, - ethsw_id_add_del_mac, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - fdb_entry_del), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_pvid, - ethsw_id_key_end, - }, - .cmd_func_offset = -1, - .keyword_function = ðsw_pvid_help_key_func, - }, { - .cmd_keyword = { - ethsw_id_pvid, - ethsw_id_help, - ethsw_id_key_end, - }, - .cmd_func_offset = -1, - .keyword_function = ðsw_pvid_help_key_func, - }, { - .cmd_keyword = { - ethsw_id_pvid, - ethsw_id_show, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - pvid_show), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_pvid, - ethsw_id_pvid_no, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - pvid_set), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_vlan, - ethsw_id_key_end, - }, - .cmd_func_offset = -1, - .keyword_function = ðsw_vlan_help_key_func, - }, { - .cmd_keyword = { - ethsw_id_vlan, - ethsw_id_help, - ethsw_id_key_end, - }, - .cmd_func_offset = -1, - .keyword_function = ðsw_vlan_help_key_func, - }, { - .cmd_keyword = { - ethsw_id_vlan, - ethsw_id_show, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - vlan_show), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_vlan, - ethsw_id_add, - ethsw_id_add_del_no, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - vlan_set), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_vlan, - ethsw_id_del, - ethsw_id_add_del_no, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - vlan_set), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_untagged, - ethsw_id_key_end, - }, - .cmd_func_offset = -1, - .keyword_function = ðsw_port_untag_help_key_func, - }, { - .cmd_keyword = { - ethsw_id_untagged, - ethsw_id_help, - ethsw_id_key_end, - }, - .cmd_func_offset = -1, - .keyword_function = ðsw_port_untag_help_key_func, - }, { - .cmd_keyword = { - ethsw_id_untagged, - ethsw_id_show, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - port_untag_show), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_untagged, - ethsw_id_all, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - port_untag_set), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_untagged, - ethsw_id_none, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - port_untag_set), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_untagged, - ethsw_id_pvid, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - port_untag_set), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_egress, - ethsw_id_tag, - ethsw_id_key_end, - }, - .cmd_func_offset = -1, - .keyword_function = ðsw_egr_tag_help_key_func, - }, { - .cmd_keyword = { - ethsw_id_egress, - ethsw_id_tag, - ethsw_id_help, - ethsw_id_key_end, - }, - .cmd_func_offset = -1, - .keyword_function = ðsw_egr_tag_help_key_func, - }, { - .cmd_keyword = { - ethsw_id_egress, - ethsw_id_tag, - ethsw_id_show, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - port_egr_vlan_show), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_egress, - ethsw_id_tag, - ethsw_id_pvid, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - port_egr_vlan_set), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_egress, - ethsw_id_tag, - ethsw_id_classified, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - port_egr_vlan_set), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_vlan, - ethsw_id_fdb, - ethsw_id_key_end, - }, - .cmd_func_offset = -1, - .keyword_function = ðsw_vlan_learn_help_key_func, - }, { - .cmd_keyword = { - ethsw_id_vlan, - ethsw_id_fdb, - ethsw_id_help, - ethsw_id_key_end, - }, - .cmd_func_offset = -1, - .keyword_function = ðsw_vlan_learn_help_key_func, - }, { - .cmd_keyword = { - ethsw_id_vlan, - ethsw_id_fdb, - ethsw_id_show, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - vlan_learn_show), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_vlan, - ethsw_id_fdb, - ethsw_id_shared, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - vlan_learn_set), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_vlan, - ethsw_id_fdb, - ethsw_id_private, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - vlan_learn_set), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_ingress, - ethsw_id_filtering, - ethsw_id_key_end, - }, - .cmd_func_offset = -1, - .keyword_function = ðsw_ingr_fltr_help_key_func, - }, { - .cmd_keyword = { - ethsw_id_ingress, - ethsw_id_filtering, - ethsw_id_help, - ethsw_id_key_end, - }, - .cmd_func_offset = -1, - .keyword_function = ðsw_ingr_fltr_help_key_func, - }, { - .cmd_keyword = { - ethsw_id_ingress, - ethsw_id_filtering, - ethsw_id_show, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - port_ingr_filt_show), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_ingress, - ethsw_id_filtering, - ethsw_id_enable, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - port_ingr_filt_set), - .keyword_function = NULL, - }, { - .cmd_keyword = { - ethsw_id_ingress, - ethsw_id_filtering, - ethsw_id_disable, - ethsw_id_key_end, - }, - .cmd_func_offset = offsetof(struct ethsw_command_func, - port_ingr_filt_set), - .keyword_function = NULL, - }, -}; - -struct keywords_optional { - int cmd_keyword[ETHSW_MAX_CMD_PARAMS]; -} cmd_opt_def[] = { - { - .cmd_keyword = { - ethsw_id_port, - ethsw_id_port_no, - ethsw_id_key_end, - }, - }, { - .cmd_keyword = { - ethsw_id_vlan, - ethsw_id_vlan_no, - ethsw_id_key_end, - }, - }, { - .cmd_keyword = { - ethsw_id_port, - ethsw_id_port_no, - ethsw_id_vlan, - ethsw_id_vlan_no, - ethsw_id_key_end, - }, - }, -}; - -static int keyword_match_gen(enum ethsw_keyword_id key_id, int argc, char - *const argv[], int *argc_nr, - struct ethsw_command_def *parsed_cmd); -static int keyword_match_port(enum ethsw_keyword_id key_id, int argc, - char *const argv[], int *argc_nr, - struct ethsw_command_def *parsed_cmd); -static int keyword_match_vlan(enum ethsw_keyword_id key_id, int argc, - char *const argv[], int *argc_nr, - struct ethsw_command_def *parsed_cmd); -static int keyword_match_pvid(enum ethsw_keyword_id key_id, int argc, - char *const argv[], int *argc_nr, - struct ethsw_command_def *parsed_cmd); -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); - -/* - * Define properties for each keyword; - * keep the order synced with enum ethsw_keyword_id - */ -struct keyword_def { - const char *keyword_name; - int (*match)(enum ethsw_keyword_id key_id, int argc, char *const argv[], - int *argc_nr, struct ethsw_command_def *parsed_cmd); -} keyword[] = { - { - .keyword_name = "help", - .match = &keyword_match_gen, - }, { - .keyword_name = "show", - .match = &keyword_match_gen, - }, { - .keyword_name = "port", - .match = &keyword_match_port - }, { - .keyword_name = "enable", - .match = &keyword_match_gen, - }, { - .keyword_name = "disable", - .match = &keyword_match_gen, - }, { - .keyword_name = "statistics", - .match = &keyword_match_gen, - }, { - .keyword_name = "clear", - .match = &keyword_match_gen, - }, { - .keyword_name = "learning", - .match = &keyword_match_gen, - }, { - .keyword_name = "auto", - .match = &keyword_match_gen, - }, { - .keyword_name = "vlan", - .match = &keyword_match_vlan, - }, { - .keyword_name = "fdb", - .match = &keyword_match_gen, - }, { - .keyword_name = "add", - .match = &keyword_match_mac_addr, - }, { - .keyword_name = "del", - .match = &keyword_match_mac_addr, - }, { - .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, - }, { - .keyword_name = "shared", - .match = &keyword_match_gen, - }, { - .keyword_name = "private", - .match = &keyword_match_gen, - }, { - .keyword_name = "ingress", - .match = &keyword_match_gen, - }, { - .keyword_name = "filtering", - .match = &keyword_match_gen, - }, -}; - -/* - * Function used by an Ethernet Switch driver to set the functions - * that must be called by the parser when an ethsw command is given - */ -int ethsw_define_functions(const struct ethsw_command_func *cmd_func) -{ - int i; - void **aux_p; - int (*cmd_func_aux)(struct ethsw_command_def *); - - if (!cmd_func->ethsw_name) - return -EINVAL; - - ethsw_name = cmd_func->ethsw_name; - - for (i = 0; i < ARRAY_SIZE(ethsw_cmd_def); i++) { - /* - * get the pointer to the function send by the Ethernet Switch - * driver that corresponds to the proper ethsw command - */ - if (ethsw_cmd_def[i].keyword_function) - continue; - - aux_p = (void *)cmd_func + ethsw_cmd_def[i].cmd_func_offset; - - cmd_func_aux = (int (*)(struct ethsw_command_def *)) *aux_p; - ethsw_cmd_def[i].keyword_function = cmd_func_aux; - } - - return 0; -} - -/* Generic function used to match a keyword only by a string */ -static int keyword_match_gen(enum ethsw_keyword_id key_id, int argc, - char *const argv[], int *argc_nr, - struct ethsw_command_def *parsed_cmd) -{ - if (strcmp(argv[*argc_nr], keyword[key_id].keyword_name) == 0) { - parsed_cmd->cmd_to_keywords[*argc_nr] = key_id; - - return 1; - } - return 0; -} - -/* Function used to match the command's port */ -static int keyword_match_port(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 0; - - if (strict_strtoul(argv[*argc_nr + 1], 10, &val) != -EINVAL) { - parsed_cmd->port = val; - (*argc_nr)++; - parsed_cmd->cmd_to_keywords[*argc_nr] = ethsw_id_port_no; - return 1; - } - - return 0; -} - -/* Function used to match the command's vlan */ -static int keyword_match_vlan(enum ethsw_keyword_id key_id, int argc, - char *const argv[], int *argc_nr, - struct ethsw_command_def *parsed_cmd) -{ - unsigned long val; - int aux; - - if (!keyword_match_gen(key_id, argc, argv, argc_nr, parsed_cmd)) - return 0; - - if (*argc_nr + 1 >= argc) - return 0; - - if (strict_strtoul(argv[*argc_nr + 1], 10, &val) != -EINVAL) { - parsed_cmd->vid = val; - (*argc_nr)++; - parsed_cmd->cmd_to_keywords[*argc_nr] = ethsw_id_vlan_no; - return 1; - } - - aux = *argc_nr + 1; - - if (keyword_match_gen(ethsw_id_add, argc, argv, &aux, parsed_cmd)) - parsed_cmd->cmd_to_keywords[*argc_nr + 1] = ethsw_id_add; - else if (keyword_match_gen(ethsw_id_del, argc, argv, &aux, parsed_cmd)) - parsed_cmd->cmd_to_keywords[*argc_nr + 1] = ethsw_id_del; - else - return 0; - - if (*argc_nr + 2 >= argc) - return 0; - - if (strict_strtoul(argv[*argc_nr + 2], 10, &val) != -EINVAL) { - parsed_cmd->vid = val; - (*argc_nr) += 2; - parsed_cmd->cmd_to_keywords[*argc_nr] = ethsw_id_add_del_no; - return 1; - } - - return 0; -} - -/* Function used to match the command's pvid */ -static int keyword_match_pvid(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->vid = val; - (*argc_nr)++; - parsed_cmd->cmd_to_keywords[*argc_nr] = ethsw_id_pvid_no; - } - - return 1; -} - -/* Function used to match the command's MAC address */ -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) -{ - if (!keyword_match_gen(key_id, argc, argv, argc_nr, parsed_cmd)) - return 0; - - if ((*argc_nr + 1 >= argc) || - !is_broadcast_ethaddr(parsed_cmd->ethaddr)) - return 1; - - if (eth_validate_ethaddr_str(argv[*argc_nr + 1])) { - printf("Invalid MAC address: %s\n", argv[*argc_nr + 1]); - return 0; - } - - eth_parse_enetaddr(argv[*argc_nr + 1], parsed_cmd->ethaddr); - - if (is_broadcast_ethaddr(parsed_cmd->ethaddr)) { - memset(parsed_cmd->ethaddr, 0xFF, sizeof(parsed_cmd->ethaddr)); - return 0; - } - - parsed_cmd->cmd_to_keywords[*argc_nr + 1] = ethsw_id_add_del_mac; - - 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) -{ - int i; - int keyw_opt_matched; - int argc_val_max; - int const *cmd_keyw_p; - int const *cmd_keyw_opt_p; - - /* remember the best match */ - argc_val_max = *argc_val; - - /* - * check if our command's optional keywords match the optional - * keywords of an available command - */ - for (i = 0; i < ARRAY_SIZE(ethsw_cmd_def); i++) { - keyw_opt_matched = 0; - cmd_keyw_p = &parsed_cmd->cmd_to_keywords[keyw_opt_matched]; - cmd_keyw_opt_p = &cmd_opt_def[i].cmd_keyword[keyw_opt_matched]; - - /* - * increase the number of keywords that - * matched with a command - */ - while (keyw_opt_matched + *argc_val < - parsed_cmd->cmd_keywords_nr && - *cmd_keyw_opt_p != ethsw_id_key_end && - *(cmd_keyw_p + *argc_val) == *cmd_keyw_opt_p) { - keyw_opt_matched++; - cmd_keyw_p++; - cmd_keyw_opt_p++; - } - - /* - * if all our optional command's keywords perfectly match an - * optional pattern, then we can move to the next defined - * keywords in our command; remember the one that matched the - * greatest number of keywords - */ - if (keyw_opt_matched + *argc_val <= - parsed_cmd->cmd_keywords_nr && - *cmd_keyw_opt_p == ethsw_id_key_end && - *argc_val + keyw_opt_matched > argc_val_max) - argc_val_max = *argc_val + keyw_opt_matched; - } - - *argc_val = argc_val_max; -} - -/* - * Finds the function to call based on keywords and - * modifies *argc_va to skip them - */ -static void cmd_keywords_check(struct ethsw_command_def *parsed_cmd, - int *argc_val) -{ - int i; - int keyw_matched; - int *cmd_keyw_p; - int *cmd_keyw_def_p; - - /* - * check if our command's keywords match the - * keywords of an available command - */ - for (i = 0; i < ARRAY_SIZE(ethsw_cmd_def); i++) { - keyw_matched = 0; - cmd_keyw_p = &parsed_cmd->cmd_to_keywords[keyw_matched]; - cmd_keyw_def_p = ðsw_cmd_def[i].cmd_keyword[keyw_matched]; - - /* - * increase the number of keywords that - * matched with a command - */ - while (keyw_matched + *argc_val < parsed_cmd->cmd_keywords_nr && - *cmd_keyw_def_p != ethsw_id_key_end && - *(cmd_keyw_p + *argc_val) == *cmd_keyw_def_p) { - keyw_matched++; - cmd_keyw_p++; - cmd_keyw_def_p++; - } - - /* - * if all our command's keywords perfectly match an - * available command, then we get the function we need to call - * to configure the Ethernet Switch - */ - if (keyw_matched && keyw_matched + *argc_val == - parsed_cmd->cmd_keywords_nr && - *cmd_keyw_def_p == ethsw_id_key_end) { - *argc_val += keyw_matched; - parsed_cmd->cmd_function = - ethsw_cmd_def[i].keyword_function; - return; - } - } -} - -/* find all the keywords in the command */ -static int keywords_find(int argc, char * const argv[], - struct ethsw_command_def *parsed_cmd) -{ - int i; - int j; - int argc_val; - int rc = CMD_RET_SUCCESS; - - for (i = 1; i < argc; i++) { - for (j = 0; j < ethsw_id_count; j++) { - if (keyword[j].match(j, argc, argv, &i, parsed_cmd)) - break; - } - } - - /* if there is no keyword match for a word, the command is invalid */ - for (i = 1; i < argc; i++) - if (parsed_cmd->cmd_to_keywords[i] == ethsw_id_key_end) - rc = CMD_RET_USAGE; - - parsed_cmd->cmd_keywords_nr = argc; - argc_val = 1; - - /* get optional parameters first */ - cmd_keywords_opt_check(parsed_cmd, &argc_val); - - if (argc_val == parsed_cmd->cmd_keywords_nr) - return CMD_RET_USAGE; - - /* - * check the keywords and if a match is found, - * get the function to call - */ - cmd_keywords_check(parsed_cmd, &argc_val); - - /* error if not all commands' parameters were matched */ - if (argc_val == parsed_cmd->cmd_keywords_nr) { - if (!parsed_cmd->cmd_function) { - printf("Command not available for: %s\n", ethsw_name); - rc = CMD_RET_FAILURE; - } - } else { - rc = CMD_RET_USAGE; - } - - return rc; -} - -static void command_def_init(struct ethsw_command_def *parsed_cmd) -{ - int i; - - for (i = 0; i < ETHSW_MAX_CMD_PARAMS; i++) - parsed_cmd->cmd_to_keywords[i] = ethsw_id_key_end; - - parsed_cmd->port = ETHSW_CMD_PORT_ALL; - parsed_cmd->vid = ETHSW_CMD_VLAN_ALL; - parsed_cmd->cmd_function = NULL; - - /* We initialize the MAC address with the Broadcast address */ - memset(parsed_cmd->ethaddr, 0xff, sizeof(parsed_cmd->ethaddr)); -} - -/* function to interpret commands starting with "ethsw " */ -static int do_ethsw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - struct ethsw_command_def parsed_cmd; - int rc = CMD_RET_SUCCESS; - - if (argc == 1 || argc >= ETHSW_MAX_CMD_PARAMS) - return CMD_RET_USAGE; - - command_def_init(&parsed_cmd); - - rc = keywords_find(argc, argv, &parsed_cmd); - - if (rc == CMD_RET_SUCCESS) - rc = parsed_cmd.cmd_function(&parsed_cmd); - - return rc; -} - -#define ETHSW_PORT_CONF_HELP "[port <port_no>] { enable | disable | show } " \ -"- enable/disable a port; show shows a port's configuration" - -U_BOOT_CMD(ethsw, ETHSW_MAX_CMD_PARAMS, 0, do_ethsw, - "Ethernet l2 switch commands", - ETHSW_PORT_CONF_HELP"\n" - ETHSW_PORT_STATS_HELP"\n" - ETHSW_LEARN_HELP"\n" - ETHSW_FDB_HELP"\n" - ETHSW_PVID_HELP"\n" - ETHSW_VLAN_HELP"\n" - ETHSW_PORT_UNTAG_HELP"\n" - ETHSW_EGR_VLAN_TAG_HELP"\n" - ETHSW_VLAN_FDB_HELP"\n" - ETHSW_PORT_INGR_FLTR_HELP"\n" -); |