--- a/drivers/net/ethernet/mediatek/mt7530.c
+++ b/drivers/net/ethernet/mediatek/mt7530.c
@@ -44,6 +44,12 @@
 #define MT7530_MAX_VID		4095
 #define MT7530_MIN_VID		0
 
+#define MT7530_PORT_MIB_TXB_ID	2	/* TxGOC */
+#define MT7530_PORT_MIB_RXB_ID	6	/* RxGOC */
+
+#define MT7621_PORT_MIB_TXB_ID	18	/* TxByte */
+#define MT7621_PORT_MIB_RXB_ID	37	/* RxByte */
+
 /* registers */
 #define REG_ESW_VLAN_VTCR		0x90
 #define REG_ESW_VLAN_VAWD1		0x94
@@ -214,6 +220,12 @@ struct mt7530_mapping {
 		.members = { 0, 0x7e, 0x41 },
 		.etags = { 0, 0x40, 0x40 },
 		.vids = { 0, 1, 2 },
+	}, {
+		.name = "lwlll",
+		.pvids = { 1, 2, 1, 1, 1, 1, 1 },
+		.members = { 0, 0x7d, 0x42 },
+		.etags = { 0, 0x40, 0x40 },
+		.vids = { 0, 1, 2 },
 	},
 };
 
@@ -467,6 +479,14 @@ mt7530_set_vid(struct switch_dev *dev, c
 }
 
 static int
