Skip to content

Commit

Permalink
net: dsa: microchip: ksz8795: Fix PVID tag insertion
Browse files Browse the repository at this point in the history
commit ef3b02a 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: e66f840 ("net: dsa: ksz: Add Microchip KSZ8795 DSA driver")
Signed-off-by: Ben Hutchings <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
[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 <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
bwh-mind authored and gregkh committed Aug 18, 2021
1 parent f365d53 commit 60c007b
Showing 1 changed file with 10 additions and 5 deletions.
15 changes: 10 additions & 5 deletions drivers/net/dsa/microchip/ksz8795.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand All @@ -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;
Expand All @@ -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;
}
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 60c007b

Please sign in to comment.