net/mlx4: Add data structures to support N-Ports per VF
Adds the required data structures to support VFs with N (1 or 2) ports instead of always using the number of physical ports. Signed-off-by: Matan Barak <matanb@mellanox.com> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
82373701be
commit
1ab95d37bc
2 changed files with 92 additions and 24 deletions
|
@ -2193,6 +2193,10 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data)
|
||||||
struct mlx4_dev *dev;
|
struct mlx4_dev *dev;
|
||||||
int err;
|
int err;
|
||||||
int port;
|
int port;
|
||||||
|
int nvfs[MLX4_MAX_PORTS + 1], prb_vf[MLX4_MAX_PORTS + 1];
|
||||||
|
unsigned total_vfs = 0;
|
||||||
|
int sriov_initialized = 0;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
pr_info(DRV_NAME ": Initializing %s\n", pci_name(pdev));
|
pr_info(DRV_NAME ": Initializing %s\n", pci_name(pdev));
|
||||||
|
|
||||||
|
@ -2207,17 +2211,39 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data)
|
||||||
* per port, we must limit the number of VFs to 63 (since their are
|
* per port, we must limit the number of VFs to 63 (since their are
|
||||||
* 128 MACs)
|
* 128 MACs)
|
||||||
*/
|
*/
|
||||||
if (num_vfs >= MLX4_MAX_NUM_VF) {
|
for (i = 0; i < sizeof(nvfs)/sizeof(nvfs[0]);
|
||||||
|
total_vfs += nvfs[i], i++) {
|
||||||
|
nvfs[i] = i == MLX4_MAX_PORTS ? num_vfs : 0;
|
||||||
|
if (nvfs[i] < 0) {
|
||||||
|
dev_err(&pdev->dev, "num_vfs module parameter cannot be negative\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < sizeof(prb_vf)/sizeof(prb_vf[0]); i++) {
|
||||||
|
prb_vf[i] = i == MLX4_MAX_PORTS ? probe_vf : 0;
|
||||||
|
if (prb_vf[i] < 0 || prb_vf[i] > nvfs[i]) {
|
||||||
|
dev_err(&pdev->dev, "probe_vf module parameter cannot be negative or greater than num_vfs\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (total_vfs >= MLX4_MAX_NUM_VF) {
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
"Requested more VF's (%d) than allowed (%d)\n",
|
"Requested more VF's (%d) than allowed (%d)\n",
|
||||||
num_vfs, MLX4_MAX_NUM_VF - 1);
|
total_vfs, MLX4_MAX_NUM_VF - 1);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_vfs < 0) {
|
for (i = 0; i < MLX4_MAX_PORTS; i++) {
|
||||||
pr_err("num_vfs module parameter cannot be negative\n");
|
if (nvfs[i] + nvfs[2] >= MLX4_MAX_NUM_VF_P_PORT) {
|
||||||
return -EINVAL;
|
dev_err(&pdev->dev,
|
||||||
|
"Requested more VF's (%d) for port (%d) than allowed (%d)\n",
|
||||||
|
nvfs[i] + nvfs[2], i + 1,
|
||||||
|
MLX4_MAX_NUM_VF_P_PORT - 1);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for BARs.
|
* Check for BARs.
|
||||||
*/
|
*/
|
||||||
|
@ -2292,11 +2318,23 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data)
|
||||||
if (pci_dev_data & MLX4_PCI_DEV_IS_VF) {
|
if (pci_dev_data & MLX4_PCI_DEV_IS_VF) {
|
||||||
/* When acting as pf, we normally skip vfs unless explicitly
|
/* When acting as pf, we normally skip vfs unless explicitly
|
||||||
* requested to probe them. */
|
* requested to probe them. */
|
||||||
if (num_vfs && extended_func_num(pdev) > probe_vf) {
|
if (total_vfs) {
|
||||||
mlx4_warn(dev, "Skipping virtual function:%d\n",
|
unsigned vfs_offset = 0;
|
||||||
extended_func_num(pdev));
|
for (i = 0; i < sizeof(nvfs)/sizeof(nvfs[0]) &&
|
||||||
err = -ENODEV;
|
vfs_offset + nvfs[i] < extended_func_num(pdev);
|
||||||
goto err_free_dev;
|
vfs_offset += nvfs[i], i++)
|
||||||
|
;
|
||||||
|
if (i == sizeof(nvfs)/sizeof(nvfs[0])) {
|
||||||
|
err = -ENODEV;
|
||||||
|
goto err_free_dev;
|
||||||
|
}
|
||||||
|
if ((extended_func_num(pdev) - vfs_offset)
|
||||||
|
> prb_vf[i]) {
|
||||||
|
mlx4_warn(dev, "Skipping virtual function:%d\n",
|
||||||
|
extended_func_num(pdev));
|
||||||
|
err = -ENODEV;
|
||||||
|
goto err_free_dev;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mlx4_warn(dev, "Detected virtual function - running in slave mode\n");
|
mlx4_warn(dev, "Detected virtual function - running in slave mode\n");
|
||||||
dev->flags |= MLX4_FLAG_SLAVE;
|
dev->flags |= MLX4_FLAG_SLAVE;
|
||||||
|
@ -2316,22 +2354,30 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_vfs) {
|
if (total_vfs) {
|
||||||
mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n", num_vfs);
|
mlx4_warn(dev, "Enabling SR-IOV with %d VFs\n",
|
||||||
|
total_vfs);
|
||||||
atomic_inc(&pf_loading);
|
dev->dev_vfs = kzalloc(
|
||||||
err = pci_enable_sriov(pdev, num_vfs);
|
total_vfs * sizeof(*dev->dev_vfs),
|
||||||
atomic_dec(&pf_loading);
|
GFP_KERNEL);
|
||||||
|
if (NULL == dev->dev_vfs) {
|
||||||
if (err) {
|
mlx4_err(dev, "Failed to allocate memory for VFs\n");
|
||||||
mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d).\n",
|
|
||||||
err);
|
|
||||||
err = 0;
|
err = 0;
|
||||||
} else {
|
} else {
|
||||||
mlx4_warn(dev, "Running in master mode\n");
|
atomic_inc(&pf_loading);
|
||||||
dev->flags |= MLX4_FLAG_SRIOV |
|
err = pci_enable_sriov(pdev, total_vfs);
|
||||||
MLX4_FLAG_MASTER;
|
atomic_dec(&pf_loading);
|
||||||
dev->num_vfs = num_vfs;
|
if (err) {
|
||||||
|
mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d).\n",
|
||||||
|
err);
|
||||||
|
err = 0;
|
||||||
|
} else {
|
||||||
|
mlx4_warn(dev, "Running in master mode\n");
|
||||||
|
dev->flags |= MLX4_FLAG_SRIOV |
|
||||||
|
MLX4_FLAG_MASTER;
|
||||||
|
dev->num_vfs = total_vfs;
|
||||||
|
sriov_initialized = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2396,12 +2442,24 @@ slave_start:
|
||||||
/* In master functions, the communication channel must be initialized
|
/* In master functions, the communication channel must be initialized
|
||||||
* after obtaining its address from fw */
|
* after obtaining its address from fw */
|
||||||
if (mlx4_is_master(dev)) {
|
if (mlx4_is_master(dev)) {
|
||||||
|
unsigned sum = 0;
|
||||||
err = mlx4_multi_func_init(dev);
|
err = mlx4_multi_func_init(dev);
|
||||||
if (err) {
|
if (err) {
|
||||||
mlx4_err(dev, "Failed to init master mfunc"
|
mlx4_err(dev, "Failed to init master mfunc"
|
||||||
"interface, aborting.\n");
|
"interface, aborting.\n");
|
||||||
goto err_close;
|
goto err_close;
|
||||||
}
|
}
|
||||||
|
if (sriov_initialized) {
|
||||||
|
for (i = 0; i < sizeof(nvfs)/sizeof(nvfs[0]); i++) {
|
||||||
|
unsigned j;
|
||||||
|
for (j = 0; j < nvfs[i]; ++sum, ++j) {
|
||||||
|
dev->dev_vfs[sum].min_port =
|
||||||
|
i < 2 ? i + 1 : 1;
|
||||||
|
dev->dev_vfs[sum].n_ports = i < 2 ? 1 :
|
||||||
|
dev->caps.num_ports;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = mlx4_alloc_eq_table(dev);
|
err = mlx4_alloc_eq_table(dev);
|
||||||
|
@ -2509,6 +2567,8 @@ err_rel_own:
|
||||||
if (!mlx4_is_slave(dev))
|
if (!mlx4_is_slave(dev))
|
||||||
mlx4_free_ownership(dev);
|
mlx4_free_ownership(dev);
|
||||||
|
|
||||||
|
kfree(priv->dev.dev_vfs);
|
||||||
|
|
||||||
err_free_dev:
|
err_free_dev:
|
||||||
kfree(priv);
|
kfree(priv);
|
||||||
|
|
||||||
|
@ -2595,6 +2655,7 @@ static void mlx4_remove_one(struct pci_dev *pdev)
|
||||||
kfree(dev->caps.qp0_proxy);
|
kfree(dev->caps.qp0_proxy);
|
||||||
kfree(dev->caps.qp1_tunnel);
|
kfree(dev->caps.qp1_tunnel);
|
||||||
kfree(dev->caps.qp1_proxy);
|
kfree(dev->caps.qp1_proxy);
|
||||||
|
kfree(dev->dev_vfs);
|
||||||
|
|
||||||
kfree(priv);
|
kfree(priv);
|
||||||
pci_release_regions(pdev);
|
pci_release_regions(pdev);
|
||||||
|
|
|
@ -84,6 +84,7 @@ enum {
|
||||||
enum {
|
enum {
|
||||||
MLX4_MAX_NUM_PF = 16,
|
MLX4_MAX_NUM_PF = 16,
|
||||||
MLX4_MAX_NUM_VF = 64,
|
MLX4_MAX_NUM_VF = 64,
|
||||||
|
MLX4_MAX_NUM_VF_P_PORT = 64,
|
||||||
MLX4_MFUNC_MAX = 80,
|
MLX4_MFUNC_MAX = 80,
|
||||||
MLX4_MAX_EQ_NUM = 1024,
|
MLX4_MAX_EQ_NUM = 1024,
|
||||||
MLX4_MFUNC_EQ_NUM = 4,
|
MLX4_MFUNC_EQ_NUM = 4,
|
||||||
|
@ -664,6 +665,11 @@ struct mlx4_quotas {
|
||||||
int xrcd;
|
int xrcd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mlx4_vf_dev {
|
||||||
|
u8 min_port;
|
||||||
|
u8 n_ports;
|
||||||
|
};
|
||||||
|
|
||||||
struct mlx4_dev {
|
struct mlx4_dev {
|
||||||
struct pci_dev *pdev;
|
struct pci_dev *pdev;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -679,6 +685,7 @@ struct mlx4_dev {
|
||||||
int oper_log_mgm_entry_size;
|
int oper_log_mgm_entry_size;
|
||||||
u64 regid_promisc_array[MLX4_MAX_PORTS + 1];
|
u64 regid_promisc_array[MLX4_MAX_PORTS + 1];
|
||||||
u64 regid_allmulti_array[MLX4_MAX_PORTS + 1];
|
u64 regid_allmulti_array[MLX4_MAX_PORTS + 1];
|
||||||
|
struct mlx4_vf_dev *dev_vfs;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mlx4_eqe {
|
struct mlx4_eqe {
|
||||||
|
|
Loading…
Add table
Reference in a new issue