summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorPetr Machata <petrm@nvidia.com>2023-11-28 16:50:47 +0100
committerJakub Kicinski <kuba@kernel.org>2023-11-29 20:03:25 -0800
commitd79b70dbb76001e51a287d0f7430009068e1e55e (patch)
tree036db7ede82c39e7c039217cd1463eb2d8398ef1 /drivers/net/ethernet
parentaf1e696fdf1e588ac0153cc8dff70b5a10a2e220 (diff)
downloadlinux-d79b70dbb76001e51a287d0f7430009068e1e55e.tar.gz
linux-d79b70dbb76001e51a287d0f7430009068e1e55e.tar.bz2
linux-d79b70dbb76001e51a287d0f7430009068e1e55e.zip
mlxsw: spectrum_fid: Initialize flood profiles in CFF mode
In CFF flood mode, the way flood vectors are looked up changes: there's a per-FID PGT base, to which a small offset is added depending on type of traffic. Thus each FID occupies a small contiguous block of PGT memory, whereas in the controlled flood mode, flood vectors for a given FID were spread across the PGT. Each FID is associated with one of a handful of profiles. The profile and the traffic type are then used as keys to look up the PGT offset. This offset is then added to the per-FID PGT base. The profile / type / offset mapping needs to be configured by the driver, and is only relevant in CFF flood mode. In this patch, add the SFFP initialization code. Only initialize the one profile currently explicitly used. As follow-up patch add more profiles, this code will pick them up and initialize as well. Signed-off-by: Petr Machata <petrm@nvidia.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://lore.kernel.org/r/2c4733ed72d439444218969c032acad22cd4ed88.1701183892.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c123
1 files changed, 122 insertions, 1 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c
index 2d61fb8bff57..8c4377081872 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c
@@ -1633,6 +1633,9 @@ static const struct mlxsw_sp_fid_family *mlxsw_sp2_fid_family_arr_ctl[] = {
[MLXSW_SP_FID_TYPE_RFID] = &mlxsw_sp_fid_rfid_family_ctl,
};
+static const struct mlxsw_sp_fid_family *mlxsw_sp2_fid_family_arr_cff[] = {
+};
+
static struct mlxsw_sp_fid *mlxsw_sp_fid_lookup(struct mlxsw_sp *mlxsw_sp,
enum mlxsw_sp_fid_type type,
const void *arg)
@@ -2008,12 +2011,130 @@ const struct mlxsw_sp_fid_core_ops mlxsw_sp1_fid_core_ops = {
.fini = mlxsw_sp_fids_fini,
};
+static int mlxsw_sp_fid_check_flood_profile_id(struct mlxsw_sp *mlxsw_sp,
+ int profile_id)
+{
+ u32 max_profiles;
+
+ if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_NVE_FLOOD_PRF))
+ return -EIO;
+
+ max_profiles = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_NVE_FLOOD_PRF);
+ if (WARN_ON_ONCE(!profile_id) ||
+ WARN_ON_ONCE(profile_id >= max_profiles))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int
+mlxsw_sp2_fids_init_flood_table(struct mlxsw_sp *mlxsw_sp,
+ enum mlxsw_sp_fid_flood_profile_id profile_id,
+ const struct mlxsw_sp_flood_table *flood_table)
+{
+ enum mlxsw_sp_flood_type packet_type = flood_table->packet_type;
+ const int *sfgc_packet_types;
+ int err;
+ int i;
+
+ sfgc_packet_types = mlxsw_sp_packet_type_sfgc_types[packet_type];
+ for (i = 0; i < MLXSW_REG_SFGC_TYPE_MAX; i++) {
+ char sffp_pl[MLXSW_REG_SFFP_LEN];
+
+ if (!sfgc_packet_types[i])
+ continue;
+
+ mlxsw_reg_sffp_pack(sffp_pl, profile_id, i,
+ flood_table->table_index);
+ err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sffp), sffp_pl);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static int
+mlxsw_sp2_fids_init_flood_profile(struct mlxsw_sp *mlxsw_sp,
+ const struct mlxsw_sp_fid_flood_profile *
+ flood_profile)
+{
+ int err;
+ int i;
+
+ err = mlxsw_sp_fid_check_flood_profile_id(mlxsw_sp,
+ flood_profile->profile_id);
+ if (err)
+ return err;
+
+ for (i = 0; i < flood_profile->nr_flood_tables; i++) {
+ const struct mlxsw_sp_flood_table *flood_table;
+
+ flood_table = &flood_profile->flood_tables[i];
+ err = mlxsw_sp2_fids_init_flood_table(mlxsw_sp,
+ flood_profile->profile_id,
+ flood_table);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static const
+struct mlxsw_sp_fid_flood_profile *mlxsw_sp_fid_flood_profiles[] = {
+ &mlxsw_sp_fid_8021d_flood_profile,
+};
+
+static int
+mlxsw_sp2_fids_init_flood_profiles(struct mlxsw_sp *mlxsw_sp)
+{
+ int err;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mlxsw_sp_fid_flood_profiles); i++) {
+ const struct mlxsw_sp_fid_flood_profile *flood_profile;
+
+ flood_profile = mlxsw_sp_fid_flood_profiles[i];
+ err = mlxsw_sp2_fids_init_flood_profile(mlxsw_sp,
+ flood_profile);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
static int mlxsw_sp2_fids_init_ctl(struct mlxsw_sp *mlxsw_sp)
{
return mlxsw_sp_fids_init(mlxsw_sp, mlxsw_sp2_fid_family_arr_ctl);
}
+static int mlxsw_sp2_fids_init_cff(struct mlxsw_sp *mlxsw_sp)
+{
+ int err;
+
+ err = mlxsw_sp2_fids_init_flood_profiles(mlxsw_sp);
+ if (err)
+ return err;
+
+ return mlxsw_sp_fids_init(mlxsw_sp, mlxsw_sp2_fid_family_arr_cff);
+}
+
+static int mlxsw_sp2_fids_init(struct mlxsw_sp *mlxsw_sp)
+{
+ switch (mlxsw_core_flood_mode(mlxsw_sp->core)) {
+ case MLXSW_CMD_MBOX_CONFIG_PROFILE_FLOOD_MODE_CONTROLLED:
+ return mlxsw_sp2_fids_init_ctl(mlxsw_sp);
+ case MLXSW_CMD_MBOX_CONFIG_PROFILE_FLOOD_MODE_CFF:
+ return mlxsw_sp2_fids_init_cff(mlxsw_sp);
+ default:
+ WARN_ON_ONCE(1);
+ return -EINVAL;
+ }
+}
+
const struct mlxsw_sp_fid_core_ops mlxsw_sp2_fid_core_ops = {
- .init = mlxsw_sp2_fids_init_ctl,
+ .init = mlxsw_sp2_fids_init,
.fini = mlxsw_sp_fids_fini,
};