aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei Yang <weiyang@linux.vnet.ibm.com>2015-03-25 04:23:46 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2015-03-30 22:02:36 -0400
commitf59dca27d20c73500c4a88ab9a077e40669755db (patch)
treea9a54e1f7ec522530614752db2f80c2cbd4e134b
parentc1fe1f96e30d31cc99826f19a058d9e9eef87712 (diff)
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: Wei Yang <weiyang@linux.vnet.ibm.com> Acked-by: Bjorn Helgaas <bhelgaas@google.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--drivers/pci/iov.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 27b98c361823..a8752c2c2b53 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -31,6 +31,21 @@ static inline u8 virtfn_devfn(struct pci_dev *dev, int id)
31 dev->sriov->stride * id) & 0xff; 31 dev->sriov->stride * id) & 0xff;
32} 32}
33 33
34/*
35 * Per SR-IOV spec sec 3.3.10 and 3.3.11, First VF Offset and VF Stride may
36 * change when NumVFs changes.
37 *
38 * Update iov->offset and iov->stride when NumVFs is written.
39 */
40static inline void pci_iov_set_numvfs(struct pci_dev *dev, int nr_virtfn)
41{
42 struct pci_sriov *iov = dev->sriov;
43
44 pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, nr_virtfn);
45 pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_OFFSET, &iov->offset);
46 pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_STRIDE, &iov->stride);
47}
48
34static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr) 49static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr)
35{ 50{
36 struct pci_bus *child; 51 struct pci_bus *child;
@@ -253,7 +268,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
253 return rc; 268 return rc;
254 } 269 }
255 270
256 pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, nr_virtfn); 271 pci_iov_set_numvfs(dev, nr_virtfn);
257 iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE; 272 iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE;
258 pci_cfg_access_lock(dev); 273 pci_cfg_access_lock(dev);
259 pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); 274 pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
@@ -282,7 +297,7 @@ failed:
282 iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE); 297 iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE);
283 pci_cfg_access_lock(dev); 298 pci_cfg_access_lock(dev);
284 pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); 299 pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
285 pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, 0); 300 pci_iov_set_numvfs(dev, 0);
286 ssleep(1); 301 ssleep(1);
287 pci_cfg_access_unlock(dev); 302 pci_cfg_access_unlock(dev);
288 303
@@ -313,7 +328,7 @@ static void sriov_disable(struct pci_dev *dev)
313 sysfs_remove_link(&dev->dev.kobj, "dep_link"); 328 sysfs_remove_link(&dev->dev.kobj, "dep_link");
314 329
315 iov->num_VFs = 0; 330 iov->num_VFs = 0;
316 pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, 0); 331 pci_iov_set_numvfs(dev, 0);
317} 332}
318 333
319static int sriov_init(struct pci_dev *dev, int pos) 334static int sriov_init(struct pci_dev *dev, int pos)
@@ -452,7 +467,7 @@ static void sriov_restore_state(struct pci_dev *dev)
452 pci_update_resource(dev, i); 467 pci_update_resource(dev, i);
453 468
454 pci_write_config_dword(dev, iov->pos + PCI_SRIOV_SYS_PGSIZE, iov->pgsz); 469 pci_write_config_dword(dev, iov->pos + PCI_SRIOV_SYS_PGSIZE, iov->pgsz);
455 pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, iov->num_VFs); 470 pci_iov_set_numvfs(dev, iov->num_VFs);
456 pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); 471 pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
457 if (iov->ctrl & PCI_SRIOV_CTRL_VFE) 472 if (iov->ctrl & PCI_SRIOV_CTRL_VFE)
458 msleep(100); 473 msleep(100);