summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/mscc/ocelot_net.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/mscc/ocelot_net.c')
-rw-r--r--drivers/net/ethernet/mscc/ocelot_net.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c
index 0a4de949f4d9..8f12fa45b1b5 100644
--- a/drivers/net/ethernet/mscc/ocelot_net.c
+++ b/drivers/net/ethernet/mscc/ocelot_net.c
@@ -1164,6 +1164,27 @@ ocelot_netdevice_lag_changeupper(struct net_device *dev,
return NOTIFY_DONE;
}
+static int
+ocelot_netdevice_changelowerstate(struct net_device *dev,
+ struct netdev_lag_lower_state_info *info)
+{
+ struct ocelot_port_private *priv = netdev_priv(dev);
+ bool is_active = info->link_up && info->tx_enabled;
+ struct ocelot_port *ocelot_port = &priv->port;
+ struct ocelot *ocelot = ocelot_port->ocelot;
+ int port = priv->chip_port;
+
+ if (!ocelot_port->bond)
+ return NOTIFY_DONE;
+
+ if (ocelot_port->lag_tx_active == is_active)
+ return NOTIFY_DONE;
+
+ ocelot_port_lag_change(ocelot, port, is_active);
+
+ return NOTIFY_OK;
+}
+
static int ocelot_netdevice_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
@@ -1181,6 +1202,15 @@ static int ocelot_netdevice_event(struct notifier_block *unused,
break;
}
+ case NETDEV_CHANGELOWERSTATE: {
+ struct netdev_notifier_changelowerstate_info *info = ptr;
+
+ if (!ocelot_netdevice_dev_check(dev))
+ break;
+
+ return ocelot_netdevice_changelowerstate(dev,
+ info->lower_state_info);
+ }
default:
break;
}