diff --git a/common/cmd_ethsw.c b/common/cmd_ethsw.c
index 1fa93effdbc99babe15bfe8caff70d9294e24f23..8cc2a19fe17a2f35786112759c2eb074956804e4 100644
--- a/common/cmd_ethsw.c
+++ b/common/cmd_ethsw.c
@@ -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 = &ethsw_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 = &ethsw_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"
 );
diff --git a/drivers/net/vsc9953.c b/drivers/net/vsc9953.c
index c5c0e5c60fef937ff1d497bba1f4730b7b06aea0..f8f52334b9a7772885476d7d8deb0e7d2b867954 100644
--- a/drivers/net/vsc9953.c
+++ b/drivers/net/vsc9953.c
@@ -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 */
diff --git a/include/ethsw.h b/include/ethsw.h
index cc9708e9ac4c75e88d9d91b3b517215d7bc6a884..18d2b26b4bd304fb81b573b0f6e736a04e5bb8ee 100644
--- a/include/ethsw.h
+++ b/include/ethsw.h
@@ -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);
diff --git a/include/vsc9953.h b/include/vsc9953.h
index 12b7acecad1c46e5409498f44eb330bd36c879f5..24a22a39258dc7eb62ac776d1f7fd3e9b6486c26 100644
--- a/include/vsc9953.h
+++ b/include/vsc9953.h
@@ -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