Skip to content

Commit

Permalink
mlxsw: spectrum_fid: Configure egress VID classification for multicast
Browse files Browse the repository at this point in the history
The device includes two main tables to support layer 2 multicast (i.e.,
MDB and flooding). These are the PGT (Port Group Table) table and the MPE
(Multicast Port Egress) table.
- PGT is {MID -> (bitmap of local_port, SPME index)}
- MPE is {(Local port, SMPE index) -> eVID}

In the legacy model, software did not interact with MPE table as it was
completely hidden in firmware. In the new model, software needs to
populate the table itself in order to map from {Local port, SMPE} to an
egress VID. This is done using the SMPE register.

Configure SMPE register when a {Local port, VID} are mapped/unmapped to a
802.1d and 802.1q emulated FIDs. The MPE table is not relevant for rFIDs as
firmware handles their flooding.

Signed-off-by: Amit Cohen <amcohen@nvidia.com>
Reviewed-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  • Loading branch information
Amit Cohen authored and Paolo Abeni committed Jun 28, 2022
1 parent aa845e3 commit 8c2da08
Showing 1 changed file with 23 additions and 0 deletions.
23 changes: 23 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,18 @@ mlxsw_sp_fid_port_vid_list_del(struct mlxsw_sp_fid *fid, u16 local_port,
}
}

static int
mlxsw_sp_fid_mpe_table_map(const struct mlxsw_sp_fid *fid, u16 local_port,
u16 vid, bool valid)
{
struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp;
char smpe_pl[MLXSW_REG_SMPE_LEN];

mlxsw_reg_smpe_pack(smpe_pl, local_port, fid->fid_index,
valid ? vid : 0);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(smpe), smpe_pl);
}

static int mlxsw_sp_fid_8021d_port_vid_map(struct mlxsw_sp_fid *fid,
struct mlxsw_sp_port *mlxsw_sp_port,
u16 vid)
Expand All @@ -635,6 +647,12 @@ static int mlxsw_sp_fid_8021d_port_vid_map(struct mlxsw_sp_fid *fid,
if (err)
return err;

if (fid->fid_family->mlxsw_sp->ubridge) {
err = mlxsw_sp_fid_mpe_table_map(fid, local_port, vid, true);
if (err)
goto err_mpe_table_map;
}

err = mlxsw_sp_fid_port_vid_list_add(fid, mlxsw_sp_port->local_port,
vid);
if (err)
Expand All @@ -652,6 +670,9 @@ static int mlxsw_sp_fid_8021d_port_vid_map(struct mlxsw_sp_fid *fid,
mlxsw_sp->fid_core->port_fid_mappings[local_port]--;
mlxsw_sp_fid_port_vid_list_del(fid, mlxsw_sp_port->local_port, vid);
err_port_vid_list_add:
if (fid->fid_family->mlxsw_sp->ubridge)
mlxsw_sp_fid_mpe_table_map(fid, local_port, vid, false);
err_mpe_table_map:
__mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid, false);
return err;
}
Expand All @@ -667,6 +688,8 @@ mlxsw_sp_fid_8021d_port_vid_unmap(struct mlxsw_sp_fid *fid,
mlxsw_sp_port_vlan_mode_trans(mlxsw_sp_port);
mlxsw_sp->fid_core->port_fid_mappings[local_port]--;
mlxsw_sp_fid_port_vid_list_del(fid, mlxsw_sp_port->local_port, vid);
if (fid->fid_family->mlxsw_sp->ubridge)
mlxsw_sp_fid_mpe_table_map(fid, local_port, vid, false);
__mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid, false);
}

Expand Down

0 comments on commit 8c2da08

Please sign in to comment.