aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/pci.c35
-rw-r--r--drivers/pci/pci.h2
-rw-r--r--drivers/pci/probe.c5
-rw-r--r--include/linux/pci_regs.h13
4 files changed, 55 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 4859669f0ab5..557218222826 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1546,6 +1546,41 @@ void pci_enable_ari(struct pci_dev *dev)
1546} 1546}
1547 1547
1548/** 1548/**
1549 * pci_enable_acs - enable ACS if hardware support it
1550 * @dev: the PCI device
1551 */
1552void pci_enable_acs(struct pci_dev *dev)
1553{
1554 int pos;
1555 u16 cap;
1556 u16 ctrl;
1557
1558 if (!dev->is_pcie)
1559 return;
1560
1561 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
1562 if (!pos)
1563 return;
1564
1565 pci_read_config_word(dev, pos + PCI_ACS_CAP, &cap);
1566 pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl);
1567
1568 /* Source Validation */
1569 ctrl |= (cap & PCI_ACS_SV);
1570
1571 /* P2P Request Redirect */
1572 ctrl |= (cap & PCI_ACS_RR);
1573
1574 /* P2P Completion Redirect */
1575 ctrl |= (cap & PCI_ACS_CR);
1576
1577 /* Upstream Forwarding */
1578 ctrl |= (cap & PCI_ACS_UF);
1579
1580 pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl);
1581}
1582
1583/**
1549 * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge 1584 * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge
1550 * @dev: the PCI device 1585 * @dev: the PCI device
1551 * @pin: the INTx pin (1=INTA, 2=INTB, 3=INTD, 4=INTD) 1586 * @pin: the INTx pin (1=INTA, 2=INTB, 3=INTD, 4=INTD)
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index d92d1954a2fb..33ed8e0aba1e 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -311,4 +311,6 @@ static inline int pci_resource_alignment(struct pci_dev *dev,
311 return resource_alignment(res); 311 return resource_alignment(res);
312} 312}
313 313
314extern void pci_enable_acs(struct pci_dev *dev);
315
314#endif /* DRIVERS_PCI_H */ 316#endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 2adb47574d86..aac5b156a5c5 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -10,6 +10,7 @@
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/cpumask.h> 11#include <linux/cpumask.h>
12#include <linux/pci-aspm.h> 12#include <linux/pci-aspm.h>
13#include <linux/iommu.h>
13#include "pci.h" 14#include "pci.h"
14 15
15#define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ 16#define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */
@@ -1004,6 +1005,10 @@ static void pci_init_capabilities(struct pci_dev *dev)
1004 1005
1005 /* Single Root I/O Virtualization */ 1006 /* Single Root I/O Virtualization */
1006 pci_iov_init(dev); 1007 pci_iov_init(dev);
1008
1009 /* Enable ACS P2P upstream forwarding */
1010 if (iommu_found())
1011 pci_enable_acs(dev);
1007} 1012}
1008 1013
1009void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) 1014void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index dd0bed4f1cf0..d798770f08cd 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -502,6 +502,7 @@
502#define PCI_EXT_CAP_ID_VC 2 502#define PCI_EXT_CAP_ID_VC 2
503#define PCI_EXT_CAP_ID_DSN 3 503#define PCI_EXT_CAP_ID_DSN 3
504#define PCI_EXT_CAP_ID_PWR 4 504#define PCI_EXT_CAP_ID_PWR 4
505#define PCI_EXT_CAP_ID_ACS 13
505#define PCI_EXT_CAP_ID_ARI 14 506#define PCI_EXT_CAP_ID_ARI 14
506#define PCI_EXT_CAP_ID_ATS 15 507#define PCI_EXT_CAP_ID_ATS 15
507#define PCI_EXT_CAP_ID_SRIOV 16 508#define PCI_EXT_CAP_ID_SRIOV 16
@@ -662,4 +663,16 @@
662#define PCI_SRIOV_VFM_MO 0x2 /* Active.MigrateOut */ 663#define PCI_SRIOV_VFM_MO 0x2 /* Active.MigrateOut */
663#define PCI_SRIOV_VFM_AV 0x3 /* Active.Available */ 664#define PCI_SRIOV_VFM_AV 0x3 /* Active.Available */
664 665
666/* Access Control Service */
667#define PCI_ACS_CAP 0x04 /* ACS Capability Register */
668#define PCI_ACS_SV 0x01 /* Source Validation */
669#define PCI_ACS_TB 0x02 /* Translation Blocking */
670#define PCI_ACS_RR 0x04 /* P2P Request Redirect */
671#define PCI_ACS_CR 0x08 /* P2P Completion Redirect */
672#define PCI_ACS_UF 0x10 /* Upstream Forwarding */
673#define PCI_ACS_EC 0x20 /* P2P Egress Control */
674#define PCI_ACS_DT 0x40 /* Direct Translated P2P */
675#define PCI_ACS_CTRL 0x06 /* ACS Control Register */
676#define PCI_ACS_EGRESS_CTL_V 0x08 /* ACS Egress Control Vector */
677
665#endif /* LINUX_PCI_REGS_H */ 678#endif /* LINUX_PCI_REGS_H */