aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ramips
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/ramips')
-rw-r--r--target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c36
1 files changed, 33 insertions, 3 deletions
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;