From 8405d6626289160fcd21b0f0c827144556be52be Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Mon, 20 Nov 2023 19:25:18 +0100 Subject: [PATCH 01/14] mlxsw: cmd: Add cmd_mbox.query_fw.cff_support PGT, a port-group table is an in-HW block of specialized memory that holds sets of ports. Allocated within the PGT are series of flood tables that describe to which ports traffic of various types (unknown UC, BC, MC) should be flooded from which FID. The hitherto-used layout of these flood tables is being replaced with a more flexible scheme, called compressed FID flooding (CFF). CFF can be configured through CONFIG_PROFILE.flood_mode. cff_support determines whether CONFIG_PROFILE.flood_mode can be set to CFF. Signed-off-by: Petr Machata Reviewed-by: Amit Cohen Reviewed-by: Ido Schimmel Link: https://lore.kernel.org/r/af727d0e1095e30fa45c7e60404637cdc491aeec.1700503643.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/mellanox/mlxsw/cmd.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/cmd.h b/drivers/net/ethernet/mellanox/mlxsw/cmd.h index e827c78be114..b45c9a04fcc4 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/cmd.h +++ b/drivers/net/ethernet/mellanox/mlxsw/cmd.h @@ -282,6 +282,12 @@ MLXSW_ITEM32(cmd_mbox, query_fw, fw_day, 0x14, 0, 8); */ MLXSW_ITEM32(cmd_mbox, query_fw, lag_mode_support, 0x18, 1, 1); +/* cmd_mbox_query_fw_cff_support + * 0: CONFIG_PROFILE.flood_mode = 5 (CFF) is not supported by FW + * 1: CONFIG_PROFILE.flood_mode = 5 (CFF) is supported by FW + */ +MLXSW_ITEM32(cmd_mbox, query_fw, cff_support, 0x18, 2, 1); + /* cmd_mbox_query_fw_clr_int_base_offset * Clear Interrupt register's offset from clr_int_bar register * in PCI address space. From 50ee67789b823ffb052f3be20349c05c30bee2e6 Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Mon, 20 Nov 2023 19:25:19 +0100 Subject: [PATCH 02/14] mlxsw: cmd: Add MLXSW_CMD_MBOX_CONFIG_PROFILE_FLOOD_MODE_CFF PGT, a port-group table is an in-HW block of specialized memory that holds sets of ports. Allocated within the PGT are series of flood tables that describe to which ports traffic of various types (unknown UC, BC, MC) should be flooded from which FID. The hitherto-used layout of these flood tables is being replaced with a more flexible scheme, called compressed FID flooding (CFF). CFF can be configured through CONFIG_PROFILE.flood_mode. In this patch, add MLXSW_CMD_MBOX_CONFIG_PROFILE_FLOOD_MODE_CFF, the value to use to enable the CFF mode. Signed-off-by: Petr Machata Reviewed-by: Amit Cohen Reviewed-by: Ido Schimmel Link: https://lore.kernel.org/r/fc2e063742856492f8f22b0b87abf431ea6d53d0.1700503643.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/mellanox/mlxsw/cmd.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/cmd.h b/drivers/net/ethernet/mellanox/mlxsw/cmd.h index b45c9a04fcc4..e3271c845ee6 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/cmd.h +++ b/drivers/net/ethernet/mellanox/mlxsw/cmd.h @@ -785,6 +785,11 @@ enum mlxsw_cmd_mbox_config_profile_flood_mode { * used. */ MLXSW_CMD_MBOX_CONFIG_PROFILE_FLOOD_MODE_CONTROLLED = 4, + /* CFF - Compressed FID Flood (CFF) mode. + * Reserved when legacy bridge model is used. + * Supported only by Spectrum-2+. + */ + MLXSW_CMD_MBOX_CONFIG_PROFILE_FLOOD_MODE_CFF = 5, }; /* cmd_mbox_config_profile_flood_mode From 2d19da9277199ec69b555ca32042be2a7cd493c6 Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Mon, 20 Nov 2023 19:25:20 +0100 Subject: [PATCH 03/14] mlxsw: resources: Add max_cap_nve_flood_prf max_cap_nve_flood_prf describes maximum number of NVE flooding profiles. The same value then applies for flooding profiles for flooding in CFF mode. Signed-off-by: Petr Machata Reviewed-by: Amit Cohen Reviewed-by: Ido Schimmel Link: https://lore.kernel.org/r/064a2e013d879e5f5494167a6c120c4bb85a2204.1700503643.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/mellanox/mlxsw/resources.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/resources.h b/drivers/net/ethernet/mellanox/mlxsw/resources.h index 89dd2777ec4d..9d7977ebe186 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/resources.h +++ b/drivers/net/ethernet/mellanox/mlxsw/resources.h @@ -27,6 +27,7 @@ enum mlxsw_res_id { MLXSW_RES_ID_FID, MLXSW_RES_ID_MAX_LAG, MLXSW_RES_ID_MAX_LAG_MEMBERS, + MLXSW_RES_ID_MAX_NVE_FLOOD_PRF, MLXSW_RES_ID_GUARANTEED_SHARED_BUFFER, MLXSW_RES_ID_CELL_SIZE, MLXSW_RES_ID_MAX_HEADROOM_SIZE, @@ -88,6 +89,7 @@ static u16 mlxsw_res_ids[] = { [MLXSW_RES_ID_FID] = 0x2512, [MLXSW_RES_ID_MAX_LAG] = 0x2520, [MLXSW_RES_ID_MAX_LAG_MEMBERS] = 0x2521, + [MLXSW_RES_ID_MAX_NVE_FLOOD_PRF] = 0x2522, [MLXSW_RES_ID_GUARANTEED_SHARED_BUFFER] = 0x2805, /* Bytes */ [MLXSW_RES_ID_CELL_SIZE] = 0x2803, /* Bytes */ [MLXSW_RES_ID_MAX_HEADROOM_SIZE] = 0x2811, /* Bytes */ From e1e4ce6c6d54ff206e55bd8c89c00bfee891458c Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Mon, 20 Nov 2023 19:25:21 +0100 Subject: [PATCH 04/14] mlxsw: reg: Add Switch FID Flooding Profiles Register The SFFP register populates the fid flooding profile tables used for the NVE flooding and Compressed-FID Flooding (CFF). Signed-off-by: Petr Machata Reviewed-by: Amit Cohen Reviewed-by: Ido Schimmel Link: https://lore.kernel.org/r/ca42eb67763bd0c7cf035afc62ef73632f3f61a6.1700503643.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/mellanox/mlxsw/reg.h | 45 +++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index e26e9d06bd72..3472f70b2482 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -2168,6 +2168,50 @@ static inline void mlxsw_reg_spvc_pack(char *payload, u16 local_port, bool et1, mlxsw_reg_spvc_et0_set(payload, et0); } +/* SFFP - Switch FID Flooding Profiles Register + * -------------------------------------------- + * The SFFP register populates the fid flooding profile tables used for the NVE + * flooding and Compressed-FID Flooding (CFF). + * + * Reserved on Spectrum-1. + */ +#define MLXSW_REG_SFFP_ID 0x2029 +#define MLXSW_REG_SFFP_LEN 0x0C + +MLXSW_REG_DEFINE(sffp, MLXSW_REG_SFFP_ID, MLXSW_REG_SFFP_LEN); + +/* reg_sffp_profile_id + * Profile ID a.k.a. SFMR.nve_flood_prf_id or SFMR.cff_prf_id + * Range 0..max_cap_nve_flood_prf-1 + * Access: Index + */ +MLXSW_ITEM32(reg, sffp, profile_id, 0x00, 16, 2); + +/* reg_sffp_type + * The traffic type to reach the flooding table. + * Same as SFGC.type + * Access: Index + */ +MLXSW_ITEM32(reg, sffp, type, 0x00, 0, 4); + +/* reg_sffp_flood_offset + * Flood offset. Offset to add to SFMR.cff_mid_base to get the final PGT address + * for FID flood; or offset to add to SFMR.nve_tunnel_flood_ptr to get KVD + * pointer for NVE underlay. + * Access: RW + */ +MLXSW_ITEM32(reg, sffp, flood_offset, 0x04, 0, 3); + +static inline void mlxsw_reg_sffp_pack(char *payload, u8 profile_id, + enum mlxsw_reg_sfgc_type type, + u8 flood_offset) +{ + MLXSW_REG_ZERO(sffp, payload); + mlxsw_reg_sffp_profile_id_set(payload, profile_id); + mlxsw_reg_sffp_type_set(payload, type); + mlxsw_reg_sffp_flood_offset_set(payload, flood_offset); +} + /* SPEVET - Switch Port Egress VLAN EtherType * ------------------------------------------ * The switch port egress VLAN EtherType configures which EtherType to push at @@ -12946,6 +12990,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = { MLXSW_REG(spvmlr), MLXSW_REG(spfsr), MLXSW_REG(spvc), + MLXSW_REG(sffp), MLXSW_REG(spevet), MLXSW_REG(smpe), MLXSW_REG(smid2), From 7eb902954b624ee338303ad735235429e036b31b Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Mon, 20 Nov 2023 19:25:22 +0100 Subject: [PATCH 05/14] mlxsw: reg: Mark SFGC & some SFMR fields as reserved in CFF mode Some existing fields and the whole register of SFGC are reserved in CFF mode. Backport the reservation note to these fields. Signed-off-by: Petr Machata Reviewed-by: Amit Cohen Reviewed-by: Ido Schimmel Link: https://lore.kernel.org/r/e1d5977a8cb778227e4ea2fd1515529957ce5de7.1700503643.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/mellanox/mlxsw/reg.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index 3472f70b2482..ec0adddd4598 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -1024,6 +1024,8 @@ static inline void mlxsw_reg_spaft_pack(char *payload, u16 local_port, * ------------------------------------------ * The following register controls the association of flooding tables and MIDs * to packet types used for flooding. + * + * Reserved when CONFIG_PROFILE.flood_mode = CFF. */ #define MLXSW_REG_SFGC_ID 0x2011 #define MLXSW_REG_SFGC_LEN 0x14 @@ -1862,6 +1864,7 @@ MLXSW_ITEM32(reg, sfmr, fid, 0x00, 0, 16); * Access: RW * * Note: Reserved when legacy bridge model is used. + * Reserved when CONFIG_PROFILE.flood_mode = CFF. */ MLXSW_ITEM32(reg, sfmr, flood_rsp, 0x08, 31, 1); @@ -1872,6 +1875,7 @@ MLXSW_ITEM32(reg, sfmr, flood_rsp, 0x08, 31, 1); * Access: RW * * Note: Reserved when legacy bridge model is used and when flood_rsp=1. + * Reserved when CONFIG_PROFILE.flood_mode = CFF */ MLXSW_ITEM32(reg, sfmr, flood_bridge_type, 0x08, 28, 1); @@ -1880,6 +1884,8 @@ MLXSW_ITEM32(reg, sfmr, flood_bridge_type, 0x08, 28, 1); * Used to point into the flooding table selected by SFGC register if * the table is of type FID-Offset. Otherwise, this field is reserved. * Access: RW + * + * Note: Reserved when CONFIG_PROFILE.flood_mode = CFF */ MLXSW_ITEM32(reg, sfmr, fid_offset, 0x08, 0, 16); From 642d6a2033d85797e0f8807d0e48bb007d5e73ca Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Mon, 20 Nov 2023 19:25:23 +0100 Subject: [PATCH 06/14] mlxsw: reg: Drop unnecessary writes from mlxsw_reg_sfmr_pack() The MLXSW_REG_ZERO at the beginning of the function wipes the whole payload. There's no need to set vtfp and vv to false explicitly. Signed-off-by: Petr Machata Reviewed-by: Amit Cohen Reviewed-by: Ido Schimmel Link: https://lore.kernel.org/r/04a51ea7cf31eea0ef7707311d8e864e2d9ef307.1700503644.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/mellanox/mlxsw/reg.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index ec0adddd4598..e8f7a4741bd3 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -1973,8 +1973,6 @@ static inline void mlxsw_reg_sfmr_pack(char *payload, mlxsw_reg_sfmr_op_set(payload, op); mlxsw_reg_sfmr_fid_set(payload, fid); mlxsw_reg_sfmr_fid_offset_set(payload, fid_offset); - mlxsw_reg_sfmr_vtfp_set(payload, false); - 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); From 446bc1e9dec63b419751b8bdecba06fee631672e Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Mon, 20 Nov 2023 19:25:24 +0100 Subject: [PATCH 07/14] mlxsw: reg: Extract flood-mode specific part of mlxsw_reg_sfmr_pack() In CFF mode, it is necessary to set a different set of SFMR fields. Leave in mlxsw_reg_sfmr_pack() only the common bits, and move the parts relevant to controlled flood mode directly to the call site. Signed-off-by: Petr Machata Reviewed-by: Amit Cohen Reviewed-by: Ido Schimmel Link: https://lore.kernel.org/r/6f29639ebc3ca0722272e6c644ca910096469413.1700503644.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/mellanox/mlxsw/reg.h | 5 ----- .../net/ethernet/mellanox/mlxsw/spectrum_fid.c | 15 ++++++++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index e8f7a4741bd3..bd709f7fcae1 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -1965,16 +1965,11 @@ 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, bool smpe_valid, u16 smpe) { MLXSW_REG_ZERO(sfmr, payload); mlxsw_reg_sfmr_op_set(payload, op); mlxsw_reg_sfmr_fid_set(payload, fid); - mlxsw_reg_sfmr_fid_offset_set(payload, fid_offset); - 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); } diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c index e954b8cd2ee8..6a509913bdc7 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c @@ -433,9 +433,12 @@ static int mlxsw_sp_fid_op(const struct mlxsw_sp_fid *fid, bool valid) 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, fid->fid_family->flood_rsp, - fid->fid_family->bridge_type, fid->fid_family->smpe_index_valid, smpe); + mlxsw_reg_sfmr_fid_offset_set(sfmr_pl, fid->fid_offset); + mlxsw_reg_sfmr_flood_rsp_set(sfmr_pl, fid->fid_family->flood_rsp); + mlxsw_reg_sfmr_flood_bridge_type_set(sfmr_pl, + fid->fid_family->bridge_type); + return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfmr), sfmr_pl); } @@ -449,10 +452,12 @@ static int mlxsw_sp_fid_edit_op(const struct mlxsw_sp_fid *fid, 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, - fid->fid_family->flood_rsp, - fid->fid_family->bridge_type, + fid->fid_index, fid->fid_family->smpe_index_valid, smpe); + mlxsw_reg_sfmr_fid_offset_set(sfmr_pl, fid->fid_offset); + mlxsw_reg_sfmr_flood_rsp_set(sfmr_pl, fid->fid_family->flood_rsp); + mlxsw_reg_sfmr_flood_bridge_type_set(sfmr_pl, + fid->fid_family->bridge_type); 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); From 6b10371c386c381651e2ea42ae11be6c35004b55 Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Mon, 20 Nov 2023 19:25:25 +0100 Subject: [PATCH 08/14] mlxsw: reg: Add to SFMR register the fields related to CFF flood mode Add the field cff_mid_base, which specifies at which point in PGT the per-FID flood table is stored. Add cff_prf_id, the profile ID, which determines on which row of the flood table a flood vector can be found for a given traffic type. Signed-off-by: Petr Machata Reviewed-by: Amit Cohen Reviewed-by: Ido Schimmel Link: https://lore.kernel.org/r/3ad7ae38cf6534bedcd876f16090d109a814b3e3.1700503644.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/mellanox/mlxsw/reg.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index bd709f7fcae1..3aae4467e431 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -1944,6 +1944,26 @@ MLXSW_ITEM32(reg, sfmr, irif_v, 0x14, 24, 1); */ MLXSW_ITEM32(reg, sfmr, irif, 0x14, 0, 16); +/* reg_sfmr_cff_mid_base + * Pointer to PGT table. + * Range: 0..(cap_max_pgt-1) + * Access: RW + * + * Note: Reserved when SwitchX/-2 and Spectrum-1. + * Supported when CONFIG_PROFILE.flood_mode = CFF. + */ +MLXSW_ITEM32(reg, sfmr, cff_mid_base, 0x20, 0, 16); + +/* reg_sfmr_cff_prf_id + * Compressed Fid Flooding profile_id + * Range 0..(max_cap_nve_flood_prf-1) + * Access: RW + * + * Note: Reserved when SwitchX/-2 and Spectrum-1 + * Supported only when CONFIG_PROFLE.flood_mode = CFF. + */ +MLXSW_ITEM32(reg, sfmr, cff_prf_id, 0x24, 0, 2); + /* reg_sfmr_smpe_valid * SMPE is valid. * Access: RW From 09591595686750b68c6d40c5349e737d78f6da47 Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Mon, 20 Nov 2023 19:25:26 +0100 Subject: [PATCH 09/14] mlxsw: core, pci: Add plumbing related to CFF mode CFF mode, for Compressed FID Flooding, is a way of organizing flood vectors in the PGT table. The bus module determines whether CFF is supported, can configure flood mode to CFF if it is, and knows what flood mode has been configured. Therefore add a bus callback to determine the configured flood mode. Also add to core an API to query it. Since after this patch, we rely on mlxsw_pci->flood_mode being set, it becomes a coding error if a driver invokes this function with a set of fields that misses the initialization. Warn and bail out in that case. The CFF mode is not used as of this patch. The code to actually use it will be added later. Signed-off-by: Petr Machata Reviewed-by: Amit Cohen Reviewed-by: Ido Schimmel Link: https://lore.kernel.org/r/889d58759dd40f5037f2206b9fc4a78a9240da80.1700503644.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/mellanox/mlxsw/core.c | 7 +++++++ drivers/net/ethernet/mellanox/mlxsw/core.h | 3 +++ drivers/net/ethernet/mellanox/mlxsw/pci.c | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c index f23421f038f3..e4d7739bd7c8 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core.c @@ -211,6 +211,13 @@ mlxsw_core_lag_mode(struct mlxsw_core *mlxsw_core) } EXPORT_SYMBOL(mlxsw_core_lag_mode); +enum mlxsw_cmd_mbox_config_profile_flood_mode +mlxsw_core_flood_mode(struct mlxsw_core *mlxsw_core) +{ + return mlxsw_core->bus->flood_mode(mlxsw_core->bus_priv); +} +EXPORT_SYMBOL(mlxsw_core_flood_mode); + void *mlxsw_core_driver_priv(struct mlxsw_core *mlxsw_core) { return mlxsw_core->driver_priv; diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h index 764d14bd5bc0..a93e9c38848a 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.h +++ b/drivers/net/ethernet/mellanox/mlxsw/core.h @@ -38,6 +38,8 @@ unsigned int mlxsw_core_max_ports(const struct mlxsw_core *mlxsw_core); int mlxsw_core_max_lag(struct mlxsw_core *mlxsw_core, u16 *p_max_lag); enum mlxsw_cmd_mbox_config_profile_lag_mode mlxsw_core_lag_mode(struct mlxsw_core *mlxsw_core); +enum mlxsw_cmd_mbox_config_profile_flood_mode +mlxsw_core_flood_mode(struct mlxsw_core *mlxsw_core); void *mlxsw_core_driver_priv(struct mlxsw_core *mlxsw_core); @@ -489,6 +491,7 @@ struct mlxsw_bus { u32 (*read_utc_sec)(void *bus_priv); u32 (*read_utc_nsec)(void *bus_priv); enum mlxsw_cmd_mbox_config_profile_lag_mode (*lag_mode)(void *bus_priv); + enum mlxsw_cmd_mbox_config_profile_flood_mode (*flood_mode)(void *priv); u8 features; }; diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c index 5b1f2483a3cc..845edd43032b 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/pci.c +++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c @@ -106,7 +106,9 @@ struct mlxsw_pci { u64 utc_sec_offset; u64 utc_nsec_offset; bool lag_mode_support; + bool cff_support; enum mlxsw_cmd_mbox_config_profile_lag_mode lag_mode; + enum mlxsw_cmd_mbox_config_profile_flood_mode flood_mode; struct mlxsw_pci_queue_type_group queues[MLXSW_PCI_QUEUE_TYPE_COUNT]; u32 doorbell_offset; struct mlxsw_core *core; @@ -1251,6 +1253,10 @@ static int mlxsw_pci_config_profile(struct mlxsw_pci *mlxsw_pci, char *mbox, mbox, 1); mlxsw_cmd_mbox_config_profile_flood_mode_set( mbox, profile->flood_mode); + mlxsw_pci->flood_mode = profile->flood_mode; + } else { + WARN_ON(1); + return -EINVAL; } if (profile->used_max_ib_mc) { mlxsw_cmd_mbox_config_profile_set_max_ib_mc_set( @@ -1654,6 +1660,9 @@ static int mlxsw_pci_init(void *bus_priv, struct mlxsw_core *mlxsw_core, mlxsw_pci->lag_mode_support = mlxsw_cmd_mbox_query_fw_lag_mode_support_get(mbox); + mlxsw_pci->cff_support = + mlxsw_cmd_mbox_query_fw_cff_support_get(mbox); + num_pages = mlxsw_cmd_mbox_query_fw_fw_pages_get(mbox); err = mlxsw_pci_fw_area_init(mlxsw_pci, mbox, num_pages); if (err) @@ -1970,6 +1979,14 @@ mlxsw_pci_lag_mode(void *bus_priv) return mlxsw_pci->lag_mode; } +static enum mlxsw_cmd_mbox_config_profile_flood_mode +mlxsw_pci_flood_mode(void *bus_priv) +{ + struct mlxsw_pci *mlxsw_pci = bus_priv; + + return mlxsw_pci->flood_mode; +} + static const struct mlxsw_bus mlxsw_pci_bus = { .kind = "pci", .init = mlxsw_pci_init, @@ -1982,6 +1999,7 @@ static const struct mlxsw_bus mlxsw_pci_bus = { .read_utc_sec = mlxsw_pci_read_utc_sec, .read_utc_nsec = mlxsw_pci_read_utc_nsec, .lag_mode = mlxsw_pci_lag_mode, + .flood_mode = mlxsw_pci_flood_mode, .features = MLXSW_BUS_F_TXRX | MLXSW_BUS_F_RESET, }; From 9aad19a363f68470ac5af677cda7120393e94a06 Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Mon, 20 Nov 2023 19:25:27 +0100 Subject: [PATCH 10/14] mlxsw: pci: Permit enabling CFF mode There are FW versions out there that do not support CFF flood mode, and on Spectrum-1 in particular, there is no plan to support it at all. mlxsw will therefore have to support both controlled flood mode as well as CFF. There are also FW versions out there that claim to support CFF flood mode, but then reject or ignore configurations enabling the same. The driver thus has to have a say in whether an attempt to configure CFF flood mode should even be made, and what to use as a fallback. Hence express the feature in terms of "does the driver prefer CFF flood mode?", and "what flood mode the PCI module managed to configure the FW with". This gives to the driver a chance to determine whether CFF flood mode configuration should be attempted. The latter bit was added in previous patches. In this patch, add the bit that allows the driver to determine whether CFF enablement should be attempted, and the enablement code itself. Signed-off-by: Petr Machata Reviewed-by: Amit Cohen Reviewed-by: Ido Schimmel Link: https://lore.kernel.org/r/41640a0ee58e0a9538f820f7b601a0e35f6449e4.1700503644.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/mellanox/mlxsw/core.h | 6 ++++++ drivers/net/ethernet/mellanox/mlxsw/pci.c | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h index a93e9c38848a..6d11225594dd 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.h +++ b/drivers/net/ethernet/mellanox/mlxsw/core.h @@ -324,7 +324,12 @@ struct mlxsw_config_profile { u16 max_regions; u8 max_flood_tables; u8 max_vid_flood_tables; + + /* Flood mode to use if used_flood_mode. If flood_mode_prefer_cff, + * the backup flood mode (if any) when CFF unsupported. + */ u8 flood_mode; + u8 max_fid_offset_flood_tables; u16 fid_offset_flood_table_size; u8 max_fid_flood_tables; @@ -340,6 +345,7 @@ struct mlxsw_config_profile { u8 kvd_hash_double_parts; u8 cqe_time_stamp_type; bool lag_mode_prefer_sw; + bool flood_mode_prefer_cff; struct mlxsw_swid_config swid_config[MLXSW_CONFIG_PROFILE_SWID_COUNT]; }; diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c index 845edd43032b..0d58f13a7c7d 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/pci.c +++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c @@ -1248,7 +1248,14 @@ static int mlxsw_pci_config_profile(struct mlxsw_pci *mlxsw_pci, char *mbox, mlxsw_cmd_mbox_config_profile_fid_flood_table_size_set( mbox, profile->fid_flood_table_size); } - if (profile->used_flood_mode) { + if (profile->flood_mode_prefer_cff && mlxsw_pci->cff_support) { + enum mlxsw_cmd_mbox_config_profile_flood_mode flood_mode = + MLXSW_CMD_MBOX_CONFIG_PROFILE_FLOOD_MODE_CFF; + + mlxsw_cmd_mbox_config_profile_set_flood_mode_set(mbox, 1); + mlxsw_cmd_mbox_config_profile_flood_mode_set(mbox, flood_mode); + mlxsw_pci->flood_mode = flood_mode; + } else if (profile->used_flood_mode) { mlxsw_cmd_mbox_config_profile_set_flood_mode_set( mbox, 1); mlxsw_cmd_mbox_config_profile_flood_mode_set( From b51c876c2297f8b32ca579712e3ab1490114d1ee Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Mon, 20 Nov 2023 19:25:28 +0100 Subject: [PATCH 11/14] mlxsw: spectrum_fid: Drop unnecessary conditions The caller already only calls mlxsw_sp_fid_flood_tables_init() and mlxsw_sp_fid_flood_tables_fini() if (fid_family->flood_tables). There is no configuration where the pointer is non-NULL, but the number of tables is zero. So drop the conditions. Signed-off-by: Petr Machata Reviewed-by: Amit Cohen Reviewed-by: Ido Schimmel Link: https://lore.kernel.org/r/897c6841bc756ac632b797bf67ac83c6a66ba359.1700503644.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c index 6a509913bdc7..d7fc579f3b29 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c @@ -1692,9 +1692,6 @@ mlxsw_sp_fid_flood_tables_init(struct mlxsw_sp_fid_family *fid_family) int err; int i; - if (!fid_family->nr_flood_tables) - return 0; - pgt_size = mlxsw_sp_fid_family_pgt_size(fid_family); err = mlxsw_sp_pgt_mid_alloc_range(mlxsw_sp, &fid_family->pgt_base, pgt_size); @@ -1723,9 +1720,6 @@ mlxsw_sp_fid_flood_tables_fini(struct mlxsw_sp_fid_family *fid_family) struct mlxsw_sp *mlxsw_sp = fid_family->mlxsw_sp; u16 pgt_size; - if (!fid_family->nr_flood_tables) - return; - pgt_size = mlxsw_sp_fid_family_pgt_size(fid_family); mlxsw_sp_pgt_mid_free_range(mlxsw_sp, fid_family->pgt_base, pgt_size); } From 2b7bccd1f167aa056206cc2551514b35c9fd30ab Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Mon, 20 Nov 2023 19:25:29 +0100 Subject: [PATCH 12/14] mlxsw: spectrum_fid: Extract SFMR packing into a helper Both mlxsw_sp_fid_op() and mlxsw_sp_fid_edit_op() pack the core of SFMR the same way. Extract the common code into a helper and call that. Extract out of that a wrapper that just calls mlxsw_reg_sfmr_pack(), because it will be useful for the dummy family later on. Signed-off-by: Petr Machata Reviewed-by: Amit Cohen Reviewed-by: Ido Schimmel Link: https://lore.kernel.org/r/31f32b4d767183f6cb197148d0792feab2efadba.1700503644.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski --- .../ethernet/mellanox/mlxsw/spectrum_fid.c | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c index d7fc579f3b29..aad4bb17dfb1 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c @@ -424,21 +424,35 @@ static enum mlxsw_reg_sfmr_op mlxsw_sp_sfmr_op(bool valid) MLXSW_REG_SFMR_OP_DESTROY_FID; } -static int mlxsw_sp_fid_op(const struct mlxsw_sp_fid *fid, bool valid) +static void mlxsw_sp_fid_pack(char *sfmr_pl, + const struct mlxsw_sp_fid *fid, + enum mlxsw_reg_sfmr_op op) { - struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; - char sfmr_pl[MLXSW_REG_SFMR_LEN]; 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, + mlxsw_reg_sfmr_pack(sfmr_pl, op, fid->fid_index, fid->fid_family->smpe_index_valid, smpe); +} + +static void mlxsw_sp_fid_pack_ctl(char *sfmr_pl, + const struct mlxsw_sp_fid *fid, + enum mlxsw_reg_sfmr_op op) +{ + mlxsw_sp_fid_pack(sfmr_pl, fid, op); mlxsw_reg_sfmr_fid_offset_set(sfmr_pl, fid->fid_offset); mlxsw_reg_sfmr_flood_rsp_set(sfmr_pl, fid->fid_family->flood_rsp); mlxsw_reg_sfmr_flood_bridge_type_set(sfmr_pl, fid->fid_family->bridge_type); +} +static int mlxsw_sp_fid_op(const struct mlxsw_sp_fid *fid, bool valid) +{ + struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; + char sfmr_pl[MLXSW_REG_SFMR_LEN]; + + mlxsw_sp_fid_pack_ctl(sfmr_pl, fid, mlxsw_sp_sfmr_op(valid)); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfmr), sfmr_pl); } @@ -447,17 +461,8 @@ static int mlxsw_sp_fid_edit_op(const struct mlxsw_sp_fid *fid, { struct mlxsw_sp *mlxsw_sp = fid->fid_family->mlxsw_sp; char sfmr_pl[MLXSW_REG_SFMR_LEN]; - 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_family->smpe_index_valid, smpe); - mlxsw_reg_sfmr_fid_offset_set(sfmr_pl, fid->fid_offset); - mlxsw_reg_sfmr_flood_rsp_set(sfmr_pl, fid->fid_family->flood_rsp); - mlxsw_reg_sfmr_flood_bridge_type_set(sfmr_pl, - fid->fid_family->bridge_type); + mlxsw_sp_fid_pack_ctl(sfmr_pl, fid, MLXSW_REG_SFMR_OP_CREATE_FID); 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); From 27851dfaa3d608ae13557a2684a0bd5e2aa5bff1 Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Mon, 20 Nov 2023 19:25:30 +0100 Subject: [PATCH 13/14] mlxsw: spectrum_router: Add a helper to get subport number from a RIF In the CFF flood mode, responsibility for management of the PGT entries for rFIDs is moved from FW to the driver. All rFIDs are based off either a front panel port, or a LAG port. The flood vectors for port-based rFIDs enable just the port itself, the ones for LAG-based rFIDs enable all member ports of the LAG in question. Since all rFIDs based off the same port have the same flood vector, and similarly for LAG-based rFIDs, the flood entries are shared. The PGT address of the flood vector is therefore determined based on the port (or LAG) number of the RIF connected with the rFID. Add a helper to determine subport number given a RIF, to be used in these calculations. Signed-off-by: Petr Machata Reviewed-by: Amit Cohen Reviewed-by: Ido Schimmel Link: https://lore.kernel.org/r/d7ab43cf5b021f785f363f236e4b6780d10eea93.1700503644.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 2 ++ .../net/ethernet/mellanox/mlxsw/spectrum_router.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h index c70333b460ea..800c461deefa 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h @@ -753,6 +753,8 @@ union mlxsw_sp_l3addr { }; u16 mlxsw_sp_rif_index(const struct mlxsw_sp_rif *rif); +int mlxsw_sp_rif_subport_port(const struct mlxsw_sp_rif *rif, + u16 *port, bool *is_lag); 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); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index 82a95125d9ca..a358ceb4e1d0 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -8660,6 +8660,20 @@ mlxsw_sp_rif_subport_rif(const struct mlxsw_sp_rif *rif) return container_of(rif, struct mlxsw_sp_rif_subport, common); } +int mlxsw_sp_rif_subport_port(const struct mlxsw_sp_rif *rif, + u16 *port, bool *is_lag) +{ + struct mlxsw_sp_rif_subport *rif_subport; + + if (WARN_ON(rif->ops->type != MLXSW_SP_RIF_TYPE_SUBPORT)) + return -EINVAL; + + rif_subport = mlxsw_sp_rif_subport_rif(rif); + *is_lag = rif_subport->lag; + *port = *is_lag ? rif_subport->lag_id : rif_subport->system_port; + return 0; +} + static struct mlxsw_sp_rif * mlxsw_sp_rif_subport_get(struct mlxsw_sp *mlxsw_sp, const struct mlxsw_sp_rif_params *params, From f7ebb4023765e728a984c628fb6b929db2a3f76b Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Mon, 20 Nov 2023 19:25:31 +0100 Subject: [PATCH 14/14] mlxsw: spectrum_router: Call RIF setup before obtaining FID For subport RIFs, the setup initializes, among other things, RIF port and LAG numbers. Those are important to determine where in the PGT the RIF FID will be stored. Therefore, call the RIF setup before fid_get. Signed-off-by: Petr Machata Reviewed-by: Amit Cohen Reviewed-by: Ido Schimmel Link: https://lore.kernel.org/r/f24d8cad7e4748b8e8e0e16894ca6a20704dea32.1700503644.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index a358ceb4e1d0..2c255ed9b8a9 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -8419,6 +8419,9 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp, rif->ops = ops; rif->rif_entries = rif_entries; + if (ops->setup) + ops->setup(rif, params); + if (ops->fid_get) { fid = ops->fid_get(rif, params, extack); if (IS_ERR(fid)) { @@ -8428,9 +8431,6 @@ mlxsw_sp_rif_create(struct mlxsw_sp *mlxsw_sp, rif->fid = fid; } - if (ops->setup) - ops->setup(rif, params); - err = ops->configure(rif, extack); if (err) goto err_configure;