diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c index 51e16f26b9..4e00315452 100644 --- a/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c +++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c @@ -484,6 +484,8 @@ mt7530_apply_config(struct switch_dev *dev) { struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev); int i, j; + u8 tag_ports; + u8 untag_ports; if (!priv->global_vlan_enable) { for (i = 0; i < MT7530_NUM_PORTS; i++) @@ -499,9 +501,37 @@ mt7530_apply_config(struct switch_dev *dev) for (i = 0; i < MT7530_NUM_PORTS; i++) mt7530_w32(priv, REG_ESW_PORT_PCR(i), 0x00ff0003); - /* set all ports as user port */ - for (i = 0; i < MT7530_NUM_PORTS; i++) - mt7530_w32(priv, REG_ESW_PORT_PVC(i), 0x81000000); + /* check if a port is used in tag/untag vlan egress mode */ + tag_ports = 0; + untag_ports = 0; + + for (i = 0; i < MT7530_NUM_VLANS; i++) { + u8 member = priv->vlan_entries[i].member; + u8 etags = priv->vlan_entries[i].etags; + + if (!member) + continue; + + for (j = 0; j < MT7530_NUM_PORTS; j++) { + if (!(member & BIT(j))) + continue; + + if (etags & BIT(j)) + tag_ports |= 1u << j; + else + untag_ports |= 1u << j; + } + } + + /* set all untag-only ports as transparent and the rest as user port */ + for (i = 0; i < MT7530_NUM_PORTS; i++) { + u32 pvc_mode = 0x81000000; + + if (untag_ports & BIT(i) && !(tag_ports & BIT(i))) + pvc_mode = 0x810000c0; + + mt7530_w32(priv, REG_ESW_PORT_PVC(i), pvc_mode); + } for (i = 0; i < MT7530_NUM_VLANS; i++) { u16 vid = priv->vlan_entries[i].vid;