[U-Boot] [PATCH 09/11 v2] drivers/net/vsc9953: Add command for shared/private VLAN learning

Codrin Ciubotariu codrin.ciubotariu at freescale.com
Tue Jun 23 18:48:54 CEST 2015


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.

Signed-off-by: Johnson Leung <johnson.leung at freescale.com>
Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu at freescale.com>
---
Changes for v2:
        - removed Change-id field;

 drivers/net/vsc9953.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/vsc9953.h     |   3 +
 2 files changed, 158 insertions(+)

diff --git a/drivers/net/vsc9953.c b/drivers/net/vsc9953.c
index b78a941..3129b03 100644
--- a/drivers/net/vsc9953.c
+++ b/drivers/net/vsc9953.c
@@ -1503,6 +1503,58 @@ static void vsc9953_mac_table_flush(int port, int vid)
 	vsc9953_mac_table_age(port, vid);
 }
 
+/* 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,
+			     CONFIG_VSC9953_FID_MASK_ALL);
+		break;
+	case PRIVATE_VLAN_LEARNING:
+		clrbits_le32(&l2ana_reg->ana.agen_ctrl,
+			     CONFIG_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 & CONFIG_VSC9953_FID_MASK_ALL)) {
+		*lrn_mode = PRIVATE_VLAN_LEARNING;
+	} else if ((val & CONFIG_VSC9953_FID_MASK_ALL) ==
+			CONFIG_VSC9953_FID_MASK_ALL) {
+		*lrn_mode = SHARED_VLAN_LEARNING;
+	} else {
+		printf("Unknown VLAN learning mode\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 enum egress_vlan_tag {
 	EGR_TAG_CLASS = 0,
 	EGR_TAG_PVID,
@@ -1572,6 +1624,8 @@ enum keyword_id {
 	id_egress,
 	id_tag,
 	id_classified,
+	id_shared,
+	id_private,
 	id_count,	/* keep last */
 };
 
@@ -1868,6 +1922,61 @@ static int vsc9953_vlan_set_key_func(struct command_def *parsed_cmd)
 	return 0;
 }
 
+#define VSC9953_VLAN_FDB_HELP "ethsw vlan fdb " \
+"{ [help] | show | shared | private } " \
+"- make VLAN learning shared or private"
+
+static int vsc9953_vlan_learn_help_key_func(struct command_def *parsed_cmd)
+{
+	printf(VSC9953_VLAN_FDB_HELP"\n");
+
+	return 0;
+}
+
+static int vsc9953_vlan_learn_show_key_func(struct command_def *parsed_cmd)
+{
+	int				rc;
+	enum vlan_learning_mode		mode;
+
+	rc = vsc9953_vlan_learning_get(&mode);
+	if (rc)
+		goto __out_return;
+
+	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 = -EINVAL;
+	}
+
+__out_return:
+	return rc;
+}
+
+static int vsc9953_vlan_learn_set_key_func(struct 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] ==
+	    id_shared)
+		mode = SHARED_VLAN_LEARNING;
+	else if (parsed_cmd->cmd_to_keywords[parsed_cmd->cmd_keywords_nr - 1] ==
+		 id_private)
+		mode = PRIVATE_VLAN_LEARNING;
+	else
+		return -1;
+
+	vsc9953_vlan_learning_set(mode);
+
+	return 0;
+}
+
 #define VSC9953_PORT_UNTAG_HELP "ethsw [port <port_no>] untagged " \
 "{ [help] | show | all | none | pvid } " \
 " - set egress tagging mod for a port"
@@ -2331,6 +2440,45 @@ struct keywords_to_function {
 					id_key_end,
 			},
 			.keyword_function = &vsc9953_fdb_entry_del_key_func,
+		}, {
+			.cmd_keyword = {
+					id_vlan,
+					id_fdb,
+					id_key_end,
+			},
+			.keyword_function = &vsc9953_vlan_learn_help_key_func,
+		}, {
+			.cmd_keyword = {
+					id_vlan,
+					id_fdb,
+					id_help,
+					id_key_end,
+			},
+			.keyword_function = &vsc9953_vlan_learn_help_key_func,
+		}, {
+			.cmd_keyword = {
+					id_vlan,
+					id_fdb,
+					id_show,
+					id_key_end,
+			},
+			.keyword_function = &vsc9953_vlan_learn_show_key_func,
+		}, {
+			.cmd_keyword = {
+					id_vlan,
+					id_fdb,
+					id_shared,
+					id_key_end,
+			},
+			.keyword_function = &vsc9953_vlan_learn_set_key_func,
+		}, {
+			.cmd_keyword = {
+					id_vlan,
+					id_fdb,
+					id_private,
+					id_key_end,
+			},
+			.keyword_function = &vsc9953_vlan_learn_set_key_func,
 		},
 };
 
@@ -2447,6 +2595,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,
 		},
 };
 
@@ -2770,6 +2924,7 @@ U_BOOT_CMD(ethsw, VSC9953_MAX_CMD_PARAMS, 0, do_ethsw,
 	   VSC9953_PVID_HELP"\n"
 	   VSC9953_PORT_UNTAG_HELP"\n"
 	   VSC9953_EGR_VLAN_TAG_HELP"\n"
+	   VSC9953_VLAN_FDB_HELP"\n"
 );
 
 #endif /* CONFIG_VSC9953_CMD */
diff --git a/include/vsc9953.h b/include/vsc9953.h
index 6eb22a9..26a08aa 100644
--- a/include/vsc9953.h
+++ b/include/vsc9953.h
@@ -142,6 +142,9 @@
 /* Macros for vsc9953_qsys_sys.switch_port_mode register */
 #define CONFIG_VSC9953_PORT_ENA		0x00002000
 
+/* Macros for vsc9953_ana_ana.agen_ctrl register */
+#define CONFIG_VSC9953_FID_MASK_ALL	0x00fff000
+
 /* Macros for vsc9953_ana_ana.adv_learn register */
 #define CONFIG_VSC9953_VLAN_CHK		0x00000400
 
-- 
1.9.3



More information about the U-Boot mailing list