diff options
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | 42 |
1 files changed, 7 insertions, 35 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c index a1ad5e6bdfa8..d1b59cdfacc1 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | |||
@@ -450,6 +450,8 @@ void mlxsw_sp_fid_destroy(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_fid *f) | |||
450 | 450 | ||
451 | kfree(f); | 451 | kfree(f); |
452 | 452 | ||
453 | mlxsw_sp_fid_map(mlxsw_sp, fid, false); | ||
454 | |||
453 | mlxsw_sp_fid_op(mlxsw_sp, fid, false); | 455 | mlxsw_sp_fid_op(mlxsw_sp, fid, false); |
454 | } | 456 | } |
455 | 457 | ||
@@ -997,13 +999,13 @@ static int mlxsw_sp_port_obj_add(struct net_device *dev, | |||
997 | } | 999 | } |
998 | 1000 | ||
999 | static int __mlxsw_sp_port_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port, | 1001 | static int __mlxsw_sp_port_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port, |
1000 | u16 vid_begin, u16 vid_end, bool init) | 1002 | u16 vid_begin, u16 vid_end) |
1001 | { | 1003 | { |
1002 | struct net_device *dev = mlxsw_sp_port->dev; | 1004 | struct net_device *dev = mlxsw_sp_port->dev; |
1003 | u16 vid, pvid; | 1005 | u16 vid, pvid; |
1004 | int err; | 1006 | int err; |
1005 | 1007 | ||
1006 | if (!init && !mlxsw_sp_port->bridged) | 1008 | if (!mlxsw_sp_port->bridged) |
1007 | return -EINVAL; | 1009 | return -EINVAL; |
1008 | 1010 | ||
1009 | err = __mlxsw_sp_port_vlans_set(mlxsw_sp_port, vid_begin, vid_end, | 1011 | err = __mlxsw_sp_port_vlans_set(mlxsw_sp_port, vid_begin, vid_end, |
@@ -1014,9 +1016,6 @@ static int __mlxsw_sp_port_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port, | |||
1014 | return err; | 1016 | return err; |
1015 | } | 1017 | } |
1016 | 1018 | ||
1017 | if (init) | ||
1018 | goto out; | ||
1019 | |||
1020 | pvid = mlxsw_sp_port->pvid; | 1019 | pvid = mlxsw_sp_port->pvid; |
1021 | if (pvid >= vid_begin && pvid <= vid_end) { | 1020 | if (pvid >= vid_begin && pvid <= vid_end) { |
1022 | err = mlxsw_sp_port_pvid_set(mlxsw_sp_port, 0); | 1021 | err = mlxsw_sp_port_pvid_set(mlxsw_sp_port, 0); |
@@ -1028,7 +1027,6 @@ static int __mlxsw_sp_port_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port, | |||
1028 | 1027 | ||
1029 | mlxsw_sp_port_fid_leave(mlxsw_sp_port, vid_begin, vid_end); | 1028 | mlxsw_sp_port_fid_leave(mlxsw_sp_port, vid_begin, vid_end); |
1030 | 1029 | ||
1031 | out: | ||
1032 | /* Changing activity bits only if HW operation succeded */ | 1030 | /* Changing activity bits only if HW operation succeded */ |
1033 | for (vid = vid_begin; vid <= vid_end; vid++) | 1031 | for (vid = vid_begin; vid <= vid_end; vid++) |
1034 | clear_bit(vid, mlxsw_sp_port->active_vlans); | 1032 | clear_bit(vid, mlxsw_sp_port->active_vlans); |
@@ -1039,8 +1037,8 @@ out: | |||
1039 | static int mlxsw_sp_port_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port, | 1037 | static int mlxsw_sp_port_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port, |
1040 | const struct switchdev_obj_port_vlan *vlan) | 1038 | const struct switchdev_obj_port_vlan *vlan) |
1041 | { | 1039 | { |
1042 | return __mlxsw_sp_port_vlans_del(mlxsw_sp_port, | 1040 | return __mlxsw_sp_port_vlans_del(mlxsw_sp_port, vlan->vid_begin, |
1043 | vlan->vid_begin, vlan->vid_end, false); | 1041 | vlan->vid_end); |
1044 | } | 1042 | } |
1045 | 1043 | ||
1046 | void mlxsw_sp_port_active_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port) | 1044 | void mlxsw_sp_port_active_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port) |
@@ -1048,7 +1046,7 @@ void mlxsw_sp_port_active_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port) | |||
1048 | u16 vid; | 1046 | u16 vid; |
1049 | 1047 | ||
1050 | for_each_set_bit(vid, mlxsw_sp_port->active_vlans, VLAN_N_VID) | 1048 | for_each_set_bit(vid, mlxsw_sp_port->active_vlans, VLAN_N_VID) |
1051 | __mlxsw_sp_port_vlans_del(mlxsw_sp_port, vid, vid, false); | 1049 | __mlxsw_sp_port_vlans_del(mlxsw_sp_port, vid, vid); |
1052 | } | 1050 | } |
1053 | 1051 | ||
1054 | static int | 1052 | static int |
@@ -1546,32 +1544,6 @@ void mlxsw_sp_switchdev_fini(struct mlxsw_sp *mlxsw_sp) | |||
1546 | mlxsw_sp_fdb_fini(mlxsw_sp); | 1544 | mlxsw_sp_fdb_fini(mlxsw_sp); |
1547 | } | 1545 | } |
1548 | 1546 | ||
1549 | int mlxsw_sp_port_vlan_init(struct mlxsw_sp_port *mlxsw_sp_port) | ||
1550 | { | ||
1551 | struct net_device *dev = mlxsw_sp_port->dev; | ||
1552 | int err; | ||
1553 | |||
1554 | /* Allow only untagged packets to ingress and tag them internally | ||
1555 | * with VID 1. | ||
1556 | */ | ||
1557 | mlxsw_sp_port->pvid = 1; | ||
1558 | err = __mlxsw_sp_port_vlans_del(mlxsw_sp_port, 0, VLAN_N_VID - 1, | ||
1559 | true); | ||
1560 | if (err) { | ||
1561 | netdev_err(dev, "Unable to init VLANs\n"); | ||
1562 | return err; | ||
1563 | } | ||
1564 | |||
1565 | /* Add implicit VLAN interface in the device, so that untagged | ||
1566 | * packets will be classified to the default vFID. | ||
1567 | */ | ||
1568 | err = mlxsw_sp_port_add_vid(dev, 0, 1); | ||
1569 | if (err) | ||
1570 | netdev_err(dev, "Failed to configure default vFID\n"); | ||
1571 | |||
1572 | return err; | ||
1573 | } | ||
1574 | |||
1575 | void mlxsw_sp_port_switchdev_init(struct mlxsw_sp_port *mlxsw_sp_port) | 1547 | void mlxsw_sp_port_switchdev_init(struct mlxsw_sp_port *mlxsw_sp_port) |
1576 | { | 1548 | { |
1577 | mlxsw_sp_port->dev->switchdev_ops = &mlxsw_sp_port_switchdev_ops; | 1549 | mlxsw_sp_port->dev->switchdev_ops = &mlxsw_sp_port_switchdev_ops; |