diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c index 9043c6cdae89..863c8055746b 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c @@ -111,10 +111,10 @@ static void mlxsw_sp_bridge_port_mdb_flush(struct mlxsw_sp_port *mlxsw_sp_port, struct mlxsw_sp_bridge_port *bridge_port); -static void +static int mlxsw_sp_bridge_mdb_mc_enable_sync(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_bridge_device - *bridge_device); + *bridge_device, bool mc_enabled); static void mlxsw_sp_port_mrouter_update_mdb(struct mlxsw_sp_port *mlxsw_sp_port, @@ -917,7 +917,10 @@ static int mlxsw_sp_port_mc_disabled_set(struct mlxsw_sp_port *mlxsw_sp_port, return 0; bridge_device->multicast_enabled = !mc_disabled; - mlxsw_sp_bridge_mdb_mc_enable_sync(mlxsw_sp, bridge_device); + err = mlxsw_sp_bridge_mdb_mc_enable_sync(mlxsw_sp, bridge_device, + !mc_disabled); + if (err) + goto err_mc_enable_sync; list_for_each_entry(bridge_port, &bridge_device->ports_list, list) { bool member = mlxsw_sp_mc_flood(bridge_port); @@ -939,9 +942,10 @@ err_flood_table_set: mlxsw_sp_bridge_ports_flood_table_set(bridge_port, packet_type, !member); } - + mlxsw_sp_bridge_mdb_mc_enable_sync(mlxsw_sp, bridge_device, + mc_disabled); +err_mc_enable_sync: bridge_device->multicast_enabled = mc_disabled; - mlxsw_sp_bridge_mdb_mc_enable_sync(mlxsw_sp, bridge_device); return err; } @@ -1911,22 +1915,37 @@ err_out: return err; } -static void +static int mlxsw_sp_bridge_mdb_mc_enable_sync(struct mlxsw_sp *mlxsw_sp, - struct mlxsw_sp_bridge_device *bridge_device) + struct mlxsw_sp_bridge_device *bridge_device, + bool mc_enabled) { struct mlxsw_sp_mid *mid; - bool mc_enabled; - - mc_enabled = bridge_device->multicast_enabled; + int err; list_for_each_entry(mid, &bridge_device->mids_list, list) { if (mc_enabled) - mlxsw_sp_mc_write_mdb_entry(mlxsw_sp, mid, - bridge_device); + err = mlxsw_sp_mc_write_mdb_entry(mlxsw_sp, mid, + bridge_device); else + err = mlxsw_sp_mc_remove_mdb_entry(mlxsw_sp, mid); + + if (err) + goto err_mdb_entry_update; + } + + return 0; + +err_mdb_entry_update: + list_for_each_entry_continue_reverse(mid, &bridge_device->mids_list, + list) { + if (mc_enabled) mlxsw_sp_mc_remove_mdb_entry(mlxsw_sp, mid); + else + mlxsw_sp_mc_write_mdb_entry(mlxsw_sp, mid, + bridge_device); } + return err; } static void |