Skip to content

Commit b7de468

Browse files
idoschdavem330
authored andcommitted
mlxsw: spectrum: Handle VLAN devices linking / unlinking
When a VLAN interface is configured on top of a physical port we should associate the VLAN device with the matching vPort. Likewise, when it's removed, we should revert back to the underlying port netdev. While not a must, this is consistent with port netdevs and also provides a more accurate error printing via netdev_err() and friends. Signed-off-by: Ido Schimmel <[email protected]> Signed-off-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9d9fe04 commit b7de468

File tree

1 file changed

+51
-3
lines changed

1 file changed

+51
-3
lines changed

drivers/net/ethernet/mellanox/mlxsw/spectrum.c

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2259,6 +2259,40 @@ static int mlxsw_sp_port_lag_changed(struct mlxsw_sp_port *mlxsw_sp_port,
22592259
return mlxsw_sp_port_lag_tx_en_set(mlxsw_sp_port, info->tx_enabled);
22602260
}
22612261

2262+
static int mlxsw_sp_port_vlan_link(struct mlxsw_sp_port *mlxsw_sp_port,
2263+
struct net_device *vlan_dev)
2264+
{
2265+
struct mlxsw_sp_port *mlxsw_sp_vport;
2266+
u16 vid = vlan_dev_vlan_id(vlan_dev);
2267+
2268+
mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, vid);
2269+
if (!mlxsw_sp_vport) {
2270+
WARN_ON(!mlxsw_sp_vport);
2271+
return -EINVAL;
2272+
}
2273+
2274+
mlxsw_sp_vport->dev = vlan_dev;
2275+
2276+
return 0;
2277+
}
2278+
2279+
static int mlxsw_sp_port_vlan_unlink(struct mlxsw_sp_port *mlxsw_sp_port,
2280+
struct net_device *vlan_dev)
2281+
{
2282+
struct mlxsw_sp_port *mlxsw_sp_vport;
2283+
u16 vid = vlan_dev_vlan_id(vlan_dev);
2284+
2285+
mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, vid);
2286+
if (!mlxsw_sp_vport) {
2287+
WARN_ON(!mlxsw_sp_vport);
2288+
return -EINVAL;
2289+
}
2290+
2291+
mlxsw_sp_vport->dev = mlxsw_sp_port->dev;
2292+
2293+
return 0;
2294+
}
2295+
22622296
static int mlxsw_sp_netdevice_port_upper_event(struct net_device *dev,
22632297
unsigned long event, void *ptr)
22642298
{
@@ -2288,9 +2322,23 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *dev,
22882322
break;
22892323
case NETDEV_CHANGEUPPER:
22902324
upper_dev = info->upper_dev;
2291-
if (!info->master)
2292-
break;
2293-
if (netif_is_bridge_master(upper_dev)) {
2325+
if (is_vlan_dev(upper_dev)) {
2326+
if (info->linking) {
2327+
err = mlxsw_sp_port_vlan_link(mlxsw_sp_port,
2328+
upper_dev);
2329+
if (err) {
2330+
netdev_err(dev, "Failed to link VLAN device\n");
2331+
return NOTIFY_BAD;
2332+
}
2333+
} else {
2334+
err = mlxsw_sp_port_vlan_unlink(mlxsw_sp_port,
2335+
upper_dev);
2336+
if (err) {
2337+
netdev_err(dev, "Failed to unlink VLAN device\n");
2338+
return NOTIFY_BAD;
2339+
}
2340+
}
2341+
} else if (netif_is_bridge_master(upper_dev)) {
22942342
if (info->linking) {
22952343
err = mlxsw_sp_port_bridge_join(mlxsw_sp_port);
22962344
if (err)

0 commit comments

Comments
 (0)