From 53d7ae53d8071fa1270c208a730d6cf205a50533 Mon Sep 17 00:00:00 2001 From: Amit Cohen Date: Mon, 4 Jul 2022 09:11:27 +0300 Subject: [PATCH 01/13] mlxsw: Configure egress VID for unicast FDB entries Using unified bridge model, firmware no longer configures the egress VID "under the hood" and moves this responsibility to software. For layer 2, this means that software needs to determine the egress VID for both unicast (i.e., FDB) and multicast (i.e., MDB and flooding) flows. Unicast FDB records and unicast LAG FDB records have new fields - "set_vid" and "vid", set them. For records which point to router port, do not set these fields. Signed-off-by: Amit Cohen Reviewed-by: Petr Machata Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/reg.h | 5 +++- .../mellanox/mlxsw/spectrum_switchdev.c | 24 ++++++++++--------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index 022b2168f3a5d5..b0b5806a22ed62 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -380,7 +380,7 @@ static inline void mlxsw_reg_sfd_rec_pack(char *payload, int rec_index, static inline void mlxsw_reg_sfd_uc_pack(char *payload, int rec_index, enum mlxsw_reg_sfd_rec_policy policy, - const char *mac, u16 fid_vid, + const char *mac, u16 fid_vid, u16 vid, enum mlxsw_reg_sfd_rec_action action, u16 local_port) { @@ -389,6 +389,8 @@ static inline void mlxsw_reg_sfd_uc_pack(char *payload, int rec_index, mlxsw_reg_sfd_rec_policy_set(payload, rec_index, policy); mlxsw_reg_sfd_uc_sub_port_set(payload, rec_index, 0); mlxsw_reg_sfd_uc_fid_vid_set(payload, rec_index, fid_vid); + mlxsw_reg_sfd_uc_set_vid_set(payload, rec_index, vid ? true : false); + mlxsw_reg_sfd_uc_vid_set(payload, rec_index, vid); mlxsw_reg_sfd_uc_system_port_set(payload, rec_index, local_port); } @@ -454,6 +456,7 @@ mlxsw_reg_sfd_uc_lag_pack(char *payload, int rec_index, mlxsw_reg_sfd_rec_policy_set(payload, rec_index, policy); mlxsw_reg_sfd_uc_lag_sub_port_set(payload, rec_index, 0); mlxsw_reg_sfd_uc_lag_fid_vid_set(payload, rec_index, fid_vid); + mlxsw_reg_sfd_uc_lag_set_vid_set(payload, rec_index, true); mlxsw_reg_sfd_uc_lag_lag_vid_set(payload, rec_index, lag_vid); mlxsw_reg_sfd_uc_lag_lag_id_set(payload, rec_index, lag_id); } diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c index 7cabe6e8edebeb..fd8f9be2d40141 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c @@ -1681,7 +1681,8 @@ static int mlxsw_sp_port_fdb_tunnel_uc_op(struct mlxsw_sp *mlxsw_sp, } static int __mlxsw_sp_port_fdb_uc_op(struct mlxsw_sp *mlxsw_sp, u16 local_port, - const char *mac, u16 fid, bool adding, + const char *mac, u16 fid, u16 vid, + bool adding, enum mlxsw_reg_sfd_rec_action action, enum mlxsw_reg_sfd_rec_policy policy) { @@ -1694,7 +1695,8 @@ static int __mlxsw_sp_port_fdb_uc_op(struct mlxsw_sp *mlxsw_sp, u16 local_port, return -ENOMEM; mlxsw_reg_sfd_pack(sfd_pl, mlxsw_sp_sfd_op(adding), 0); - mlxsw_reg_sfd_uc_pack(sfd_pl, 0, policy, mac, fid, action, local_port); + mlxsw_reg_sfd_uc_pack(sfd_pl, 0, policy, mac, fid, vid, action, + local_port); num_rec = mlxsw_reg_sfd_num_rec_get(sfd_pl); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfd), sfd_pl); if (err) @@ -1709,18 +1711,18 @@ static int __mlxsw_sp_port_fdb_uc_op(struct mlxsw_sp *mlxsw_sp, u16 local_port, } static int mlxsw_sp_port_fdb_uc_op(struct mlxsw_sp *mlxsw_sp, u16 local_port, - const char *mac, u16 fid, bool adding, - bool dynamic) + const char *mac, u16 fid, u16 vid, + bool adding, bool dynamic) { - return __mlxsw_sp_port_fdb_uc_op(mlxsw_sp, local_port, mac, fid, adding, - MLXSW_REG_SFD_REC_ACTION_NOP, + return __mlxsw_sp_port_fdb_uc_op(mlxsw_sp, local_port, mac, fid, vid, + adding, MLXSW_REG_SFD_REC_ACTION_NOP, mlxsw_sp_sfd_rec_policy(dynamic)); } int mlxsw_sp_rif_fdb_op(struct mlxsw_sp *mlxsw_sp, const char *mac, u16 fid, bool adding) { - return __mlxsw_sp_port_fdb_uc_op(mlxsw_sp, 0, mac, fid, adding, + return __mlxsw_sp_port_fdb_uc_op(mlxsw_sp, 0, mac, fid, 0, adding, MLXSW_REG_SFD_REC_ACTION_FORWARD_IP_ROUTER, MLXSW_REG_SFD_REC_POLICY_STATIC_ENTRY); } @@ -1782,7 +1784,7 @@ mlxsw_sp_port_fdb_set(struct mlxsw_sp_port *mlxsw_sp_port, if (!bridge_port->lagged) return mlxsw_sp_port_fdb_uc_op(mlxsw_sp, bridge_port->system_port, - fdb_info->addr, fid_index, + fdb_info->addr, fid_index, vid, adding, false); else return mlxsw_sp_port_fdb_uc_lag_op(mlxsw_sp, @@ -2906,10 +2908,9 @@ static void mlxsw_sp_fdb_notify_mac_process(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_bridge_device *bridge_device; struct mlxsw_sp_bridge_port *bridge_port; struct mlxsw_sp_port *mlxsw_sp_port; + u16 local_port, vid, fid, evid = 0; enum switchdev_notifier_type type; char mac[ETH_ALEN]; - u16 local_port; - u16 vid, fid; bool do_notification = true; int err; @@ -2940,9 +2941,10 @@ static void mlxsw_sp_fdb_notify_mac_process(struct mlxsw_sp *mlxsw_sp, bridge_device = bridge_port->bridge_device; vid = bridge_device->vlan_enabled ? mlxsw_sp_port_vlan->vid : 0; + evid = mlxsw_sp_port_vlan->vid; do_fdb_op: - err = mlxsw_sp_port_fdb_uc_op(mlxsw_sp, local_port, mac, fid, + err = mlxsw_sp_port_fdb_uc_op(mlxsw_sp, local_port, mac, fid, evid, adding, true); if (err) { dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Failed to set FDB entry\n"); From 8cfc7f7707c1812d879e942ddc45b25bf088c0b4 Mon Sep 17 00:00:00 2001 From: Amit Cohen Date: Mon, 4 Jul 2022 09:11:28 +0300 Subject: [PATCH 02/13] mlxsw: spectrum_fid: Configure VNI to FID classification In the new model, SFMR no longer configures both VNI->FID and FID->VNI classifications, but only the later. The former needs to be configured via SVFA. Add SVFA configuration as part of vni_set() and vni_clear(). Signed-off-by: Amit Cohen Reviewed-by: Petr Machata Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- .../ethernet/mellanox/mlxsw/spectrum_fid.c | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c index 160c5af5235d58..ffe8c583865d48 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c @@ -487,6 +487,40 @@ static int mlxsw_sp_fid_edit_op(const struct mlxsw_sp_fid *fid) return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfmr), sfmr_pl); } +static int mlxsw_sp_fid_vni_to_fid_map(const struct mlxsw_sp_fid *fid, + bool valid) +{ + struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; + char svfa_pl[MLXSW_REG_SVFA_LEN]; + + mlxsw_reg_svfa_vni_pack(svfa_pl, valid, fid->fid_index, + be32_to_cpu(fid->vni)); + return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(svfa), svfa_pl); +} + +static int mlxsw_sp_fid_vni_op(const struct mlxsw_sp_fid *fid) +{ + struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; + int err; + + if (mlxsw_sp->ubridge) { + err = mlxsw_sp_fid_vni_to_fid_map(fid, fid->vni_valid); + if (err) + return err; + } + + err = mlxsw_sp_fid_edit_op(fid); + if (err) + goto err_fid_edit_op; + + return 0; + +err_fid_edit_op: + if (mlxsw_sp->ubridge) + mlxsw_sp_fid_vni_to_fid_map(fid, !fid->vni_valid); + return err; +} + static int __mlxsw_sp_fid_port_vid_map(const struct mlxsw_sp_fid *fid, u16 local_port, u16 vid, bool valid) { @@ -724,12 +758,12 @@ mlxsw_sp_fid_8021d_port_vid_unmap(struct mlxsw_sp_fid *fid, static int mlxsw_sp_fid_8021d_vni_set(struct mlxsw_sp_fid *fid) { - return mlxsw_sp_fid_edit_op(fid); + return mlxsw_sp_fid_vni_op(fid); } static void mlxsw_sp_fid_8021d_vni_clear(struct mlxsw_sp_fid *fid) { - mlxsw_sp_fid_edit_op(fid); + mlxsw_sp_fid_vni_op(fid); } static int mlxsw_sp_fid_8021d_nve_flood_index_set(struct mlxsw_sp_fid *fid) From fea20547d5b50017e1a0525e6788bd3db22f5ca3 Mon Sep 17 00:00:00 2001 From: Amit Cohen Date: Mon, 4 Jul 2022 09:11:29 +0300 Subject: [PATCH 03/13] mlxsw: Configure ingress RIF classification Before layer 2 forwarding, the device classifies an incoming packet to a FID. The classification is done based on one of the following keys: 1. FID 2. VNI (after decapsulation) 3. VID / {Port, VID} After classification, the FID is known, but also all the attributes of the FID, such as the router interface (RIF) via which a packet that needs to be routed will ingress the router block. In the legacy model, when a RIF was created / destroyed, it was firmware's responsibility to update it in the previously mentioned FID classification records. In the unified bridge model, this responsibility moved to software. The third classification requires to iterate over the FID's {Port, VID} list and issue SVFA write with the correct mapping table according to the port's mode (virtual or not). We never map multiple VLANs to the same FID using VID->FID mapping, so such a mapping needs to be performed once. When a new FID classification entry is configured and the FID already has a RIF, set the RIF as part of SVFA configuration. The reverse needs to be done when clearing a RIF from a FID. Currently, clearing is done by issuing mlxsw_sp_fid_rif_set() with a NULL RIF pointer. Instead, introduce mlxsw_sp_fid_rif_unset(). Note that mlxsw_sp_fid_rif_set() is called after the RIF is fully operational, so it conforms to the internal requirement regarding SVFA.irif_v: "Must not be set for a non-enabled RIF". Do not set the ingress RIF for rFIDs, as the {Port, VID}->rFID entry is configured by firmware when legacy model is used, a next patch will handle this configuration for rFIDs and unified bridge model. Signed-off-by: Amit Cohen Reviewed-by: Petr Machata Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/reg.h | 17 +- .../net/ethernet/mellanox/mlxsw/spectrum.h | 4 +- .../ethernet/mellanox/mlxsw/spectrum_fid.c | 173 ++++++++++++++++-- .../ethernet/mellanox/mlxsw/spectrum_router.c | 20 +- .../ethernet/mellanox/mlxsw/spectrum_router.h | 1 - 5 files changed, 189 insertions(+), 26 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index b0b5806a22ed62..46ed2c1810becd 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -1658,40 +1658,43 @@ MLXSW_ITEM32(reg, svfa, irif, 0x14, 0, 16); static inline void __mlxsw_reg_svfa_pack(char *payload, enum mlxsw_reg_svfa_mt mt, bool valid, - u16 fid) + u16 fid, bool irif_v, u16 irif) { MLXSW_REG_ZERO(svfa, payload); mlxsw_reg_svfa_swid_set(payload, 0); mlxsw_reg_svfa_mapping_table_set(payload, mt); mlxsw_reg_svfa_v_set(payload, valid); mlxsw_reg_svfa_fid_set(payload, fid); + mlxsw_reg_svfa_irif_v_set(payload, irif_v); + mlxsw_reg_svfa_irif_set(payload, irif_v ? irif : 0); } static inline void mlxsw_reg_svfa_port_vid_pack(char *payload, u16 local_port, - bool valid, u16 fid, u16 vid) + bool valid, u16 fid, u16 vid, + bool irif_v, u16 irif) { enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_PORT_VID_TO_FID; - __mlxsw_reg_svfa_pack(payload, mt, valid, fid); + __mlxsw_reg_svfa_pack(payload, mt, valid, fid, irif_v, irif); mlxsw_reg_svfa_local_port_set(payload, local_port); mlxsw_reg_svfa_vid_set(payload, vid); } static inline void mlxsw_reg_svfa_vid_pack(char *payload, bool valid, u16 fid, - u16 vid) + u16 vid, bool irif_v, u16 irif) { enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_VID_TO_FID; - __mlxsw_reg_svfa_pack(payload, mt, valid, fid); + __mlxsw_reg_svfa_pack(payload, mt, valid, fid, irif_v, irif); mlxsw_reg_svfa_vid_set(payload, vid); } static inline void mlxsw_reg_svfa_vni_pack(char *payload, bool valid, u16 fid, - u32 vni) + u32 vni, bool irif_v, u16 irif) { enum mlxsw_reg_svfa_mt mt = MLXSW_REG_SVFA_MT_VNI_TO_FID; - __mlxsw_reg_svfa_pack(payload, mt, valid, fid); + __mlxsw_reg_svfa_pack(payload, mt, valid, fid, irif_v, irif); mlxsw_reg_svfa_vni_set(payload, vni); } diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h index 8de3bdcdf14343..b1810a22a1a61e 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h @@ -737,6 +737,7 @@ union mlxsw_sp_l3addr { struct in6_addr addr6; }; +u16 mlxsw_sp_rif_index(const struct mlxsw_sp_rif *rif); int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp, struct netlink_ext_ack *extack); void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp); @@ -1285,7 +1286,8 @@ void mlxsw_sp_fid_port_vid_unmap(struct mlxsw_sp_fid *fid, struct mlxsw_sp_port *mlxsw_sp_port, u16 vid); u16 mlxsw_sp_fid_index(const struct mlxsw_sp_fid *fid); enum mlxsw_sp_fid_type mlxsw_sp_fid_type(const struct mlxsw_sp_fid *fid); -void mlxsw_sp_fid_rif_set(struct mlxsw_sp_fid *fid, struct mlxsw_sp_rif *rif); +int mlxsw_sp_fid_rif_set(struct mlxsw_sp_fid *fid, struct mlxsw_sp_rif *rif); +void mlxsw_sp_fid_rif_unset(struct mlxsw_sp_fid *fid); struct mlxsw_sp_rif *mlxsw_sp_fid_rif(const struct mlxsw_sp_fid *fid); enum mlxsw_sp_rif_type mlxsw_sp_fid_type_rif_type(const struct mlxsw_sp *mlxsw_sp, diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c index ffe8c583865d48..a8fecf47eaf534 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c @@ -404,11 +404,6 @@ enum mlxsw_sp_fid_type mlxsw_sp_fid_type(const struct mlxsw_sp_fid *fid) return fid->fid_family->type; } -void mlxsw_sp_fid_rif_set(struct mlxsw_sp_fid *fid, struct mlxsw_sp_rif *rif) -{ - fid->rif = rif; -} - struct mlxsw_sp_rif *mlxsw_sp_fid_rif(const struct mlxsw_sp_fid *fid) { return fid->rif; @@ -465,7 +460,8 @@ static int mlxsw_sp_fid_op(const struct mlxsw_sp_fid *fid, bool valid) return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfmr), sfmr_pl); } -static int mlxsw_sp_fid_edit_op(const struct mlxsw_sp_fid *fid) +static int mlxsw_sp_fid_edit_op(const struct mlxsw_sp_fid *fid, + const struct mlxsw_sp_rif *rif) { struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; enum mlxsw_reg_bridge_type bridge_type = 0; @@ -484,32 +480,176 @@ static int mlxsw_sp_fid_edit_op(const struct mlxsw_sp_fid *fid) 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); + + if (mlxsw_sp->ubridge && rif) { + mlxsw_reg_sfmr_irif_v_set(sfmr_pl, true); + mlxsw_reg_sfmr_irif_set(sfmr_pl, mlxsw_sp_rif_index(rif)); + } + return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfmr), sfmr_pl); } static int mlxsw_sp_fid_vni_to_fid_map(const struct mlxsw_sp_fid *fid, + const struct mlxsw_sp_rif *rif, bool valid) { struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; char svfa_pl[MLXSW_REG_SVFA_LEN]; + bool irif_valid; + u16 irif_index; + + irif_valid = !!rif; + irif_index = rif ? mlxsw_sp_rif_index(rif) : 0; mlxsw_reg_svfa_vni_pack(svfa_pl, valid, fid->fid_index, - be32_to_cpu(fid->vni)); + be32_to_cpu(fid->vni), irif_valid, irif_index); + return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(svfa), svfa_pl); +} + +static int mlxsw_sp_fid_to_fid_rif_update(const struct mlxsw_sp_fid *fid, + const struct mlxsw_sp_rif *rif) +{ + return mlxsw_sp_fid_edit_op(fid, rif); +} + +static int mlxsw_sp_fid_vni_to_fid_rif_update(const struct mlxsw_sp_fid *fid, + const struct mlxsw_sp_rif *rif) +{ + if (!fid->vni_valid) + return 0; + + return mlxsw_sp_fid_vni_to_fid_map(fid, rif, fid->vni_valid); +} + +static int +mlxsw_sp_fid_port_vid_to_fid_rif_update_one(const struct mlxsw_sp_fid *fid, + struct mlxsw_sp_fid_port_vid *pv, + bool irif_valid, u16 irif_index) +{ + 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, pv->local_port, true, + fid->fid_index, pv->vid, irif_valid, + irif_index); + return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(svfa), svfa_pl); } +static int mlxsw_sp_fid_vid_to_fid_rif_set(const struct mlxsw_sp_fid *fid, + const struct mlxsw_sp_rif *rif) +{ + struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; + struct mlxsw_sp_fid_port_vid *pv; + u16 irif_index; + int err; + + irif_index = mlxsw_sp_rif_index(rif); + + list_for_each_entry(pv, &fid->port_vid_list, list) { + /* If port is not in virtual mode, then it does not have any + * {Port, VID}->FID mappings that need to be updated with the + * ingress RIF. + */ + if (!mlxsw_sp->fid_core->port_fid_mappings[pv->local_port]) + continue; + + err = mlxsw_sp_fid_port_vid_to_fid_rif_update_one(fid, pv, + true, + irif_index); + if (err) + goto err_port_vid_to_fid_rif_update_one; + } + + return 0; + +err_port_vid_to_fid_rif_update_one: + list_for_each_entry_continue_reverse(pv, &fid->port_vid_list, list) { + if (!mlxsw_sp->fid_core->port_fid_mappings[pv->local_port]) + continue; + + mlxsw_sp_fid_port_vid_to_fid_rif_update_one(fid, pv, false, 0); + } + + return err; +} + +static void mlxsw_sp_fid_vid_to_fid_rif_unset(const struct mlxsw_sp_fid *fid) +{ + struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; + struct mlxsw_sp_fid_port_vid *pv; + + list_for_each_entry(pv, &fid->port_vid_list, list) { + /* If port is not in virtual mode, then it does not have any + * {Port, VID}->FID mappings that need to be updated. + */ + if (!mlxsw_sp->fid_core->port_fid_mappings[pv->local_port]) + continue; + + mlxsw_sp_fid_port_vid_to_fid_rif_update_one(fid, pv, false, 0); + } +} + +int mlxsw_sp_fid_rif_set(struct mlxsw_sp_fid *fid, struct mlxsw_sp_rif *rif) +{ + int err; + + if (!fid->fid_family->mlxsw_sp->ubridge) { + fid->rif = rif; + return 0; + } + + err = mlxsw_sp_fid_to_fid_rif_update(fid, rif); + if (err) + return err; + + err = mlxsw_sp_fid_vni_to_fid_rif_update(fid, rif); + if (err) + goto err_vni_to_fid_rif_update; + + err = mlxsw_sp_fid_vid_to_fid_rif_set(fid, rif); + if (err) + goto err_vid_to_fid_rif_set; + + fid->rif = rif; + return 0; + +err_vid_to_fid_rif_set: + mlxsw_sp_fid_vni_to_fid_rif_update(fid, NULL); +err_vni_to_fid_rif_update: + mlxsw_sp_fid_to_fid_rif_update(fid, NULL); + return err; +} + +void mlxsw_sp_fid_rif_unset(struct mlxsw_sp_fid *fid) +{ + if (!fid->fid_family->mlxsw_sp->ubridge) { + fid->rif = NULL; + return; + } + + if (!fid->rif) + return; + + fid->rif = NULL; + mlxsw_sp_fid_vid_to_fid_rif_unset(fid); + mlxsw_sp_fid_vni_to_fid_rif_update(fid, NULL); + mlxsw_sp_fid_to_fid_rif_update(fid, NULL); +} + static int mlxsw_sp_fid_vni_op(const struct mlxsw_sp_fid *fid) { struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; int err; if (mlxsw_sp->ubridge) { - err = mlxsw_sp_fid_vni_to_fid_map(fid, fid->vni_valid); + err = mlxsw_sp_fid_vni_to_fid_map(fid, fid->rif, + fid->vni_valid); if (err) return err; } - err = mlxsw_sp_fid_edit_op(fid); + err = mlxsw_sp_fid_edit_op(fid, fid->rif); if (err) goto err_fid_edit_op; @@ -517,7 +657,7 @@ static int mlxsw_sp_fid_vni_op(const struct mlxsw_sp_fid *fid) err_fid_edit_op: if (mlxsw_sp->ubridge) - mlxsw_sp_fid_vni_to_fid_map(fid, !fid->vni_valid); + mlxsw_sp_fid_vni_to_fid_map(fid, fid->rif, !fid->vni_valid); return err; } @@ -526,9 +666,16 @@ static int __mlxsw_sp_fid_port_vid_map(const struct mlxsw_sp_fid *fid, { struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; char svfa_pl[MLXSW_REG_SVFA_LEN]; + bool irif_valid = false; + u16 irif_index = 0; + + if (mlxsw_sp->ubridge && fid->rif) { + irif_valid = true; + irif_index = mlxsw_sp_rif_index(fid->rif); + } mlxsw_reg_svfa_port_vid_pack(svfa_pl, local_port, valid, fid->fid_index, - vid); + vid, irif_valid, irif_index); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(svfa), svfa_pl); } @@ -768,12 +915,12 @@ static void mlxsw_sp_fid_8021d_vni_clear(struct mlxsw_sp_fid *fid) static int mlxsw_sp_fid_8021d_nve_flood_index_set(struct mlxsw_sp_fid *fid) { - return mlxsw_sp_fid_edit_op(fid); + return mlxsw_sp_fid_edit_op(fid, fid->rif); } static void mlxsw_sp_fid_8021d_nve_flood_index_clear(struct mlxsw_sp_fid *fid) { - mlxsw_sp_fid_edit_op(fid); + mlxsw_sp_fid_edit_op(fid, fid->rif); } static void diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index 63652460c40d1c..4a34138985bf67 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -9351,9 +9351,15 @@ static int mlxsw_sp_rif_subport_configure(struct mlxsw_sp_rif *rif, if (err) goto err_rif_fdb_op; - mlxsw_sp_fid_rif_set(rif->fid, rif); + err = mlxsw_sp_fid_rif_set(rif->fid, rif); + if (err) + goto err_fid_rif_set; + return 0; +err_fid_rif_set: + mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr, + mlxsw_sp_fid_index(rif->fid), false); err_rif_fdb_op: mlxsw_sp_rif_subport_op(rif, false); err_rif_subport_op: @@ -9365,7 +9371,7 @@ static void mlxsw_sp_rif_subport_deconfigure(struct mlxsw_sp_rif *rif) { struct mlxsw_sp_fid *fid = rif->fid; - mlxsw_sp_fid_rif_set(fid, NULL); + mlxsw_sp_fid_rif_unset(fid); mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr, mlxsw_sp_fid_index(fid), false); mlxsw_sp_rif_macvlan_flush(rif); @@ -9442,9 +9448,15 @@ static int mlxsw_sp_rif_fid_configure(struct mlxsw_sp_rif *rif, if (err) goto err_rif_fdb_op; - mlxsw_sp_fid_rif_set(rif->fid, rif); + err = mlxsw_sp_fid_rif_set(rif->fid, rif); + if (err) + goto err_fid_rif_set; + return 0; +err_fid_rif_set: + mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr, + mlxsw_sp_fid_index(rif->fid), false); err_rif_fdb_op: mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC, mlxsw_sp_router_port(mlxsw_sp), false); @@ -9464,7 +9476,7 @@ static void mlxsw_sp_rif_fid_deconfigure(struct mlxsw_sp_rif *rif) struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp; struct mlxsw_sp_fid *fid = rif->fid; - mlxsw_sp_fid_rif_set(fid, NULL); + mlxsw_sp_fid_rif_unset(fid); mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr, mlxsw_sp_fid_index(fid), false); mlxsw_sp_rif_macvlan_flush(rif); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h index b5c83ec7a87f91..c5dfb972b433dd 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h @@ -82,7 +82,6 @@ struct mlxsw_sp_ipip_entry; struct mlxsw_sp_rif *mlxsw_sp_rif_by_index(const struct mlxsw_sp *mlxsw_sp, u16 rif_index); -u16 mlxsw_sp_rif_index(const struct mlxsw_sp_rif *rif); u16 mlxsw_sp_ipip_lb_rif_index(const struct mlxsw_sp_rif_ipip_lb *rif); u16 mlxsw_sp_ipip_lb_ul_vr_id(const struct mlxsw_sp_rif_ipip_lb *rif); u16 mlxsw_sp_ipip_lb_ul_rif_id(const struct mlxsw_sp_rif_ipip_lb *lb_rif); From d4b464d20bc122699a7258cb44158d83d7fdc0ec Mon Sep 17 00:00:00 2001 From: Amit Cohen Date: Mon, 4 Jul 2022 09:11:30 +0300 Subject: [PATCH 04/13] mlxsw: spectrum_fid: Configure layer 3 egress VID classification After routing, the device always consults a table that determines the packet's egress VID based on {egress RIF, egress local port}. In the unified bridge model, it is up to software to maintain this table via REIV register. The table needs to be updated in the following flows: 1. When a RIF is set on a FID, need to iterate over the FID's {Port, VID} list and issue REIV write to map the {RIF, Port} to the given VID. 2. When a {Port, VID} is mapped to a FID and the FID already has a RIF, need to issue REIV write with a single record to map the {RIF, Port} to the given VID. REIV register supports a simultaneous update of 256 ports, so use this capability for the first flow. Handle the two above mentioned flows. Add mlxsw_sp_fid_evid_map() function to handle egress VID classification for both unicast and multicast. Layer 2 multicast configuration is already done in the driver, just move it to the new function. Signed-off-by: Amit Cohen Reviewed-by: Petr Machata Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- .../ethernet/mellanox/mlxsw/spectrum_fid.c | 142 +++++++++++++++++- 1 file changed, 137 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c index a8fecf47eaf534..c6397f81c2d78f 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c @@ -590,8 +590,82 @@ static void mlxsw_sp_fid_vid_to_fid_rif_unset(const struct mlxsw_sp_fid *fid) } } +static int mlxsw_sp_fid_reiv_handle(struct mlxsw_sp_fid *fid, u16 rif_index, + bool valid, u8 port_page) +{ + u16 local_port_end = (port_page + 1) * MLXSW_REG_REIV_REC_MAX_COUNT - 1; + u16 local_port_start = port_page * MLXSW_REG_REIV_REC_MAX_COUNT; + struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; + struct mlxsw_sp_fid_port_vid *port_vid; + u8 rec_num, entries_num = 0; + char *reiv_pl; + int err; + + reiv_pl = kmalloc(MLXSW_REG_REIV_LEN, GFP_KERNEL); + if (!reiv_pl) + return -ENOMEM; + + mlxsw_reg_reiv_pack(reiv_pl, port_page, rif_index); + + list_for_each_entry(port_vid, &fid->port_vid_list, list) { + /* port_vid_list is sorted by local_port. */ + if (port_vid->local_port < local_port_start) + continue; + + if (port_vid->local_port > local_port_end) + break; + + rec_num = port_vid->local_port % MLXSW_REG_REIV_REC_MAX_COUNT; + mlxsw_reg_reiv_rec_update_set(reiv_pl, rec_num, true); + mlxsw_reg_reiv_rec_evid_set(reiv_pl, rec_num, + valid ? port_vid->vid : 0); + entries_num++; + } + + if (!entries_num) { + kfree(reiv_pl); + return 0; + } + + err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(reiv), reiv_pl); + if (err) + goto err_reg_write; + + kfree(reiv_pl); + return 0; + +err_reg_write: + kfree(reiv_pl); + return err; +} + +static int mlxsw_sp_fid_erif_eport_to_vid_map(struct mlxsw_sp_fid *fid, + u16 rif_index, bool valid) +{ + struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; + u8 num_port_pages; + int err, i; + + num_port_pages = mlxsw_core_max_ports(mlxsw_sp->core) / + MLXSW_REG_REIV_REC_MAX_COUNT + 1; + + for (i = 0; i < num_port_pages; i++) { + err = mlxsw_sp_fid_reiv_handle(fid, rif_index, valid, i); + if (err) + goto err_reiv_handle; + } + + return 0; + +err_reiv_handle: + for (; i >= 0; i--) + mlxsw_sp_fid_reiv_handle(fid, rif_index, !valid, i); + return err; +} + int mlxsw_sp_fid_rif_set(struct mlxsw_sp_fid *fid, struct mlxsw_sp_rif *rif) { + u16 rif_index = mlxsw_sp_rif_index(rif); int err; if (!fid->fid_family->mlxsw_sp->ubridge) { @@ -611,9 +685,15 @@ int mlxsw_sp_fid_rif_set(struct mlxsw_sp_fid *fid, struct mlxsw_sp_rif *rif) if (err) goto err_vid_to_fid_rif_set; + err = mlxsw_sp_fid_erif_eport_to_vid_map(fid, rif_index, true); + if (err) + goto err_erif_eport_to_vid_map; + fid->rif = rif; return 0; +err_erif_eport_to_vid_map: + mlxsw_sp_fid_vid_to_fid_rif_unset(fid); err_vid_to_fid_rif_set: mlxsw_sp_fid_vni_to_fid_rif_update(fid, NULL); err_vni_to_fid_rif_update: @@ -623,6 +703,8 @@ int mlxsw_sp_fid_rif_set(struct mlxsw_sp_fid *fid, struct mlxsw_sp_rif *rif) void mlxsw_sp_fid_rif_unset(struct mlxsw_sp_fid *fid) { + u16 rif_index; + if (!fid->fid_family->mlxsw_sp->ubridge) { fid->rif = NULL; return; @@ -631,7 +713,10 @@ void mlxsw_sp_fid_rif_unset(struct mlxsw_sp_fid *fid) if (!fid->rif) return; + rif_index = mlxsw_sp_rif_index(fid->rif); fid->rif = NULL; + + mlxsw_sp_fid_erif_eport_to_vid_map(fid, rif_index, false); mlxsw_sp_fid_vid_to_fid_rif_unset(fid); mlxsw_sp_fid_vni_to_fid_rif_update(fid, NULL); mlxsw_sp_fid_to_fid_rif_update(fid, NULL); @@ -844,6 +929,53 @@ mlxsw_sp_fid_mpe_table_map(const struct mlxsw_sp_fid *fid, u16 local_port, return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(smpe), smpe_pl); } +static int +mlxsw_sp_fid_erif_eport_to_vid_map_one(const struct mlxsw_sp_fid *fid, + u16 local_port, u16 vid, bool valid) +{ + u8 port_page = local_port / MLXSW_REG_REIV_REC_MAX_COUNT; + u8 rec_num = local_port % MLXSW_REG_REIV_REC_MAX_COUNT; + struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; + u16 rif_index = mlxsw_sp_rif_index(fid->rif); + char *reiv_pl; + int err; + + reiv_pl = kmalloc(MLXSW_REG_REIV_LEN, GFP_KERNEL); + if (!reiv_pl) + return -ENOMEM; + + mlxsw_reg_reiv_pack(reiv_pl, port_page, rif_index); + mlxsw_reg_reiv_rec_update_set(reiv_pl, rec_num, true); + mlxsw_reg_reiv_rec_evid_set(reiv_pl, rec_num, valid ? vid : 0); + err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(reiv), reiv_pl); + kfree(reiv_pl); + return err; +} + +static int mlxsw_sp_fid_evid_map(const struct mlxsw_sp_fid *fid, u16 local_port, + u16 vid, bool valid) +{ + int err; + + err = mlxsw_sp_fid_mpe_table_map(fid, local_port, vid, valid); + if (err) + return err; + + if (!fid->rif) + return 0; + + err = mlxsw_sp_fid_erif_eport_to_vid_map_one(fid, local_port, vid, + valid); + if (err) + goto err_erif_eport_to_vid_map_one; + + return 0; + +err_erif_eport_to_vid_map_one: + mlxsw_sp_fid_mpe_table_map(fid, local_port, vid, !valid); + return err; +} + static int mlxsw_sp_fid_8021d_port_vid_map(struct mlxsw_sp_fid *fid, struct mlxsw_sp_port *mlxsw_sp_port, u16 vid) @@ -858,9 +990,9 @@ static int mlxsw_sp_fid_8021d_port_vid_map(struct mlxsw_sp_fid *fid, return err; if (fid->fid_family->mlxsw_sp->ubridge) { - err = mlxsw_sp_fid_mpe_table_map(fid, local_port, vid, true); + err = mlxsw_sp_fid_evid_map(fid, local_port, vid, true); if (err) - goto err_mpe_table_map; + goto err_fid_evid_map; } err = mlxsw_sp_fid_port_vid_list_add(fid, mlxsw_sp_port->local_port, @@ -881,8 +1013,8 @@ static int mlxsw_sp_fid_8021d_port_vid_map(struct mlxsw_sp_fid *fid, 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_evid_map(fid, local_port, vid, false); +err_fid_evid_map: __mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid, false); return err; } @@ -899,7 +1031,7 @@ mlxsw_sp_fid_8021d_port_vid_unmap(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); if (fid->fid_family->mlxsw_sp->ubridge) - mlxsw_sp_fid_mpe_table_map(fid, local_port, vid, false); + mlxsw_sp_fid_evid_map(fid, local_port, vid, false); __mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid, false); } From 2c3ae763eb703760a5388015582c10fd62d6ea18 Mon Sep 17 00:00:00 2001 From: Amit Cohen Date: Mon, 4 Jul 2022 09:11:31 +0300 Subject: [PATCH 05/13] mlxsw: spectrum_router: Do not configure VID for sub-port RIFs The field 'vid' in RITR is reserved when unified bridge model is used and the RIF's type is sub-port RIF. Instead, ingress VID is configured via SVFA and egress VID is configured via REIV. Set 'vid' to zero in RITR register for sub-port RIF when unified bridge model is used. Signed-off-by: Amit Cohen Reviewed-by: Petr Machata Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index 4a34138985bf67..fe3ae524f340d3 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -9325,7 +9325,7 @@ static int mlxsw_sp_rif_subport_op(struct mlxsw_sp_rif *rif, bool enable) mlxsw_reg_ritr_sp_if_pack(ritr_pl, rif_subport->lag, rif_subport->lag ? rif_subport->lag_id : rif_subport->system_port, - rif_subport->vid); + mlxsw_sp->ubridge ? 0 : rif_subport->vid); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl); } From 058de325a4fbbdfbaf111d31a28918c3fd92e096 Mon Sep 17 00:00:00 2001 From: Amit Cohen Date: Mon, 4 Jul 2022 09:11:32 +0300 Subject: [PATCH 06/13] mlxsw: Configure egress FID classification after routing After routing, a packet needs to perform an L2 lookup using the DMAC it got from the routing and a FID. In unified bridge model, the egress FID configuration needs to be performed by software. It is configured by RITR for both sub-port RIFs and FID RIFs. Currently FID RIFs already configure eFID. Add eFID configuration for sub-port RIFs. Signed-off-by: Amit Cohen Reviewed-by: Petr Machata Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/reg.h | 3 ++- drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index 46ed2c1810becd..520b990054eb4f 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -7113,10 +7113,11 @@ static inline void mlxsw_reg_ritr_rif_pack(char *payload, u16 rif) } static inline void mlxsw_reg_ritr_sp_if_pack(char *payload, bool lag, - u16 system_port, u16 vid) + u16 system_port, u16 efid, u16 vid) { mlxsw_reg_ritr_sp_if_lag_set(payload, lag); mlxsw_reg_ritr_sp_if_system_port_set(payload, system_port); + mlxsw_reg_ritr_sp_if_efid_set(payload, efid); mlxsw_reg_ritr_sp_if_vid_set(payload, vid); } diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index fe3ae524f340d3..eec4fb0561e942 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -9316,15 +9316,18 @@ static int mlxsw_sp_rif_subport_op(struct mlxsw_sp_rif *rif, bool enable) struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp; struct mlxsw_sp_rif_subport *rif_subport; char ritr_pl[MLXSW_REG_RITR_LEN]; + u16 efid; rif_subport = mlxsw_sp_rif_subport_rif(rif); mlxsw_reg_ritr_pack(ritr_pl, enable, MLXSW_REG_RITR_SP_IF, rif->rif_index, rif->vr_id, 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); + efid = mlxsw_sp->ubridge ? mlxsw_sp_fid_index(rif->fid) : 0; mlxsw_reg_ritr_sp_if_pack(ritr_pl, rif_subport->lag, rif_subport->lag ? rif_subport->lag_id : rif_subport->system_port, + efid, mlxsw_sp->ubridge ? 0 : rif_subport->vid); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl); From 662761d8987dc232e85fc35b529f80e01fd4fc71 Mon Sep 17 00:00:00 2001 From: Amit Cohen Date: Mon, 4 Jul 2022 09:11:33 +0300 Subject: [PATCH 07/13] mlxsw: Add support for VLAN RIFs Router interfaces (RIFs) constructed on top of VLAN-aware bridges are of 'VLAN' type, whereas RIFs constructed on top of VLAN-unaware bridges are of 'FID' type. Currently 802.1Q FIDs are emulated using 802.1D FIDs, therefore VLAN RIFs are emulated using FID RIFs. As part of converting the driver to use unified bridge model, 802.1Q FIDs and VLAN RIFs will be used. The egress FID is required for VLAN RIFs in Spectrum-2 and above, but not in Spectrum-1, as in Spectrum-1 the mapping for VLAN RIFs is VID->FID, while in other ASICs it is FID->FID. The reason for the change is that it is more scalable to reuse the FID->FID entry than creating multiple {Port, VID}->FID entries for the router port. Use the existing operation structure to separate the configuration between different ASICs. Add support for VLAN RIFs, most of the configurations are same to FID RIFs. Signed-off-by: Amit Cohen Reviewed-by: Petr Machata Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- .../net/ethernet/mellanox/mlxsw/spectrum.h | 1 + .../ethernet/mellanox/mlxsw/spectrum_router.c | 119 ++++++++++++++++++ 2 files changed, 120 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h index b1810a22a1a61e..c67bc562b13e60 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h @@ -85,6 +85,7 @@ struct mlxsw_sp_upper { enum mlxsw_sp_rif_type { MLXSW_SP_RIF_TYPE_SUBPORT, MLXSW_SP_RIF_TYPE_VLAN_EMU, + MLXSW_SP_RIF_TYPE_VLAN, MLXSW_SP_RIF_TYPE_FID, MLXSW_SP_RIF_TYPE_IPIP_LB, /* IP-in-IP loopback. */ MLXSW_SP_RIF_TYPE_MAX, diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index eec4fb0561e942..7186f6a336853e 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -9573,6 +9573,123 @@ static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_vlan_emu_ops = { .fdb_del = mlxsw_sp_rif_vlan_fdb_del, }; +static int mlxsw_sp_rif_vlan_op(struct mlxsw_sp_rif *rif, u16 vid, u16 efid, + bool enable) +{ + struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp; + char ritr_pl[MLXSW_REG_RITR_LEN]; + + mlxsw_reg_ritr_vlan_if_pack(ritr_pl, enable, rif->rif_index, rif->vr_id, + rif->dev->mtu, rif->dev->dev_addr, + rif->mac_profile_id, vid, efid); + + return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl); +} + +static int mlxsw_sp_rif_vlan_configure(struct mlxsw_sp_rif *rif, u16 efid, + struct netlink_ext_ack *extack) +{ + u16 vid = mlxsw_sp_fid_8021q_vid(rif->fid); + struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp; + u8 mac_profile; + int err; + + err = mlxsw_sp_rif_mac_profile_get(mlxsw_sp, rif->addr, + &mac_profile, extack); + if (err) + return err; + rif->mac_profile_id = mac_profile; + + err = mlxsw_sp_rif_vlan_op(rif, vid, efid, true); + if (err) + goto err_rif_vlan_fid_op; + + err = mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_MC, + mlxsw_sp_router_port(mlxsw_sp), true); + if (err) + goto err_fid_mc_flood_set; + + err = mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC, + mlxsw_sp_router_port(mlxsw_sp), true); + if (err) + goto err_fid_bc_flood_set; + + err = mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr, + mlxsw_sp_fid_index(rif->fid), true); + if (err) + goto err_rif_fdb_op; + + err = mlxsw_sp_fid_rif_set(rif->fid, rif); + if (err) + goto err_fid_rif_set; + + return 0; + +err_fid_rif_set: + mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr, + mlxsw_sp_fid_index(rif->fid), false); +err_rif_fdb_op: + mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC, + mlxsw_sp_router_port(mlxsw_sp), false); +err_fid_bc_flood_set: + 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_op(rif, vid, 0, false); +err_rif_vlan_fid_op: + mlxsw_sp_rif_mac_profile_put(mlxsw_sp, mac_profile); + return err; +} + +static void mlxsw_sp_rif_vlan_deconfigure(struct mlxsw_sp_rif *rif) +{ + u16 vid = mlxsw_sp_fid_8021q_vid(rif->fid); + struct mlxsw_sp *mlxsw_sp = rif->mlxsw_sp; + + mlxsw_sp_fid_rif_unset(rif->fid); + mlxsw_sp_rif_fdb_op(rif->mlxsw_sp, rif->dev->dev_addr, + mlxsw_sp_fid_index(rif->fid), false); + mlxsw_sp_rif_macvlan_flush(rif); + mlxsw_sp_fid_flood_set(rif->fid, MLXSW_SP_FLOOD_TYPE_BC, + 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_op(rif, vid, 0, false); + mlxsw_sp_rif_mac_profile_put(rif->mlxsw_sp, rif->mac_profile_id); +} + +static int mlxsw_sp1_rif_vlan_configure(struct mlxsw_sp_rif *rif, + struct netlink_ext_ack *extack) +{ + return mlxsw_sp_rif_vlan_configure(rif, 0, extack); +} + +static const struct mlxsw_sp_rif_ops mlxsw_sp1_rif_vlan_ops = { + .type = MLXSW_SP_RIF_TYPE_VLAN, + .rif_size = sizeof(struct mlxsw_sp_rif), + .configure = mlxsw_sp1_rif_vlan_configure, + .deconfigure = mlxsw_sp_rif_vlan_deconfigure, + .fid_get = mlxsw_sp_rif_vlan_fid_get, + .fdb_del = mlxsw_sp_rif_vlan_fdb_del, +}; + +static int mlxsw_sp2_rif_vlan_configure(struct mlxsw_sp_rif *rif, + struct netlink_ext_ack *extack) +{ + u16 efid = mlxsw_sp_fid_index(rif->fid); + + return mlxsw_sp_rif_vlan_configure(rif, efid, extack); +} + +static const struct mlxsw_sp_rif_ops mlxsw_sp2_rif_vlan_ops = { + .type = MLXSW_SP_RIF_TYPE_VLAN, + .rif_size = sizeof(struct mlxsw_sp_rif), + .configure = mlxsw_sp2_rif_vlan_configure, + .deconfigure = mlxsw_sp_rif_vlan_deconfigure, + .fid_get = mlxsw_sp_rif_vlan_fid_get, + .fdb_del = mlxsw_sp_rif_vlan_fdb_del, +}; + static struct mlxsw_sp_rif_ipip_lb * mlxsw_sp_rif_ipip_lb_rif(struct mlxsw_sp_rif *rif) { @@ -9644,6 +9761,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_EMU] = &mlxsw_sp_rif_vlan_emu_ops, + [MLXSW_SP_RIF_TYPE_VLAN] = &mlxsw_sp1_rif_vlan_ops, [MLXSW_SP_RIF_TYPE_FID] = &mlxsw_sp_rif_fid_ops, [MLXSW_SP_RIF_TYPE_IPIP_LB] = &mlxsw_sp1_rif_ipip_lb_ops, }; @@ -9832,6 +9950,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_EMU] = &mlxsw_sp_rif_vlan_emu_ops, + [MLXSW_SP_RIF_TYPE_VLAN] = &mlxsw_sp2_rif_vlan_ops, [MLXSW_SP_RIF_TYPE_FID] = &mlxsw_sp_rif_fid_ops, [MLXSW_SP_RIF_TYPE_IPIP_LB] = &mlxsw_sp2_rif_ipip_lb_ops, }; From d4324e3194c78a304cc86ffb4f79fef2fdadf599 Mon Sep 17 00:00:00 2001 From: Amit Cohen Date: Mon, 4 Jul 2022 09:11:34 +0300 Subject: [PATCH 08/13] mlxsw: Add new FID families for unified bridge model In the unified bridge model, mlxsw will no longer emulate 802.1Q FIDs using 802.1D FIDs. The new FID table will look as follows: +---------------+ | 802.1q FIDs | 4K entries | [1..4094] | +---------------+ | 802.1d FIDs | 1K entries | [4095..5118] | +---------------+ | Dummy FIDs | 1 entry | [5119..5119] | +---------------+ | rFIDs | 11K entries | [5120..16383] | +---------------+ In order to make the change easier to review, four new temporary FID families will be added (e.g., MLXSW_SP_FID_TYPE_8021D_UB) and will not be registered with the FID core until mlxsw is flipped to use the unified bridge model. Add .1d, rfid and dummy FID families for unified bridge, the next patch will add .1q family separately as it requires more changes. The following changes are required: 1. Add 'smpe_index_valid' field to 'struct mlxsw_sp_fid_family' and set SFMR.smpe accordingly. SMPE index is reserved for rFIDs, as their flooding is handled by firmware, and always reserved in Spectrum-1, as it is configured as part of PGT table. 2. Add 'ubridge' field to 'struct mlxsw_sp_fid_family'. This field will be removed later, use it in mlxsw_sp_fid_family_{register,unregister}() to skip the registration / unregistration of the new families when the legacy model is used. 3. Indexes - the start and end indexes of each FID family will need to be changed according to the above diagram. 4. Add flood tables for unified bridge model, use 'fid_offset' as table type, as in the new model the access to flood tables will be using 'fid_offset' calculation. 5. FID family operation changes: a. rFID supposed to be created using SFMR, as it is not created by firmware using unified bridge model. b. port_vid_map() should perform SVFA for rFID, as the mapping is not created by firmware using unified bridge model. c. flood_index() is not aligned to the new model, as this function will be removed later. Signed-off-by: Amit Cohen Reviewed-by: Petr Machata Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/reg.h | 5 +- .../net/ethernet/mellanox/mlxsw/spectrum.h | 4 + .../ethernet/mellanox/mlxsw/spectrum_fid.c | 187 +++++++++++++++++- 3 files changed, 189 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index 520b990054eb4f..17ce28e65464fa 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -1969,7 +1969,8 @@ MLXSW_ITEM32(reg, sfmr, smpe, 0x28, 0, 16); static inline void mlxsw_reg_sfmr_pack(char *payload, enum mlxsw_reg_sfmr_op op, u16 fid, u16 fid_offset, bool flood_rsp, - enum mlxsw_reg_bridge_type bridge_type) + enum mlxsw_reg_bridge_type bridge_type, + bool smpe_valid, u16 smpe) { MLXSW_REG_ZERO(sfmr, payload); mlxsw_reg_sfmr_op_set(payload, op); @@ -1979,6 +1980,8 @@ static inline void mlxsw_reg_sfmr_pack(char *payload, mlxsw_reg_sfmr_vv_set(payload, false); mlxsw_reg_sfmr_flood_rsp_set(payload, flood_rsp); mlxsw_reg_sfmr_flood_bridge_type_set(payload, bridge_type); + mlxsw_reg_sfmr_smpe_valid_set(payload, smpe_valid); + mlxsw_reg_sfmr_smpe_set(payload, smpe); } /* SPVMLR - Switch Port VLAN MAC Learning Register diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h index c67bc562b13e60..701aea8f3872ed 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h @@ -106,6 +106,10 @@ enum mlxsw_sp_fid_type { MLXSW_SP_FID_TYPE_8021D, MLXSW_SP_FID_TYPE_RFID, MLXSW_SP_FID_TYPE_DUMMY, + MLXSW_SP_FID_TYPE_8021Q_UB, + MLXSW_SP_FID_TYPE_8021D_UB, + MLXSW_SP_FID_TYPE_RFID_UB, + MLXSW_SP_FID_TYPE_DUMMY_UB, MLXSW_SP_FID_TYPE_MAX, }; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c index c6397f81c2d78f..9dca74bbabb468 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c @@ -111,6 +111,8 @@ struct mlxsw_sp_fid_family { bool flood_rsp; enum mlxsw_reg_bridge_type bridge_type; u16 pgt_base; + bool smpe_index_valid; + bool ubridge; }; static const int mlxsw_sp_sfgc_uc_packet_types[MLXSW_REG_SFGC_TYPE_MAX] = { @@ -448,15 +450,20 @@ static int mlxsw_sp_fid_op(const struct mlxsw_sp_fid *fid, bool valid) struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; enum mlxsw_reg_bridge_type bridge_type = 0; char sfmr_pl[MLXSW_REG_SFMR_LEN]; + bool smpe_valid = false; bool flood_rsp = false; + u16 smpe = 0; if (mlxsw_sp->ubridge) { flood_rsp = fid->fid_family->flood_rsp; bridge_type = fid->fid_family->bridge_type; + smpe_valid = fid->fid_family->smpe_index_valid; + smpe = smpe_valid ? fid->fid_index : 0; } mlxsw_reg_sfmr_pack(sfmr_pl, mlxsw_sp_sfmr_op(valid), fid->fid_index, - fid->fid_offset, flood_rsp, bridge_type); + fid->fid_offset, flood_rsp, bridge_type, smpe_valid, + smpe); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfmr), sfmr_pl); } @@ -466,16 +473,20 @@ static int mlxsw_sp_fid_edit_op(const struct mlxsw_sp_fid *fid, struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; enum mlxsw_reg_bridge_type bridge_type = 0; char sfmr_pl[MLXSW_REG_SFMR_LEN]; + bool smpe_valid = false; bool flood_rsp = false; + u16 smpe = 0; if (mlxsw_sp->ubridge) { flood_rsp = fid->fid_family->flood_rsp; bridge_type = fid->fid_family->bridge_type; + smpe_valid = fid->fid_family->smpe_index_valid; + smpe = smpe_valid ? fid->fid_index : 0; } mlxsw_reg_sfmr_pack(sfmr_pl, MLXSW_REG_SFMR_OP_CREATE_FID, fid->fid_index, fid->fid_offset, flood_rsp, - bridge_type); + bridge_type, smpe_valid, smpe); 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); @@ -772,10 +783,15 @@ mlxsw_sp_fid_8021d_fid(const struct mlxsw_sp_fid *fid) static void mlxsw_sp_fid_8021d_setup(struct mlxsw_sp_fid *fid, const void *arg) { + struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; int br_ifindex = *(int *) arg; mlxsw_sp_fid_8021d_fid(fid)->br_ifindex = br_ifindex; - fid->fid_offset = 0; + + if (mlxsw_sp->ubridge) + fid->fid_offset = fid->fid_index - fid->fid_family->start_index; + else + fid->fid_offset = 0; } static int mlxsw_sp_fid_8021d_configure(struct mlxsw_sp_fid *fid) @@ -1079,6 +1095,7 @@ static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_8021d_ops = { }; #define MLXSW_SP_FID_8021Q_MAX (VLAN_N_VID - 2) +#define MLXSW_SP_FID_RFID_UB_MAX (11 * 1024) #define MLXSW_SP_FID_8021Q_PGT_BASE 0 #define MLXSW_SP_FID_8021D_PGT_BASE (3 * MLXSW_SP_FID_8021Q_MAX) @@ -1100,6 +1117,24 @@ static const struct mlxsw_sp_flood_table mlxsw_sp_fid_8021d_flood_tables[] = { }, }; +static const struct mlxsw_sp_flood_table mlxsw_sp_fid_8021d_ub_flood_tables[] = { + { + .packet_type = MLXSW_SP_FLOOD_TYPE_UC, + .table_type = MLXSW_REG_SFGC_TABLE_TYPE_FID_OFFSET, + .table_index = 0, + }, + { + .packet_type = MLXSW_SP_FLOOD_TYPE_MC, + .table_type = MLXSW_REG_SFGC_TABLE_TYPE_FID_OFFSET, + .table_index = 1, + }, + { + .packet_type = MLXSW_SP_FLOOD_TYPE_BC, + .table_type = MLXSW_REG_SFGC_TABLE_TYPE_FID_OFFSET, + .table_index = 2, + }, +}; + /* Range and flood configuration must match mlxsw_config_profile */ static const struct mlxsw_sp_fid_family mlxsw_sp_fid_8021d_family = { .type = MLXSW_SP_FID_TYPE_8021D, @@ -1171,12 +1206,23 @@ static void mlxsw_sp_fid_rfid_setup(struct mlxsw_sp_fid *fid, const void *arg) static int mlxsw_sp_fid_rfid_configure(struct mlxsw_sp_fid *fid) { - /* rFIDs are allocated by the device during init */ + struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; + + /* rFIDs are allocated by the device during init using legacy + * bridge model. + */ + if (mlxsw_sp->ubridge) + return mlxsw_sp_fid_op(fid, true); + return 0; } static void mlxsw_sp_fid_rfid_deconfigure(struct mlxsw_sp_fid *fid) { + struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; + + if (mlxsw_sp->ubridge) + mlxsw_sp_fid_op(fid, false); } static int mlxsw_sp_fid_rfid_index_alloc(struct mlxsw_sp_fid *fid, @@ -1210,9 +1256,27 @@ static int mlxsw_sp_fid_rfid_port_vid_map(struct mlxsw_sp_fid *fid, 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. + /* Using legacy bridge model, we only need to transition the port to + * virtual mode since {Port, VID} => FID is done by the firmware upon + * RIF creation. Using unified bridge model, we need to map + * {Port, VID} => FID and map egress VID. */ + if (mlxsw_sp->ubridge) { + err = __mlxsw_sp_fid_port_vid_map(fid, + mlxsw_sp_port->local_port, + vid, true); + if (err) + goto err_port_vid_map; + + if (fid->rif) { + err = mlxsw_sp_fid_erif_eport_to_vid_map_one(fid, + local_port, + vid, true); + if (err) + goto err_erif_eport_to_vid_map_one; + } + } + if (mlxsw_sp->fid_core->port_fid_mappings[local_port]++ == 0) { err = mlxsw_sp_port_vp_mode_trans(mlxsw_sp_port); if (err) @@ -1223,6 +1287,14 @@ 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]--; + if (mlxsw_sp->ubridge && fid->rif) + mlxsw_sp_fid_erif_eport_to_vid_map_one(fid, local_port, vid, + false); +err_erif_eport_to_vid_map_one: + if (mlxsw_sp->ubridge) + __mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid, + false); +err_port_vid_map: mlxsw_sp_fid_port_vid_list_del(fid, mlxsw_sp_port->local_port, vid); return err; } @@ -1237,6 +1309,15 @@ 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]--; + + if (mlxsw_sp->ubridge) { + if (fid->rif) + mlxsw_sp_fid_erif_eport_to_vid_map_one(fid, local_port, + vid, false); + __mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid, + false); + } + mlxsw_sp_fid_port_vid_list_del(fid, mlxsw_sp_port->local_port, vid); } @@ -1356,11 +1437,95 @@ static const struct mlxsw_sp_fid_family mlxsw_sp_fid_dummy_family = { .ops = &mlxsw_sp_fid_dummy_ops, }; +/* There are 4K-2 802.1Q FIDs */ +#define MLXSW_SP_FID_8021Q_UB_START 1 /* FID 0 is reserved. */ +#define MLXSW_SP_FID_8021Q_UB_END (MLXSW_SP_FID_8021Q_UB_START + \ + MLXSW_SP_FID_8021Q_MAX - 1) + +/* There are 1K 802.1D FIDs */ +#define MLXSW_SP_FID_8021D_UB_START (MLXSW_SP_FID_8021Q_UB_END + 1) +#define MLXSW_SP_FID_8021D_UB_END (MLXSW_SP_FID_8021D_UB_START + \ + MLXSW_SP_FID_8021D_MAX - 1) + +/* There is one dummy FID */ +#define MLXSW_SP_FID_DUMMY_UB (MLXSW_SP_FID_8021D_UB_END + 1) + +/* There are 11K rFIDs */ +#define MLXSW_SP_RFID_UB_START (MLXSW_SP_FID_DUMMY_UB + 1) +#define MLXSW_SP_RFID_UB_END (MLXSW_SP_RFID_UB_START + \ + MLXSW_SP_FID_RFID_UB_MAX - 1) + +static const struct mlxsw_sp_fid_family mlxsw_sp1_fid_8021d_ub_family = { + .type = MLXSW_SP_FID_TYPE_8021D_UB, + .fid_size = sizeof(struct mlxsw_sp_fid_8021d), + .start_index = MLXSW_SP_FID_8021D_UB_START, + .end_index = MLXSW_SP_FID_8021D_UB_END, + .flood_tables = mlxsw_sp_fid_8021d_ub_flood_tables, + .nr_flood_tables = ARRAY_SIZE(mlxsw_sp_fid_8021d_ub_flood_tables), + .rif_type = MLXSW_SP_RIF_TYPE_FID, + .ops = &mlxsw_sp_fid_8021d_ops, + .bridge_type = MLXSW_REG_BRIDGE_TYPE_1, + .pgt_base = MLXSW_SP_FID_8021D_PGT_BASE, + .smpe_index_valid = false, + .ubridge = true, +}; + +static const struct mlxsw_sp_fid_family mlxsw_sp1_fid_dummy_ub_family = { + .type = MLXSW_SP_FID_TYPE_DUMMY_UB, + .fid_size = sizeof(struct mlxsw_sp_fid), + .start_index = MLXSW_SP_FID_DUMMY_UB, + .end_index = MLXSW_SP_FID_DUMMY_UB, + .ops = &mlxsw_sp_fid_dummy_ops, + .smpe_index_valid = false, + .ubridge = true, +}; + +static const struct mlxsw_sp_fid_family mlxsw_sp_fid_rfid_ub_family = { + .type = MLXSW_SP_FID_TYPE_RFID_UB, + .fid_size = sizeof(struct mlxsw_sp_fid), + .start_index = MLXSW_SP_RFID_UB_START, + .end_index = MLXSW_SP_RFID_UB_END, + .rif_type = MLXSW_SP_RIF_TYPE_SUBPORT, + .ops = &mlxsw_sp_fid_rfid_ops, + .flood_rsp = true, + .smpe_index_valid = false, + .ubridge = true, +}; + 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, + + [MLXSW_SP_FID_TYPE_8021D_UB] = &mlxsw_sp1_fid_8021d_ub_family, + [MLXSW_SP_FID_TYPE_DUMMY_UB] = &mlxsw_sp1_fid_dummy_ub_family, + [MLXSW_SP_FID_TYPE_RFID_UB] = &mlxsw_sp_fid_rfid_ub_family, +}; + +static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_8021d_ub_family = { + .type = MLXSW_SP_FID_TYPE_8021D_UB, + .fid_size = sizeof(struct mlxsw_sp_fid_8021d), + .start_index = MLXSW_SP_FID_8021D_UB_START, + .end_index = MLXSW_SP_FID_8021D_UB_END, + .flood_tables = mlxsw_sp_fid_8021d_ub_flood_tables, + .nr_flood_tables = ARRAY_SIZE(mlxsw_sp_fid_8021d_ub_flood_tables), + .rif_type = MLXSW_SP_RIF_TYPE_FID, + .ops = &mlxsw_sp_fid_8021d_ops, + .bridge_type = MLXSW_REG_BRIDGE_TYPE_1, + .pgt_base = MLXSW_SP_FID_8021D_PGT_BASE, + .smpe_index_valid = true, + .ubridge = true, +}; + +static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_dummy_ub_family = { + .type = MLXSW_SP_FID_TYPE_DUMMY_UB, + .fid_size = sizeof(struct mlxsw_sp_fid), + .start_index = MLXSW_SP_FID_DUMMY_UB, + .end_index = MLXSW_SP_FID_DUMMY_UB, + .ops = &mlxsw_sp_fid_dummy_ops, + .smpe_index_valid = false, + .ubridge = true, }; const struct mlxsw_sp_fid_family *mlxsw_sp2_fid_family_arr[] = { @@ -1368,6 +1533,10 @@ const struct mlxsw_sp_fid_family *mlxsw_sp2_fid_family_arr[] = { [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, + + [MLXSW_SP_FID_TYPE_8021D_UB] = &mlxsw_sp2_fid_8021d_ub_family, + [MLXSW_SP_FID_TYPE_DUMMY_UB] = &mlxsw_sp2_fid_dummy_ub_family, + [MLXSW_SP_FID_TYPE_RFID_UB] = &mlxsw_sp_fid_rfid_ub_family, }; static struct mlxsw_sp_fid *mlxsw_sp_fid_lookup(struct mlxsw_sp *mlxsw_sp, @@ -1676,6 +1845,9 @@ int mlxsw_sp_fids_init(struct mlxsw_sp *mlxsw_sp) } for (i = 0; i < MLXSW_SP_FID_TYPE_MAX; i++) { + if (mlxsw_sp->ubridge != mlxsw_sp->fid_family_arr[i]->ubridge) + continue; + err = mlxsw_sp_fid_family_register(mlxsw_sp, mlxsw_sp->fid_family_arr[i]); @@ -1690,6 +1862,9 @@ int mlxsw_sp_fids_init(struct mlxsw_sp *mlxsw_sp) struct mlxsw_sp_fid_family *fid_family; fid_family = fid_core->fid_family_arr[i]; + if (mlxsw_sp->ubridge != fid_family->ubridge) + continue; + mlxsw_sp_fid_family_unregister(mlxsw_sp, fid_family); } kfree(fid_core->port_fid_mappings); From bf73904f5fba7c92c0c11ebe8cf91788354bf068 Mon Sep 17 00:00:00 2001 From: Amit Cohen Date: Mon, 4 Jul 2022 09:11:35 +0300 Subject: [PATCH 09/13] mlxsw: Add support for 802.1Q FID family Using the legacy bridge model, there is no VID classification at egress for 802.1Q FIDs, which means that the VID is maintained. This behavior cause the limitation that 802.1Q FIDs cannot work with VXLAN. This limitation stems from the fact that a decapsulated VXLAN packet should not contain a VLAN tag. If such a packet was to egress from a local port using a 802.1Q FID, it would "maintain" its VLAN on egress, which is no VLAN at all. Currently 802.1Q FIDs are emulated in mlxsw driver using 802.1D FIDs. Using unified bridge model, there is a FID->VID mapping, so it is possible to stop emulating 802.1Q FIDs. The main changes are: 1. Use 'SFGC.bridge_type' = 0, to separate between 802.1Q FIDs and 802.1D FIDs. 2. Use VLAN RIF instead of the emulated one (VLAN_EMU which is emulated using FID RIF). 3. Create VID->FID mapping when the FID is created. Then when a new port is mapped to the FID, if it not in virtual mode, no new mapping is needed. Save the new port in 'port_vid_list', to be able to update a RIF in all {Port, VID}->FID mappings in case that the port will be in virtual mode later. 4. Add a dedicated operation function per FID family to update RIF for VID->FID mappings. For 802.1d and rFID families, just return. For 802.1q family, handle the global mapping which is created for new 802.1q FID. Signed-off-by: Amit Cohen Reviewed-by: Petr Machata Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- .../ethernet/mellanox/mlxsw/spectrum_fid.c | 192 +++++++++++++++++- .../ethernet/mellanox/mlxsw/spectrum_router.c | 3 +- 2 files changed, 193 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c index 9dca74bbabb468..385deef75eed77 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c @@ -94,6 +94,8 @@ struct mlxsw_sp_fid_ops { 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); + int (*vid_to_fid_rif_update)(const struct mlxsw_sp_fid *fid, + const struct mlxsw_sp_rif *rif); }; struct mlxsw_sp_fid_family { @@ -433,10 +435,15 @@ u16 mlxsw_sp_fid_8021q_vid(const struct mlxsw_sp_fid *fid) static void mlxsw_sp_fid_8021q_setup(struct mlxsw_sp_fid *fid, const void *arg) { + struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; u16 vid = *(u16 *) arg; mlxsw_sp_fid_8021q_fid(fid)->vid = vid; - fid->fid_offset = 0; + + if (mlxsw_sp->ubridge) + fid->fid_offset = fid->fid_index - fid->fid_family->start_index; + else + fid->fid_offset = 0; } static enum mlxsw_reg_sfmr_op mlxsw_sp_sfmr_op(bool valid) @@ -532,6 +539,35 @@ static int mlxsw_sp_fid_vni_to_fid_rif_update(const struct mlxsw_sp_fid *fid, return mlxsw_sp_fid_vni_to_fid_map(fid, rif, fid->vni_valid); } +static int +mlxsw_sp_fid_vid_to_fid_map(const struct mlxsw_sp_fid *fid, u16 vid, bool valid, + const struct mlxsw_sp_rif *rif) +{ + struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; + char svfa_pl[MLXSW_REG_SVFA_LEN]; + bool irif_valid; + u16 irif_index; + + irif_valid = !!rif; + irif_index = rif ? mlxsw_sp_rif_index(rif) : 0; + + mlxsw_reg_svfa_vid_pack(svfa_pl, valid, fid->fid_index, vid, irif_valid, + irif_index); + return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(svfa), svfa_pl); +} + +static int +mlxsw_sp_fid_8021q_vid_to_fid_rif_update(const struct mlxsw_sp_fid *fid, + const struct mlxsw_sp_rif *rif) +{ + struct mlxsw_sp_fid_8021q *fid_8021q = mlxsw_sp_fid_8021q_fid(fid); + + /* Update the global VID => FID mapping we created when the FID was + * configured. + */ + return mlxsw_sp_fid_vid_to_fid_map(fid, fid_8021q->vid, true, rif); +} + static int mlxsw_sp_fid_port_vid_to_fid_rif_update_one(const struct mlxsw_sp_fid *fid, struct mlxsw_sp_fid_port_vid *pv, @@ -555,6 +591,10 @@ static int mlxsw_sp_fid_vid_to_fid_rif_set(const struct mlxsw_sp_fid *fid, u16 irif_index; int err; + err = fid->fid_family->ops->vid_to_fid_rif_update(fid, rif); + if (err) + return err; + irif_index = mlxsw_sp_rif_index(rif); list_for_each_entry(pv, &fid->port_vid_list, list) { @@ -582,6 +622,7 @@ static int mlxsw_sp_fid_vid_to_fid_rif_set(const struct mlxsw_sp_fid *fid, mlxsw_sp_fid_port_vid_to_fid_rif_update_one(fid, pv, false, 0); } + fid->fid_family->ops->vid_to_fid_rif_update(fid, NULL); return err; } @@ -599,6 +640,8 @@ static void mlxsw_sp_fid_vid_to_fid_rif_unset(const struct mlxsw_sp_fid *fid) mlxsw_sp_fid_port_vid_to_fid_rif_update_one(fid, pv, false, 0); } + + fid->fid_family->ops->vid_to_fid_rif_update(fid, NULL); } static int mlxsw_sp_fid_reiv_handle(struct mlxsw_sp_fid *fid, u16 rif_index, @@ -1078,6 +1121,13 @@ mlxsw_sp_fid_8021d_fdb_clear_offload(const struct mlxsw_sp_fid *fid, br_fdb_clear_offload(nve_dev, 0); } +static int +mlxsw_sp_fid_8021d_vid_to_fid_rif_update(const struct mlxsw_sp_fid *fid, + const struct mlxsw_sp_rif *rif) +{ + return 0; +} + static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_8021d_ops = { .setup = mlxsw_sp_fid_8021d_setup, .configure = mlxsw_sp_fid_8021d_configure, @@ -1092,6 +1142,7 @@ static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_8021d_ops = { .nve_flood_index_set = mlxsw_sp_fid_8021d_nve_flood_index_set, .nve_flood_index_clear = mlxsw_sp_fid_8021d_nve_flood_index_clear, .fdb_clear_offload = mlxsw_sp_fid_8021d_fdb_clear_offload, + .vid_to_fid_rif_update = mlxsw_sp_fid_8021d_vid_to_fid_rif_update, }; #define MLXSW_SP_FID_8021Q_MAX (VLAN_N_VID - 2) @@ -1341,6 +1392,13 @@ static void mlxsw_sp_fid_rfid_nve_flood_index_clear(struct mlxsw_sp_fid *fid) WARN_ON_ONCE(1); } +static int +mlxsw_sp_fid_rfid_vid_to_fid_rif_update(const struct mlxsw_sp_fid *fid, + const struct mlxsw_sp_rif *rif) +{ + return 0; +} + static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_rfid_ops = { .setup = mlxsw_sp_fid_rfid_setup, .configure = mlxsw_sp_fid_rfid_configure, @@ -1353,6 +1411,7 @@ static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_rfid_ops = { .vni_clear = mlxsw_sp_fid_rfid_vni_clear, .nve_flood_index_set = mlxsw_sp_fid_rfid_nve_flood_index_set, .nve_flood_index_clear = mlxsw_sp_fid_rfid_nve_flood_index_clear, + .vid_to_fid_rif_update = mlxsw_sp_fid_rfid_vid_to_fid_rif_update, }; #define MLXSW_SP_RFID_BASE (15 * 1024) @@ -1437,6 +1496,103 @@ static const struct mlxsw_sp_fid_family mlxsw_sp_fid_dummy_family = { .ops = &mlxsw_sp_fid_dummy_ops, }; +static int mlxsw_sp_fid_8021q_configure(struct mlxsw_sp_fid *fid) +{ + struct mlxsw_sp_fid_8021q *fid_8021q = mlxsw_sp_fid_8021q_fid(fid); + int err; + + err = mlxsw_sp_fid_op(fid, true); + if (err) + return err; + + err = mlxsw_sp_fid_vid_to_fid_map(fid, fid_8021q->vid, true, fid->rif); + if (err) + goto err_vid_to_fid_map; + + return 0; + +err_vid_to_fid_map: + mlxsw_sp_fid_op(fid, false); + return err; +} + +static void mlxsw_sp_fid_8021q_deconfigure(struct mlxsw_sp_fid *fid) +{ + struct mlxsw_sp_fid_8021q *fid_8021q = mlxsw_sp_fid_8021q_fid(fid); + + if (fid->vni_valid) + mlxsw_sp_nve_fid_disable(fid->fid_family->mlxsw_sp, fid); + + mlxsw_sp_fid_vid_to_fid_map(fid, fid_8021q->vid, false, NULL); + mlxsw_sp_fid_op(fid, false); +} + +static int mlxsw_sp_fid_8021q_port_vid_map(struct mlxsw_sp_fid *fid, + struct mlxsw_sp_port *mlxsw_sp_port, + u16 vid) +{ + struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; + u8 local_port = mlxsw_sp_port->local_port; + int err; + + /* In case there are no {Port, VID} => FID mappings on the port, + * we can use the global VID => FID mapping we created when the + * FID was configured, otherwise, configure new mapping. + */ + if (mlxsw_sp->fid_core->port_fid_mappings[local_port]) { + err = __mlxsw_sp_fid_port_vid_map(fid, local_port, vid, true); + if (err) + return err; + } + + err = mlxsw_sp_fid_evid_map(fid, local_port, vid, true); + if (err) + goto err_fid_evid_map; + + err = mlxsw_sp_fid_port_vid_list_add(fid, mlxsw_sp_port->local_port, + vid); + if (err) + goto err_port_vid_list_add; + + return 0; + +err_port_vid_list_add: + mlxsw_sp_fid_evid_map(fid, local_port, vid, false); +err_fid_evid_map: + if (mlxsw_sp->fid_core->port_fid_mappings[local_port]) + __mlxsw_sp_fid_port_vid_map(fid, local_port, vid, false); + return err; +} + +static void +mlxsw_sp_fid_8021q_port_vid_unmap(struct mlxsw_sp_fid *fid, + struct mlxsw_sp_port *mlxsw_sp_port, u16 vid) +{ + struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp; + u8 local_port = mlxsw_sp_port->local_port; + + mlxsw_sp_fid_port_vid_list_del(fid, mlxsw_sp_port->local_port, vid); + mlxsw_sp_fid_evid_map(fid, local_port, vid, false); + if (mlxsw_sp->fid_core->port_fid_mappings[local_port]) + __mlxsw_sp_fid_port_vid_map(fid, local_port, vid, false); +} + +static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_8021q_ops = { + .setup = mlxsw_sp_fid_8021q_setup, + .configure = mlxsw_sp_fid_8021q_configure, + .deconfigure = mlxsw_sp_fid_8021q_deconfigure, + .index_alloc = mlxsw_sp_fid_8021d_index_alloc, + .compare = mlxsw_sp_fid_8021q_compare, + .port_vid_map = mlxsw_sp_fid_8021q_port_vid_map, + .port_vid_unmap = mlxsw_sp_fid_8021q_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, + .fdb_clear_offload = mlxsw_sp_fid_8021q_fdb_clear_offload, + .vid_to_fid_rif_update = mlxsw_sp_fid_8021q_vid_to_fid_rif_update, +}; + /* There are 4K-2 802.1Q FIDs */ #define MLXSW_SP_FID_8021Q_UB_START 1 /* FID 0 is reserved. */ #define MLXSW_SP_FID_8021Q_UB_END (MLXSW_SP_FID_8021Q_UB_START + \ @@ -1455,6 +1611,22 @@ static const struct mlxsw_sp_fid_family mlxsw_sp_fid_dummy_family = { #define MLXSW_SP_RFID_UB_END (MLXSW_SP_RFID_UB_START + \ MLXSW_SP_FID_RFID_UB_MAX - 1) +static const struct mlxsw_sp_fid_family mlxsw_sp1_fid_8021q_ub_family = { + .type = MLXSW_SP_FID_TYPE_8021Q_UB, + .fid_size = sizeof(struct mlxsw_sp_fid_8021q), + .start_index = MLXSW_SP_FID_8021Q_UB_START, + .end_index = MLXSW_SP_FID_8021Q_UB_END, + .flood_tables = mlxsw_sp_fid_8021d_ub_flood_tables, + .nr_flood_tables = ARRAY_SIZE(mlxsw_sp_fid_8021d_ub_flood_tables), + .rif_type = MLXSW_SP_RIF_TYPE_VLAN, + .ops = &mlxsw_sp_fid_8021q_ops, + .flood_rsp = false, + .bridge_type = MLXSW_REG_BRIDGE_TYPE_0, + .pgt_base = MLXSW_SP_FID_8021Q_PGT_BASE, + .smpe_index_valid = false, + .ubridge = true, +}; + static const struct mlxsw_sp_fid_family mlxsw_sp1_fid_8021d_ub_family = { .type = MLXSW_SP_FID_TYPE_8021D_UB, .fid_size = sizeof(struct mlxsw_sp_fid_8021d), @@ -1498,11 +1670,28 @@ const struct mlxsw_sp_fid_family *mlxsw_sp1_fid_family_arr[] = { [MLXSW_SP_FID_TYPE_RFID] = &mlxsw_sp_fid_rfid_family, [MLXSW_SP_FID_TYPE_DUMMY] = &mlxsw_sp_fid_dummy_family, + [MLXSW_SP_FID_TYPE_8021Q_UB] = &mlxsw_sp1_fid_8021q_ub_family, [MLXSW_SP_FID_TYPE_8021D_UB] = &mlxsw_sp1_fid_8021d_ub_family, [MLXSW_SP_FID_TYPE_DUMMY_UB] = &mlxsw_sp1_fid_dummy_ub_family, [MLXSW_SP_FID_TYPE_RFID_UB] = &mlxsw_sp_fid_rfid_ub_family, }; +static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_8021q_ub_family = { + .type = MLXSW_SP_FID_TYPE_8021Q_UB, + .fid_size = sizeof(struct mlxsw_sp_fid_8021q), + .start_index = MLXSW_SP_FID_8021Q_UB_START, + .end_index = MLXSW_SP_FID_8021Q_UB_END, + .flood_tables = mlxsw_sp_fid_8021d_ub_flood_tables, + .nr_flood_tables = ARRAY_SIZE(mlxsw_sp_fid_8021d_ub_flood_tables), + .rif_type = MLXSW_SP_RIF_TYPE_VLAN, + .ops = &mlxsw_sp_fid_8021q_ops, + .flood_rsp = false, + .bridge_type = MLXSW_REG_BRIDGE_TYPE_0, + .pgt_base = MLXSW_SP_FID_8021Q_PGT_BASE, + .smpe_index_valid = true, + .ubridge = true, +}; + static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_8021d_ub_family = { .type = MLXSW_SP_FID_TYPE_8021D_UB, .fid_size = sizeof(struct mlxsw_sp_fid_8021d), @@ -1534,6 +1723,7 @@ const struct mlxsw_sp_fid_family *mlxsw_sp2_fid_family_arr[] = { [MLXSW_SP_FID_TYPE_RFID] = &mlxsw_sp_fid_rfid_family, [MLXSW_SP_FID_TYPE_DUMMY] = &mlxsw_sp_fid_dummy_family, + [MLXSW_SP_FID_TYPE_8021Q_UB] = &mlxsw_sp2_fid_8021q_ub_family, [MLXSW_SP_FID_TYPE_8021D_UB] = &mlxsw_sp2_fid_8021d_ub_family, [MLXSW_SP_FID_TYPE_DUMMY_UB] = &mlxsw_sp2_fid_dummy_ub_family, [MLXSW_SP_FID_TYPE_RFID_UB] = &mlxsw_sp_fid_rfid_ub_family, diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index 7186f6a336853e..aeaba07c17b085 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -7730,7 +7730,8 @@ 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_EMU) + if (rif->ops->type != MLXSW_SP_RIF_TYPE_VLAN_EMU && + rif->ops->type != MLXSW_SP_RIF_TYPE_VLAN) goto out; vid = mlxsw_sp_fid_8021q_vid(rif->fid); From e9cf8990faea42a0809b9f1e618effd6fd836e8a Mon Sep 17 00:00:00 2001 From: Amit Cohen Date: Mon, 4 Jul 2022 09:11:36 +0300 Subject: [PATCH 10/13] mlxsw: Add ubridge to config profile The unified bridge model is enabled via the CONFIG_PROFILE command during driver initialization. Add the definition of the relevant fields to the command's payload in preparation for unified bridge enablement. Signed-off-by: Amit Cohen Reviewed-by: Petr Machata Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/cmd.h | 13 +++++++++++++ drivers/net/ethernet/mellanox/mlxsw/core.h | 2 ++ drivers/net/ethernet/mellanox/mlxsw/pci.c | 5 +++++ 3 files changed, 20 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/cmd.h b/drivers/net/ethernet/mellanox/mlxsw/cmd.h index 8a89c2773294d6..666d6b6e4dbfbd 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/cmd.h +++ b/drivers/net/ethernet/mellanox/mlxsw/cmd.h @@ -633,6 +633,12 @@ MLXSW_ITEM32(cmd_mbox, config_profile, */ MLXSW_ITEM32(cmd_mbox, config_profile, set_ar_sec, 0x0C, 15, 1); +/* cmd_mbox_config_set_ubridge + * Capability bit. Setting a bit to 1 configures the profile + * according to the mailbox contents. + */ +MLXSW_ITEM32(cmd_mbox, config_profile, set_ubridge, 0x0C, 22, 1); + /* cmd_mbox_config_set_kvd_linear_size * Capability bit. Setting a bit to 1 configures the profile * according to the mailbox contents. @@ -792,6 +798,13 @@ MLXSW_ITEM32(cmd_mbox, config_profile, adaptive_routing_group_cap, 0x4C, 0, 16); */ MLXSW_ITEM32(cmd_mbox, config_profile, arn, 0x50, 31, 1); +/* cmd_mbox_config_profile_ubridge + * Unified Bridge + * 0 - non unified bridge + * 1 - unified bridge + */ +MLXSW_ITEM32(cmd_mbox, config_profile, ubridge, 0x50, 4, 1); + /* cmd_mbox_config_kvd_linear_size * KVD Linear Size * Valid for Spectrum only diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h index d1e8b8b8d0c129..a3491ef2aa7e21 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.h +++ b/drivers/net/ethernet/mellanox/mlxsw/core.h @@ -295,6 +295,7 @@ struct mlxsw_config_profile { used_max_pkey:1, used_ar_sec:1, used_adaptive_routing_group_cap:1, + used_ubridge:1, used_kvd_sizes:1; u8 max_vepa_channels; u16 max_mid; @@ -314,6 +315,7 @@ struct mlxsw_config_profile { u8 ar_sec; u16 adaptive_routing_group_cap; u8 arn; + u8 ubridge; u32 kvd_linear_size; u8 kvd_hash_single_parts; u8 kvd_hash_double_parts; diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c index 4687dabaaf0923..41f0f68bc911af 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/pci.c +++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c @@ -1235,6 +1235,11 @@ static int mlxsw_pci_config_profile(struct mlxsw_pci *mlxsw_pci, char *mbox, mlxsw_cmd_mbox_config_profile_adaptive_routing_group_cap_set( mbox, profile->adaptive_routing_group_cap); } + if (profile->used_ubridge) { + mlxsw_cmd_mbox_config_profile_set_ubridge_set(mbox, 1); + mlxsw_cmd_mbox_config_profile_ubridge_set(mbox, + profile->ubridge); + } if (profile->used_kvd_sizes && MLXSW_RES_VALID(res, KVD_SIZE)) { err = mlxsw_pci_profile_get_kvd_sizes(mlxsw_pci, profile, res); if (err) From 77b7f83d5c2594c5dbdd217aec03bd2265c0f11c Mon Sep 17 00:00:00 2001 From: Amit Cohen Date: Mon, 4 Jul 2022 09:11:37 +0300 Subject: [PATCH 11/13] mlxsw: Enable unified bridge model After all the preparations for unified bridge model, finally flip mlxsw driver to use the new model. Change config profile, set 'ubridge' to true and remove the configurations that are relevant only for the legacy model. Set 'flood_mode' to 'controlled' as the current mode is not supported with unified bridge model. Remove all the code which is dedicated to the legacy model. Remove 'struct mlxsw_sp.ubridge' variable which was temporarily added to separate configurations between the models. Signed-off-by: Amit Cohen Reviewed-by: Petr Machata Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- .../net/ethernet/mellanox/mlxsw/spectrum.c | 29 +- .../net/ethernet/mellanox/mlxsw/spectrum.h | 7 - .../ethernet/mellanox/mlxsw/spectrum_fid.c | 326 ++++-------------- .../ethernet/mellanox/mlxsw/spectrum_pgt.c | 21 +- .../ethernet/mellanox/mlxsw/spectrum_router.c | 20 +- .../mellanox/mlxsw/spectrum_switchdev.c | 4 +- 6 files changed, 79 insertions(+), 328 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index ff94cd9d872f0e..a703ca257198e6 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -3161,7 +3161,6 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core, goto err_ports_create; } - mlxsw_sp->ubridge = false; return 0; err_ports_create: @@ -3383,24 +3382,15 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core) mlxsw_sp_parsing_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 = { - .used_max_mid = 1, - .max_mid = MLXSW_SP_MID_MAX, - .used_flood_tables = 1, - .used_flood_mode = 1, - .flood_mode = MLXSW_CMD_MBOX_CONFIG_PROFILE_FLOOD_MODE_MIXED, - .max_fid_flood_tables = 3, - .fid_flood_table_size = MLXSW_SP_FID_FLOOD_TABLE_SIZE, + .used_flood_mode = 1, + .flood_mode = MLXSW_CMD_MBOX_CONFIG_PROFILE_FLOOD_MODE_CONTROLLED, .used_max_ib_mc = 1, .max_ib_mc = 0, .used_max_pkey = 1, .max_pkey = 0, + .used_ubridge = 1, + .ubridge = 1, .used_kvd_sizes = 1, .kvd_hash_single_parts = 59, .kvd_hash_double_parts = 41, @@ -3414,17 +3404,14 @@ static const struct mlxsw_config_profile mlxsw_sp1_config_profile = { }; static const struct mlxsw_config_profile mlxsw_sp2_config_profile = { - .used_max_mid = 1, - .max_mid = MLXSW_SP_MID_MAX, - .used_flood_tables = 1, - .used_flood_mode = 1, - .flood_mode = MLXSW_CMD_MBOX_CONFIG_PROFILE_FLOOD_MODE_MIXED, - .max_fid_flood_tables = 3, - .fid_flood_table_size = MLXSW_SP_FID_FLOOD_TABLE_SIZE, + .used_flood_mode = 1, + .flood_mode = MLXSW_CMD_MBOX_CONFIG_PROFILE_FLOOD_MODE_CONTROLLED, .used_max_ib_mc = 1, .max_ib_mc = 0, .used_max_pkey = 1, .max_pkey = 0, + .used_ubridge = 1, + .ubridge = 1, .swid_config = { { .used_type = 1, diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h index 701aea8f3872ed..50a9380b76e91b 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h @@ -84,7 +84,6 @@ struct mlxsw_sp_upper { enum mlxsw_sp_rif_type { MLXSW_SP_RIF_TYPE_SUBPORT, - MLXSW_SP_RIF_TYPE_VLAN_EMU, MLXSW_SP_RIF_TYPE_VLAN, MLXSW_SP_RIF_TYPE_FID, MLXSW_SP_RIF_TYPE_IPIP_LB, /* IP-in-IP loopback. */ @@ -106,10 +105,6 @@ enum mlxsw_sp_fid_type { MLXSW_SP_FID_TYPE_8021D, MLXSW_SP_FID_TYPE_RFID, MLXSW_SP_FID_TYPE_DUMMY, - MLXSW_SP_FID_TYPE_8021Q_UB, - MLXSW_SP_FID_TYPE_8021D_UB, - MLXSW_SP_FID_TYPE_RFID_UB, - MLXSW_SP_FID_TYPE_DUMMY_UB, MLXSW_SP_FID_TYPE_MAX, }; @@ -213,7 +208,6 @@ struct mlxsw_sp { u32 lowest_shaper_bs; struct rhashtable ipv6_addr_ht; struct mutex ipv6_addr_ht_lock; /* Protects ipv6_addr_ht */ - bool ubridge; struct mlxsw_sp_pgt *pgt; bool pgt_smpe_index_valid; }; @@ -1483,7 +1477,6 @@ void mlxsw_sp_pgt_mid_free_range(struct mlxsw_sp *mlxsw_sp, u16 mid_base, u16 count); int mlxsw_sp_pgt_entry_port_set(struct mlxsw_sp *mlxsw_sp, u16 mid, u16 smpe, u16 local_port, bool member); -u16 mlxsw_sp_pgt_index_to_mid(const struct mlxsw_sp *mlxsw_sp, u16 pgt_index); int mlxsw_sp_pgt_init(struct mlxsw_sp *mlxsw_sp); void mlxsw_sp_pgt_fini(struct mlxsw_sp *mlxsw_sp); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c index 385deef75eed77..818e458eb3ad3c 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c @@ -114,7 +114,6 @@ struct mlxsw_sp_fid_family { enum mlxsw_reg_bridge_type bridge_type; u16 pgt_base; bool smpe_index_valid; - bool ubridge; }; static const int mlxsw_sp_sfgc_uc_packet_types[MLXSW_REG_SFGC_TYPE_MAX] = { @@ -351,9 +350,7 @@ int mlxsw_sp_fid_flood_set(struct mlxsw_sp_fid *fid, struct mlxsw_sp_fid_family *fid_family = fid->fid_family; const struct mlxsw_sp_fid_ops *ops = fid_family->ops; const struct mlxsw_sp_flood_table *flood_table; - char *sftr2_pl; u16 mid_index; - int err; if (WARN_ON(!fid_family->flood_tables || !ops->flood_index)) return -EINVAL; @@ -362,26 +359,10 @@ int mlxsw_sp_fid_flood_set(struct mlxsw_sp_fid *fid, if (!flood_table) return -ESRCH; - if (fid_family->mlxsw_sp->ubridge) { - mid_index = mlxsw_sp_fid_flood_table_mid(fid_family, - flood_table, - fid->fid_offset); - return mlxsw_sp_pgt_entry_port_set(fid_family->mlxsw_sp, - mid_index, fid->fid_index, - local_port, member); - } - - sftr2_pl = kmalloc(MLXSW_REG_SFTR2_LEN, GFP_KERNEL); - if (!sftr2_pl) - return -ENOMEM; - - mlxsw_reg_sftr2_pack(sftr2_pl, flood_table->table_index, - ops->flood_index(fid), flood_table->table_type, 1, - local_port, member); - err = mlxsw_reg_write(fid_family->mlxsw_sp->core, MLXSW_REG(sftr2), - sftr2_pl); - kfree(sftr2_pl); - return err; + mid_index = mlxsw_sp_fid_flood_table_mid(fid_family, flood_table, + fid->fid_offset); + return mlxsw_sp_pgt_entry_port_set(fid_family->mlxsw_sp, mid_index, + fid->fid_index, local_port, member); } int mlxsw_sp_fid_port_vid_map(struct mlxsw_sp_fid *fid, @@ -435,15 +416,10 @@ u16 mlxsw_sp_fid_8021q_vid(const struct mlxsw_sp_fid *fid) static void mlxsw_sp_fid_8021q_setup(struct mlxsw_sp_fid *fid, const void *arg) { - struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; u16 vid = *(u16 *) arg; mlxsw_sp_fid_8021q_fid(fid)->vid = vid; - - if (mlxsw_sp->ubridge) - fid->fid_offset = fid->fid_index - fid->fid_family->start_index; - else - fid->fid_offset = 0; + fid->fid_offset = fid->fid_index - fid->fid_family->start_index; } static enum mlxsw_reg_sfmr_op mlxsw_sp_sfmr_op(bool valid) @@ -455,22 +431,15 @@ static enum mlxsw_reg_sfmr_op mlxsw_sp_sfmr_op(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; - enum mlxsw_reg_bridge_type bridge_type = 0; char sfmr_pl[MLXSW_REG_SFMR_LEN]; - bool smpe_valid = false; - bool flood_rsp = false; - u16 smpe = 0; - - if (mlxsw_sp->ubridge) { - flood_rsp = fid->fid_family->flood_rsp; - bridge_type = fid->fid_family->bridge_type; - smpe_valid = fid->fid_family->smpe_index_valid; - smpe = smpe_valid ? fid->fid_index : 0; - } + u16 smpe; + + smpe = fid->fid_family->smpe_index_valid ? fid->fid_index : 0; mlxsw_reg_sfmr_pack(sfmr_pl, mlxsw_sp_sfmr_op(valid), fid->fid_index, - fid->fid_offset, flood_rsp, bridge_type, smpe_valid, - smpe); + fid->fid_offset, fid->fid_family->flood_rsp, + fid->fid_family->bridge_type, + fid->fid_family->smpe_index_valid, smpe); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfmr), sfmr_pl); } @@ -478,28 +447,22 @@ static int mlxsw_sp_fid_edit_op(const struct mlxsw_sp_fid *fid, const struct mlxsw_sp_rif *rif) { struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; - enum mlxsw_reg_bridge_type bridge_type = 0; char sfmr_pl[MLXSW_REG_SFMR_LEN]; - bool smpe_valid = false; - bool flood_rsp = false; - u16 smpe = 0; - - if (mlxsw_sp->ubridge) { - flood_rsp = fid->fid_family->flood_rsp; - bridge_type = fid->fid_family->bridge_type; - smpe_valid = fid->fid_family->smpe_index_valid; - smpe = smpe_valid ? fid->fid_index : 0; - } + u16 smpe; + + smpe = fid->fid_family->smpe_index_valid ? fid->fid_index : 0; mlxsw_reg_sfmr_pack(sfmr_pl, MLXSW_REG_SFMR_OP_CREATE_FID, - fid->fid_index, fid->fid_offset, flood_rsp, - bridge_type, smpe_valid, smpe); + fid->fid_index, fid->fid_offset, + fid->fid_family->flood_rsp, + fid->fid_family->bridge_type, + fid->fid_family->smpe_index_valid, smpe); 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); - if (mlxsw_sp->ubridge && rif) { + if (rif) { mlxsw_reg_sfmr_irif_v_set(sfmr_pl, true); mlxsw_reg_sfmr_irif_set(sfmr_pl, mlxsw_sp_rif_index(rif)); } @@ -722,11 +685,6 @@ int mlxsw_sp_fid_rif_set(struct mlxsw_sp_fid *fid, struct mlxsw_sp_rif *rif) u16 rif_index = mlxsw_sp_rif_index(rif); int err; - if (!fid->fid_family->mlxsw_sp->ubridge) { - fid->rif = rif; - return 0; - } - err = mlxsw_sp_fid_to_fid_rif_update(fid, rif); if (err) return err; @@ -759,11 +717,6 @@ void mlxsw_sp_fid_rif_unset(struct mlxsw_sp_fid *fid) { u16 rif_index; - if (!fid->fid_family->mlxsw_sp->ubridge) { - fid->rif = NULL; - return; - } - if (!fid->rif) return; @@ -778,15 +731,11 @@ void mlxsw_sp_fid_rif_unset(struct mlxsw_sp_fid *fid) static int mlxsw_sp_fid_vni_op(const struct mlxsw_sp_fid *fid) { - struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; int err; - if (mlxsw_sp->ubridge) { - err = mlxsw_sp_fid_vni_to_fid_map(fid, fid->rif, - fid->vni_valid); - if (err) - return err; - } + err = mlxsw_sp_fid_vni_to_fid_map(fid, fid->rif, fid->vni_valid); + if (err) + return err; err = mlxsw_sp_fid_edit_op(fid, fid->rif); if (err) @@ -795,8 +744,7 @@ static int mlxsw_sp_fid_vni_op(const struct mlxsw_sp_fid *fid) return 0; err_fid_edit_op: - if (mlxsw_sp->ubridge) - mlxsw_sp_fid_vni_to_fid_map(fid, fid->rif, !fid->vni_valid); + mlxsw_sp_fid_vni_to_fid_map(fid, fid->rif, !fid->vni_valid); return err; } @@ -808,7 +756,7 @@ static int __mlxsw_sp_fid_port_vid_map(const struct mlxsw_sp_fid *fid, bool irif_valid = false; u16 irif_index = 0; - if (mlxsw_sp->ubridge && fid->rif) { + if (fid->rif) { irif_valid = true; irif_index = mlxsw_sp_rif_index(fid->rif); } @@ -826,15 +774,10 @@ mlxsw_sp_fid_8021d_fid(const struct mlxsw_sp_fid *fid) static void mlxsw_sp_fid_8021d_setup(struct mlxsw_sp_fid *fid, const void *arg) { - struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; int br_ifindex = *(int *) arg; mlxsw_sp_fid_8021d_fid(fid)->br_ifindex = br_ifindex; - - if (mlxsw_sp->ubridge) - fid->fid_offset = fid->fid_index - fid->fid_family->start_index; - else - fid->fid_offset = 0; + fid->fid_offset = fid->fid_index - fid->fid_family->start_index; } static int mlxsw_sp_fid_8021d_configure(struct mlxsw_sp_fid *fid) @@ -1048,11 +991,9 @@ 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_evid_map(fid, local_port, vid, true); - if (err) - goto err_fid_evid_map; - } + err = mlxsw_sp_fid_evid_map(fid, local_port, vid, true); + if (err) + goto err_fid_evid_map; err = mlxsw_sp_fid_port_vid_list_add(fid, mlxsw_sp_port->local_port, vid); @@ -1071,8 +1012,7 @@ 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_evid_map(fid, local_port, vid, false); + mlxsw_sp_fid_evid_map(fid, local_port, vid, false); err_fid_evid_map: __mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid, false); return err; @@ -1089,8 +1029,7 @@ 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_evid_map(fid, local_port, vid, false); + mlxsw_sp_fid_evid_map(fid, local_port, vid, false); __mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid, false); } @@ -1150,24 +1089,6 @@ static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_8021d_ops = { #define MLXSW_SP_FID_8021Q_PGT_BASE 0 #define MLXSW_SP_FID_8021D_PGT_BASE (3 * MLXSW_SP_FID_8021Q_MAX) -static const struct mlxsw_sp_flood_table mlxsw_sp_fid_8021d_flood_tables[] = { - { - .packet_type = MLXSW_SP_FLOOD_TYPE_UC, - .table_type = MLXSW_REG_SFGC_TABLE_TYPE_FID, - .table_index = 0, - }, - { - .packet_type = MLXSW_SP_FLOOD_TYPE_MC, - .table_type = MLXSW_REG_SFGC_TABLE_TYPE_FID, - .table_index = 1, - }, - { - .packet_type = MLXSW_SP_FLOOD_TYPE_BC, - .table_type = MLXSW_REG_SFGC_TABLE_TYPE_FID, - .table_index = 2, - }, -}; - static const struct mlxsw_sp_flood_table mlxsw_sp_fid_8021d_ub_flood_tables[] = { { .packet_type = MLXSW_SP_FLOOD_TYPE_UC, @@ -1186,20 +1107,6 @@ static const struct mlxsw_sp_flood_table mlxsw_sp_fid_8021d_ub_flood_tables[] = }, }; -/* Range and flood configuration must match mlxsw_config_profile */ -static const struct mlxsw_sp_fid_family mlxsw_sp_fid_8021d_family = { - .type = MLXSW_SP_FID_TYPE_8021D, - .fid_size = sizeof(struct mlxsw_sp_fid_8021d), - .start_index = VLAN_N_VID, - .end_index = VLAN_N_VID + MLXSW_SP_FID_8021D_MAX - 1, - .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_FID, - .ops = &mlxsw_sp_fid_8021d_ops, - .bridge_type = MLXSW_REG_BRIDGE_TYPE_1, - .pgt_base = MLXSW_SP_FID_8021D_PGT_BASE, -}; - static bool mlxsw_sp_fid_8021q_compare(const struct mlxsw_sp_fid *fid, const void *arg) { @@ -1215,41 +1122,6 @@ mlxsw_sp_fid_8021q_fdb_clear_offload(const struct mlxsw_sp_fid *fid, br_fdb_clear_offload(nve_dev, mlxsw_sp_fid_8021q_vid(fid)); } -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, - .fdb_clear_offload = mlxsw_sp_fid_8021q_fdb_clear_offload, -}; - -/* 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 + \ - MLXSW_SP_FID_8021Q_MAX - 1) - -/* 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_EMU, - .ops = &mlxsw_sp_fid_8021q_emu_ops, - .bridge_type = MLXSW_REG_BRIDGE_TYPE_1, - .pgt_base = MLXSW_SP_FID_8021Q_PGT_BASE, -}; - static void mlxsw_sp_fid_rfid_setup(struct mlxsw_sp_fid *fid, const void *arg) { fid->fid_offset = 0; @@ -1257,23 +1129,12 @@ static void mlxsw_sp_fid_rfid_setup(struct mlxsw_sp_fid *fid, const void *arg) static int mlxsw_sp_fid_rfid_configure(struct mlxsw_sp_fid *fid) { - struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; - - /* rFIDs are allocated by the device during init using legacy - * bridge model. - */ - if (mlxsw_sp->ubridge) - return mlxsw_sp_fid_op(fid, true); - - return 0; + return mlxsw_sp_fid_op(fid, true); } static void mlxsw_sp_fid_rfid_deconfigure(struct mlxsw_sp_fid *fid) { - struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; - - if (mlxsw_sp->ubridge) - mlxsw_sp_fid_op(fid, false); + mlxsw_sp_fid_op(fid, false); } static int mlxsw_sp_fid_rfid_index_alloc(struct mlxsw_sp_fid *fid, @@ -1312,20 +1173,16 @@ static int mlxsw_sp_fid_rfid_port_vid_map(struct mlxsw_sp_fid *fid, * RIF creation. Using unified bridge model, we need to map * {Port, VID} => FID and map egress VID. */ - if (mlxsw_sp->ubridge) { - err = __mlxsw_sp_fid_port_vid_map(fid, - mlxsw_sp_port->local_port, - vid, true); + err = __mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid, + true); + if (err) + goto err_port_vid_map; + + if (fid->rif) { + err = mlxsw_sp_fid_erif_eport_to_vid_map_one(fid, local_port, + vid, true); if (err) - goto err_port_vid_map; - - if (fid->rif) { - err = mlxsw_sp_fid_erif_eport_to_vid_map_one(fid, - local_port, - vid, true); - if (err) - goto err_erif_eport_to_vid_map_one; - } + goto err_erif_eport_to_vid_map_one; } if (mlxsw_sp->fid_core->port_fid_mappings[local_port]++ == 0) { @@ -1338,13 +1195,11 @@ 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]--; - if (mlxsw_sp->ubridge && fid->rif) + if (fid->rif) mlxsw_sp_fid_erif_eport_to_vid_map_one(fid, local_port, vid, false); err_erif_eport_to_vid_map_one: - if (mlxsw_sp->ubridge) - __mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid, - false); + __mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid, false); err_port_vid_map: mlxsw_sp_fid_port_vid_list_del(fid, mlxsw_sp_port->local_port, vid); return err; @@ -1361,14 +1216,10 @@ mlxsw_sp_fid_rfid_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]--; - if (mlxsw_sp->ubridge) { - if (fid->rif) - mlxsw_sp_fid_erif_eport_to_vid_map_one(fid, local_port, - vid, false); - __mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid, - false); - } - + if (fid->rif) + mlxsw_sp_fid_erif_eport_to_vid_map_one(fid, local_port, vid, + false); + __mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port->local_port, vid, false); mlxsw_sp_fid_port_vid_list_del(fid, mlxsw_sp_port->local_port, vid); } @@ -1414,19 +1265,6 @@ static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_rfid_ops = { .vid_to_fid_rif_update = mlxsw_sp_fid_rfid_vid_to_fid_rif_update, }; -#define MLXSW_SP_RFID_BASE (15 * 1024) -#define MLXSW_SP_RFID_MAX 1024 - -static const struct mlxsw_sp_fid_family mlxsw_sp_fid_rfid_family = { - .type = MLXSW_SP_FID_TYPE_RFID, - .fid_size = sizeof(struct mlxsw_sp_fid), - .start_index = MLXSW_SP_RFID_BASE, - .end_index = MLXSW_SP_RFID_BASE + MLXSW_SP_RFID_MAX - 1, - .rif_type = MLXSW_SP_RIF_TYPE_SUBPORT, - .ops = &mlxsw_sp_fid_rfid_ops, - .flood_rsp = true, -}; - static void mlxsw_sp_fid_dummy_setup(struct mlxsw_sp_fid *fid, const void *arg) { fid->fid_offset = 0; @@ -1488,14 +1326,6 @@ static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_dummy_ops = { .nve_flood_index_clear = mlxsw_sp_fid_dummy_nve_flood_index_clear, }; -static const struct mlxsw_sp_fid_family mlxsw_sp_fid_dummy_family = { - .type = MLXSW_SP_FID_TYPE_DUMMY, - .fid_size = sizeof(struct mlxsw_sp_fid), - .start_index = VLAN_N_VID - 1, - .end_index = VLAN_N_VID - 1, - .ops = &mlxsw_sp_fid_dummy_ops, -}; - static int mlxsw_sp_fid_8021q_configure(struct mlxsw_sp_fid *fid) { struct mlxsw_sp_fid_8021q *fid_8021q = mlxsw_sp_fid_8021q_fid(fid); @@ -1612,7 +1442,7 @@ static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_8021q_ops = { MLXSW_SP_FID_RFID_UB_MAX - 1) static const struct mlxsw_sp_fid_family mlxsw_sp1_fid_8021q_ub_family = { - .type = MLXSW_SP_FID_TYPE_8021Q_UB, + .type = MLXSW_SP_FID_TYPE_8021Q, .fid_size = sizeof(struct mlxsw_sp_fid_8021q), .start_index = MLXSW_SP_FID_8021Q_UB_START, .end_index = MLXSW_SP_FID_8021Q_UB_END, @@ -1624,11 +1454,10 @@ static const struct mlxsw_sp_fid_family mlxsw_sp1_fid_8021q_ub_family = { .bridge_type = MLXSW_REG_BRIDGE_TYPE_0, .pgt_base = MLXSW_SP_FID_8021Q_PGT_BASE, .smpe_index_valid = false, - .ubridge = true, }; static const struct mlxsw_sp_fid_family mlxsw_sp1_fid_8021d_ub_family = { - .type = MLXSW_SP_FID_TYPE_8021D_UB, + .type = MLXSW_SP_FID_TYPE_8021D, .fid_size = sizeof(struct mlxsw_sp_fid_8021d), .start_index = MLXSW_SP_FID_8021D_UB_START, .end_index = MLXSW_SP_FID_8021D_UB_END, @@ -1639,21 +1468,19 @@ static const struct mlxsw_sp_fid_family mlxsw_sp1_fid_8021d_ub_family = { .bridge_type = MLXSW_REG_BRIDGE_TYPE_1, .pgt_base = MLXSW_SP_FID_8021D_PGT_BASE, .smpe_index_valid = false, - .ubridge = true, }; static const struct mlxsw_sp_fid_family mlxsw_sp1_fid_dummy_ub_family = { - .type = MLXSW_SP_FID_TYPE_DUMMY_UB, + .type = MLXSW_SP_FID_TYPE_DUMMY, .fid_size = sizeof(struct mlxsw_sp_fid), .start_index = MLXSW_SP_FID_DUMMY_UB, .end_index = MLXSW_SP_FID_DUMMY_UB, .ops = &mlxsw_sp_fid_dummy_ops, .smpe_index_valid = false, - .ubridge = true, }; static const struct mlxsw_sp_fid_family mlxsw_sp_fid_rfid_ub_family = { - .type = MLXSW_SP_FID_TYPE_RFID_UB, + .type = MLXSW_SP_FID_TYPE_RFID, .fid_size = sizeof(struct mlxsw_sp_fid), .start_index = MLXSW_SP_RFID_UB_START, .end_index = MLXSW_SP_RFID_UB_END, @@ -1661,23 +1488,17 @@ static const struct mlxsw_sp_fid_family mlxsw_sp_fid_rfid_ub_family = { .ops = &mlxsw_sp_fid_rfid_ops, .flood_rsp = true, .smpe_index_valid = false, - .ubridge = true, }; 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, - - [MLXSW_SP_FID_TYPE_8021Q_UB] = &mlxsw_sp1_fid_8021q_ub_family, - [MLXSW_SP_FID_TYPE_8021D_UB] = &mlxsw_sp1_fid_8021d_ub_family, - [MLXSW_SP_FID_TYPE_DUMMY_UB] = &mlxsw_sp1_fid_dummy_ub_family, - [MLXSW_SP_FID_TYPE_RFID_UB] = &mlxsw_sp_fid_rfid_ub_family, + [MLXSW_SP_FID_TYPE_8021Q] = &mlxsw_sp1_fid_8021q_ub_family, + [MLXSW_SP_FID_TYPE_8021D] = &mlxsw_sp1_fid_8021d_ub_family, + [MLXSW_SP_FID_TYPE_DUMMY] = &mlxsw_sp1_fid_dummy_ub_family, + [MLXSW_SP_FID_TYPE_RFID] = &mlxsw_sp_fid_rfid_ub_family, }; static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_8021q_ub_family = { - .type = MLXSW_SP_FID_TYPE_8021Q_UB, + .type = MLXSW_SP_FID_TYPE_8021Q, .fid_size = sizeof(struct mlxsw_sp_fid_8021q), .start_index = MLXSW_SP_FID_8021Q_UB_START, .end_index = MLXSW_SP_FID_8021Q_UB_END, @@ -1689,11 +1510,10 @@ static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_8021q_ub_family = { .bridge_type = MLXSW_REG_BRIDGE_TYPE_0, .pgt_base = MLXSW_SP_FID_8021Q_PGT_BASE, .smpe_index_valid = true, - .ubridge = true, }; static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_8021d_ub_family = { - .type = MLXSW_SP_FID_TYPE_8021D_UB, + .type = MLXSW_SP_FID_TYPE_8021D, .fid_size = sizeof(struct mlxsw_sp_fid_8021d), .start_index = MLXSW_SP_FID_8021D_UB_START, .end_index = MLXSW_SP_FID_8021D_UB_END, @@ -1704,29 +1524,22 @@ static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_8021d_ub_family = { .bridge_type = MLXSW_REG_BRIDGE_TYPE_1, .pgt_base = MLXSW_SP_FID_8021D_PGT_BASE, .smpe_index_valid = true, - .ubridge = true, }; static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_dummy_ub_family = { - .type = MLXSW_SP_FID_TYPE_DUMMY_UB, + .type = MLXSW_SP_FID_TYPE_DUMMY, .fid_size = sizeof(struct mlxsw_sp_fid), .start_index = MLXSW_SP_FID_DUMMY_UB, .end_index = MLXSW_SP_FID_DUMMY_UB, .ops = &mlxsw_sp_fid_dummy_ops, .smpe_index_valid = false, - .ubridge = true, }; 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, - [MLXSW_SP_FID_TYPE_DUMMY] = &mlxsw_sp_fid_dummy_family, - - [MLXSW_SP_FID_TYPE_8021Q_UB] = &mlxsw_sp2_fid_8021q_ub_family, - [MLXSW_SP_FID_TYPE_8021D_UB] = &mlxsw_sp2_fid_8021d_ub_family, - [MLXSW_SP_FID_TYPE_DUMMY_UB] = &mlxsw_sp2_fid_dummy_ub_family, - [MLXSW_SP_FID_TYPE_RFID_UB] = &mlxsw_sp_fid_rfid_ub_family, + [MLXSW_SP_FID_TYPE_8021Q] = &mlxsw_sp2_fid_8021q_ub_family, + [MLXSW_SP_FID_TYPE_8021D] = &mlxsw_sp2_fid_8021d_ub_family, + [MLXSW_SP_FID_TYPE_DUMMY] = &mlxsw_sp2_fid_dummy_ub_family, + [MLXSW_SP_FID_TYPE_RFID] = &mlxsw_sp_fid_rfid_ub_family, }; static struct mlxsw_sp_fid *mlxsw_sp_fid_lookup(struct mlxsw_sp *mlxsw_sp, @@ -1858,8 +1671,8 @@ mlxsw_sp_fid_flood_table_init(struct mlxsw_sp_fid_family *fid_family, { enum mlxsw_sp_flood_type packet_type = flood_table->packet_type; struct mlxsw_sp *mlxsw_sp = fid_family->mlxsw_sp; - u16 mid_base, num_fids, table_index; const int *sfgc_packet_types; + u16 num_fids, mid_base; int err, i; mid_base = mlxsw_sp_fid_flood_table_mid(fid_family, flood_table, 0); @@ -1875,12 +1688,8 @@ mlxsw_sp_fid_flood_table_init(struct mlxsw_sp_fid_family *fid_family, if (!sfgc_packet_types[i]) continue; - mid_base = mlxsw_sp->ubridge ? mid_base : 0; - table_index = mlxsw_sp->ubridge ? 0 : flood_table->table_index; - mlxsw_reg_sfgc_pack(sfgc_pl, i, fid_family->bridge_type, - flood_table->table_type, table_index, - mid_base); + flood_table->table_type, 0, mid_base); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfgc), sfgc_pl); if (err) @@ -1890,7 +1699,6 @@ mlxsw_sp_fid_flood_table_init(struct mlxsw_sp_fid_family *fid_family, return 0; err_reg_write: - mid_base = mlxsw_sp_fid_flood_table_mid(fid_family, flood_table, 0); mlxsw_sp_pgt_mid_free_range(mlxsw_sp, mid_base, num_fids); return err; } @@ -2035,9 +1843,6 @@ int mlxsw_sp_fids_init(struct mlxsw_sp *mlxsw_sp) } for (i = 0; i < MLXSW_SP_FID_TYPE_MAX; i++) { - if (mlxsw_sp->ubridge != mlxsw_sp->fid_family_arr[i]->ubridge) - continue; - err = mlxsw_sp_fid_family_register(mlxsw_sp, mlxsw_sp->fid_family_arr[i]); @@ -2052,9 +1857,6 @@ int mlxsw_sp_fids_init(struct mlxsw_sp *mlxsw_sp) struct mlxsw_sp_fid_family *fid_family; fid_family = fid_core->fid_family_arr[i]; - if (mlxsw_sp->ubridge != fid_family->ubridge) - continue; - mlxsw_sp_fid_family_unregister(mlxsw_sp, fid_family); } kfree(fid_core->port_fid_mappings); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_pgt.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_pgt.c index e6bbe08ef3791a..7dd3dba0fa8314 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_pgt.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_pgt.c @@ -182,16 +182,6 @@ static void mlxsw_sp_pgt_entry_put(struct mlxsw_sp_pgt *pgt, u16 mid) mlxsw_sp_pgt_entry_destroy(pgt, pgt_entry); } -#define MLXSW_SP_FID_PGT_FLOOD_ENTRIES 15354 /* Reserved for flooding. */ - -u16 mlxsw_sp_pgt_index_to_mid(const struct mlxsw_sp *mlxsw_sp, u16 pgt_index) -{ - if (mlxsw_sp->ubridge) - return pgt_index; - - return pgt_index - MLXSW_SP_FID_PGT_FLOOD_ENTRIES; -} - static void mlxsw_sp_pgt_smid2_port_set(char *smid2_pl, u16 local_port, bool member) { @@ -204,21 +194,16 @@ mlxsw_sp_pgt_entry_port_write(struct mlxsw_sp *mlxsw_sp, const struct mlxsw_sp_pgt_entry *pgt_entry, u16 local_port, bool member) { - bool smpe_index_valid; char *smid2_pl; - u16 smpe, mid; int err; smid2_pl = kmalloc(MLXSW_REG_SMID2_LEN, GFP_KERNEL); if (!smid2_pl) return -ENOMEM; - smpe_index_valid = mlxsw_sp->ubridge ? mlxsw_sp->pgt->smpe_index_valid : - false; - smpe = mlxsw_sp->ubridge ? pgt_entry->smpe_index : 0; - mid = mlxsw_sp_pgt_index_to_mid(mlxsw_sp, pgt_entry->index); - - mlxsw_reg_smid2_pack(smid2_pl, mid, 0, 0, smpe_index_valid, smpe); + mlxsw_reg_smid2_pack(smid2_pl, pgt_entry->index, 0, 0, + mlxsw_sp->pgt->smpe_index_valid, + pgt_entry->smpe_index); mlxsw_sp_pgt_smid2_port_set(smid2_pl, local_port, member); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(smid2), smid2_pl); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index aeaba07c17b085..09009e80cd7169 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -7730,8 +7730,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_EMU && - rif->ops->type != MLXSW_SP_RIF_TYPE_VLAN) + if (rif->ops->type != MLXSW_SP_RIF_TYPE_VLAN) goto out; vid = mlxsw_sp_fid_8021q_vid(rif->fid); @@ -9324,13 +9323,11 @@ static int mlxsw_sp_rif_subport_op(struct mlxsw_sp_rif *rif, bool enable) rif->rif_index, rif->vr_id, 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); - efid = mlxsw_sp->ubridge ? mlxsw_sp_fid_index(rif->fid) : 0; + efid = mlxsw_sp_fid_index(rif->fid); mlxsw_reg_ritr_sp_if_pack(ritr_pl, rif_subport->lag, rif_subport->lag ? rif_subport->lag_id : rif_subport->system_port, - efid, - mlxsw_sp->ubridge ? 0 : rif_subport->vid); - + efid, 0); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl); } @@ -9565,15 +9562,6 @@ static void mlxsw_sp_rif_vlan_fdb_del(struct mlxsw_sp_rif *rif, const char *mac) NULL); } -static const struct mlxsw_sp_rif_ops mlxsw_sp_rif_vlan_emu_ops = { - .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, - .fid_get = mlxsw_sp_rif_vlan_fid_get, - .fdb_del = mlxsw_sp_rif_vlan_fdb_del, -}; - static int mlxsw_sp_rif_vlan_op(struct mlxsw_sp_rif *rif, u16 vid, u16 efid, bool enable) { @@ -9761,7 +9749,6 @@ 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_EMU] = &mlxsw_sp_rif_vlan_emu_ops, [MLXSW_SP_RIF_TYPE_VLAN] = &mlxsw_sp1_rif_vlan_ops, [MLXSW_SP_RIF_TYPE_FID] = &mlxsw_sp_rif_fid_ops, [MLXSW_SP_RIF_TYPE_IPIP_LB] = &mlxsw_sp1_rif_ipip_lb_ops, @@ -9950,7 +9937,6 @@ 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_EMU] = &mlxsw_sp_rif_vlan_emu_ops, [MLXSW_SP_RIF_TYPE_VLAN] = &mlxsw_sp2_rif_vlan_ops, [MLXSW_SP_RIF_TYPE_FID] = &mlxsw_sp_rif_fid_ops, [MLXSW_SP_RIF_TYPE_IPIP_LB] = &mlxsw_sp2_rif_ipip_lb_ops, diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c index fd8f9be2d40141..4efccd942fb89b 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c @@ -1798,7 +1798,6 @@ static int mlxsw_sp_mdb_entry_write(struct mlxsw_sp *mlxsw_sp, bool adding) { char *sfd_pl; - u16 mid_idx; u8 num_rec; int err; @@ -1806,11 +1805,10 @@ static int mlxsw_sp_mdb_entry_write(struct mlxsw_sp *mlxsw_sp, if (!sfd_pl) return -ENOMEM; - mid_idx = mlxsw_sp_pgt_index_to_mid(mlxsw_sp, mdb_entry->mid); mlxsw_reg_sfd_pack(sfd_pl, mlxsw_sp_sfd_op(adding), 0); mlxsw_reg_sfd_mc_pack(sfd_pl, 0, mdb_entry->key.addr, mdb_entry->key.fid, MLXSW_REG_SFD_REC_ACTION_NOP, - mid_idx); + mdb_entry->mid); num_rec = mlxsw_reg_sfd_num_rec_get(sfd_pl); err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfd), sfd_pl); if (err) From 8928fd47782c77c81c9219dfce08e8c768f6c111 Mon Sep 17 00:00:00 2001 From: Amit Cohen Date: Mon, 4 Jul 2022 09:11:38 +0300 Subject: [PATCH 12/13] mlxsw: spectrum_fid: Remove flood_index() from FID operation structure The flood_index() function is not needed anymore, as in the unified bridge model the flood index is calculated using 'mid_base' and 'fid_offset'. Remove this function. Signed-off-by: Amit Cohen Reviewed-by: Petr Machata Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c index 818e458eb3ad3c..da581a792009a2 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c @@ -83,7 +83,6 @@ struct mlxsw_sp_fid_ops { u16 *p_fid_index); bool (*compare)(const struct mlxsw_sp_fid *fid, const void *arg); - u16 (*flood_index)(const struct mlxsw_sp_fid *fid); int (*port_vid_map)(struct mlxsw_sp_fid *fid, struct mlxsw_sp_port *port, u16 vid); void (*port_vid_unmap)(struct mlxsw_sp_fid *fid, @@ -348,11 +347,10 @@ int mlxsw_sp_fid_flood_set(struct mlxsw_sp_fid *fid, bool member) { struct mlxsw_sp_fid_family *fid_family = fid->fid_family; - const struct mlxsw_sp_fid_ops *ops = fid_family->ops; const struct mlxsw_sp_flood_table *flood_table; u16 mid_index; - if (WARN_ON(!fid_family->flood_tables || !ops->flood_index)) + if (WARN_ON(!fid_family->flood_tables)) return -EINVAL; flood_table = mlxsw_sp_fid_flood_table_lookup(fid, packet_type); @@ -815,11 +813,6 @@ mlxsw_sp_fid_8021d_compare(const struct mlxsw_sp_fid *fid, const void *arg) return mlxsw_sp_fid_8021d_fid(fid)->br_ifindex == br_ifindex; } -static u16 mlxsw_sp_fid_8021d_flood_index(const struct mlxsw_sp_fid *fid) -{ - return fid->fid_index - VLAN_N_VID; -} - static int mlxsw_sp_port_vp_mode_trans(struct mlxsw_sp_port *mlxsw_sp_port) { struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan; @@ -1073,7 +1066,6 @@ static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_8021d_ops = { .deconfigure = mlxsw_sp_fid_8021d_deconfigure, .index_alloc = mlxsw_sp_fid_8021d_index_alloc, .compare = mlxsw_sp_fid_8021d_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, From 88840d697f6e01de885f012fb9b21b9c26743346 Mon Sep 17 00:00:00 2001 From: Amit Cohen Date: Mon, 4 Jul 2022 09:11:39 +0300 Subject: [PATCH 13/13] mlxsw: spectrum_fid: Remove '_ub_' indication from structures and defines Some structures and defines were added with '_ub_' indication, as there were equivalent objects for the legacy model. Now when the legacy model is not used anymore, remove the '_ub_' indication. Signed-off-by: Amit Cohen Reviewed-by: Petr Machata Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- .../ethernet/mellanox/mlxsw/spectrum_fid.c | 94 +++++++++---------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c index da581a792009a2..045a24cacfa517 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c @@ -1077,11 +1077,11 @@ static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_8021d_ops = { }; #define MLXSW_SP_FID_8021Q_MAX (VLAN_N_VID - 2) -#define MLXSW_SP_FID_RFID_UB_MAX (11 * 1024) +#define MLXSW_SP_FID_RFID_MAX (11 * 1024) #define MLXSW_SP_FID_8021Q_PGT_BASE 0 #define MLXSW_SP_FID_8021D_PGT_BASE (3 * MLXSW_SP_FID_8021Q_MAX) -static const struct mlxsw_sp_flood_table mlxsw_sp_fid_8021d_ub_flood_tables[] = { +static const struct mlxsw_sp_flood_table mlxsw_sp_fid_8021d_flood_tables[] = { { .packet_type = MLXSW_SP_FLOOD_TYPE_UC, .table_type = MLXSW_REG_SFGC_TABLE_TYPE_FID_OFFSET, @@ -1416,30 +1416,30 @@ static const struct mlxsw_sp_fid_ops mlxsw_sp_fid_8021q_ops = { }; /* There are 4K-2 802.1Q FIDs */ -#define MLXSW_SP_FID_8021Q_UB_START 1 /* FID 0 is reserved. */ -#define MLXSW_SP_FID_8021Q_UB_END (MLXSW_SP_FID_8021Q_UB_START + \ +#define MLXSW_SP_FID_8021Q_START 1 /* FID 0 is reserved. */ +#define MLXSW_SP_FID_8021Q_END (MLXSW_SP_FID_8021Q_START + \ MLXSW_SP_FID_8021Q_MAX - 1) /* There are 1K 802.1D FIDs */ -#define MLXSW_SP_FID_8021D_UB_START (MLXSW_SP_FID_8021Q_UB_END + 1) -#define MLXSW_SP_FID_8021D_UB_END (MLXSW_SP_FID_8021D_UB_START + \ +#define MLXSW_SP_FID_8021D_START (MLXSW_SP_FID_8021Q_END + 1) +#define MLXSW_SP_FID_8021D_END (MLXSW_SP_FID_8021D_START + \ MLXSW_SP_FID_8021D_MAX - 1) /* There is one dummy FID */ -#define MLXSW_SP_FID_DUMMY_UB (MLXSW_SP_FID_8021D_UB_END + 1) +#define MLXSW_SP_FID_DUMMY (MLXSW_SP_FID_8021D_END + 1) /* There are 11K rFIDs */ -#define MLXSW_SP_RFID_UB_START (MLXSW_SP_FID_DUMMY_UB + 1) -#define MLXSW_SP_RFID_UB_END (MLXSW_SP_RFID_UB_START + \ - MLXSW_SP_FID_RFID_UB_MAX - 1) +#define MLXSW_SP_RFID_START (MLXSW_SP_FID_DUMMY + 1) +#define MLXSW_SP_RFID_END (MLXSW_SP_RFID_START + \ + MLXSW_SP_FID_RFID_MAX - 1) -static const struct mlxsw_sp_fid_family mlxsw_sp1_fid_8021q_ub_family = { +static const struct mlxsw_sp_fid_family mlxsw_sp1_fid_8021q_family = { .type = MLXSW_SP_FID_TYPE_8021Q, .fid_size = sizeof(struct mlxsw_sp_fid_8021q), - .start_index = MLXSW_SP_FID_8021Q_UB_START, - .end_index = MLXSW_SP_FID_8021Q_UB_END, - .flood_tables = mlxsw_sp_fid_8021d_ub_flood_tables, - .nr_flood_tables = ARRAY_SIZE(mlxsw_sp_fid_8021d_ub_flood_tables), + .start_index = MLXSW_SP_FID_8021Q_START, + .end_index = MLXSW_SP_FID_8021Q_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_ops, .flood_rsp = false, @@ -1448,13 +1448,13 @@ static const struct mlxsw_sp_fid_family mlxsw_sp1_fid_8021q_ub_family = { .smpe_index_valid = false, }; -static const struct mlxsw_sp_fid_family mlxsw_sp1_fid_8021d_ub_family = { +static const struct mlxsw_sp_fid_family mlxsw_sp1_fid_8021d_family = { .type = MLXSW_SP_FID_TYPE_8021D, .fid_size = sizeof(struct mlxsw_sp_fid_8021d), - .start_index = MLXSW_SP_FID_8021D_UB_START, - .end_index = MLXSW_SP_FID_8021D_UB_END, - .flood_tables = mlxsw_sp_fid_8021d_ub_flood_tables, - .nr_flood_tables = ARRAY_SIZE(mlxsw_sp_fid_8021d_ub_flood_tables), + .start_index = MLXSW_SP_FID_8021D_START, + .end_index = MLXSW_SP_FID_8021D_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_FID, .ops = &mlxsw_sp_fid_8021d_ops, .bridge_type = MLXSW_REG_BRIDGE_TYPE_1, @@ -1462,20 +1462,20 @@ static const struct mlxsw_sp_fid_family mlxsw_sp1_fid_8021d_ub_family = { .smpe_index_valid = false, }; -static const struct mlxsw_sp_fid_family mlxsw_sp1_fid_dummy_ub_family = { +static const struct mlxsw_sp_fid_family mlxsw_sp1_fid_dummy_family = { .type = MLXSW_SP_FID_TYPE_DUMMY, .fid_size = sizeof(struct mlxsw_sp_fid), - .start_index = MLXSW_SP_FID_DUMMY_UB, - .end_index = MLXSW_SP_FID_DUMMY_UB, + .start_index = MLXSW_SP_FID_DUMMY, + .end_index = MLXSW_SP_FID_DUMMY, .ops = &mlxsw_sp_fid_dummy_ops, .smpe_index_valid = false, }; -static const struct mlxsw_sp_fid_family mlxsw_sp_fid_rfid_ub_family = { +static const struct mlxsw_sp_fid_family mlxsw_sp_fid_rfid_family = { .type = MLXSW_SP_FID_TYPE_RFID, .fid_size = sizeof(struct mlxsw_sp_fid), - .start_index = MLXSW_SP_RFID_UB_START, - .end_index = MLXSW_SP_RFID_UB_END, + .start_index = MLXSW_SP_RFID_START, + .end_index = MLXSW_SP_RFID_END, .rif_type = MLXSW_SP_RIF_TYPE_SUBPORT, .ops = &mlxsw_sp_fid_rfid_ops, .flood_rsp = true, @@ -1483,19 +1483,19 @@ static const struct mlxsw_sp_fid_family mlxsw_sp_fid_rfid_ub_family = { }; const struct mlxsw_sp_fid_family *mlxsw_sp1_fid_family_arr[] = { - [MLXSW_SP_FID_TYPE_8021Q] = &mlxsw_sp1_fid_8021q_ub_family, - [MLXSW_SP_FID_TYPE_8021D] = &mlxsw_sp1_fid_8021d_ub_family, - [MLXSW_SP_FID_TYPE_DUMMY] = &mlxsw_sp1_fid_dummy_ub_family, - [MLXSW_SP_FID_TYPE_RFID] = &mlxsw_sp_fid_rfid_ub_family, + [MLXSW_SP_FID_TYPE_8021Q] = &mlxsw_sp1_fid_8021q_family, + [MLXSW_SP_FID_TYPE_8021D] = &mlxsw_sp1_fid_8021d_family, + [MLXSW_SP_FID_TYPE_DUMMY] = &mlxsw_sp1_fid_dummy_family, + [MLXSW_SP_FID_TYPE_RFID] = &mlxsw_sp_fid_rfid_family, }; -static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_8021q_ub_family = { +static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_8021q_family = { .type = MLXSW_SP_FID_TYPE_8021Q, .fid_size = sizeof(struct mlxsw_sp_fid_8021q), - .start_index = MLXSW_SP_FID_8021Q_UB_START, - .end_index = MLXSW_SP_FID_8021Q_UB_END, - .flood_tables = mlxsw_sp_fid_8021d_ub_flood_tables, - .nr_flood_tables = ARRAY_SIZE(mlxsw_sp_fid_8021d_ub_flood_tables), + .start_index = MLXSW_SP_FID_8021Q_START, + .end_index = MLXSW_SP_FID_8021Q_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_ops, .flood_rsp = false, @@ -1504,13 +1504,13 @@ static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_8021q_ub_family = { .smpe_index_valid = true, }; -static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_8021d_ub_family = { +static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_8021d_family = { .type = MLXSW_SP_FID_TYPE_8021D, .fid_size = sizeof(struct mlxsw_sp_fid_8021d), - .start_index = MLXSW_SP_FID_8021D_UB_START, - .end_index = MLXSW_SP_FID_8021D_UB_END, - .flood_tables = mlxsw_sp_fid_8021d_ub_flood_tables, - .nr_flood_tables = ARRAY_SIZE(mlxsw_sp_fid_8021d_ub_flood_tables), + .start_index = MLXSW_SP_FID_8021D_START, + .end_index = MLXSW_SP_FID_8021D_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_FID, .ops = &mlxsw_sp_fid_8021d_ops, .bridge_type = MLXSW_REG_BRIDGE_TYPE_1, @@ -1518,20 +1518,20 @@ static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_8021d_ub_family = { .smpe_index_valid = true, }; -static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_dummy_ub_family = { +static const struct mlxsw_sp_fid_family mlxsw_sp2_fid_dummy_family = { .type = MLXSW_SP_FID_TYPE_DUMMY, .fid_size = sizeof(struct mlxsw_sp_fid), - .start_index = MLXSW_SP_FID_DUMMY_UB, - .end_index = MLXSW_SP_FID_DUMMY_UB, + .start_index = MLXSW_SP_FID_DUMMY, + .end_index = MLXSW_SP_FID_DUMMY, .ops = &mlxsw_sp_fid_dummy_ops, .smpe_index_valid = false, }; const struct mlxsw_sp_fid_family *mlxsw_sp2_fid_family_arr[] = { - [MLXSW_SP_FID_TYPE_8021Q] = &mlxsw_sp2_fid_8021q_ub_family, - [MLXSW_SP_FID_TYPE_8021D] = &mlxsw_sp2_fid_8021d_ub_family, - [MLXSW_SP_FID_TYPE_DUMMY] = &mlxsw_sp2_fid_dummy_ub_family, - [MLXSW_SP_FID_TYPE_RFID] = &mlxsw_sp_fid_rfid_ub_family, + [MLXSW_SP_FID_TYPE_8021Q] = &mlxsw_sp2_fid_8021q_family, + [MLXSW_SP_FID_TYPE_8021D] = &mlxsw_sp2_fid_8021d_family, + [MLXSW_SP_FID_TYPE_DUMMY] = &mlxsw_sp2_fid_dummy_family, + [MLXSW_SP_FID_TYPE_RFID] = &mlxsw_sp_fid_rfid_family, }; static struct mlxsw_sp_fid *mlxsw_sp_fid_lookup(struct mlxsw_sp *mlxsw_sp,