提交 f59dca27 编写于 作者: W Wei Yang 提交者: Benjamin Herrenschmidt

PCI: Refresh First VF Offset and VF Stride when updating NumVFs

The First VF Offset and VF Stride fields depend on the NumVFs setting, so
refresh the cached fields in struct pci_sriov when updating NumVFs.  See
the SR-IOV spec r1.1, sec 3.3.9 and 3.3.10.

[bhelgaas: changelog, remove kernel-doc comment marker]
Signed-off-by: NWei Yang <weiyang@linux.vnet.ibm.com>
Acked-by: NBjorn Helgaas <bhelgaas@google.com>
Signed-off-by: NBenjamin Herrenschmidt <benh@kernel.crashing.org>
上级 c1fe1f96
...@@ -31,6 +31,21 @@ static inline u8 virtfn_devfn(struct pci_dev *dev, int id) ...@@ -31,6 +31,21 @@ static inline u8 virtfn_devfn(struct pci_dev *dev, int id)
dev->sriov->stride * id) & 0xff; dev->sriov->stride * id) & 0xff;
} }
/*
* Per SR-IOV spec sec 3.3.10 and 3.3.11, First VF Offset and VF Stride may
* change when NumVFs changes.
*
* Update iov->offset and iov->stride when NumVFs is written.
*/
static inline void pci_iov_set_numvfs(struct pci_dev *dev, int nr_virtfn)
{
struct pci_sriov *iov = dev->sriov;
pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, nr_virtfn);
pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_OFFSET, &iov->offset);
pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_STRIDE, &iov->stride);
}
static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr) static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr)
{ {
struct pci_bus *child; struct pci_bus *child;
...@@ -253,7 +268,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) ...@@ -253,7 +268,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
return rc; return rc;
} }
pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, nr_virtfn); pci_iov_set_numvfs(dev, nr_virtfn);
iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE; iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE;
pci_cfg_access_lock(dev); pci_cfg_access_lock(dev);
pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
...@@ -282,7 +297,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) ...@@ -282,7 +297,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE); iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE);
pci_cfg_access_lock(dev); pci_cfg_access_lock(dev);
pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, 0); pci_iov_set_numvfs(dev, 0);
ssleep(1); ssleep(1);
pci_cfg_access_unlock(dev); pci_cfg_access_unlock(dev);
...@@ -313,7 +328,7 @@ static void sriov_disable(struct pci_dev *dev) ...@@ -313,7 +328,7 @@ static void sriov_disable(struct pci_dev *dev)
sysfs_remove_link(&dev->dev.kobj, "dep_link"); sysfs_remove_link(&dev->dev.kobj, "dep_link");
iov->num_VFs = 0; iov->num_VFs = 0;
pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, 0); pci_iov_set_numvfs(dev, 0);
} }
static int sriov_init(struct pci_dev *dev, int pos) static int sriov_init(struct pci_dev *dev, int pos)
...@@ -452,7 +467,7 @@ static void sriov_restore_state(struct pci_dev *dev) ...@@ -452,7 +467,7 @@ static void sriov_restore_state(struct pci_dev *dev)
pci_update_resource(dev, i); pci_update_resource(dev, i);
pci_write_config_dword(dev, iov->pos + PCI_SRIOV_SYS_PGSIZE, iov->pgsz); pci_write_config_dword(dev, iov->pos + PCI_SRIOV_SYS_PGSIZE, iov->pgsz);
pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, iov->num_VFs); pci_iov_set_numvfs(dev, iov->num_VFs);
pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
if (iov->ctrl & PCI_SRIOV_CTRL_VFE) if (iov->ctrl & PCI_SRIOV_CTRL_VFE)
msleep(100); msleep(100);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册