]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net/mlx5: Initialize satellite PF SF vports
authorMoshe Shemesh <moshe@nvidia.com>
Thu, 21 May 2026 11:08:35 +0000 (14:08 +0300)
committerJakub Kicinski <kuba@kernel.org>
Mon, 25 May 2026 20:48:51 +0000 (13:48 -0700)
Extend satellite PF (SPF) initialization to allocate SF vports for each
SPF. For each discovered SPF, query its SF capabilities, allocate SF
vports, and store the host_number for controller identification.

Add accessor APIs mlx5_esw_get_num_spfs(),
mlx5_esw_spf_get_host_number(), mlx5_esw_sf_max_spf_functions(), and
mlx5_esw_has_spf_sfs() for use by the SF hardware table in a subsequent
patch. Also extend mlx5_esw_offloads_controller_valid() to accept SPF
controllers in addition to the host PF controller.

Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260521110843.367329-5-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c

index 959b85e2f61e6e2c8aa63e09baa5dec1bc406e33..b4fcfcdaccd1d77f04d048ff0ab8b4b825688dc0 100644 (file)
@@ -2083,6 +2083,51 @@ int mlx5_esw_sf_max_hpf_functions(struct mlx5_core_dev *dev, u16 *max_sfs,
                                            sf_base_id);
 }
 
+int mlx5_esw_sf_max_spf_functions(struct mlx5_core_dev *dev, int spf_idx,
+                                 u16 *max_sfs, u16 *sf_base_id)
+{
+       struct mlx5_eswitch *esw = dev->priv.eswitch;
+       u16 vport_num;
+
+       if (!mlx5_esw_allowed(esw)) {
+               *max_sfs = 0;
+               return 0;
+       }
+
+       if (spf_idx >= esw->esw_funcs.num_spfs)
+               return -EINVAL;
+
+       vport_num = esw->esw_funcs.spfs[spf_idx].vport_num;
+       return mlx5_esw_sf_max_pf_functions(dev, vport_num, max_sfs,
+                                           sf_base_id);
+}
+
+int mlx5_esw_get_num_spfs(struct mlx5_core_dev *dev)
+{
+       struct mlx5_eswitch *esw = dev->priv.eswitch;
+
+       if (!mlx5_esw_allowed(esw))
+               return 0;
+
+       return esw->esw_funcs.num_spfs;
+}
+
+int mlx5_esw_spf_get_host_number(struct mlx5_core_dev *dev, int spf_idx,
+                                u16 *host_number)
+{
+       struct mlx5_eswitch *esw = dev->priv.eswitch;
+
+       if (!mlx5_esw_allowed(esw))
+               return -EPERM;
+
+       if (spf_idx >= esw->esw_funcs.num_spfs)
+               return -EINVAL;
+
+       *host_number = esw->esw_funcs.spfs[spf_idx].host_number;
+
+       return 0;
+}
+
 u16 mlx5_esw_get_hpf_host_number(struct mlx5_core_dev *dev)
 {
        struct mlx5_eswitch *esw = dev->priv.eswitch;
@@ -2093,6 +2138,16 @@ u16 mlx5_esw_get_hpf_host_number(struct mlx5_core_dev *dev)
        return esw->esw_funcs.hpf_host_number;
 }
 
