Commit 80bedf1a authored by Ido Schimmel's avatar Ido Schimmel Committed by David S. Miller

mlxsw: spectrum: Use notifier_from_errno() in notifier block

Instead of checking the error value and returning NOTIFY_BAD, just use
notifier_from_errno() and simplify the code.
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 527f2273
......@@ -49,6 +49,7 @@
#include <linux/jiffies.h>
#include <linux/bitops.h>
#include <linux/list.h>
#include <linux/notifier.h>
#include <linux/dcbnl.h>
#include <net/switchdev.h>
#include <generated/utsrelease.h>
......@@ -3024,7 +3025,7 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *dev,
struct mlxsw_sp_port *mlxsw_sp_port;
struct net_device *upper_dev;
struct mlxsw_sp *mlxsw_sp;
int err;
int err = 0;
mlxsw_sp_port = netdev_priv(dev);
mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
......@@ -3038,68 +3039,42 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *dev,
/* HW limitation forbids to put ports to multiple bridges. */
if (netif_is_bridge_master(upper_dev) &&
!mlxsw_sp_master_bridge_check(mlxsw_sp, upper_dev))
return NOTIFY_BAD;
return -EINVAL;
if (netif_is_lag_master(upper_dev) &&
!mlxsw_sp_master_lag_check(mlxsw_sp, upper_dev,
info->upper_info))
return NOTIFY_BAD;
return -EINVAL;
break;
case NETDEV_CHANGEUPPER:
upper_dev = info->upper_dev;
if (is_vlan_dev(upper_dev)) {
if (info->linking) {
if (info->linking)
err = mlxsw_sp_port_vlan_link(mlxsw_sp_port,
upper_dev);
if (err) {
netdev_err(dev, "Failed to link VLAN device\n");
return NOTIFY_BAD;
}
} else {
else
err = mlxsw_sp_port_vlan_unlink(mlxsw_sp_port,
upper_dev);
if (err) {
netdev_err(dev, "Failed to unlink VLAN device\n");
return NOTIFY_BAD;
}
}
} else if (netif_is_bridge_master(upper_dev)) {
if (info->linking) {
err = mlxsw_sp_port_bridge_join(mlxsw_sp_port);
if (err) {
netdev_err(dev, "Failed to join bridge\n");
return NOTIFY_BAD;
}
mlxsw_sp_master_bridge_inc(mlxsw_sp, upper_dev);
} else {
err = mlxsw_sp_port_bridge_leave(mlxsw_sp_port,
true);
mlxsw_sp_master_bridge_dec(mlxsw_sp, upper_dev);
if (err) {
netdev_err(dev, "Failed to leave bridge\n");
return NOTIFY_BAD;
}
}
} else if (netif_is_lag_master(upper_dev)) {
if (info->linking) {
if (info->linking)
err = mlxsw_sp_port_lag_join(mlxsw_sp_port,
upper_dev);
if (err) {
netdev_err(dev, "Failed to join link aggregation\n");
return NOTIFY_BAD;
}
} else {
else
err = mlxsw_sp_port_lag_leave(mlxsw_sp_port,
upper_dev);
if (err) {
netdev_err(dev, "Failed to leave link aggregation\n");
return NOTIFY_BAD;
}
}
}
break;
}
return NOTIFY_DONE;
return err;
}
static int mlxsw_sp_netdevice_port_lower_event(struct net_device *dev,
......@@ -3123,7 +3098,7 @@ static int mlxsw_sp_netdevice_port_lower_event(struct net_device *dev,
break;
}
return NOTIFY_DONE;
return 0;
}
static int mlxsw_sp_netdevice_port_event(struct net_device *dev,
......@@ -3137,7 +3112,7 @@ static int mlxsw_sp_netdevice_port_event(struct net_device *dev,
return mlxsw_sp_netdevice_port_lower_event(dev, event, ptr);
}
return NOTIFY_DONE;
return 0;
}
static int mlxsw_sp_netdevice_lag_event(struct net_device *lag_dev,
......@@ -3150,12 +3125,12 @@ static int mlxsw_sp_netdevice_lag_event(struct net_device *lag_dev,
netdev_for_each_lower_dev(lag_dev, dev, iter) {
if (mlxsw_sp_port_dev_check(dev)) {
ret = mlxsw_sp_netdevice_port_event(dev, event, ptr);
if (ret == NOTIFY_BAD)
if (ret)
return ret;
}
}
return NOTIFY_DONE;
return 0;
}
static struct mlxsw_sp_vfid *
......@@ -3446,7 +3421,7 @@ static int mlxsw_sp_netdevice_vport_event(struct net_device *dev,
struct netdev_notifier_changeupper_info *info = ptr;
struct mlxsw_sp_port *mlxsw_sp_vport;
struct net_device *upper_dev;
int err;
int err = 0;
mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, vid);
......@@ -3456,13 +3431,13 @@ static int mlxsw_sp_netdevice_vport_event(struct net_device *dev,
if (!info->master || !info->linking)
break;
if (!netif_is_bridge_master(upper_dev))
return NOTIFY_BAD;
return -EINVAL;
/* We can't have multiple VLAN interfaces configured on
* the same port and being members in the same bridge.
*/
if (!mlxsw_sp_port_master_bridge_check(mlxsw_sp_port,
upper_dev))
return NOTIFY_BAD;
return -EINVAL;
break;
case NETDEV_CHANGEUPPER:
upper_dev = info->upper_dev;
......@@ -3471,31 +3446,23 @@ static int mlxsw_sp_netdevice_vport_event(struct net_device *dev,
if (info->linking) {
if (!mlxsw_sp_vport) {
WARN_ON(!mlxsw_sp_vport);
return NOTIFY_BAD;
return -EINVAL;
}
err = mlxsw_sp_vport_bridge_join(mlxsw_sp_vport,
upper_dev);
if (err) {
netdev_err(dev, "Failed to join bridge\n");
return NOTIFY_BAD;
}
} else {
/* We ignore bridge's unlinking notifications if vPort
* is gone, since we already left the bridge when the
* VLAN device was unlinked from the real device.
*/
if (!mlxsw_sp_vport)
return NOTIFY_DONE;
return 0;
err = mlxsw_sp_vport_bridge_leave(mlxsw_sp_vport,
upper_dev, true);
if (err) {
netdev_err(dev, "Failed to leave bridge\n");
return NOTIFY_BAD;
}
}
}
return NOTIFY_DONE;
return err;
}
static int mlxsw_sp_netdevice_lag_vport_event(struct net_device *lag_dev,
......@@ -3510,12 +3477,12 @@ static int mlxsw_sp_netdevice_lag_vport_event(struct net_device *lag_dev,
if (mlxsw_sp_port_dev_check(dev)) {
ret = mlxsw_sp_netdevice_vport_event(dev, event, ptr,
vid);
if (ret == NOTIFY_BAD)
if (ret)
return ret;
}
}
return NOTIFY_DONE;
return 0;
}
static int mlxsw_sp_netdevice_vlan_event(struct net_device *vlan_dev,
......@@ -3531,24 +3498,23 @@ static int mlxsw_sp_netdevice_vlan_event(struct net_device *vlan_dev,
return mlxsw_sp_netdevice_lag_vport_event(real_dev, event, ptr,
vid);
return NOTIFY_DONE;
return 0;
}
static int mlxsw_sp_netdevice_event(struct notifier_block *unused,
unsigned long event, void *ptr)
{
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
int err = 0;
if (mlxsw_sp_port_dev_check(dev))
return mlxsw_sp_netdevice_port_event(dev, event, ptr);
if (netif_is_lag_master(dev))
return mlxsw_sp_netdevice_lag_event(dev, event, ptr);
if (is_vlan_dev(dev))
return mlxsw_sp_netdevice_vlan_event(dev, event, ptr);
err = mlxsw_sp_netdevice_port_event(dev, event, ptr);
else if (netif_is_lag_master(dev))
err = mlxsw_sp_netdevice_lag_event(dev, event, ptr);
else if (is_vlan_dev(dev))
err = mlxsw_sp_netdevice_vlan_event(dev, event, ptr);
return NOTIFY_DONE;
return notifier_from_errno(err);
}
static struct notifier_block mlxsw_sp_netdevice_nb __read_mostly = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment