aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/dsa
diff options
context:
space:
mode:
authorTristram Ha <Tristram.Ha@microchip.com>2018-12-19 18:59:31 -0800
committerDavid S. Miller <davem@davemloft.net>2018-12-20 16:19:29 -0800
commit962ad710f7d64d441c4e02c0e9e5fddd1aeb54b7 (patch)
treeab908f9bda3feb144430e3b3f7e94a7355e0b2f9 /drivers/net/dsa
parentvxlan: Correct merge error. (diff)
downloadlinux-dev-962ad710f7d64d441c4e02c0e9e5fddd1aeb54b7.tar.xz
linux-dev-962ad710f7d64d441c4e02c0e9e5fddd1aeb54b7.zip
net: dsa: microchip: fix unicast frame leak
Port partitioning is done by enabling UNICAST_VLAN_BOUNDARY and changing the default port membership of 0x7f to other values such that there is no communication between ports. In KSZ9477 the member for port 1 is 0x41; port 2, 0x42; port 3, 0x44; port 4, 0x48; port 5, 0x50; and port 7, 0x60. Port 6 is the host port. Setting a zero value can be used to stop port from receiving. However, when UNICAST_VLAN_BOUNDARY is disabled and the unicast addresses are already learned in the dynamic MAC table, setting zero still allows devices connected to those ports to communicate. This does not apply to multicast and broadcast addresses though. To prevent these leaks and make the function of port membership consistent UNICAST_VLAN_BOUNDARY should never be disabled. Note that UNICAST_VLAN_BOUNDARY is enabled by default in KSZ9477. Fixes: b987e98e50ab90e5 ("dsa: add DSA switch driver for Microchip KSZ9477") Signed-off-by: Tristram Ha <Tristram.Ha@microchip.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa')
-rw-r--r--drivers/net/dsa/microchip/ksz9477.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c
index 57a146a0dd4a..89ed059bb576 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -500,13 +500,9 @@ static int ksz9477_port_vlan_filtering(struct dsa_switch *ds, int port,
if (flag) {
ksz_port_cfg(dev, port, REG_PORT_LUE_CTRL,
PORT_VLAN_LOOKUP_VID_0, true);
- ksz9477_cfg32(dev, REG_SW_QM_CTRL__4, UNICAST_VLAN_BOUNDARY,
- true);
ksz_cfg(dev, REG_SW_LUE_CTRL_0, SW_VLAN_ENABLE, true);
} else {
ksz_cfg(dev, REG_SW_LUE_CTRL_0, SW_VLAN_ENABLE, false);
- ksz9477_cfg32(dev, REG_SW_QM_CTRL__4, UNICAST_VLAN_BOUNDARY,
- false);
ksz_port_cfg(dev, port, REG_PORT_LUE_CTRL,
PORT_VLAN_LOOKUP_VID_0, false);
}
@@ -1130,6 +1126,10 @@ static int ksz9477_setup(struct dsa_switch *ds)
return ret;
}
+ /* Required for port partitioning. */
+ ksz9477_cfg32(dev, REG_SW_QM_CTRL__4, UNICAST_VLAN_BOUNDARY,
+ true);
+
/* accept packet up to 2000bytes */
ksz_cfg(dev, REG_SW_MAC_CTRL_1, SW_LEGAL_PACKET_DISABLE, true);