drivers/net/vsc9953: Add command for shared/private VLAN learning
The command: ethsw vlan fdb { [help] | show | shared | private } - make VLAN learning shared or private" configures the FDB to share the FDB entries learned on multiple VLANs or to keep them separated. By default, the FBD uses private VLAN learning. This command has also been added to the ethsw generic parser from common/cmd_ethsw.c Signed-off-by: Johnson Leung <johnson.leung@freescale.com> Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@freescale.com> Acked-by: Joe Hershberger <joe.hershberger@ni.com> Reviewed-by: York Sun <yorksun@freescale.com>
This commit is contained in:
parent
a2477924cd
commit
21d214fcd0
|
@ -92,6 +92,17 @@ static int ethsw_egr_tag_help_key_func(struct ethsw_command_def *parsed_cmd)
|
|||
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;
|
||||
}
|
||||
|
||||
static struct keywords_to_function {
|
||||
enum ethsw_keyword_id cmd_keyword[ETHSW_MAX_CMD_PARAMS];
|
||||
int cmd_func_offset;
|
||||
|
@ -416,6 +427,53 @@ static struct keywords_to_function {
|
|||
.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,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -533,6 +591,12 @@ struct keyword_def {
|
|||
}, {
|
||||
.keyword_name = "classified",
|
||||
.match = &keyword_match_gen,
|
||||
}, {
|
||||
.keyword_name = "shared",
|
||||
.match = &keyword_match_gen,
|
||||
}, {
|
||||
.keyword_name = "private",
|
||||
.match = &keyword_match_gen,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -894,4 +958,5 @@ U_BOOT_CMD(ethsw, ETHSW_MAX_CMD_PARAMS, 0, do_ethsw,
|
|||
ETHSW_VLAN_HELP"\n"
|
||||
ETHSW_PORT_UNTAG_HELP"\n"
|
||||
ETHSW_EGR_VLAN_TAG_HELP"\n"
|
||||
ETHSW_VLAN_FDB_HELP"\n"
|
||||
);
|
||||
|
|
|
@ -1398,6 +1398,55 @@ static void vsc9953_port_vlan_egress_tag_get(int port_no,
|
|||
*mode = EGR_TAG_CLASS;
|
||||
}
|
||||
|
||||
/* VSC9953 VLAN learning modes */
|
||||
enum vlan_learning_mode {
|
||||
SHARED_VLAN_LEARNING,
|
||||
PRIVATE_VLAN_LEARNING,
|
||||
};
|
||||
|
||||
/* Set VLAN learning mode for VSC9953 */
|
||||
static void vsc9953_vlan_learning_set(enum vlan_learning_mode lrn_mode)
|
||||
{
|
||||
struct vsc9953_analyzer *l2ana_reg;
|
||||
|
||||
l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
|
||||
VSC9953_ANA_OFFSET);
|
||||
|
||||
switch (lrn_mode) {
|
||||
case SHARED_VLAN_LEARNING:
|
||||
setbits_le32(&l2ana_reg->ana.agen_ctrl, VSC9953_FID_MASK_ALL);
|
||||
break;
|
||||
case PRIVATE_VLAN_LEARNING:
|
||||
clrbits_le32(&l2ana_reg->ana.agen_ctrl, VSC9953_FID_MASK_ALL);
|
||||
break;
|
||||
default:
|
||||
printf("Unknown VLAN learn mode\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Get VLAN learning mode for VSC9953 */
|
||||
static int vsc9953_vlan_learning_get(enum vlan_learning_mode *lrn_mode)
|
||||
{
|
||||
u32 val;
|
||||
struct vsc9953_analyzer *l2ana_reg;
|
||||
|
||||
l2ana_reg = (struct vsc9953_analyzer *)(VSC9953_OFFSET +
|
||||
VSC9953_ANA_OFFSET);
|
||||
|
||||
val = in_le32(&l2ana_reg->ana.agen_ctrl);
|
||||
|
||||
if (!(val & VSC9953_FID_MASK_ALL)) {
|
||||
*lrn_mode = PRIVATE_VLAN_LEARNING;
|
||||
} else if ((val & VSC9953_FID_MASK_ALL) == VSC9953_FID_MASK_ALL) {
|
||||
*lrn_mode = SHARED_VLAN_LEARNING;
|
||||
} else {
|
||||
printf("Unknown VLAN learning mode\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vsc9953_port_status_key_func(struct ethsw_command_def *parsed_cmd)
|
||||
{
|
||||
int i;
|
||||
|
@ -1887,6 +1936,50 @@ static int vsc9953_egr_vlan_tag_set_key_func(
|
|||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
static int vsc9953_vlan_learn_show_key_func(
|
||||
struct ethsw_command_def *parsed_cmd)
|
||||
{
|
||||
int rc;
|
||||
enum vlan_learning_mode mode;
|
||||
|
||||
rc = vsc9953_vlan_learning_get(&mode);
|
||||
if (rc)
|
||||
return CMD_RET_FAILURE;
|
||||
|
||||
switch (mode) {
|
||||
case SHARED_VLAN_LEARNING:
|
||||
printf("VLAN learning mode: shared\n");
|
||||
break;
|
||||
case PRIVATE_VLAN_LEARNING:
|
||||
printf("VLAN learning mode: private\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown VLAN learning mode\n");
|
||||
rc = CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
static int vsc9953_vlan_learn_set_key_func(struct ethsw_command_def *parsed_cmd)
|
||||
{
|
||||
enum vlan_learning_mode mode;
|
||||
|
||||
/* keywords for shared/private are the last in the array */
|
||||
if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
|
||||
ethsw_id_shared)
|
||||
mode = SHARED_VLAN_LEARNING;
|
||||
else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
|
||||
ethsw_id_private)
|
||||
mode = PRIVATE_VLAN_LEARNING;
|
||||
else
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
vsc9953_vlan_learning_set(mode);
|
||||
|
||||
return CMD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
static struct ethsw_command_func vsc9953_cmd_func = {
|
||||
.ethsw_name = "L2 Switch VSC9953",
|
||||
.port_enable = &vsc9953_port_status_key_func,
|
||||
|
@ -1908,6 +2001,8 @@ static struct ethsw_command_func vsc9953_cmd_func = {
|
|||
.port_untag_set = &vsc9953_port_untag_set_key_func,
|
||||
.port_egr_vlan_show = &vsc9953_egr_vlan_tag_show_key_func,
|
||||
.port_egr_vlan_set = &vsc9953_egr_vlan_tag_set_key_func,
|
||||
.vlan_learn_show = &vsc9953_vlan_learn_show_key_func,
|
||||
.vlan_learn_set = &vsc9953_vlan_learn_set_key_func,
|
||||
};
|
||||
|
||||
#endif /* CONFIG_CMD_ETHSW */
|
||||
|
|
|
@ -37,6 +37,8 @@ enum ethsw_keyword_id {
|
|||
ethsw_id_egress,
|
||||
ethsw_id_tag,
|
||||
ethsw_id_classified,
|
||||
ethsw_id_shared,
|
||||
ethsw_id_private,
|
||||
ethsw_id_count, /* keep last */
|
||||
};
|
||||
|
||||
|
@ -80,6 +82,8 @@ struct ethsw_command_func {
|
|||
int (*port_untag_set)(struct ethsw_command_def *parsed_cmd);
|
||||
int (*port_egr_vlan_show)(struct ethsw_command_def *parsed_cmd);
|
||||
int (*port_egr_vlan_set)(struct ethsw_command_def *parsed_cmd);
|
||||
int (*vlan_learn_show)(struct ethsw_command_def *parsed_cmd);
|
||||
int (*vlan_learn_set)(struct ethsw_command_def *parsed_cmd);
|
||||
};
|
||||
|
||||
int ethsw_define_functions(const struct ethsw_command_func *cmd_func);
|
||||
|
|
|
@ -135,6 +135,9 @@
|
|||
/* Macros for vsc9953_qsys_sys.switch_port_mode register */
|
||||
#define VSC9953_PORT_ENA 0x00002000
|
||||
|
||||
/* Macros for vsc9953_ana_ana.agen_ctrl register */
|
||||
#define VSC9953_FID_MASK_ALL 0x00fff000
|
||||
|
||||
/* Macros for vsc9953_ana_ana.adv_learn register */
|
||||
#define VSC9953_VLAN_CHK 0x00000400
|
||||
|
||||
|
|
Loading…
Reference in a new issue