Save and restore SRIOV-related config registers.
Save the value of the IOV control and page size registers and restore them (along with the VF count) in pci_cfg_save/pci_cfg_restore. This ensures ARI remains enabled if a PF driver resets itself during the PCI_IOV_INIT callback. This might also properly restore SRIOV state across suspend/resume. Reviewed by: rstone, vangyzen Differential Revision: https://reviews.freebsd.org/D6192
This commit is contained in:
parent
804dbb21fc
commit
aa74485681
@ -5643,6 +5643,10 @@ pci_cfg_restore(device_t dev, struct pci_devinfo *dinfo)
|
||||
pci_resume_msi(dev);
|
||||
if (dinfo->cfg.msix.msix_location != 0)
|
||||
pci_resume_msix(dev);
|
||||
|
||||
if (dinfo->cfg.iov != NULL)
|
||||
pci_iov_cfg_restore(dev, dinfo);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@ -5755,6 +5759,9 @@ pci_cfg_save(device_t dev, struct pci_devinfo *dinfo, int setstate)
|
||||
if (dinfo->cfg.pcix.pcix_location != 0)
|
||||
pci_cfg_save_pcix(dev, dinfo);
|
||||
|
||||
if (dinfo->cfg.iov != NULL)
|
||||
pci_iov_cfg_save(dev, dinfo);
|
||||
|
||||
/*
|
||||
* don't set the state for display devices, base peripherals and
|
||||
* memory devices since bad things happen when they are powered down.
|
||||
|
@ -770,6 +770,29 @@ pci_iov_config(struct cdev *cdev, struct pci_iov_arg *arg)
|
||||
return (error);
|
||||
}
|
||||
|
||||
void
|
||||
pci_iov_cfg_restore(device_t dev, struct pci_devinfo *dinfo)
|
||||
{
|
||||
struct pcicfg_iov *iov;
|
||||
|
||||
iov = dinfo->cfg.iov;
|
||||
|
||||
IOV_WRITE(dinfo, PCIR_SRIOV_PAGE_SIZE, iov->iov_page_size, 4);
|
||||
IOV_WRITE(dinfo, PCIR_SRIOV_NUM_VFS, iov->iov_num_vfs, 2);
|
||||
IOV_WRITE(dinfo, PCIR_SRIOV_CTL, iov->iov_ctl, 2);
|
||||
}
|
||||
|
||||
void
|
||||
pci_iov_cfg_save(device_t dev, struct pci_devinfo *dinfo)
|
||||
{
|
||||
struct pcicfg_iov *iov;
|
||||
|
||||
iov = dinfo->cfg.iov;
|
||||
|
||||
iov->iov_page_size = IOV_READ(dinfo, PCIR_SRIOV_PAGE_SIZE, 4);
|
||||
iov->iov_ctl = IOV_READ(dinfo, PCIR_SRIOV_CTL, 2);
|
||||
}
|
||||
|
||||
/* Return true if child is a VF of the given PF. */
|
||||
static int
|
||||
pci_iov_is_child_vf(struct pcicfg_iov *pf, device_t child)
|
||||
|
@ -47,10 +47,16 @@ struct pcicfg_iov {
|
||||
int iov_pos;
|
||||
int iov_num_vfs;
|
||||
uint32_t iov_flags;
|
||||
|
||||
uint16_t iov_ctl;
|
||||
uint32_t iov_page_size;
|
||||
};
|
||||
|
||||
#define IOV_RMAN_INITED 0x0001
|
||||
#define IOV_BUSY 0x0002
|
||||
|
||||
void pci_iov_cfg_restore(device_t dev, struct pci_devinfo *dinfo);
|
||||
void pci_iov_cfg_save(device_t dev, struct pci_devinfo *dinfo);
|
||||
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user