Skip to content

Commit

Permalink
mlxsw: spectrum: Offload learning to the switch ASIC
Browse files Browse the repository at this point in the history
Up until now we simply stored the learning configuration of a bridge
port in the driver and decided whether to learn a new FDB record based
on this value.

However, this is sub-optimal in cases where learning is disabled on the
bridge port, as the device repeatedly generates learning notifications
for the same record.

Instead, offload the learning configuration to the device, thereby
preventing it from generating notifications when learning is disabled.

Signed-off-by: Ido Schimmel <[email protected]>
Signed-off-by: Jiri Pirko <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
idosch authored and davem330 committed Aug 24, 2016
1 parent 584d73d commit 89b548f
Showing 1 changed file with 44 additions and 3 deletions.
47 changes: 44 additions & 3 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,12 +261,40 @@ int mlxsw_sp_vport_flood_set(struct mlxsw_sp_port *mlxsw_sp_vport, u16 fid,
false);
}

static int mlxsw_sp_port_learning_set(struct mlxsw_sp_port *mlxsw_sp_port,
bool set)
{
u16 vid;
int err;

if (mlxsw_sp_port_is_vport(mlxsw_sp_port)) {
vid = mlxsw_sp_vport_vid_get(mlxsw_sp_port);

return __mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, vid,
set);
}

for_each_set_bit(vid, mlxsw_sp_port->active_vlans, VLAN_N_VID) {
err = __mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, vid,
set);
if (err)
goto err_port_vid_learning_set;
}

return 0;

err_port_vid_learning_set:
for_each_set_bit(vid, mlxsw_sp_port->active_vlans, VLAN_N_VID)
__mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, vid, !set);
return err;
}

static int mlxsw_sp_port_attr_br_flags_set(struct mlxsw_sp_port *mlxsw_sp_port,
struct switchdev_trans *trans,
unsigned long brport_flags)
{
unsigned long learning = mlxsw_sp_port->learning ? BR_LEARNING : 0;
unsigned long uc_flood = mlxsw_sp_port->uc_flood ? BR_FLOOD : 0;
bool set;
int err;

if (!mlxsw_sp_port->bridged)
Expand All @@ -276,17 +304,30 @@ static int mlxsw_sp_port_attr_br_flags_set(struct mlxsw_sp_port *mlxsw_sp_port,
return 0;

if ((uc_flood ^ brport_flags) & BR_FLOOD) {
set = mlxsw_sp_port->uc_flood ? false : true;
err = mlxsw_sp_port_uc_flood_set(mlxsw_sp_port, set);
err = mlxsw_sp_port_uc_flood_set(mlxsw_sp_port,
!mlxsw_sp_port->uc_flood);
if (err)
return err;
}

if ((learning ^ brport_flags) & BR_LEARNING) {
err = mlxsw_sp_port_learning_set(mlxsw_sp_port,
!mlxsw_sp_port->learning);
if (err)
goto err_port_learning_set;
}

mlxsw_sp_port->uc_flood = brport_flags & BR_FLOOD ? 1 : 0;
mlxsw_sp_port->learning = brport_flags & BR_LEARNING ? 1 : 0;
mlxsw_sp_port->learning_sync = brport_flags & BR_LEARNING_SYNC ? 1 : 0;

return 0;

err_port_learning_set:
if ((uc_flood ^ brport_flags) & BR_FLOOD)
mlxsw_sp_port_uc_flood_set(mlxsw_sp_port,
mlxsw_sp_port->uc_flood);
return err;
}

static int mlxsw_sp_ageing_set(struct mlxsw_sp *mlxsw_sp, u32 ageing_time)
Expand Down

0 comments on commit 89b548f

Please sign in to comment.