Commit 50853808 authored by David S. Miller's avatar David S. Miller

Merge branch 'mlxsw-Prepare-for-VLAN-aware-bridge-w-VxLAN'

Ido Schimmel says:

====================
mlxsw: Prepare for VLAN-aware bridge w/VxLAN

The driver is using 802.1Q filtering identifiers (FIDs) to represent the
different VLANs in the VLAN-aware bridge (only one is supported).

However, the device cannot assign a VNI to such FIDs, which prevents the
driver from supporting the enslavement of VxLAN devices to the
VLAN-aware bridge.

This patchset works around this limitation by emulating 802.1Q FIDs
using 802.1D FIDs, which can be assigned a VNI and so far have only been
used in conjunction with VLAN-unaware bridges.

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

First four patches introduce the new FID family of emulated 802.1Q FIDs
and the associated type of router interfaces (RIFs). Last patch flips
the driver to use this new FID family.

The diff is relatively small because the internal implementation of each
FID family is contained and hidden in spectrum_fid.c. Different internal
users (e.g., bridge, router) are aware of the different FID types, but
do not care about their internal implementation. This makes it trivial
to swap the current implementation of 802.1Q FIDs with the new one,
using 802.1D FIDs.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 4e3c7c00 c2e7490c
...@@ -4111,16 +4111,20 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core) ...@@ -4111,16 +4111,20 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
mlxsw_sp_kvdl_fini(mlxsw_sp); mlxsw_sp_kvdl_fini(mlxsw_sp);
} }
/* Per-FID flood tables are used for both "true" 802.1D FIDs and emulated
* 802.1Q FIDs
*/
#define MLXSW_SP_FID_FLOOD_TABLE_SIZE (MLXSW_SP_FID_8021D_MAX + \
VLAN_VID_MASK - 1)
static const struct mlxsw_config_profile mlxsw_sp1_config_profile = { static const struct mlxsw_config_profile mlxsw_sp1_config_profile = {
.used_max_mid = 1, .used_max_mid = 1,
.max_mid = MLXSW_SP_MID_MAX, .max_mid = MLXSW_SP_MID_MAX,
.used_flood_tables = 1, .used_flood_tables = 1,
.used_flood_mode = 1, .used_flood_mode = 1,
.flood_mode = 3, .flood_mode = 3,
.max_fid_offset_flood_tables = 3,
.fid_offset_flood_table_size = VLAN_N_VID - 1,
.max_fid_flood_tables = 3, .max_fid_flood_tables = 3,
.fid_flood_table_size = MLXSW_SP_FID_8021D_MAX, .fid_flood_table_size = MLXSW_SP_FID_FLOOD_TABLE_SIZE,
.used_max_ib_mc = 1, .used_max_ib_mc = 1,
.max_ib_mc = 0, .max_ib_mc = 0,
.used_max_pkey = 1, .used_max_pkey = 1,
...@@ -4143,10 +4147,8 @@ static const struct mlxsw_config_profile mlxsw_sp2_config_profile = { ...@@ -4143,10 +4147,8 @@ static const struct mlxsw_config_profile mlxsw_sp2_config_profile = {
.used_flood_tables = 1, .used_flood_tables = 1,
.used_flood_mode = 1, .used_flood_mode = 1,
.flood_mode = 3, .flood_mode = 3,
.max_fid_offset_flood_tables = 3,
.fid_offset_flood_table_size = VLAN_N_VID - 1,
.max_fid_flood_tables = 3, .max_fid_flood_tables = 3,
.fid_flood_table_size = MLXSW_SP_FID_8021D_MAX, .fid_flood_table_size = MLXSW_SP_FID_FLOOD_TABLE_SIZE,
.used_max_ib_mc = 1, .used_max_ib_mc = 1,
.max_ib_mc = 0, .max_ib_mc = 0,
.used_max_pkey = 1, .used_max_pkey = 1,
......
...@@ -721,6 +721,7 @@ int mlxsw_sp_setup_tc_prio(struct mlxsw_sp_port *mlxsw_sp_port, ...@@ -721,6 +721,7 @@ int mlxsw_sp_setup_tc_prio(struct mlxsw_sp_port *mlxsw_sp_port,
struct tc_prio_qopt_offload *p); struct tc_prio_qopt_offload *p);
/* spectrum_fid.c */ /* spectrum_fid.c */
bool mlxsw_sp_fid_lag_vid_valid(const struct mlxsw_sp_fid *fid);
struct mlxsw_sp_fid *mlxsw_sp_fid_lookup_by_index(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_fid *mlxsw_sp_fid_lookup_by_index(struct mlxsw_sp *mlxsw_sp,
u16 fid_index); u16 fid_index);
int mlxsw_sp_fid_nve_ifindex(const struct mlxsw_sp_fid *fid, int *nve_ifindex); int mlxsw_sp_fid_nve_ifindex(const struct mlxsw_sp_fid *fid, int *nve_ifindex);
......
...@@ -98,6 +98,7 @@ struct mlxsw_sp_fid_family { ...@@ -98,6 +98,7 @@ struct mlxsw_sp_fid_family {
enum mlxsw_sp_rif_type rif_type; enum mlxsw_sp_rif_type rif_type;
const struct mlxsw_sp_fid_ops *ops; const struct mlxsw_sp_fid_ops *ops;
struct mlxsw_sp *mlxsw_sp; struct mlxsw_sp *mlxsw_sp;
u8 lag_vid_valid:1;
}; };
static const int mlxsw_sp_sfgc_uc_packet_types[MLXSW_REG_SFGC_TYPE_MAX] = { static const int mlxsw_sp_sfgc_uc_packet_types[MLXSW_REG_SFGC_TYPE_MAX] = {
...@@ -122,6 +123,11 @@ static const int *mlxsw_sp_packet_type_sfgc_types[] = { ...@@ -122,6 +123,11 @@ static const int *mlxsw_sp_packet_type_sfgc_types[] = {
[MLXSW_SP_FLOOD_TYPE_MC] = mlxsw_sp_sfgc_mc_packet_types, [MLXSW_SP_FLOOD_TYPE_MC] = mlxsw_sp_sfgc_mc_packet_types,
}; };
bool mlxsw_sp_fid_lag_vid_valid(const struct mlxsw_sp_fid *fid)
{
return fid->fid_family->lag_vid_valid;
}
struct mlxsw_sp_fid *mlxsw_sp_fid_lookup_by_index(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_fid *mlxsw_sp_fid_lookup_by_index(struct mlxsw_sp *mlxsw_sp,
u16 fid_index) u16 fid_index)
{ {
...@@ -601,7 +607,7 @@ mlxsw_sp_fid_8021d_compare(const struct mlxsw_sp_fid *fid, const void *arg) ...@@ -601,7 +607,7 @@ mlxsw_sp_fid_8021d_compare(const struct mlxsw_sp_fid *fid, const void *arg)
static u16 mlxsw_sp_fid_8021d_flood_index(const struct mlxsw_sp_fid *fid) static u16 mlxsw_sp_fid_8021d_flood_index(const struct mlxsw_sp_fid *fid)
{ {
return fid->fid_index - fid->fid_family->start_index; return fid->fid_index - VLAN_N_VID;
} }
static int mlxsw_sp_port_vp_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port) static int mlxsw_sp_port_vp_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port)
...@@ -792,6 +798,40 @@ static const struct mlxsw_sp_fid_family mlxsw_sp_fid_8021d_family = { ...@@ -792,6 +798,40 @@ static const struct mlxsw_sp_fid_family mlxsw_sp_fid_8021d_family = {
.nr_flood_tables = ARRAY_SIZE(mlxsw_sp_fid_8021d_flood_tables), .nr_flood_tables = ARRAY_SIZE(mlxsw_sp_fid_8021d_flood_tables),
.rif_type = MLXSW_SP_RIF_TYPE_FID, .rif_type = MLXSW_SP_RIF_TYPE_FID,
.ops = &mlxsw_sp_fid_8021d_ops, .ops = &mlxsw_sp_fid_8021d_ops,
.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) static int mlxsw_sp_fid_rfid_configure(struct mlxsw_sp_fid *fid)
...@@ -921,7 +961,7 @@ static const struct mlxsw_sp_fid_family mlxsw_sp_fid_dummy_family = { ...@@ -921,7 +961,7 @@ static const struct mlxsw_sp_fid_family mlxsw_sp_fid_dummy_family = {
}; };
static const struct mlxsw_sp_fid_family *mlxsw_sp_fid_family_arr[] = { static const struct mlxsw_sp_fid_family *mlxsw_sp_fid_family_arr[] = {
[MLXSW_SP_FID_TYPE_8021Q] = &mlxsw_sp_fid_8021q_family, [MLXSW_SP_FID_TYPE_8021Q] = &mlxsw_sp_fid_8021q_emu_family,
[MLXSW_SP_FID_TYPE_8021D] = &mlxsw_sp_fid_8021d_family, [MLXSW_SP_FID_TYPE_8021D] = &mlxsw_sp_fid_8021d_family,
[MLXSW_SP_FID_TYPE_RFID] = &mlxsw_sp_fid_rfid_family, [MLXSW_SP_FID_TYPE_RFID] = &mlxsw_sp_fid_rfid_family,
[MLXSW_SP_FID_TYPE_DUMMY] = &mlxsw_sp_fid_dummy_family, [MLXSW_SP_FID_TYPE_DUMMY] = &mlxsw_sp_fid_dummy_family,
......
...@@ -7296,6 +7296,15 @@ static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_fid_ops = { ...@@ -7296,6 +7296,15 @@ static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_fid_ops = {
.fdb_del = mlxsw_sp_rif_fid_fdb_del, .fdb_del = mlxsw_sp_rif_fid_fdb_del,
}; };
static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_vlan_emu_ops = {
.type = MLXSW_SP_RIF_TYPE_VLAN,
.rif_size = sizeof(struct mlxsw_sp_rif),
.configure = mlxsw_sp_rif_fid_configure,
.deconfigure = mlxsw_sp_rif_fid_deconfigure,
.fid_get = mlxsw_sp_rif_vlan_fid_get,
.fdb_del = mlxsw_sp_rif_vlan_fdb_del,
};
static struct mlxsw_sp_rif_ipip_lb * static struct mlxsw_sp_rif_ipip_lb *
mlxsw_sp_rif_ipip_lb_rif(struct mlxsw_sp_rif *rif) mlxsw_sp_rif_ipip_lb_rif(struct mlxsw_sp_rif *rif)
{ {
...@@ -7364,7 +7373,7 @@ static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_ipip_lb_ops = { ...@@ -7364,7 +7373,7 @@ static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_ipip_lb_ops = {
static const struct mlxsw_sp_rif_ops *mlxsw_sp_rif_ops_arr[] = { static const struct mlxsw_sp_rif_ops *mlxsw_sp_rif_ops_arr[] = {
[MLXSW_SP_RIF_TYPE_SUBPORT] = &mlxsw_sp_rif_subport_ops, [MLXSW_SP_RIF_TYPE_SUBPORT] = &mlxsw_sp_rif_subport_ops,
[MLXSW_SP_RIF_TYPE_VLAN] = &mlxsw_sp_rif_vlan_ops, [MLXSW_SP_RIF_TYPE_VLAN] = &mlxsw_sp_rif_vlan_emu_ops,
[MLXSW_SP_RIF_TYPE_FID] = &mlxsw_sp_rif_fid_ops, [MLXSW_SP_RIF_TYPE_FID] = &mlxsw_sp_rif_fid_ops,
[MLXSW_SP_RIF_TYPE_IPIP_LB] = &mlxsw_sp_rif_ipip_lb_ops, [MLXSW_SP_RIF_TYPE_IPIP_LB] = &mlxsw_sp_rif_ipip_lb_ops,
}; };
......
...@@ -2482,7 +2482,8 @@ static void mlxsw_sp_fdb_notify_mac_lag_process(struct mlxsw_sp *mlxsw_sp, ...@@ -2482,7 +2482,8 @@ static void mlxsw_sp_fdb_notify_mac_lag_process(struct mlxsw_sp *mlxsw_sp,
bridge_device = bridge_port->bridge_device; bridge_device = bridge_port->bridge_device;
vid = bridge_device->vlan_enabled ? mlxsw_sp_port_vlan->vid : 0; vid = bridge_device->vlan_enabled ? mlxsw_sp_port_vlan->vid : 0;
lag_vid = mlxsw_sp_port_vlan->vid; lag_vid = mlxsw_sp_fid_lag_vid_valid(mlxsw_sp_port_vlan->fid) ?
mlxsw_sp_port_vlan->vid : 0;
do_fdb_op: do_fdb_op:
err = mlxsw_sp_port_fdb_uc_lag_op(mlxsw_sp, lag_id, mac, fid, lag_vid, err = mlxsw_sp_port_fdb_uc_lag_op(mlxsw_sp, lag_id, mac, fid, lag_vid,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment