aboutsummaryrefslogtreecommitdiff
path: root/net/dsa
diff options
context:
space:
mode:
Diffstat (limited to 'net/dsa')
-rw-r--r--net/dsa/port.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 982e18771d76..7accda066149 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -292,6 +292,8 @@ int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br,
.port = dp->index,
.br = br,
};
+ struct net_device *dev = dp->slave;
+ struct net_device *brport_dev;
int err;
/* Here the interface is already bridged. Reflect the current
@@ -299,16 +301,24 @@ int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br,
*/
dp->bridge_dev = br;
+ brport_dev = dsa_port_to_bridge_port(dp);
+
err = dsa_broadcast(DSA_NOTIFIER_BRIDGE_JOIN, &info);
if (err)
goto out_rollback;
- err = dsa_port_switchdev_sync(dp, extack);
+ err = switchdev_bridge_port_offload(brport_dev, dev, extack);
if (err)
goto out_rollback_unbridge;
+ err = dsa_port_switchdev_sync(dp, extack);
+ if (err)
+ goto out_rollback_unoffload;
+
return 0;
+out_rollback_unoffload:
+ switchdev_bridge_port_unoffload(brport_dev);
out_rollback_unbridge:
dsa_broadcast(DSA_NOTIFIER_BRIDGE_LEAVE, &info);
out_rollback:
@@ -319,6 +329,10 @@ out_rollback:
int dsa_port_pre_bridge_leave(struct dsa_port *dp, struct net_device *br,
struct netlink_ext_ack *extack)
{
+ struct net_device *brport_dev = dsa_port_to_bridge_port(dp);
+
+ switchdev_bridge_port_unoffload(brport_dev);
+
return dsa_port_switchdev_unsync_objs(dp, br, extack);
}