Commit 86eec50b authored by Bodong Wang's avatar Bodong Wang Committed by Saeed Mahameed

net/mlx5: Support querying max VFs from device

For ECPF with eswitch manager privilege, query the host max VF count
by querying the device using query_functions command.

With this enhancement:
1. flow steering entries are created only for valid vports based on
   the max VF count of the PF.
2. Driver only queries cap of valid vport.

Eswitch requires the max VFs when doing initialization, so do sr-iov
init before eswitch init.
Signed-off-by: default avatarBodong Wang <bodong@mellanox.com>
Reviewed-by: default avatarParav Pandit <parav@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent 10ee82ce
...@@ -844,32 +844,32 @@ static int mlx5_init_once(struct mlx5_core_dev *dev) ...@@ -844,32 +844,32 @@ static int mlx5_init_once(struct mlx5_core_dev *dev)
goto err_rl_cleanup; goto err_rl_cleanup;
} }
err = mlx5_eswitch_init(dev); err = mlx5_sriov_init(dev);
if (err) { if (err) {
mlx5_core_err(dev, "Failed to init eswitch %d\n", err); mlx5_core_err(dev, "Failed to init sriov %d\n", err);
goto err_mpfs_cleanup; goto err_mpfs_cleanup;
} }
err = mlx5_sriov_init(dev); err = mlx5_eswitch_init(dev);
if (err) { if (err) {
mlx5_core_err(dev, "Failed to init sriov %d\n", err); mlx5_core_err(dev, "Failed to init eswitch %d\n", err);
goto err_eswitch_cleanup; goto err_sriov_cleanup;
} }
err = mlx5_fpga_init(dev); err = mlx5_fpga_init(dev);
if (err) { if (err) {
mlx5_core_err(dev, "Failed to init fpga device %d\n", err); mlx5_core_err(dev, "Failed to init fpga device %d\n", err);
goto err_sriov_cleanup; goto err_eswitch_cleanup;
} }
dev->tracer = mlx5_fw_tracer_create(dev); dev->tracer = mlx5_fw_tracer_create(dev);
return 0; return 0;
err_sriov_cleanup:
mlx5_sriov_cleanup(dev);
err_eswitch_cleanup: err_eswitch_cleanup:
mlx5_eswitch_cleanup(dev->priv.eswitch); mlx5_eswitch_cleanup(dev->priv.eswitch);
err_sriov_cleanup:
mlx5_sriov_cleanup(dev);
err_mpfs_cleanup: err_mpfs_cleanup:
mlx5_mpfs_cleanup(dev); mlx5_mpfs_cleanup(dev);
err_rl_cleanup: err_rl_cleanup:
...@@ -893,8 +893,8 @@ static void mlx5_cleanup_once(struct mlx5_core_dev *dev) ...@@ -893,8 +893,8 @@ static void mlx5_cleanup_once(struct mlx5_core_dev *dev)
{ {
mlx5_fw_tracer_destroy(dev->tracer); mlx5_fw_tracer_destroy(dev->tracer);
mlx5_fpga_cleanup(dev); mlx5_fpga_cleanup(dev);
mlx5_sriov_cleanup(dev);
mlx5_eswitch_cleanup(dev->priv.eswitch); mlx5_eswitch_cleanup(dev->priv.eswitch);
mlx5_sriov_cleanup(dev);
mlx5_mpfs_cleanup(dev); mlx5_mpfs_cleanup(dev);
mlx5_cleanup_rl_table(dev); mlx5_cleanup_rl_table(dev);
mlx5_vxlan_destroy(dev->vxlan); mlx5_vxlan_destroy(dev->vxlan);
......
...@@ -208,6 +208,27 @@ void mlx5_sriov_detach(struct mlx5_core_dev *dev) ...@@ -208,6 +208,27 @@ void mlx5_sriov_detach(struct mlx5_core_dev *dev)
mlx5_device_disable_sriov(dev); mlx5_device_disable_sriov(dev);
} }
static u16 mlx5_get_max_vfs(struct mlx5_core_dev *dev)
{
u32 out[MLX5_ST_SZ_DW(query_esw_functions_out)] = {};
u16 host_total_vfs;
int err;
if (mlx5_core_is_ecpf_esw_manager(dev)) {
err = mlx5_esw_query_functions(dev, out, sizeof(out));
host_total_vfs = MLX5_GET(query_esw_functions_out, out,
host_params_context.host_total_vfs);
/* Old FW doesn't support getting total_vfs from esw func
* but supports getting it from pci_sriov.
*/
if (!err && host_total_vfs)
return host_total_vfs;
}
return pci_sriov_get_totalvfs(dev->pdev);
}
int mlx5_sriov_init(struct mlx5_core_dev *dev) int mlx5_sriov_init(struct mlx5_core_dev *dev)
{ {
struct mlx5_core_sriov *sriov = &dev->priv.sriov; struct mlx5_core_sriov *sriov = &dev->priv.sriov;
...@@ -218,6 +239,7 @@ int mlx5_sriov_init(struct mlx5_core_dev *dev) ...@@ -218,6 +239,7 @@ int mlx5_sriov_init(struct mlx5_core_dev *dev)
return 0; return 0;
total_vfs = pci_sriov_get_totalvfs(pdev); total_vfs = pci_sriov_get_totalvfs(pdev);
sriov->max_vfs = mlx5_get_max_vfs(dev);
sriov->num_vfs = pci_num_vf(pdev); sriov->num_vfs = pci_num_vf(pdev);
sriov->vfs_ctx = kcalloc(total_vfs, sizeof(*sriov->vfs_ctx), GFP_KERNEL); sriov->vfs_ctx = kcalloc(total_vfs, sizeof(*sriov->vfs_ctx), GFP_KERNEL);
if (!sriov->vfs_ctx) if (!sriov->vfs_ctx)
......
...@@ -470,6 +470,7 @@ struct mlx5_core_sriov { ...@@ -470,6 +470,7 @@ struct mlx5_core_sriov {
struct mlx5_vf_context *vfs_ctx; struct mlx5_vf_context *vfs_ctx;
int num_vfs; int num_vfs;
int enabled_vfs; int enabled_vfs;
u16 max_vfs;
}; };
struct mlx5_fc_stats { struct mlx5_fc_stats {
...@@ -1103,13 +1104,9 @@ static inline bool mlx5_ecpf_vport_exists(struct mlx5_core_dev *dev) ...@@ -1103,13 +1104,9 @@ static inline bool mlx5_ecpf_vport_exists(struct mlx5_core_dev *dev)
return mlx5_core_is_pf(dev) && MLX5_CAP_ESW(dev, ecpf_vport_exists); return mlx5_core_is_pf(dev) && MLX5_CAP_ESW(dev, ecpf_vport_exists);
} }
#define MLX5_HOST_PF_MAX_VFS (127u)
static inline u16 mlx5_core_max_vfs(struct mlx5_core_dev *dev) static inline u16 mlx5_core_max_vfs(struct mlx5_core_dev *dev)
{ {
if (mlx5_core_is_ecpf_esw_manager(dev)) return dev->priv.sriov.max_vfs;
return MLX5_HOST_PF_MAX_VFS;
else
return pci_sriov_get_totalvfs(dev->pdev);
} }
static inline int mlx5_get_gid_table_len(u16 param) static inline int mlx5_get_gid_table_len(u16 param)
......
...@@ -9711,7 +9711,7 @@ struct mlx5_ifc_host_params_context_bits { ...@@ -9711,7 +9711,7 @@ struct mlx5_ifc_host_params_context_bits {
u8 reserved_at_8[0x8]; u8 reserved_at_8[0x8];
u8 host_num_of_vfs[0x10]; u8 host_num_of_vfs[0x10];
u8 reserved_at_20[0x10]; u8 host_total_vfs[0x10];
u8 host_pci_bus[0x10]; u8 host_pci_bus[0x10];
u8 reserved_at_40[0x10]; u8 reserved_at_40[0x10];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment