lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 22 Dec 2021 12:07:59 +0100
From:   Horatiu Vultur <horatiu.vultur@...rochip.com>
To:     <netdev@...r.kernel.org>, <linux-kernel@...r.kernel.org>
CC:     <davem@...emloft.net>, <kuba@...nel.org>, <linux@...linux.org.uk>,
        <f.fainelli@...il.com>, <vivien.didelot@...il.com>,
        <vladimir.oltean@....com>, <andrew@...n.ch>,
        Horatiu Vultur <horatiu.vultur@...rochip.com>
Subject: [PATCH net-next] net: lan966x: Add support for multiple bridge flags

This patch series extends the current supported bridge flags with the
following flags: BR_FLOOD, BR_BCAST_FLOOD and BR_LEARNING.

Signed-off-by: Horatiu Vultur <horatiu.vultur@...rochip.com>
---
 .../ethernet/microchip/lan966x/lan966x_main.c |  7 ++
 .../ethernet/microchip/lan966x/lan966x_main.h |  2 +
 .../ethernet/microchip/lan966x/lan966x_regs.h |  6 ++
 .../microchip/lan966x/lan966x_switchdev.c     | 69 ++++++++++++++++++-
 4 files changed, 82 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
index 5b9f004ad902..16f4d8737d7b 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
@@ -715,8 +715,10 @@ static void lan966x_init(struct lan966x *lan966x)
 	/* There are 8 priorities */
 	for (i = 0; i < 8; ++i)
 		lan_rmw(ANA_FLOODING_FLD_MULTICAST_SET(PGID_MC) |
+			ANA_FLOODING_FLD_UNICAST_SET(PGID_UC) |
 			ANA_FLOODING_FLD_BROADCAST_SET(PGID_BC),
 			ANA_FLOODING_FLD_MULTICAST |
+			ANA_FLOODING_FLD_UNICAST |
 			ANA_FLOODING_FLD_BROADCAST,
 			lan966x, ANA_FLOODING(i));
 
@@ -768,6 +770,11 @@ static void lan966x_init(struct lan966x *lan966x)
 		ANA_PGID_PGID,
 		lan966x, ANA_PGID(PGID_MCIPV4));
 
