aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/iov.c47
-rw-r--r--drivers/pci/pci-sysfs.c4
-rw-r--r--drivers/pci/pci.h1
-rw-r--r--include/linux/pci.h10
4 files changed, 60 insertions, 2 deletions
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index aeccc911abb8..f6781e42d00d 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -735,3 +735,50 @@ int pci_num_vf(struct pci_dev *dev)
735 return dev->sriov->nr_virtfn; 735 return dev->sriov->nr_virtfn;
736} 736}
737EXPORT_SYMBOL_GPL(pci_num_vf); 737EXPORT_SYMBOL_GPL(pci_num_vf);
738
739/**
740 * pci_sriov_set_totalvfs -- reduce the TotalVFs available
741 * @dev: the PCI PF device
742 * numvfs: number that should be used for TotalVFs supported
743 *
744 * Should be called from PF driver's probe routine with
745 * device's mutex held.
746 *
747 * Returns 0 if PF is an SRIOV-capable device and
748 * value of numvfs valid. If not a PF with VFS, return -EINVAL;
749 * if VFs already enabled, return -EBUSY.
750 */
751int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs)
752{
753 if (!dev || !dev->is_physfn || (numvfs > dev->sriov->total))
754 return -EINVAL;
755
756 /* Shouldn't change if VFs already enabled */
757 if (dev->sriov->ctrl & PCI_SRIOV_CTRL_VFE)
758 return -EBUSY;
759 else
760 dev->sriov->drvttl = numvfs;
761
762 return 0;
763}
764EXPORT_SYMBOL_GPL(pci_sriov_set_totalvfs);
765
766/**
767 * pci_sriov_get_totalvfs -- get total VFs supported on this devic3
768 * @dev: the PCI PF device
769 *
770 * For a PCIe device with SRIOV support, return the PCIe
771 * SRIOV capability value of TotalVFs or the value of drvttl
772 * if the driver reduced it. Otherwise, -EINVAL.
773 */
774int pci_sriov_get_totalvfs(struct pci_dev *dev)
775{
776 if (!dev || !dev->is_physfn)
777 return -EINVAL;
778
779 if (dev->sriov->drvttl)
780 return dev->sriov->drvttl;
781 else
782 return dev->sriov->total;
783}
784EXPORT_SYMBOL_GPL(pci_sriov_get_totalvfs);
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 74508c63bd47..99b5f83d2468 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -411,7 +411,7 @@ static ssize_t sriov_totalvfs_show(struct device *dev,
411{ 411{
412 struct pci_dev *pdev = to_pci_dev(dev); 412 struct pci_dev *pdev = to_pci_dev(dev);
413 413
414 return sprintf(buf, "%u\n", pdev->sriov->total); 414 return sprintf(buf, "%u\n", pci_sriov_get_totalvfs(pdev));
415} 415}
416 416
417 417
@@ -452,7 +452,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
452 } 452 }
453 453
454 /* if enabling vf's ... */ 454 /* if enabling vf's ... */
455 total = pdev->sriov->total; 455 total = pci_sriov_get_totalvfs(pdev);
456 /* Requested VFs to enable < totalvfs and none enabled already */ 456 /* Requested VFs to enable < totalvfs and none enabled already */
457 if ((num_vfs > 0) && (num_vfs <= total)) { 457 if ((num_vfs > 0) && (num_vfs <= total)) {
458 if (pdev->sriov->nr_virtfn == 0) { 458 if (pdev->sriov->nr_virtfn == 0) {
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 6f6cd145bb7e..553bbba76eec 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -240,6 +240,7 @@ struct pci_sriov {
240 u16 stride; /* following VF stride */ 240 u16 stride; /* following VF stride */
241 u32 pgsz; /* page size for BAR alignment */ 241 u32 pgsz; /* page size for BAR alignment */
242 u8 link; /* Function Dependency Link */ 242 u8 link; /* Function Dependency Link */
243 u16 drvttl; /* max num VFs driver supports */
243 struct pci_dev *dev; /* lowest numbered PF */ 244 struct pci_dev *dev; /* lowest numbered PF */
244 struct pci_dev *self; /* this PF */ 245 struct pci_dev *self; /* this PF */
245 struct mutex lock; /* lock for VF bus */ 246 struct mutex lock; /* lock for VF bus */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 7ef8fba319da..1ad824966e64 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1611,6 +1611,8 @@ extern int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn);
1611extern void pci_disable_sriov(struct pci_dev *dev); 1611extern void pci_disable_sriov(struct pci_dev *dev);
1612extern irqreturn_t pci_sriov_migration(struct pci_dev *dev); 1612extern irqreturn_t pci_sriov_migration(struct pci_dev *dev);
1613extern int pci_num_vf(struct pci_dev *dev); 1613extern int pci_num_vf(struct pci_dev *dev);
1614extern int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs);
1615extern int pci_sriov_get_totalvfs(struct pci_dev *dev);
1614#else 1616#else
1615static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn) 1617static inline int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn)
1616{ 1618{
@@ -1627,6 +1629,14 @@ static inline int pci_num_vf(struct pci_dev *dev)
1627{ 1629{
1628 return 0; 1630 return 0;
1629} 1631}
1632static inline int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs)
1633{
1634 return 0;
1635}
1636static inline int pci_sriov_get_totalvfs(struct pci_dev *dev)
1637{
1638 return 0;
1639}
1630#endif 1640#endif
1631 1641
1632#if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE) 1642#if defined(CONFIG_HOTPLUG_PCI) || defined(CONFIG_HOTPLUG_PCI_MODULE)