+mt7621_get_vid(struct switch_dev *dev, const struct switch_attr *attr,
+		struct switch_val *val)
+{
+	val->value.i = val->port_vlan;
+	return 0;
+}
+
+static int
 mt7530_get_vid(struct switch_dev *dev, const struct switch_attr *attr,
 		struct switch_val *val)
 {
@@ -485,6 +505,52 @@ mt7530_get_vid(struct switch_dev *dev, c
 	return 0;
 }
 
+static void
+mt7530_write_vlan_entry(struct mt7530_priv *priv, int vlan, u16 vid,
+	                    u8 ports, u8 etags)
+{
+	int port;
+	u32 val;
+
+#ifndef CONFIG_SOC_MT7621
+	/* vid of vlan */
+	val = mt7530_r32(priv, REG_ESW_VLAN_VTIM(vlan));
+	if (vlan % 2 == 0) {
+		val &= 0xfff000;
+		val |= vid;
+	} else {
+		val &= 0xfff;
+		val |= (vid << 12);
+	}
+	mt7530_w32(priv, REG_ESW_VLAN_VTIM(vlan), val);
+#endif
+
+	/* vlan port membership */
+	if (ports)
+		mt7530_w32(priv, REG_ESW_VLAN_VAWD1, REG_ESW_VLAN_VAWD1_IVL_MAC |
+			REG_ESW_VLAN_VAWD1_VTAG_EN | (ports << 16) |
+			REG_ESW_VLAN_VAWD1_VALID);
+	else
+		mt7530_w32(priv, REG_ESW_VLAN_VAWD1, 0);
+
+	/* egress mode */
+	val = 0;
+	for (port = 0; port < MT7530_NUM_PORTS; port++) {
+		if (etags & BIT(port))
+			val |= ETAG_CTRL_TAG << (port * 2);
+		else
+			val |= ETAG_CTRL_UNTAG << (port * 2);
+	}
+	mt7530_w32(priv, REG_ESW_VLAN_VAWD2, val);
+
+	/* write to vlan table */
+#ifdef CONFIG_SOC_MT7621
+	mt7530_vtcr(priv, 1, vid);
+#else
+	mt7530_vtcr(priv, 1, vlan);
+#endif
+}
+
 static int
 mt7530_apply_config(struct switch_dev *dev)
 {
@@ -541,51 +607,33 @@ mt7530_apply_config(struct switch_dev *d
 		mt7530_w32(priv, REG_ESW_PORT_PVC(i), pvc_mode);
 	}
 
+	/* first clear the swtich vlan table */
+	for (i = 0; i < MT7530_NUM_VLANS; i++)
+		mt7530_write_vlan_entry(priv, i, i, 0, 0);
+
+	/* now program only vlans with members to avoid
+	   clobbering remapped entries in later iterations */
 	for (i = 0; i < MT7530_NUM_VLANS; i++) {
 		u16 vid = priv->vlan_entries[i].vid;
 		u8 member = priv->vlan_entries[i].member;
 		u8 etags = priv->vlan_entries[i].etags;
-		u32 val;
 
-		/* vid of vlan */
-		val = mt7530_r32(priv, REG_ESW_VLAN_VTIM(i));
-		if (i % 2 == 0) {
-			val &= 0xfff000;
-			val |= vid;
-		} else {
-			val &= 0xfff;
-			val |= (vid << 12);
-		}
-		mt7530_w32(priv, REG_ESW_VLAN_VTIM(i), val);
-
-		/* vlan port membership */
 		if (member)
-			mt7530_w32(priv, REG_ESW_VLAN_VAWD1, REG_ESW_VLAN_VAWD1_IVL_MAC |
-				REG_ESW_VLAN_VAWD1_VTAG_EN | (member << 16) |
-				REG_ESW_VLAN_VAWD1_VALID);
-		else
-			mt7530_w32(priv, REG_ESW_VLAN_VAWD1, 0);
-
-		/* egress mode */
-		val = 0;
-		for (j = 0; j < MT7530_NUM_PORTS; j++) {
-			if (etags & BIT(j))
-				val |= ETAG_CTRL_TAG << (j * 2);
-			else
-				val |= ETAG_CTRL_UNTAG << (j * 2);
-		}
-		mt7530_w32(priv, REG_ESW_VLAN_VAWD2, val);
-
-		/* write to vlan table */
-		mt7530_vtcr(priv, 1, i);
+			mt7530_write_vlan_entry(priv, i, vid, member, etags);
 	}
 
 	/* Port Default PVID */
 	for (i = 0; i < MT7530_NUM_PORTS; i++) {
+		int vlan = priv->port_entries[i].pvid;
+		u16 pvid = 0;
 		u32 val;
+
+		if (vlan < MT7530_NUM_VLANS && priv->vlan_entries[vlan].member)
+			pvid = priv->vlan_entries[vlan].vid;
+
 		val = mt7530_r32(priv, REG_ESW_PORT_PPBV1(i));
 		val &= ~0xfff;
-		val |= priv->port_entries[i].pvid;
+		val |= pvid;
 		mt7530_w32(priv, REG_ESW_PORT_PPBV1(i), val);
 	}
 
@@ -739,6 +787,34 @@ static int mt7530_sw_get_port_mib(struct
 	return 0;
 }
 
+static int mt7530_get_port_stats(struct switch_dev *dev, int port,
+					struct switch_port_stats *stats)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+
+	if (port < 0 || port >= MT7530_NUM_PORTS)
+		return -EINVAL;
+
+	stats->tx_bytes = get_mib_counter_port_7620(priv, MT7530_PORT_MIB_TXB_ID, port);
+	stats->rx_bytes = get_mib_counter_port_7620(priv, MT7530_PORT_MIB_RXB_ID, port);
+
+	return 0;
+}
+
+static int mt7621_get_port_stats(struct switch_dev *dev, int port,
+					struct switch_port_stats *stats)
+{
+	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+
+	if (port < 0 || port >= MT7530_NUM_PORTS)
+		return -EINVAL;
+
+	stats->tx_bytes = get_mib_counter(priv, MT7621_PORT_MIB_TXB_ID, port);
+	stats->rx_bytes = get_mib_counter(priv, MT7621_PORT_MIB_RXB_ID, port);
+
+	return 0;
+}
+
 static const struct switch_attr mt7530_global[] = {
 	{
 		.type = SWITCH_TYPE_INT,
@@ -767,6 +843,17 @@ static const struct switch_attr mt7621_p
 	},
 };
 
+static const struct switch_attr mt7621_vlan[] = {
+	{
+		.type = SWITCH_TYPE_INT,
+		.name = "vid",
+		.description = "VLAN ID (0-4094)",
+		.set = mt7530_set_vid,
+		.get = mt7621_get_vid,
+		.max = 4094,
+	},
+};
+
 static const struct switch_attr mt7530_port[] = {
 	{
 		.type = SWITCH_TYPE_STRING,
@@ -798,14 +885,15 @@ static const struct switch_dev_ops mt762
 		.n_attr = ARRAY_SIZE(mt7621_port),
 	},
 	.attr_vlan = {
-		.attr = mt7530_vlan,
-		.n_attr = ARRAY_SIZE(mt7530_vlan),
+		.attr = mt7621_vlan,
+		.n_attr = ARRAY_SIZE(mt7621_vlan),
 	},
 	.get_vlan_ports = mt7530_get_vlan_ports,
 	.set_vlan_ports = mt7530_set_vlan_ports,
 	.get_port_pvid = mt7530_get_port_pvid,
 	.set_port_pvid = mt7530_set_port_pvid,
 	.get_port_link = mt7530_get_port_link,
+	.get_port_stats = mt7621_get_port_stats,
 	.apply_config = mt7530_apply_config,
 	.reset_switch = mt7530_reset_switch,
 };
@@ -828,6 +916,7 @@ static const struct switch_dev_ops mt753
 	.get_port_pvid = mt7530_get_port_pvid,
 	.set_port_pvid = mt7530_set_port_pvid,
 	.get_port_link = mt7530_get_port_link,
+	.get_port_stats = mt7530_get_port_stats,
 	.apply_config = mt7530_apply_config,
 	.reset_switch = mt7530_reset_switch,
 };
@@ -881,7 +970,7 @@ mt7530_probe(struct device *dev, void __
 
 	/* magic vodoo */
 	if (!IS_ENABLED(CONFIG_SOC_MT7621) && bus && mt7530_r32(mt7530, REG_HWTRAP) !=  0x1117edf) {
-	        dev_info(dev, "fixing up MHWTRAP register - bootloader probably played with it\n");
+		dev_info(dev, "fixing up MHWTRAP register - bootloader probably played with it\n");
 		mt7530_w32(mt7530, REG_HWTRAP, 0x1117edf);
 	}
 	dev_info(dev, "loaded %s driver\n", swdev->name);
