summaryrefslogtreecommitdiff
path: root/drivers/vfio
diff options
context:
space:
mode:
authorMinghuan Lian <Minghuan.Lian@freescale.com>2014-01-24 06:23:54 (GMT)
committerJose Rivera <German.Rivera@freescale.com>2014-03-17 19:40:36 (GMT)
commit1f65e59b45115b55a7526dc30a255b0f27be9177 (patch)
tree1b346e74fbf05ec46799fdd5e651264acef4b25b /drivers/vfio
parent62f0a17ff5dfcba040175e9c1c90a39a08f26447 (diff)
downloadlinux-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.c60
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;