From: Ben Hutchings ben.hutchings@mind.be
stable inclusion from stable-5.10.60 commit 60c007b52779fdea6ae5116c00079cb6a7017c02 bugzilla: 177018 https://gitee.com/openeuler/kernel/issues/I4EAUG
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
commit ef3b02a1d79b691f9a354c4903cf1e6917e315f9 upstream.
ksz8795 has never actually enabled PVID tag insertion, and it also programmed the PVID incorrectly. To fix this:
* Allow tag insertion to be controlled per ingress port. On most chips, set bit 2 in Global Control 19. On KSZ88x3 this control flag doesn't exist.
* When adding a PVID: - Set the appropriate register bits to enable tag insertion on egress at every other port if this was the packet's ingress port. - Mask *out* the VID from the default tag, before or-ing in the new PVID.
* When removing a PVID: - Clear the same control bits to disable tag insertion. - Don't update the default tag. This wasn't doing anything useful.
Fixes: e66f840c08a2 ("net: dsa: ksz: Add Microchip KSZ8795 DSA driver") Signed-off-by: Ben Hutchings ben.hutchings@mind.be Signed-off-by: David S. Miller davem@davemloft.net [bwh: Backport to 5.10: - Drop the KSZ88x3 cases as those chips are not supported here - Handle VID ranges in ksz8795_port_vlan_del()] Signed-off-by: Ben Hutchings ben.hutchings@mind.be Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
Signed-off-by: Chen Jun chenjun102@huawei.com Acked-by: Weilong Chen chenweilong@huawei.com Signed-off-by: Chen Jun chenjun102@huawei.com --- drivers/net/dsa/microchip/ksz8795.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c index 108a14db1f1a..3d36ffff1f4e 100644 --- a/drivers/net/dsa/microchip/ksz8795.c +++ b/drivers/net/dsa/microchip/ksz8795.c @@ -833,9 +833,11 @@ static void ksz8795_port_vlan_add(struct dsa_switch *ds, int port,
if (new_pvid) { ksz_pread16(dev, port, REG_PORT_CTRL_VID, &vid); - vid &= 0xfff; + vid &= ~VLAN_VID_MASK; vid |= new_pvid; ksz_pwrite16(dev, port, REG_PORT_CTRL_VID, vid); + + ksz_pwrite8(dev, port, REG_PORT_CTRL_12, 0x0f); } }
@@ -844,8 +846,9 @@ static int ksz8795_port_vlan_del(struct dsa_switch *ds, int port, { bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; struct ksz_device *dev = ds->priv; - u16 data, vid, pvid, new_pvid = 0; + u16 data, vid, pvid; u8 fid, member, valid; + bool del_pvid = false;
ksz_pread16(dev, port, REG_PORT_CTRL_VID, &pvid); pvid = pvid & 0xFFF; @@ -865,14 +868,14 @@ static int ksz8795_port_vlan_del(struct dsa_switch *ds, int port, }
if (pvid == vid) - new_pvid = 1; + del_pvid = true;
ksz8795_to_vlan(fid, member, valid, &data); ksz8795_w_vlan_table(dev, vid, data); }
- if (new_pvid != pvid) - ksz_pwrite16(dev, port, REG_PORT_CTRL_VID, pvid); + if (del_pvid) + ksz_pwrite8(dev, port, REG_PORT_CTRL_12, 0x00);
return 0; } @@ -1085,6 +1088,8 @@ static int ksz8795_setup(struct dsa_switch *ds)
ksz_cfg(dev, S_MIRROR_CTRL, SW_MIRROR_RX_TX, false);
+ ksz_cfg(dev, REG_SW_CTRL_19, SW_INS_TAG_ENABLE, true); + /* set broadcast storm protection 10% rate */ regmap_update_bits(dev->regmap[1], S_REPLACE_VID_CTRL, BROADCAST_STORM_RATE,