+	/* Unicast to all other ports */
+	lan_rmw(GENMASK(lan966x->num_phys_ports - 1, 0),
+		ANA_PGID_PGID,
+		lan966x, ANA_PGID(PGID_UC));
+
 	/* Broadcast to the CPU port and to other ports */
 	lan_rmw(ANA_PGID_PGID_SET(BIT(CPU_PORT) | GENMASK(lan966x->num_phys_ports - 1, 0)),
 		ANA_PGID_PGID,
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
index 051182890237..c399b1256edc 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h
@@ -126,6 +126,8 @@ struct lan966x_port {
 	u16 vid;
 	bool vlan_aware;
 
+	bool learn_ena;
+
 	struct phylink_config phylink_config;
 	struct phylink_pcs phylink_pcs;
 	struct lan966x_port_config config;
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h b/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h
index 2f2b26b9f8c6..a13c469e139a 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_regs.h
@@ -91,6 +91,12 @@ enum lan966x_target {
 /*      ANA:ANA:FLOODING */
 #define ANA_FLOODING(r)           __REG(TARGET_ANA, 0, 1, 29824, 0, 1, 244, 68, r, 8, 4)
 
+#define ANA_FLOODING_FLD_UNICAST                 GENMASK(17, 12)
+#define ANA_FLOODING_FLD_UNICAST_SET(x)\
+	FIELD_PREP(ANA_FLOODING_FLD_UNICAST, x)
+#define ANA_FLOODING_FLD_UNICAST_GET(x)\
+	FIELD_GET(ANA_FLOODING_FLD_UNICAST, x)
+
 #define ANA_FLOODING_FLD_BROADCAST               GENMASK(11, 6)
 #define ANA_FLOODING_FLD_BROADCAST_SET(x)\
 	FIELD_PREP(ANA_FLOODING_FLD_BROADCAST, x)
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c b/drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c
index 42c3170030d0..deb3dd5be67a 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_switchdev.c
@@ -25,18 +25,72 @@ static void lan966x_port_set_mcast_flood(struct lan966x_port *port,
 		port->lan966x, ANA_PGID(PGID_MC));
 }
 
+static void lan966x_port_set_ucast_flood(struct lan966x_port *port,
+					 bool enabled)
+{
+	u32 val = lan_rd(port->lan966x, ANA_PGID(PGID_UC));
+
+	val = ANA_PGID_PGID_GET(val);
+	if (enabled)
+		val |= BIT(port->chip_port);
+	else
+		val &= ~BIT(port->chip_port);
+
+	lan_rmw(ANA_PGID_PGID_SET(val),
+		ANA_PGID_PGID,
+		port->lan966x, ANA_PGID(PGID_UC));
+}
+
+static void lan966x_port_set_bcast_flood(struct lan966x_port *port,
+					 bool enabled)
+{
+	u32 val = lan_rd(port->lan966x, ANA_PGID(PGID_BC));
+
+	val = ANA_PGID_PGID_GET(val);
+	if (enabled)
+		val |= BIT(port->chip_port);
+	else
+		val &= ~BIT(port->chip_port);
+
+	lan_rmw(ANA_PGID_PGID_SET(val),
+		ANA_PGID_PGID,
+		port->lan966x, ANA_PGID(PGID_BC));
+}
+
+static void lan966x_port_set_learning(struct lan966x_port *port, bool enabled)
+{
+	lan_rmw(ANA_PORT_CFG_LEARN_ENA_SET(enabled),
+		ANA_PORT_CFG_LEARN_ENA,
+		port->lan966x, ANA_PORT_CFG(port->chip_port));
+
+	port->learn_ena = enabled;
+}
+
 static void lan966x_port_bridge_flags(struct lan966x_port *port,
 				      struct switchdev_brport_flags flags)
 {
 	if (flags.mask & BR_MCAST_FLOOD)
 		lan966x_port_set_mcast_flood(port,
 					     !!(flags.val & BR_MCAST_FLOOD));
+
+	if (flags.mask & BR_FLOOD)
+		lan966x_port_set_ucast_flood(port,
+					     !!(flags.val & BR_FLOOD));
+
+	if (flags.mask & BR_BCAST_FLOOD)
+		lan966x_port_set_bcast_flood(port,
+					     !!(flags.val & BR_BCAST_FLOOD));
+
+	if (flags.mask & BR_LEARNING)
+		lan966x_port_set_learning(port,
+					  !!(flags.val & BR_LEARNING));
 }
 
 static int lan966x_port_pre_bridge_flags(struct lan966x_port *port,
 					 struct switchdev_brport_flags flags)
 {
-	if (flags.mask & ~BR_MCAST_FLOOD)
+	if (flags.mask & ~(BR_MCAST_FLOOD | BR_FLOOD | BR_BCAST_FLOOD |
+			   BR_LEARNING))
 		return -EINVAL;
 
 	return 0;
@@ -65,7 +119,8 @@ static void lan966x_port_stp_state_set(struct lan966x_port *port, u8 state)
 	struct lan966x *lan966x = port->lan966x;
 	bool learn_ena = false;
 
-	if (state == BR_STATE_FORWARDING || state == BR_STATE_LEARNING)
+	if ((state == BR_STATE_FORWARDING || state == BR_STATE_LEARNING) &&
+	    port->learn_ena)
 		learn_ena = true;
 
 	if (state == BR_STATE_FORWARDING)
@@ -128,6 +183,7 @@ static int lan966x_port_bridge_join(struct lan966x_port *port,
 				    struct net_device *bridge,
 				    struct netlink_ext_ack *extack)
 {
+	struct switchdev_brport_flags flags = {0};
 	struct lan966x *lan966x = port->lan966x;
 	struct net_device *dev = port->dev;
 	int err;
@@ -150,14 +206,23 @@ static int lan966x_port_bridge_join(struct lan966x_port *port,
 
 	lan966x->bridge_mask |= BIT(port->chip_port);
 
+	flags.mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD;
+	flags.val = flags.mask;
+	lan966x_port_bridge_flags(port, flags);
+
 	return 0;
 }
 
 static void lan966x_port_bridge_leave(struct lan966x_port *port,
 				      struct net_device *bridge)
 {
+	struct switchdev_brport_flags flags = {0};
 	struct lan966x *lan966x = port->lan966x;
 
+	flags.mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD;
+	flags.val = flags.mask & ~BR_LEARNING;
+	lan966x_port_bridge_flags(port, flags);
+
 	lan966x->bridge_mask &= ~BIT(port->chip_port);
 
 	if (!lan966x->bridge_mask)
-- 
2.33.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