diff options
-rw-r--r-- | drivers/vfio/fsl_pci_ep/fsl_pci_ep.c | 60 |
1 files changed, 42 insertions, 18 deletions
diff --git a/drivers/vfio/fsl_pci_ep/fsl_pci_ep.c b/drivers/vfio/fsl_pci_ep/fsl_pci_ep.c index 8fda88d..47380f2 100644 --- a/drivers/vfio/fsl_pci_ep/fsl_pci_ep.c +++ b/drivers/vfio/fsl_pci_ep/fsl_pci_ep.c @@ -42,6 +42,9 @@ #define CONFIG_ACCESS_TYPE_VF_SRIOV 3 #define CONFIG_ACCESS_ENABLE (1 << 31) +#define PCI_ATMU_MIN_SIZE (4 * 1024) /* The smallest window size is 4 Kbytes */ +#define PCI_OB_WIN_MEM_ATTR 0x80044000 /* enable & mem R/W */ + static DEFINE_SPINLOCK(pci_ep_spinlock); LIST_HEAD(pci_ep_controllers); @@ -407,17 +410,24 @@ static int fsl_pci_ep_set_ibwin(struct pci_ep_dev *ep, return -EINVAL; if (ep->type == PCI_EP_TYPE_PF) { - int bits = ilog2(win->size); - u32 piwar = PIWAR_EN | PIWAR_PF | PIWAR_TGI_LOCAL | - PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP; + u32 attr; + iw_regs = &pf->regs->piw[ep->iw_num - win->idx - 1]; + + if (win->size < PCI_ATMU_MIN_SIZE) + attr = 0; + else + attr = PIWAR_EN | PIWAR_PF | PIWAR_TGI_LOCAL | + PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | + (ilog2(win->size) - 1); + /* Setup inbound memory window */ spin_lock(&pf->lock); out_be32(&iw_regs->pitar, win->cpu_addr >> 12); if (win->attr) /* use the specific attribute */ out_be32(&iw_regs->piwar, win->attr); else /* use the default attribute */ - out_be32(&iw_regs->piwar, piwar | (bits - 1)); + out_be32(&iw_regs->piwar, attr); spin_unlock(&pf->lock); } else { /* @@ -445,11 +455,15 @@ static int fsl_pci_ep_set_obwin(struct pci_ep_dev *ep, if (ep->type == PCI_EP_TYPE_PF) { int bits; - u32 flags = 0x80044000; /* enable & mem R/W */ - - bits = min(ilog2(win->size), - __ffs(win->pci_addr | win->cpu_addr)); - + u32 attr; /* enable & mem R/W */ + + if (win->size < PCI_ATMU_MIN_SIZE) + attr = 0; + else { + bits = min(ilog2(win->size), + __ffs(win->pci_addr | win->cpu_addr)); + attr = PCI_OB_WIN_MEM_ATTR | (bits - 1); + } spin_lock(&pf->lock); out_be32(&ow_regs->potar, win->pci_addr >> 12); out_be32(&ow_regs->potear, win->pci_addr >> 44); @@ -457,7 +471,7 @@ static int fsl_pci_ep_set_obwin(struct pci_ep_dev *ep, if (win->attr) /* use the specific attribute */ out_be32(&ow_regs->powar, win->attr); else /* use the default attribute */ - out_be32(&ow_regs->powar, flags | (bits - 1)); + out_be32(&ow_regs->powar, attr); spin_unlock(&pf->lock); } else { /* @@ -506,9 +520,7 @@ static int fsl_pci_ep_set_vfibwin(struct pci_ep_dev *ep, { struct pci_pf_dev *pf = ep->pf; struct pci_inbound_window_regs *iw_regs; - int bits; - u32 piwar = PIWAR_EN | PIWAR_PF | PIWAR_TGI_LOCAL | - PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP; + u32 attr; if (win->idx >= ep->iw_num) return -EINVAL; @@ -517,7 +529,13 @@ static int fsl_pci_ep_set_vfibwin(struct pci_ep_dev *ep, if (ep->type != PCI_EP_TYPE_PF) return -EINVAL; - bits = ilog2(win->size); + if (win->size < PCI_ATMU_MIN_SIZE) + attr = 0; + else + attr = PIWAR_EN | PIWAR_PF | PIWAR_TGI_LOCAL | + PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | + (ilog2(win->size) - 1); + iw_regs = &pf->vf_regs->vfiw[ep->iw_num - win->idx - 1]; /* Setup inbound memory window */ @@ -526,7 +544,7 @@ static int fsl_pci_ep_set_vfibwin(struct pci_ep_dev *ep, if (win->attr) /* use the specified attribute */ out_be32(&iw_regs->piwar, win->attr); else /* use the default attribute */ - out_be32(&iw_regs->piwar, piwar | (bits - 1)); + out_be32(&iw_regs->piwar, attr); spin_unlock(&pf->lock); return 0; @@ -538,7 +556,7 @@ static int fsl_pci_ep_set_vfobwin(struct pci_ep_dev *ep, struct pci_pf_dev *pf = ep->pf; struct pci_outbound_window_regs *ow_regs; int bits; - u32 flags = 0x80044000; /* enable & mem R/W */ + u32 attr; if (win->idx >= ep->iw_num) return -EINVAL; @@ -549,14 +567,20 @@ static int fsl_pci_ep_set_vfobwin(struct pci_ep_dev *ep, ow_regs = &pf->vf_regs->vfow[win->idx]; - bits = min(ilog2(win->size), __ffs(win->pci_addr | win->cpu_addr)); + if (win->size < PCI_ATMU_MIN_SIZE) + attr = 0; + else { + bits = min(ilog2(win->size), + __ffs(win->pci_addr | win->cpu_addr)); + attr = PCI_OB_WIN_MEM_ATTR | (bits - 1); + } spin_lock(&pf->lock); out_be32(&ow_regs->powbar, win->cpu_addr >> 12); if (win->attr) /* use the specified attribute */ out_be32(&ow_regs->powar, win->attr); else /* use the default attribute */ - out_be32(&ow_regs->powar, flags | (bits - 1)); + out_be32(&ow_regs->powar, attr); spin_unlock(&pf->lock); return 0; |