mlxsw: spectrum_fid: Introduce emulated 802.1Q FIDs
authorIdo Schimmel <idosch@mellanox.com>
Sun, 25 Nov 2018 09:43:57 +0000 (09:43 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 27 Nov 2018 23:27:08 +0000 (15:27 -0800)
The driver uses 802.1Q FIDs when offloading a VLAN-aware bridge.
Unfortunately, it is not possible to assign a VNI to such FIDs, which
prompts the driver to forbid the enslavement of VxLAN devices to a
VLAN-aware bridge.

Workaround this hardware limitation by creating a new family of FIDs,
emulated 802.1Q FIDs. These FIDs are emulated using 802.1D FIDs, which
can be assigned a VNI.

The downside of this approach is that multiple {Port, VID}->FID entries
are required, whereas only a single VID->FID is required with "true"
802.1Q FIDs.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c

index e1739cd..99ccb11 100644 (file)
@@ -801,6 +801,39 @@ static const struct mlxsw_sp_fid_family mlxsw_sp_fid_8021d_family = {
        .lag_vid_valid          = 1,
 };
 
+static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_8021q_emu_ops = {
+       .setup                  = mlxsw_sp_fid_8021q_setup,
+       .configure              = mlxsw_sp_fid_8021d_configure,
+       .deconfigure            = mlxsw_sp_fid_8021d_deconfigure,
+       .index_alloc            = mlxsw_sp_fid_8021d_index_alloc,
+       .compare                = mlxsw_sp_fid_8021q_compare,
+       .flood_index            = mlxsw_sp_fid_8021d_flood_index,
+       .port_vid_map           = mlxsw_sp_fid_8021d_port_vid_map,
+       .port_vid_unmap         = mlxsw_sp_fid_8021d_port_vid_unmap,
+       .vni_set                = mlxsw_sp_fid_8021d_vni_set,
+       .vni_clear              = mlxsw_sp_fid_8021d_vni_clear,
+       .nve_flood_index_set    = mlxsw_sp_fid_8021d_nve_flood_index_set,
+       .nve_flood_index_clear  = mlxsw_sp_fid_8021d_nve_flood_index_clear,
+};
+
+/* There are 4K-2 emulated 802.1Q FIDs, starting right after the 802.1D FIDs */
+#define MLXSW_SP_FID_8021Q_EMU_START   (VLAN_N_VID + MLXSW_SP_FID_8021D_MAX)
+#define MLXSW_SP_FID_8021Q_EMU_END     (MLXSW_SP_FID_8021Q_EMU_START + \
+                                        VLAN_VID_MASK - 2)
+
+/* Range and flood configuration must match mlxsw_config_profile */
+static const struct mlxsw_sp_fid_family mlxsw_sp_fid_8021q_emu_family = {
+       .type                   = MLXSW_SP_FID_TYPE_8021Q,
+       .fid_size               = sizeof(struct mlxsw_sp_fid_8021q),
+       .start_index            = MLXSW_SP_FID_8021Q_EMU_START,
+       .end_index              = MLXSW_SP_FID_8021Q_EMU_END,
+       .flood_tables           = mlxsw_sp_fid_8021d_flood_tables,
+       .nr_flood_tables        = ARRAY_SIZE(mlxsw_sp_fid_8021d_flood_tables),
+       .rif_type               = MLXSW_SP_RIF_TYPE_VLAN,
+       .ops                    = &mlxsw_sp_fid_8021q_emu_ops,
+       .lag_vid_valid          = 1,
+};
+
 static int mlxsw_sp_fid_rfid_configure(struct mlxsw_sp_fid *fid)
 {
        /* rFIDs are allocated by the device during init */