diff --git a/package/switch/src/switch-robo.c b/package/switch/src/switch-robo.c
index 41f0c1826dbd6b01bc481b77b51c063880788f0a..aaccdd9f6b8873144b52abd9f2e5497231820475 100644
--- a/package/switch/src/switch-robo.c
+++ b/package/switch/src/switch-robo.c
@@ -74,6 +74,7 @@ struct robo_switch {
 	u16 devid;			/* ROBO_DEVICE_ID_53xx */
 	bool is_5365;
 	bool gmii;			/* gigabit mii */
+	u8 corerev;
 	int gpio_robo_reset;
 	int gpio_lanports_enable;
 	struct ifreq ifr;
@@ -419,8 +420,7 @@ err_done:
 	return err;
 }
 
-
-static int handle_vlan_port_read(void *driver, char *buf, int nr)
+static int handle_vlan_port_read_old(switch_driver *d, char *buf, int nr)
 {
 	__u16 val16;
 	int len = 0;
@@ -433,11 +433,11 @@ static int handle_vlan_port_read(void *driver, char *buf, int nr)
 		/* actual read */
 		val16 = robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_READ);
 		if ((val16 & (1 << 14)) /* valid */) {
-			for (j = 0; j < 6; j++) {
+			for (j = 0; j < d->ports; j++) {
 				if (val16 & (1 << j)) {
 					len += sprintf(buf + len, "%d", j);
 					if (val16 & (1 << (j + 7))) {
-						if (j == 5)
+						if (j == d->cpuport)
 							buf[len++] = 'u';
 					} else {
 						buf[len++] = 't';
@@ -455,11 +455,11 @@ static int handle_vlan_port_read(void *driver, char *buf, int nr)
 		/* actual read */
 		val32 = robo_read32(ROBO_VLAN_PAGE, ROBO_VLAN_READ);
 		if ((val32 & (1 << 20)) /* valid */) {
-			for (j = 0; j < 6; j++) {
+			for (j = 0; j < d->ports; j++) {
 				if (val32 & (1 << j)) {
 					len += sprintf(buf + len, "%d", j);
-					if (val32 & (1 << (j + 6))) {
-						if (j == 5)
+					if (val32 & (1 << (j + d->ports))) {
+						if (j == d->cpuport)
 							buf[len++] = 'u';
 					} else {
 						buf[len++] = 't';
@@ -478,45 +478,120 @@ static int handle_vlan_port_read(void *driver, char *buf, int nr)
 	return len;
 }
 
-static int handle_vlan_port_write(void *driver, char *buf, int nr)
+static int handle_vlan_port_read_new(switch_driver *d, char *buf, int nr)
 {
-	switch_driver *d = (switch_driver *) driver;
-	switch_vlan_config *c = switch_parse_vlan(d, buf);
+	__u8 vtbl_entry, vtbl_index, vtbl_access;
+	__u32 val32;
+	int len = 0;
 	int j;
-	__u16 val16;
 
-	if (c == NULL)
-		return -EINVAL;
+	if ((robo.devid == ROBO_DEVICE_ID_5395) ||
+	    (robo.devid == ROBO_DEVICE_ID_53115)) {
+		vtbl_access = ROBO_VTBL_ACCESS_5395;
+		vtbl_index = ROBO_VTBL_INDX_5395;
+		vtbl_entry = ROBO_VTBL_ENTRY_5395;
+	} else {
+		vtbl_access = ROBO_VTBL_ACCESS;
+		vtbl_index = ROBO_VTBL_INDX;
+		vtbl_entry = ROBO_VTBL_ENTRY;
+	}
 
+	robo_write16(ROBO_ARLIO_PAGE, vtbl_index, nr);
+	robo_write16(ROBO_ARLIO_PAGE, vtbl_access, (1 << 7) | (1 << 0));
+	val32 = robo_read32(ROBO_ARLIO_PAGE, vtbl_entry);
 	for (j = 0; j < d->ports; j++) {
-		if ((c->untag | c->pvid) & (1 << j))
-			/* change default vlan tag */
-			robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (j << 1), nr);
+		if (val32 & (1 << j)) {
+			len += sprintf(buf + len, "%d", j);
+			if (val32 & (1 << (j + d->ports))) {
+				if (j == d->cpuport)
+					buf[len++] = 'u';
+			} else {
+				buf[len++] = 't';
+				if (robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (j << 1)) == nr)
+					buf[len++] = '*';
+			}
+			buf[len++] = '\t';
+		}
 	}
+	len += sprintf(buf + len, "\n");
+	buf[len] = '\0';
+	return len;
+}
 
-	/* write config now */
+static int handle_vlan_port_read(void *driver, char *buf, int nr)
+{
+	switch_driver *d = (switch_driver *) driver;
 
-	if (robo.devid != ROBO_DEVICE_ID_5325) {
-		__u8 regoff = ((robo.devid == ROBO_DEVICE_ID_5395) ||
-			(robo.devid == ROBO_DEVICE_ID_53115)) ? 0x20 : 0;
+	if (robo.devid != ROBO_DEVICE_ID_5325)
+		return handle_vlan_port_read_new(d, buf, nr);
+	else
+		return handle_vlan_port_read_old(d, buf, nr);
+}
 
-		robo_write32(ROBO_ARLIO_PAGE, 0x63 + regoff, (c->untag << 9) | c->port);
-		robo_write16(ROBO_ARLIO_PAGE, 0x61 + regoff, nr);
-		robo_write16(ROBO_ARLIO_PAGE, 0x60 + regoff, 1 << 7);
-		kfree(c);
-		return 0;
-	}
+static void handle_vlan_port_write_old(switch_driver *d, switch_vlan_config *c, int nr)
+{
+	__u16 val16;
+	__u32 val32;
+	__u32 untag = ((c->untag  & ~(1 << d->cpuport)) << d->ports);
 
+	/* write config now */
 	val16 = (nr) /* vlan */ | (1 << 12) /* write */ | (1 << 13) /* enable */;
 	if (robo.is_5365) {
-		robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE_5365,
-			(1 << 14)  /* valid */ | (c->untag << 7) | c->port);
+		robo_write32(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE_5365,
+			(1 << 14)  /* valid */ | (untag << 1 ) | c->port);
 		robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5365, val16);
 	} else {
-		robo_write32(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE,
-			(1 << 20) /* valid */ | (c->untag << 6) | c->port);
+		if (robo.corerev < 3)
+			val32 = (1 << 20) | ((nr >> 4) << 12) | untag | c->port;
+		else
+			val32 = (1 << 24) | (nr << 12) | untag | c->port;
+		robo_write32(ROBO_VLAN_PAGE, ROBO_VLAN_WRITE, val32);
 		robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS, val16);
 	}
+}
+
+static void handle_vlan_port_write_new(switch_driver *d, switch_vlan_config *c, int nr)
+{
+	__u8 vtbl_entry, vtbl_index, vtbl_access;
+	__u32 untag = ((c->untag  & ~(1 << d->cpuport)) << d->ports);
+
+	/* write config now */
+	if ((robo.devid == ROBO_DEVICE_ID_5395) ||
+	    (robo.devid == ROBO_DEVICE_ID_53115)) {
+		vtbl_access = ROBO_VTBL_ACCESS_5395;
+		vtbl_index = ROBO_VTBL_INDX_5395;
+		vtbl_entry = ROBO_VTBL_ENTRY_5395;
+	} else {
+		vtbl_access = ROBO_VTBL_ACCESS;
+		vtbl_index = ROBO_VTBL_INDX;
+		vtbl_entry = ROBO_VTBL_ENTRY;
+	}
+
+	robo_write32(ROBO_ARLIO_PAGE, vtbl_entry, untag | c->port);
+	robo_write16(ROBO_ARLIO_PAGE, vtbl_index, nr);
+	robo_write16(ROBO_ARLIO_PAGE, vtbl_access, 1 << 7);
+}
+
+static int handle_vlan_port_write(void *driver, char *buf, int nr)
+{
+	switch_driver *d = (switch_driver *)driver;
+	switch_vlan_config *c = switch_parse_vlan(d, buf);
+	int j;
+
+	if (c == NULL)
+		return -EINVAL;
+
+	for (j = 0; j < d->ports; j++) {
+		if ((c->untag | c->pvid) & (1 << j)) {
+			/* change default vlan tag */
+			robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (j << 1), nr);
+		}
+	}
+
+	if (robo.devid != ROBO_DEVICE_ID_5325)
+		handle_vlan_port_write_new(d, c, nr);
+	else
+		handle_vlan_port_write_old(d, c, nr);
 
 	kfree(c);
 	return 0;