diff options
author | Minghuan Lian <Minghuan.Lian@freescale.com> | 2014-01-24 06:23:54 (GMT) |
---|---|---|
committer | Jose Rivera <German.Rivera@freescale.com> | 2014-03-17 19:40:36 (GMT) |
commit | 1f65e59b45115b55a7526dc30a255b0f27be9177 (patch) | |
tree | 1b346e74fbf05ec46799fdd5e651264acef4b25b /drivers/vfio | |
parent | 62f0a17ff5dfcba040175e9c1c90a39a08f26447 (diff) | |
download | linux-fsl-qoriq-1f65e59b45115b55a7526dc30a255b0f27be9177.tar.xz |
fsl_pci_ep: fix ATMU window attribute setting
If window size is 0, the bits of size will be 0xffffffff, so window
attribute will be set a wrong value. The patch fixes this issue.
Signed-off-by: Minghuan Lian <Minghuan.Lian@freescale.com>
Change-Id: Ieac8428eb1b41a245c89637186d4eb27eedcff55
Reviewed-on: http://git.am.freescale.net:8181/9606
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Tiefei Zang <tie-fei.zang@freescale.com>
Reviewed-by: Jose Rivera <German.Rivera@freescale.com>
Diffstat (limited to 'drivers/vfio')
-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; |