Commit ca6139ff authored by Raghu Vatsavayi's avatar Raghu Vatsavayi Committed by David S. Miller

liquidio CN23XX: sysfs VF config support

Adds sysfs based support for enabling or disabling VFs.
Signed-off-by: default avatarRaghu Vatsavayi <raghu.vatsavayi@caviumnetworks.com>
Signed-off-by: default avatarDerek Chickles <derek.chickles@caviumnetworks.com>
Signed-off-by: default avatarSatanand Burla <satananda.burla@caviumnetworks.com>
Signed-off-by: default avatarFelix Manlunas <felix.manlunas@caviumnetworks.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d13520c7
......@@ -180,6 +180,10 @@ struct octeon_device_priv {
unsigned long napi_mask;
};
#ifdef CONFIG_PCI_IOV
static int liquidio_enable_sriov(struct pci_dev *dev, int num_vfs);
#endif
static int octeon_device_init(struct octeon_device *);
static int liquidio_stop(struct net_device *netdev);
static void liquidio_remove(struct pci_dev *pdev);
......@@ -518,6 +522,9 @@ static struct pci_driver liquidio_pci_driver = {
.suspend = liquidio_suspend,
.resume = liquidio_resume,
#endif
#ifdef CONFIG_PCI_IOV
.sriov_configure = liquidio_enable_sriov,
#endif
};
/**
......@@ -1472,6 +1479,10 @@ static void octeon_destroy_resources(struct octeon_device *oct)
continue;
octeon_delete_instr_queue(oct, i);
}
#ifdef CONFIG_PCI_IOV
if (oct->sriov_info.sriov_enabled)
pci_disable_sriov(oct->pci_dev);
#endif
/* fallthrough */
case OCT_DEV_SC_BUFF_POOL_INIT_DONE:
octeon_free_sc_buffer_pool(oct);
......@@ -3990,6 +4001,101 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
return -ENODEV;
}
#ifdef CONFIG_PCI_IOV
static int octeon_enable_sriov(struct octeon_device *oct)
{
unsigned int num_vfs_alloced = oct->sriov_info.num_vfs_alloced;
struct pci_dev *vfdev;
int err;
u32 u;
if (OCTEON_CN23XX_PF(oct) && num_vfs_alloced) {
err = pci_enable_sriov(oct->pci_dev,
oct->sriov_info.num_vfs_alloced);
if (err) {
dev_err(&oct->pci_dev->dev,
"OCTEON: Failed to enable PCI sriov: %d\n",
err);
oct->sriov_info.num_vfs_alloced = 0;
return err;
}
oct->sriov_info.sriov_enabled = 1;
/* init lookup table that maps DPI ring number to VF pci_dev
* struct pointer
*/
u = 0;
vfdev = pci_get_device(PCI_VENDOR_ID_CAVIUM,
OCTEON_CN23XX_VF_VID, NULL);
while (vfdev) {
if (vfdev->is_virtfn &&
(vfdev->physfn == oct->pci_dev)) {
oct->sriov_info.dpiring_to_vfpcidev_lut[u] =
vfdev;
u += oct->sriov_info.rings_per_vf;
}
vfdev = pci_get_device(PCI_VENDOR_ID_CAVIUM,
OCTEON_CN23XX_VF_VID, vfdev);
}
}
return num_vfs_alloced;
}
static int lio_pci_sriov_disable(struct octeon_device *oct)
{
int u;
if (pci_vfs_assigned(oct->pci_dev)) {
dev_err(&oct->pci_dev->dev, "VFs are still assigned to VMs.\n");
return -EPERM;
}
pci_disable_sriov(oct->pci_dev);
u = 0;
while (u < MAX_POSSIBLE_VFS) {
oct->sriov_info.dpiring_to_vfpcidev_lut[u] = NULL;
u += oct->sriov_info.rings_per_vf;
}
oct->sriov_info.num_vfs_alloced = 0;
dev_info(&oct->pci_dev->dev, "oct->pf_num:%d disabled VFs\n",
oct->pf_num);
return 0;
}
static int liquidio_enable_sriov(struct pci_dev *dev, int num_vfs)
{
struct octeon_device *oct = pci_get_drvdata(dev);
int ret = 0;
if ((num_vfs == oct->sriov_info.num_vfs_alloced) &&
(oct->sriov_info.sriov_enabled)) {
dev_info(&oct->pci_dev->dev, "oct->pf_num:%d already enabled num_vfs:%d\n",
oct->pf_num, num_vfs);
return 0;
}
if (!num_vfs) {
ret = lio_pci_sriov_disable(oct);
} else if (num_vfs > oct->sriov_info.max_vfs) {
dev_err(&oct->pci_dev->dev,
"OCTEON: Max allowed VFs:%d user requested:%d",
oct->sriov_info.max_vfs, num_vfs);
ret = -EPERM;
} else {
oct->sriov_info.num_vfs_alloced = num_vfs;
ret = octeon_enable_sriov(oct);
dev_info(&oct->pci_dev->dev, "oct->pf_num:%d num_vfs:%d\n",
oct->pf_num, num_vfs);
}
return ret;
}
#endif
/**
* \brief initialize the NIC
* @param oct octeon device
......
......@@ -472,4 +472,7 @@ struct octeon_config {
#define MAX_POSSIBLE_OCTEON_INSTR_QUEUES CN23XX_MAX_INPUT_QUEUES
#define MAX_POSSIBLE_OCTEON_OUTPUT_QUEUES CN23XX_MAX_OUTPUT_QUEUES
#define MAX_POSSIBLE_VFS 64
#endif /* __OCTEON_CONFIG_H__ */
......@@ -38,6 +38,7 @@
#define OCTEON_CN68XX 0x0091
#define OCTEON_CN66XX 0x0092
#define OCTEON_CN23XX_PF_VID 0x9702
#define OCTEON_CN23XX_VF_VID 0x9712
/**RevisionId for the chips */
#define OCTEON_CN23XX_REV_1_0 0x00
......@@ -331,6 +332,9 @@ struct octeon_sriov_info {
**/
u32 max_vfs;
/** Number of VF devices enabled using sysfs. */
u32 num_vfs_alloced;
/* Actual rings left for PF device */
u32 num_pf_rings;
......@@ -340,6 +344,10 @@ struct octeon_sriov_info {
/* total pf rings */
u32 trs;
u32 sriov_enabled;
/*lookup table that maps DPI ring number to VF pci_dev struct pointer*/
struct pci_dev *dpiring_to_vfpcidev_lut[MAX_POSSIBLE_VFS];
};
struct octeon_ioq_vector {
......
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