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

Merge branch 'mlxsw-unified-bridge-conversion-part-3'

Ido Schimmel says:

====================
mlxsw: Unified bridge conversion - part 3/6

This is the third part of the conversion of mlxsw to the unified bridge
model.

Like the second part, this patchset does not begin the conversion, but
instead prepares the FID code for it. The individual changes are
relatively small and self-contained with detailed description and
motivation in the commit message.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 23f94f1b 7dd19648
......@@ -6937,16 +6937,6 @@ MLXSW_ITEM32(reg, ritr, vlan_if_efid, 0x0C, 0, 16);
*/
MLXSW_ITEM32(reg, ritr, fid_if_fid, 0x08, 0, 16);
static inline void mlxsw_reg_ritr_fid_set(char *payload,
enum mlxsw_reg_ritr_if_type rif_type,
u16 fid)
{
if (rif_type == MLXSW_REG_RITR_FID_IF)
mlxsw_reg_ritr_fid_if_fid_set(payload, fid);
else
mlxsw_reg_ritr_vlan_if_vlan_id_set(payload, fid);
}
/* Sub-port Interface */
/* reg_ritr_sp_if_lag
......
......@@ -3232,6 +3232,7 @@ static int mlxsw_sp1_init(struct mlxsw_core *mlxsw_core,
mlxsw_sp->router_ops = &mlxsw_sp1_router_ops;
mlxsw_sp->listeners = mlxsw_sp1_listener;
mlxsw_sp->listeners_count = ARRAY_SIZE(mlxsw_sp1_listener);
mlxsw_sp->fid_family_arr = mlxsw_sp1_fid_family_arr;
mlxsw_sp->lowest_shaper_bs = MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP1;
return mlxsw_sp_init(mlxsw_core, mlxsw_bus_info, extack);
......@@ -3264,6 +3265,7 @@ static int mlxsw_sp2_init(struct mlxsw_core *mlxsw_core,
mlxsw_sp->router_ops = &mlxsw_sp2_router_ops;
mlxsw_sp->listeners = mlxsw_sp2_listener;
mlxsw_sp->listeners_count = ARRAY_SIZE(mlxsw_sp2_listener);
mlxsw_sp->fid_family_arr = mlxsw_sp2_fid_family_arr;
mlxsw_sp->lowest_shaper_bs = MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP2;
return mlxsw_sp_init(mlxsw_core, mlxsw_bus_info, extack);
......@@ -3296,6 +3298,7 @@ static int mlxsw_sp3_init(struct mlxsw_core *mlxsw_core,
mlxsw_sp->router_ops = &mlxsw_sp2_router_ops;
mlxsw_sp->listeners = mlxsw_sp2_listener;
mlxsw_sp->listeners_count = ARRAY_SIZE(mlxsw_sp2_listener);
mlxsw_sp->fid_family_arr = mlxsw_sp2_fid_family_arr;
mlxsw_sp->lowest_shaper_bs = MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP3;
return mlxsw_sp_init(mlxsw_core, mlxsw_bus_info, extack);
......@@ -3328,6 +3331,7 @@ static int mlxsw_sp4_init(struct mlxsw_core *mlxsw_core,
mlxsw_sp->router_ops = &mlxsw_sp2_router_ops;
mlxsw_sp->listeners = mlxsw_sp2_listener;
mlxsw_sp->listeners_count = ARRAY_SIZE(mlxsw_sp2_listener);
mlxsw_sp->fid_family_arr = mlxsw_sp2_fid_family_arr;
mlxsw_sp->lowest_shaper_bs = MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP4;
return mlxsw_sp_init(mlxsw_core, mlxsw_bus_info, extack);
......
......@@ -84,7 +84,7 @@ struct mlxsw_sp_upper {
enum mlxsw_sp_rif_type {
MLXSW_SP_RIF_TYPE_SUBPORT,
MLXSW_SP_RIF_TYPE_VLAN,
MLXSW_SP_RIF_TYPE_VLAN_EMU,
MLXSW_SP_RIF_TYPE_FID,
MLXSW_SP_RIF_TYPE_IPIP_LB, /* IP-in-IP loopback. */
MLXSW_SP_RIF_TYPE_MAX,
......@@ -211,6 +211,7 @@ struct mlxsw_sp {
const struct mlxsw_sp_mall_ops *mall_ops;
const struct mlxsw_sp_router_ops *router_ops;
const struct mlxsw_listener *listeners;
const struct mlxsw_sp_fid_family **fid_family_arr;
size_t listeners_count;
u32 lowest_shaper_bs;
struct rhashtable ipv6_addr_ht;
......@@ -1286,6 +1287,9 @@ void mlxsw_sp_port_fids_fini(struct mlxsw_sp_port *mlxsw_sp_port);
int mlxsw_sp_fids_init(struct mlxsw_sp *mlxsw_sp);
void mlxsw_sp_fids_fini(struct mlxsw_sp *mlxsw_sp);
extern const struct mlxsw_sp_fid_family *mlxsw_sp1_fid_family_arr[];
extern const struct mlxsw_sp_fid_family *mlxsw_sp2_fid_family_arr[];
/* spectrum_mr.c */
enum mlxsw_sp_mr_route_prio {
MLXSW_SP_MR_ROUTE_PRIO_SG,
......
......@@ -22,6 +22,12 @@ struct mlxsw_sp_fid_core {
unsigned int *port_fid_mappings;
};
struct mlxsw_sp_fid_port_vid {
struct list_head list;
u16 local_port;
u16 vid;
};
struct mlxsw_sp_fid {
struct list_head list;
struct mlxsw_sp_rif *rif;
......@@ -38,6 +44,7 @@ struct mlxsw_sp_fid {
int nve_ifindex;
u8 vni_valid:1,
nve_flood_index_valid:1;
struct list_head port_vid_list; /* Ordered by local port. */
};
struct mlxsw_sp_fid_8021q {
......@@ -82,10 +89,9 @@ struct mlxsw_sp_fid_ops {
struct mlxsw_sp_port *port, u16 vid);
void (*port_vid_unmap)(struct mlxsw_sp_fid *fid,
struct mlxsw_sp_port *port, u16 vid);
int (*vni_set)(struct mlxsw_sp_fid *fid, __be32 vni);
int (*vni_set)(struct mlxsw_sp_fid *fid);
void (*vni_clear)(struct mlxsw_sp_fid *fid);
int (*nve_flood_index_set)(struct mlxsw_sp_fid *fid,
u32 nve_flood_index);
int (*nve_flood_index_set)(struct mlxsw_sp_fid *fid);
void (*nve_flood_index_clear)(struct mlxsw_sp_fid *fid);
void (*fdb_clear_offload)(const struct mlxsw_sp_fid *fid,
const struct net_device *nve_dev);
......@@ -204,14 +210,17 @@ int mlxsw_sp_fid_nve_flood_index_set(struct mlxsw_sp_fid *fid,
if (WARN_ON(fid->nve_flood_index_valid))
return -EINVAL;
err = ops->nve_flood_index_set(fid, nve_flood_index);
if (err)
return err;
fid->nve_flood_index = nve_flood_index;
fid->nve_flood_index_valid = true;
err = ops->nve_flood_index_set(fid);
if (err)
goto err_nve_flood_index_set;
return 0;
err_nve_flood_index_set:
fid->nve_flood_index_valid = false;
return err;
}
void mlxsw_sp_fid_nve_flood_index_clear(struct mlxsw_sp_fid *fid)
......@@ -251,15 +260,15 @@ int mlxsw_sp_fid_vni_set(struct mlxsw_sp_fid *fid, enum mlxsw_sp_nve_type type,
if (err)
return err;
err = ops->vni_set(fid, vni);
fid->vni_valid = true;
err = ops->vni_set(fid);
if (err)
goto err_vni_set;
fid->vni_valid = true;
return 0;
err_vni_set:
fid->vni_valid = false;
rhashtable_remove_fast(&mlxsw_sp->fid_core->vni_ht, &fid->vni_ht_node,
mlxsw_sp_fid_vni_ht_params);
return err;
......@@ -409,37 +418,37 @@ static enum mlxsw_reg_sfmr_op mlxsw_sp_sfmr_op(bool valid)
MLXSW_REG_SFMR_OP_DESTROY_FID;
}
static int mlxsw_sp_fid_op(struct mlxsw_sp *mlxsw_sp, u16 fid_index,
u16 fid_offset, bool valid)
static int mlxsw_sp_fid_op(const struct mlxsw_sp_fid *fid, bool valid)
{
struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp;
char sfmr_pl[MLXSW_REG_SFMR_LEN];
mlxsw_reg_sfmr_pack(sfmr_pl, mlxsw_sp_sfmr_op(valid), fid_index,
fid_offset);
mlxsw_reg_sfmr_pack(sfmr_pl, mlxsw_sp_sfmr_op(valid), fid->fid_index,
fid->fid_offset);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfmr), sfmr_pl);
}
static int mlxsw_sp_fid_vni_op(struct mlxsw_sp *mlxsw_sp, u16 fid_index,
u16 fid_offset, __be32 vni, bool vni_valid,
u32 nve_flood_index, bool nve_flood_index_valid)
static int mlxsw_sp_fid_edit_op(const struct mlxsw_sp_fid *fid)
{
struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp;
char sfmr_pl[MLXSW_REG_SFMR_LEN];
mlxsw_reg_sfmr_pack(sfmr_pl, MLXSW_REG_SFMR_OP_CREATE_FID, fid_index,
fid_offset);
mlxsw_reg_sfmr_vv_set(sfmr_pl, vni_valid);
mlxsw_reg_sfmr_vni_set(sfmr_pl, be32_to_cpu(vni));
mlxsw_reg_sfmr_vtfp_set(sfmr_pl, nve_flood_index_valid);
mlxsw_reg_sfmr_nve_tunnel_flood_ptr_set(sfmr_pl, nve_flood_index);
mlxsw_reg_sfmr_pack(sfmr_pl, MLXSW_REG_SFMR_OP_CREATE_FID,
fid->fid_index, fid->fid_offset);
mlxsw_reg_sfmr_vv_set(sfmr_pl, fid->vni_valid);
mlxsw_reg_sfmr_vni_set(sfmr_pl, be32_to_cpu(fid->vni));
mlxsw_reg_sfmr_vtfp_set(sfmr_pl, fid->nve_flood_index_valid);
mlxsw_reg_sfmr_nve_tunnel_flood_ptr_set(sfmr_pl, fid->nve_flood_index);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfmr), sfmr_pl);
}
static int __mlxsw_sp_fid_port_vid_map(struct mlxsw_sp *mlxsw_sp, u16 fid_index,
static int __mlxsw_sp_fid_port_vid_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 svfa_pl[MLXSW_REG_SVFA_LEN];
mlxsw_reg_svfa_port_vid_pack(svfa_pl, local_port, valid, fid_index,
mlxsw_reg_svfa_port_vid_pack(svfa_pl, local_port, valid, fid->fid_index,
vid);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(svfa), svfa_pl);
}
......@@ -460,18 +469,14 @@ static void mlxsw_sp_fid_8021d_setup(struct mlxsw_sp_fid *fid, const void *arg)
static int mlxsw_sp_fid_8021d_configure(struct mlxsw_sp_fid *fid)
{
struct mlxsw_sp_fid_family *fid_family = fid->fid_family;
return mlxsw_sp_fid_op(fid_family->mlxsw_sp, fid->fid_index,
fid->fid_offset, true);
return mlxsw_sp_fid_op(fid, true);
}
static void mlxsw_sp_fid_8021d_deconfigure(struct mlxsw_sp_fid *fid)
{
if (fid->vni_valid)
mlxsw_sp_nve_fid_disable(fid->fid_family->mlxsw_sp, fid);
mlxsw_sp_fid_op(fid->fid_family->mlxsw_sp, fid->fid_index,
fid->fid_offset, false);
mlxsw_sp_fid_op(fid, false);
}
static int mlxsw_sp_fid_8021d_index_alloc(struct mlxsw_sp_fid *fid,
......@@ -504,7 +509,6 @@ static u16 mlxsw_sp_fid_8021d_flood_index(const struct mlxsw_sp_fid *fid)
static int mlxsw_sp_port_vp_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port)
{
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
int err;
......@@ -516,7 +520,7 @@ static int mlxsw_sp_port_vp_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port)
if (!fid)
continue;
err = __mlxsw_sp_fid_port_vid_map(mlxsw_sp, fid->fid_index,
err = __mlxsw_sp_fid_port_vid_map(fid,
mlxsw_sp_port->local_port,
vid, true);
if (err)
......@@ -539,8 +543,7 @@ static int mlxsw_sp_port_vp_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port)
if (!fid)
continue;
__mlxsw_sp_fid_port_vid_map(mlxsw_sp, fid->fid_index,
mlxsw_sp_port->local_port, vid,
__mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid,
false);
}
return err;
......@@ -548,7 +551,6 @@ static int mlxsw_sp_port_vp_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port)
static void mlxsw_sp_port_vlan_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port)
{
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
mlxsw_sp_port_vp_mode_set(mlxsw_sp_port, false);
......@@ -561,12 +563,49 @@ static void mlxsw_sp_port_vlan_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port)
if (!fid)
continue;
__mlxsw_sp_fid_port_vid_map(mlxsw_sp, fid->fid_index,
mlxsw_sp_port->local_port, vid,
__mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid,
false);
}
}
static int
mlxsw_sp_fid_port_vid_list_add(struct mlxsw_sp_fid *fid, u16 local_port,
u16 vid)
{
struct mlxsw_sp_fid_port_vid *port_vid, *tmp_port_vid;
port_vid = kzalloc(sizeof(*port_vid), GFP_KERNEL);
if (!port_vid)
return -ENOMEM;
port_vid->local_port = local_port;
port_vid->vid = vid;
list_for_each_entry(tmp_port_vid, &fid->port_vid_list, list) {
if (tmp_port_vid->local_port > local_port)
break;
}
list_add_tail(&port_vid->list, &tmp_port_vid->list);
return 0;
}
static void
mlxsw_sp_fid_port_vid_list_del(struct mlxsw_sp_fid *fid, u16 local_port,
u16 vid)
{
struct mlxsw_sp_fid_port_vid *port_vid, *tmp;
list_for_each_entry_safe(port_vid, tmp, &fid->port_vid_list, list) {
if (port_vid->local_port != local_port || port_vid->vid != vid)
continue;
list_del(&port_vid->list);
kfree(port_vid);
return;
}
}
static int mlxsw_sp_fid_8021d_port_vid_map(struct mlxsw_sp_fid *fid,
struct mlxsw_sp_port *mlxsw_sp_port,
u16 vid)
......@@ -575,11 +614,16 @@ static int mlxsw_sp_fid_8021d_port_vid_map(struct mlxsw_sp_fid *fid,
u16 local_port = mlxsw_sp_port->local_port;
int err;
err = __mlxsw_sp_fid_port_vid_map(mlxsw_sp, fid->fid_index,
mlxsw_sp_port->local_port, vid, true);
err = __mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid,
true);
if (err)
return err;
err = mlxsw_sp_fid_port_vid_list_add(fid, mlxsw_sp_port->local_port,
vid);
if (err)
goto err_port_vid_list_add;
if (mlxsw_sp->fid_core->port_fid_mappings[local_port]++ == 0) {
err = mlxsw_sp_port_vp_mode_trans(mlxsw_sp_port);
if (err)
......@@ -590,8 +634,9 @@ static int mlxsw_sp_fid_8021d_port_vid_map(struct mlxsw_sp_fid *fid,
err_port_vp_mode_trans:
mlxsw_sp->fid_core->port_fid_mappings[local_port]--;
__mlxsw_sp_fid_port_vid_map(mlxsw_sp, fid->fid_index,
mlxsw_sp_port->local_port, vid, false);
mlxsw_sp_fid_port_vid_list_del(fid, mlxsw_sp_port->local_port, vid);
err_port_vid_list_add:
__mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid, false);
return err;
}
......@@ -605,46 +650,28 @@ mlxsw_sp_fid_8021d_port_vid_unmap(struct mlxsw_sp_fid *fid,
if (mlxsw_sp->fid_core->port_fid_mappings[local_port] == 1)
mlxsw_sp_port_vlan_mode_trans(mlxsw_sp_port);
mlxsw_sp->fid_core->port_fid_mappings[local_port]--;
__mlxsw_sp_fid_port_vid_map(mlxsw_sp, fid->fid_index,
mlxsw_sp_port->local_port, vid, false);
mlxsw_sp_fid_port_vid_list_del(fid, mlxsw_sp_port->local_port, vid);
__mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid, false);
}
static int mlxsw_sp_fid_8021d_vni_set(struct mlxsw_sp_fid *fid, __be32 vni)
static int mlxsw_sp_fid_8021d_vni_set(struct mlxsw_sp_fid *fid)
{
struct mlxsw_sp_fid_family *fid_family = fid->fid_family;
return mlxsw_sp_fid_vni_op(fid_family->mlxsw_sp, fid->fid_index,
fid->fid_offset, vni, true,
fid->nve_flood_index,
fid->nve_flood_index_valid);
return mlxsw_sp_fid_edit_op(fid);
}
static void mlxsw_sp_fid_8021d_vni_clear(struct mlxsw_sp_fid *fid)
{
struct mlxsw_sp_fid_family *fid_family = fid->fid_family;
mlxsw_sp_fid_vni_op(fid_family->mlxsw_sp, fid->fid_index,
fid->fid_offset, 0, false, fid->nve_flood_index,
fid->nve_flood_index_valid);
mlxsw_sp_fid_edit_op(fid);
}
static int mlxsw_sp_fid_8021d_nve_flood_index_set(struct mlxsw_sp_fid *fid,
u32 nve_flood_index)
static int mlxsw_sp_fid_8021d_nve_flood_index_set(struct mlxsw_sp_fid *fid)
{
struct mlxsw_sp_fid_family *fid_family = fid->fid_family;
return mlxsw_sp_fid_vni_op(fid_family->mlxsw_sp, fid->fid_index,
fid->fid_offset, fid->vni, fid->vni_valid,
nve_flood_index, true);
return mlxsw_sp_fid_edit_op(fid);
}
static void mlxsw_sp_fid_8021d_nve_flood_index_clear(struct mlxsw_sp_fid *fid)
{
struct mlxsw_sp_fid_family *fid_family = fid->fid_family;
mlxsw_sp_fid_vni_op(fid_family->mlxsw_sp, fid->fid_index,
fid->fid_offset, fid->vni, fid->vni_valid, 0,
false);
mlxsw_sp_fid_edit_op(fid);
}
static void
......@@ -747,7 +774,7 @@ static const struct mlxsw_sp_fid_family mlxsw_sp_fid_8021q_emu_family = {
.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,
.rif_type = MLXSW_SP_RIF_TYPE_VLAN_EMU,
.ops = &mlxsw_sp_fid_8021q_emu_ops,
};
......@@ -792,6 +819,11 @@ static int mlxsw_sp_fid_rfid_port_vid_map(struct mlxsw_sp_fid *fid,
u16 local_port = mlxsw_sp_port->local_port;
int err;
err = mlxsw_sp_fid_port_vid_list_add(fid, mlxsw_sp_port->local_port,
vid);
if (err)
return err;
/* We only need to transition the port to virtual mode since
* {Port, VID} => FID is done by the firmware upon RIF creation.
*/
......@@ -805,6 +837,7 @@ static int mlxsw_sp_fid_rfid_port_vid_map(struct mlxsw_sp_fid *fid,
err_port_vp_mode_trans:
mlxsw_sp->fid_core->port_fid_mappings[local_port]--;
mlxsw_sp_fid_port_vid_list_del(fid, mlxsw_sp_port->local_port, vid);
return err;
}
......@@ -818,9 +851,10 @@ mlxsw_sp_fid_rfid_port_vid_unmap(struct mlxsw_sp_fid *fid,
if (mlxsw_sp->fid_core->port_fid_mappings[local_port] == 1)
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);
}
static int mlxsw_sp_fid_rfid_vni_set(struct mlxsw_sp_fid *fid, __be32 vni)
static int mlxsw_sp_fid_rfid_vni_set(struct mlxsw_sp_fid *fid)
{
return -EOPNOTSUPP;
}
......@@ -830,8 +864,7 @@ static void mlxsw_sp_fid_rfid_vni_clear(struct mlxsw_sp_fid *fid)
WARN_ON_ONCE(1);
}
static int mlxsw_sp_fid_rfid_nve_flood_index_set(struct mlxsw_sp_fid *fid,
u32 nve_flood_index)
static int mlxsw_sp_fid_rfid_nve_flood_index_set(struct mlxsw_sp_fid *fid)
{
return -EOPNOTSUPP;
}
......@@ -874,15 +907,12 @@ static void mlxsw_sp_fid_dummy_setup(struct mlxsw_sp_fid *fid, const void *arg)
static int mlxsw_sp_fid_dummy_configure(struct mlxsw_sp_fid *fid)
{
struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp;
return mlxsw_sp_fid_op(mlxsw_sp, fid->fid_index, fid->fid_offset, true);
return mlxsw_sp_fid_op(fid, true);
}
static void mlxsw_sp_fid_dummy_deconfigure(struct mlxsw_sp_fid *fid)
{
mlxsw_sp_fid_op(fid->fid_family->mlxsw_sp, fid->fid_index,
fid->fid_offset, false);
mlxsw_sp_fid_op(fid, false);
}
static int mlxsw_sp_fid_dummy_index_alloc(struct mlxsw_sp_fid *fid,
......@@ -899,7 +929,7 @@ static bool mlxsw_sp_fid_dummy_compare(const struct mlxsw_sp_fid *fid,
return true;
}
static int mlxsw_sp_fid_dummy_vni_set(struct mlxsw_sp_fid *fid, __be32 vni)
static int mlxsw_sp_fid_dummy_vni_set(struct mlxsw_sp_fid *fid)
{
return -EOPNOTSUPP;
}
......@@ -909,8 +939,7 @@ static void mlxsw_sp_fid_dummy_vni_clear(struct mlxsw_sp_fid *fid)
WARN_ON_ONCE(1);
}
static int mlxsw_sp_fid_dummy_nve_flood_index_set(struct mlxsw_sp_fid *fid,
u32 nve_flood_index)
static int mlxsw_sp_fid_dummy_nve_flood_index_set(struct mlxsw_sp_fid *fid)
{
return -EOPNOTSUPP;
}
......@@ -940,7 +969,14 @@ static const struct mlxsw_sp_fid_family mlxsw_sp_fid_dummy_family = {
.ops = &mlxsw_sp_fid_dummy_ops,
};
static const struct mlxsw_sp_fid_family *mlxsw_sp_fid_family_arr[] = {
const struct mlxsw_sp_fid_family *mlxsw_sp1_fid_family_arr[] = {
[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_RFID] = &mlxsw_sp_fid_rfid_family,
[MLXSW_SP_FID_TYPE_DUMMY] = &mlxsw_sp_fid_dummy_family,
};
const struct mlxsw_sp_fid_family *mlxsw_sp2_fid_family_arr[] = {
[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_RFID] = &mlxsw_sp_fid_rfid_family,
......@@ -982,6 +1018,8 @@ static struct mlxsw_sp_fid *mlxsw_sp_fid_get(struct mlxsw_sp *mlxsw_sp,
fid = kzalloc(fid_family->fid_size, GFP_KERNEL);
if (!fid)
return ERR_PTR(-ENOMEM);
INIT_LIST_HEAD(&fid->port_vid_list);
fid->fid_family = fid_family;
err = fid->fid_family->ops->index_alloc(fid, arg, &fid_index);
......@@ -1029,6 +1067,7 @@ void mlxsw_sp_fid_put(struct mlxsw_sp_fid *fid)
fid->fid_family->ops->deconfigure(fid);
__clear_bit(fid->fid_index - fid_family->start_index,
fid_family->fids_bitmap);
WARN_ON_ONCE(!list_empty(&fid->port_vid_list));
kfree(fid);
}
......@@ -1206,7 +1245,7 @@ int mlxsw_sp_fids_init(struct mlxsw_sp *mlxsw_sp)
for (i = 0; i < MLXSW_SP_FID_TYPE_MAX; i++) {
err = mlxsw_sp_fid_family_register(mlxsw_sp,
mlxsw_sp_fid_family_arr[i]);
mlxsw_sp->fid_family_arr[i]);
if (err)
goto err_fid_ops_register;
......
......@@ -7718,7 +7718,7 @@ u16 mlxsw_sp_rif_vid(struct mlxsw_sp *mlxsw_sp, const struct net_device *dev)
/* We only return the VID for VLAN RIFs. Otherwise we return an
* invalid value (0).
*/
if (rif->ops->type != MLXSW_SP_RIF_TYPE_VLAN)
if (rif->ops->type != MLXSW_SP_RIF_TYPE_VLAN_EMU)
goto out;
vid = mlxsw_sp_fid_8021q_vid(rif->fid);
......@@ -9377,10 +9377,9 @@ static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_subport_ops = {
.fid_get = mlxsw_sp_rif_subport_fid_get,
};
static int mlxsw_sp_rif_vlan_fid_op(struct mlxsw_sp_rif *rif,
enum mlxsw_reg_ritr_if_type type,
u16 vid_fid, bool enable)
static int mlxsw_sp_rif_fid_op(struct mlxsw_sp_rif *rif, u16 fid, bool enable)
{
enum mlxsw_reg_ritr_if_type type = MLXSW_REG_RITR_FID_IF;
struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp;
char ritr_pl[MLXSW_REG_RITR_LEN];
......@@ -9388,7 +9387,7 @@ static int mlxsw_sp_rif_vlan_fid_op(struct mlxsw_sp_rif *rif,
rif->dev->mtu);
mlxsw_reg_ritr_mac_pack(ritr_pl, rif->dev->dev_addr);
mlxsw_reg_ritr_if_mac_profile_id_set(ritr_pl, rif->mac_profile_id);
mlxsw_reg_ritr_fid_set(ritr_pl, type, vid_fid);
mlxsw_reg_ritr_fid_if_fid_set(ritr_pl, fid);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
}
......@@ -9412,10 +9411,9 @@ static int mlxsw_sp_rif_fid_configure(struct mlxsw_sp_rif *rif,
return err;
rif->mac_profile_id = mac_profile;
err = mlxsw_sp_rif_vlan_fid_op(rif, MLXSW_REG_RITR_FID_IF, fid_index,
true);
err = mlxsw_sp_rif_fid_op(rif, fid_index, true);
if (err)
goto err_rif_vlan_fid_op;
goto err_rif_fid_op;
err = mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC,
mlxsw_sp_router_port(mlxsw_sp), true);
......@@ -9442,8 +9440,8 @@ static int mlxsw_sp_rif_fid_configure(struct mlxsw_sp_rif *rif,
mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC,
mlxsw_sp_router_port(mlxsw_sp), false);
err_fid_mc_flood_set:
mlxsw_sp_rif_vlan_fid_op(rif, MLXSW_REG_RITR_FID_IF, fid_index, false);
err_rif_vlan_fid_op:
mlxsw_sp_rif_fid_op(rif, fid_index, false);
err_rif_fid_op:
mlxsw_sp_rif_mac_profile_put(mlxsw_sp, mac_profile);
return err;
}
......@@ -9462,7 +9460,7 @@ static void mlxsw_sp_rif_fid_deconfigure(struct mlxsw_sp_rif *rif)
mlxsw_sp_router_port(mlxsw_sp), false);
mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC,
mlxsw_sp_router_port(mlxsw_sp), false);
mlxsw_sp_rif_vlan_fid_op(rif, MLXSW_REG_RITR_FID_IF, fid_index, false);
mlxsw_sp_rif_fid_op(rif, fid_index, false);
mlxsw_sp_rif_mac_profile_put(rif->mlxsw_sp, rif->mac_profile_id);
}
......@@ -9540,7 +9538,7 @@ static void mlxsw_sp_rif_vlan_fdb_del(struct mlxsw_sp_rif *rif, const char *mac)
}
static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_vlan_emu_ops = {
.type = MLXSW_SP_RIF_TYPE_VLAN,
.type = MLXSW_SP_RIF_TYPE_VLAN_EMU,
.rif_size = sizeof(struct mlxsw_sp_rif),
.configure = mlxsw_sp_rif_fid_configure,
.deconfigure = mlxsw_sp_rif_fid_deconfigure,
......@@ -9618,7 +9616,7 @@ static const struct mlxsw_sp_rif_ops mlxsw_sp1_rif_ipip_lb_ops = {
static const struct mlxsw_sp_rif_ops *mlxsw_sp1_rif_ops_arr[] = {
[MLXSW_SP_RIF_TYPE_SUBPORT] = &mlxsw_sp_rif_subport_ops,
[MLXSW_SP_RIF_TYPE_VLAN] = &mlxsw_sp_rif_vlan_emu_ops,
[MLXSW_SP_RIF_TYPE_VLAN_EMU] = &mlxsw_sp_rif_vlan_emu_ops,
[MLXSW_SP_RIF_TYPE_FID] = &mlxsw_sp_rif_fid_ops,
[MLXSW_SP_RIF_TYPE_IPIP_LB] = &mlxsw_sp1_rif_ipip_lb_ops,
};
......@@ -9806,7 +9804,7 @@ static const struct mlxsw_sp_rif_ops mlxsw_sp2_rif_ipip_lb_ops = {
static const struct mlxsw_sp_rif_ops *mlxsw_sp2_rif_ops_arr[] = {
[MLXSW_SP_RIF_TYPE_SUBPORT] = &mlxsw_sp_rif_subport_ops,
[MLXSW_SP_RIF_TYPE_VLAN] = &mlxsw_sp_rif_vlan_emu_ops,
[MLXSW_SP_RIF_TYPE_VLAN_EMU] = &mlxsw_sp_rif_vlan_emu_ops,
[MLXSW_SP_RIF_TYPE_FID] = &mlxsw_sp_rif_fid_ops,
[MLXSW_SP_RIF_TYPE_IPIP_LB] = &mlxsw_sp2_rif_ipip_lb_ops,
};
......
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