Adds the DSA API for bridge configuration (flooding, L2 learning, and aging) offload as found in Linux 5.12 so that we can implement it in our drivver. Signed-off-by: Sebastian Gottschall <s.gottschall@dd-wrt.com> Signed-off-by: Birger Koblitz <git@birger-koblitz.de>
		
			
				
	
	
		
			145 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
--- a/include/net/dsa.h
 | 
						|
+++ b/include/net/dsa.h
 | 
						|
@@ -552,8 +552,14 @@ struct dsa_switch_ops {
 | 
						|
 	void	(*port_stp_state_set)(struct dsa_switch *ds, int port,
 | 
						|
 				      u8 state);
 | 
						|
 	void	(*port_fast_age)(struct dsa_switch *ds, int port);
 | 
						|
-	int	(*port_egress_floods)(struct dsa_switch *ds, int port,
 | 
						|
-				      bool unicast, bool multicast);
 | 
						|
+	int	(*port_pre_bridge_flags)(struct dsa_switch *ds, int port,
 | 
						|
+					 unsigned long flags,
 | 
						|
+					 struct netlink_ext_ack *extack);
 | 
						|
+	int	(*port_bridge_flags)(struct dsa_switch *ds, int port,
 | 
						|
+				     unsigned long flags,
 | 
						|
+				     struct netlink_ext_ack *extack);
 | 
						|
+	int	(*port_set_mrouter)(struct dsa_switch *ds, int port, bool mrouter,
 | 
						|
+				    struct netlink_ext_ack *extack);
 | 
						|
 
 | 
						|
 	/*
 | 
						|
 	 * VLAN support
 | 
						|
--- a/net/dsa/dsa_priv.h
 | 
						|
+++ b/net/dsa/dsa_priv.h
 | 
						|
@@ -167,11 +167,11 @@ int dsa_port_mdb_add(const struct dsa_po
 | 
						|
 int dsa_port_mdb_del(const struct dsa_port *dp,
 | 
						|
 		     const struct switchdev_obj_port_mdb *mdb);
 | 
						|
 int dsa_port_pre_bridge_flags(const struct dsa_port *dp, unsigned long flags,
 | 
						|
-			      struct switchdev_trans *trans);
 | 
						|
+			      struct switchdev_trans *trans, struct netlink_ext_ack *extack);
 | 
						|
 int dsa_port_bridge_flags(const struct dsa_port *dp, unsigned long flags,
 | 
						|
-			  struct switchdev_trans *trans);
 | 
						|
+			  struct switchdev_trans *trans, struct netlink_ext_ack *extack);
 | 
						|
 int dsa_port_mrouter(struct dsa_port *dp, bool mrouter,
 | 
						|
-		     struct switchdev_trans *trans);
 | 
						|
+		     struct switchdev_trans *trans, struct netlink_ext_ack *extack);
 | 
						|
 int dsa_port_vlan_add(struct dsa_port *dp,
 | 
						|
 		      const struct switchdev_obj_port_vlan *vlan,
 | 
						|
 		      struct switchdev_trans *trans);
 | 
						|
--- a/net/dsa/port.c
 | 
						|
+++ b/net/dsa/port.c
 | 
						|
@@ -145,7 +145,7 @@ int dsa_port_bridge_join(struct dsa_port
 | 
						|
 	int err;
 | 
						|
 
 | 
						|
 	/* Set the flooding mode before joining the port in the switch */
 | 
						|
-	err = dsa_port_bridge_flags(dp, BR_FLOOD | BR_MCAST_FLOOD, NULL);
 | 
						|
+	err = dsa_port_bridge_flags(dp, BR_FLOOD | BR_MCAST_FLOOD, NULL, NULL);
 | 
						|
 	if (err)
 | 
						|
 		return err;
 | 
						|
 
 | 
						|
@@ -158,7 +158,7 @@ int dsa_port_bridge_join(struct dsa_port
 | 
						|
 
 | 
						|
 	/* The bridging is rolled back on error */
 | 
						|
 	if (err) {
 | 
						|
-		dsa_port_bridge_flags(dp, 0, NULL);
 | 
						|
+		dsa_port_bridge_flags(dp, 0, NULL, NULL);
 | 
						|
 		dp->bridge_dev = NULL;
 | 
						|
 	}
 | 
						|
 
 | 
						|
@@ -185,7 +185,7 @@ void dsa_port_bridge_leave(struct dsa_po
 | 
						|
 		pr_err("DSA: failed to notify DSA_NOTIFIER_BRIDGE_LEAVE\n");
 | 
						|
 
 | 
						|
 	/* Port is leaving the bridge, disable flooding */
 | 
						|
-	dsa_port_bridge_flags(dp, 0, NULL);
 | 
						|
+	dsa_port_bridge_flags(dp, 0, NULL, NULL);
 | 
						|
 
 | 
						|
 	/* Port left the bridge, put in BR_STATE_DISABLED by the bridge layer,
 | 
						|
 	 * so allow it to be in BR_STATE_FORWARDING to be kept functional
 | 
						|
@@ -333,44 +333,44 @@ int dsa_port_ageing_time(struct dsa_port
 | 
						|
 }
 | 
						|
 
 | 
						|
 int dsa_port_pre_bridge_flags(const struct dsa_port *dp, unsigned long flags,
 | 
						|
-			      struct switchdev_trans *trans)
 | 
						|
+			      struct switchdev_trans *trans, struct netlink_ext_ack *extack)
 | 
						|
 {
 | 
						|
 	struct dsa_switch *ds = dp->ds;
 | 
						|
 
 | 
						|
-	if (!ds->ops->port_egress_floods ||
 | 
						|
-	    (flags & ~(BR_FLOOD | BR_MCAST_FLOOD)))
 | 
						|
+	if (!ds->ops->port_pre_bridge_flags)
 | 
						|
 		return -EINVAL;
 | 
						|
 
 | 
						|
-	return 0;
 | 
						|
+	return ds->ops->port_pre_bridge_flags(ds, dp->index, flags, extack);
 | 
						|
 }
 | 
						|
 
 | 
						|
 int dsa_port_bridge_flags(const struct dsa_port *dp, unsigned long flags,
 | 
						|
-			  struct switchdev_trans *trans)
 | 
						|
+			  struct switchdev_trans *trans, struct netlink_ext_ack *extack)
 | 
						|
 {
 | 
						|
 	struct dsa_switch *ds = dp->ds;
 | 
						|
-	int port = dp->index;
 | 
						|
-	int err = 0;
 | 
						|
 
 | 
						|
 	if (switchdev_trans_ph_prepare(trans))
 | 
						|
 		return 0;
 | 
						|
 
 | 
						|
-	if (ds->ops->port_egress_floods)
 | 
						|
-		err = ds->ops->port_egress_floods(ds, port, flags & BR_FLOOD,
 | 
						|
-						  flags & BR_MCAST_FLOOD);
 | 
						|
+	if (!ds->ops->port_bridge_flags)
 | 
						|
+		return -EINVAL;
 | 
						|
+ 
 | 
						|
+	return ds->ops->port_bridge_flags(ds, dp->index, flags, extack);
 | 
						|
 
 | 
						|
-	return err;
 | 
						|
 }
 | 
						|
 
 | 
						|
 int dsa_port_mrouter(struct dsa_port *dp, bool mrouter,
 | 
						|
-		     struct switchdev_trans *trans)
 | 
						|
+		     struct switchdev_trans *trans,
 | 
						|
+		     struct netlink_ext_ack *extack)
 | 
						|
 {
 | 
						|
 	struct dsa_switch *ds = dp->ds;
 | 
						|
-	int port = dp->index;
 | 
						|
 
 | 
						|
 	if (switchdev_trans_ph_prepare(trans))
 | 
						|
-		return ds->ops->port_egress_floods ? 0 : -EOPNOTSUPP;
 | 
						|
+		return ds->ops->port_set_mrouter ? 0 : -EOPNOTSUPP;
 | 
						|
+
 | 
						|
+	if (!ds->ops->port_set_mrouter)
 | 
						|
+ 		return -EOPNOTSUPP;
 | 
						|
 
 | 
						|
-	return ds->ops->port_egress_floods(ds, port, true, mrouter);
 | 
						|
+	return ds->ops->port_set_mrouter(ds, dp->index, mrouter, extack);
 | 
						|
 }
 | 
						|
 
 | 
						|
 int dsa_port_mtu_change(struct dsa_port *dp, int new_mtu,
 | 
						|
--- a/net/dsa/slave.c
 | 
						|
+++ b/net/dsa/slave.c
 | 
						|
@@ -290,13 +290,13 @@ static int dsa_slave_port_attr_set(struc
 | 
						|
 		break;
 | 
						|
 	case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS:
 | 
						|
 		ret = dsa_port_pre_bridge_flags(dp, attr->u.brport_flags,
 | 
						|
-						trans);
 | 
						|
+						trans, NULL);
 | 
						|
 		break;
 | 
						|
 	case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
 | 
						|
-		ret = dsa_port_bridge_flags(dp, attr->u.brport_flags, trans);
 | 
						|
+		ret = dsa_port_bridge_flags(dp, attr->u.brport_flags, trans, NULL);
 | 
						|
 		break;
 | 
						|
 	case SWITCHDEV_ATTR_ID_BRIDGE_MROUTER:
 | 
						|
-		ret = dsa_port_mrouter(dp->cpu_dp, attr->u.mrouter, trans);
 | 
						|
+		ret = dsa_port_mrouter(dp->cpu_dp, attr->u.mrouter, trans, NULL);
 | 
						|
 		break;
 | 
						|
 	default:
 | 
						|
 		ret = -EOPNOTSUPP;
 |