mirror of
https://github.com/openwrt/openwrt.git
synced 2025-01-22 04:18:10 +00:00
ramips: don't clobber vlans with remapped vid on mt7530/762x switches
Avoid overwriting vlan entries with remapped vid in later iterations of the vlan enumeration loop of mt7530_apply_config(). Fix the problem by refactoring the code to first reset the entire table, then reprogram only vlans with members to prevent overwriting configured vlans with unconfigured ones. Fixes FS#1147, FS#1341 Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
parent
b9aca834e8
commit
bb4002c79d
@ -497,6 +497,52 @@ mt7530_get_vid(struct switch_dev *dev, const struct switch_attr *attr,
|
|||||||
return 0;
|
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
|
static int
|
||||||
mt7530_apply_config(struct switch_dev *dev)
|
mt7530_apply_config(struct switch_dev *dev)
|
||||||
{
|
{
|
||||||
@ -553,48 +599,19 @@ mt7530_apply_config(struct switch_dev *dev)
|
|||||||
mt7530_w32(priv, REG_ESW_PORT_PVC(i), pvc_mode);
|
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++) {
|
for (i = 0; i < MT7530_NUM_VLANS; i++) {
|
||||||
u16 vid = priv->vlan_entries[i].vid;
|
u16 vid = priv->vlan_entries[i].vid;
|
||||||
u8 member = priv->vlan_entries[i].member;
|
u8 member = priv->vlan_entries[i].member;
|
||||||
u8 etags = priv->vlan_entries[i].etags;
|
u8 etags = priv->vlan_entries[i].etags;
|
||||||
u32 val;
|
|
||||||
|
|
||||||
#ifndef CONFIG_SOC_MT7621
|
|
||||||
/* 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);
|
|
||||||
#endif
|
|
||||||
/* vlan port membership */
|
|
||||||
if (member)
|
if (member)
|
||||||
mt7530_w32(priv, REG_ESW_VLAN_VAWD1, REG_ESW_VLAN_VAWD1_IVL_MAC |
|
mt7530_write_vlan_entry(priv, i, vid, member, etags);
|
||||||
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 */
|
|
||||||
#ifdef CONFIG_SOC_MT7621
|
|
||||||
mt7530_vtcr(priv, 1, vid);
|
|
||||||
#else
|
|
||||||
mt7530_vtcr(priv, 1, i);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Port Default PVID */
|
/* Port Default PVID */
|
||||||
|
Loading…
Reference in New Issue
Block a user