+bool mlx5_esw_has_spf_sfs(struct mlx5_core_dev *dev)
+{
+       struct mlx5_eswitch *esw = dev->priv.eswitch;
+
+       if (!mlx5_esw_allowed(esw))
+               return false;
+
+       return esw->esw_funcs.has_spf_sfs;
+}
+
 static int mlx5_esw_hpf_host_number_init(struct mlx5_eswitch *esw)
 {
        struct mlx5_esw_pf_info host_pf_info;
@@ -2219,6 +2274,8 @@ static int mlx5_esw_spfs_init(struct mlx5_eswitch *esw)
 
                esw_funcs->spfs[esw_funcs->num_spfs].vport_num = vport_num;
                esw_funcs->spfs[esw_funcs->num_spfs].vhca_id = vhca_id;
+               esw_funcs->spfs[esw_funcs->num_spfs].host_number =
+                       MLX5_GET(network_function_params, entry, host_number);
                esw_funcs->num_spfs++;
 
                entry += MLX5_UN_SZ_BYTES(net_function_params);
@@ -2245,6 +2302,7 @@ static void mlx5_esw_vports_cleanup(struct mlx5_eswitch *esw)
        unsigned long i;
 
        mlx5_esw_spfs_cleanup(esw);
+       esw->esw_funcs.has_spf_sfs = false;
        mlx5_esw_for_each_vport(esw, i, vport)
                mlx5_esw_vport_free(esw, vport);
        xa_destroy(&esw->vports);
@@ -2253,8 +2311,7 @@ static void mlx5_esw_vports_cleanup(struct mlx5_eswitch *esw)
 static int mlx5_esw_vports_init(struct mlx5_eswitch *esw)
 {
        struct mlx5_core_dev *dev = esw->dev;
-       u16 max_host_pf_sfs;
-       u16 base_sf_num;
+       u16 max_sfs, base_sf_num;
        int idx = 0;
        int err;
        int i;
@@ -2291,10 +2348,10 @@ static int mlx5_esw_vports_init(struct mlx5_eswitch *esw)
                idx++;
        }
 
-       err = mlx5_esw_sf_max_hpf_functions(dev, &max_host_pf_sfs, &base_sf_num);
+       err = mlx5_esw_sf_max_hpf_functions(dev, &max_sfs, &base_sf_num);
        if (err)
                goto err;
-       for (i = 0; i < max_host_pf_sfs; i++) {
+       for (i = 0; i < max_sfs; i++) {
                err = mlx5_esw_vport_alloc(esw, idx, base_sf_num + i);
                if (err)
                        goto err;
@@ -2316,6 +2373,22 @@ static int mlx5_esw_vports_init(struct mlx5_eswitch *esw)
                        goto err;
                vport = mlx5_eswitch_get_vport(esw, vport_num);
                vport->vhca_id = esw->esw_funcs.spfs[i].vhca_id;
+
+               err = mlx5_esw_sf_max_spf_functions(dev, i,
+                                                   &max_sfs, &base_sf_num);
+               if (err)
+                       goto err;
+               if (max_sfs)
+                       esw->esw_funcs.has_spf_sfs = true;
+               for (int j = 0; j < max_sfs; j++) {
+                       err = mlx5_esw_vport_alloc(esw, idx,
+                                                  base_sf_num + j);
+                       if (err)
+                               goto err;
+                       xa_set_mark(&esw->vports, base_sf_num + j,
+                                   MLX5_ESW_VPT_SF);
+                       idx++;
+               }
        }
 
        if (mlx5_core_ec_sriov_enabled(esw->dev)) {
index 0f552ef468d891ec325393f3b506c11f3d419b84..35b722b4aee85a43aa7be2afba246aa4858024a4 100644 (file)
@@ -352,6 +352,7 @@ struct mlx5_host_work {
 struct mlx5_esw_spf {
        u16 vport_num;
        u16 vhca_id;
+       u16 host_number;
 };
 
 struct mlx5_esw_functions {
@@ -360,6 +361,7 @@ struct mlx5_esw_functions {
        u16                     num_vfs;
        u16                     num_ec_vfs;
        u16                     hpf_host_number;
+       bool                    has_spf_sfs;
        struct mlx5_esw_spf     *spfs;
        int                     num_spfs;
 };
@@ -879,8 +881,14 @@ void mlx5_esw_offloads_devlink_port_unregister(struct mlx5_vport *vport);
 struct devlink_port *mlx5_esw_offloads_devlink_port(struct mlx5_eswitch *esw, u16 vport_num);
 
 int mlx5_esw_sf_max_hpf_functions(struct mlx5_core_dev *dev, u16 *max_sfs, u16 *sf_base_id);
+int mlx5_esw_sf_max_spf_functions(struct mlx5_core_dev *dev, int spf_idx,
+                                 u16 *max_sfs, u16 *sf_base_id);
 
+int mlx5_esw_get_num_spfs(struct mlx5_core_dev *dev);
+int mlx5_esw_spf_get_host_number(struct mlx5_core_dev *dev, int spf_idx,
+                                u16 *host_number);
 u16 mlx5_esw_get_hpf_host_number(struct mlx5_core_dev *dev);
+bool mlx5_esw_has_spf_sfs(struct mlx5_core_dev *dev);
 
 int mlx5_esw_vport_vhca_id_map(struct mlx5_eswitch *esw,
                               struct mlx5_vport *vport);
index f17db51abe2d4be80a8850fc94a38392d2860c2b..c229a96a111fbfbe1d2e799609748b8b650326a8 100644 (file)
@@ -3821,6 +3821,9 @@ int mlx5_esw_funcs_changed_handler(struct notifier_block *nb,
 
 bool mlx5_esw_offloads_controller_valid(const struct mlx5_eswitch *esw, u32 controller)
 {
+       const struct mlx5_esw_functions *esw_funcs;
+       int i;
+
        /* Local controller is always valid */
        if (controller == 0)
                return true;
@@ -3829,7 +3832,15 @@ bool mlx5_esw_offloads_controller_valid(const struct mlx5_eswitch *esw, u32 cont
                return false;
 
        /* External host number starts with zero in device */
-       return (controller == mlx5_esw_get_hpf_host_number(esw->dev) + 1);
+       if (controller == mlx5_esw_get_hpf_host_number(esw->dev) + 1)
+               return true;
+
+       esw_funcs = &esw->esw_funcs;
+       for (i = 0; i < esw_funcs->num_spfs; i++) {
+               if (controller == esw_funcs->spfs[i].host_number + 1)
+                       return true;
+       }
+       return false;
 }
 
 int esw_offloads_enable(struct mlx5_eswitch *esw)