diff options
-rw-r--r-- | drivers/pci/pci.c | 32 | ||||
-rw-r--r-- | drivers/pci/pci.h | 12 | ||||
-rw-r--r-- | drivers/pci/probe.c | 3 | ||||
-rw-r--r-- | include/linux/pci.h | 1 | ||||
-rw-r--r-- | include/linux/pci_regs.h | 14 |
5 files changed, 62 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 553ca6657955..4db261e13e69 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -1299,6 +1299,38 @@ void pci_pm_init(struct pci_dev *dev) | |||
1299 | } | 1299 | } |
1300 | } | 1300 | } |
1301 | 1301 | ||
1302 | /** | ||
1303 | * pci_enable_ari - enable ARI forwarding if hardware support it | ||
1304 | * @dev: the PCI device | ||
1305 | */ | ||
1306 | void pci_enable_ari(struct pci_dev *dev) | ||
1307 | { | ||
1308 | int pos; | ||
1309 | u32 cap; | ||
1310 | u16 ctrl; | ||
1311 | |||
1312 | if (!dev->is_pcie) | ||
1313 | return; | ||
1314 | |||
1315 | if (dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && | ||
1316 | dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) | ||
1317 | return; | ||
1318 | |||
1319 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | ||
1320 | if (!pos) | ||
1321 | return; | ||
1322 | |||
1323 | pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap); | ||
1324 | if (!(cap & PCI_EXP_DEVCAP2_ARI)) | ||
1325 | return; | ||
1326 | |||
1327 | pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl); | ||
1328 | ctrl |= PCI_EXP_DEVCTL2_ARI; | ||
1329 | pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl); | ||
1330 | |||
1331 | dev->ari_enabled = 1; | ||
1332 | } | ||
1333 | |||
1302 | int | 1334 | int |
1303 | pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge) | 1335 | pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge) |
1304 | { | 1336 | { |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 601abdc8dd9f..39684c1415c5 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -151,4 +151,16 @@ struct pci_slot_attribute { | |||
151 | }; | 151 | }; |
152 | #define to_pci_slot_attr(s) container_of(s, struct pci_slot_attribute, attr) | 152 | #define to_pci_slot_attr(s) container_of(s, struct pci_slot_attribute, attr) |
153 | 153 | ||
154 | extern void pci_enable_ari(struct pci_dev *dev); | ||
155 | /** | ||
156 | * pci_ari_enabled - query ARI forwarding status | ||
157 | * @dev: the PCI device | ||
158 | * | ||
159 | * Returns 1 if ARI forwarding is enabled, or 0 if not enabled; | ||
160 | */ | ||
161 | static inline int pci_ari_enabled(struct pci_dev *dev) | ||
162 | { | ||
163 | return dev->ari_enabled; | ||
164 | } | ||
165 | |||
154 | #endif /* DRIVERS_PCI_H */ | 166 | #endif /* DRIVERS_PCI_H */ |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 8c158b9abd41..3141e8deeac4 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -1025,6 +1025,9 @@ static void pci_init_capabilities(struct pci_dev *dev) | |||
1025 | 1025 | ||
1026 | /* Vital Product Data */ | 1026 | /* Vital Product Data */ |
1027 | pci_vpd_pci22_init(dev); | 1027 | pci_vpd_pci22_init(dev); |
1028 | |||
1029 | /* Alternative Routing-ID Forwarding */ | ||
1030 | pci_enable_ari(dev); | ||
1028 | } | 1031 | } |
1029 | 1032 | ||
1030 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | 1033 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 008005674b60..7e9a1f0715e6 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -214,6 +214,7 @@ struct pci_dev { | |||
214 | unsigned int broken_parity_status:1; /* Device generates false positive parity */ | 214 | unsigned int broken_parity_status:1; /* Device generates false positive parity */ |
215 | unsigned int msi_enabled:1; | 215 | unsigned int msi_enabled:1; |
216 | unsigned int msix_enabled:1; | 216 | unsigned int msix_enabled:1; |
217 | unsigned int ari_enabled:1; /* ARI forwarding */ | ||
217 | unsigned int is_managed:1; | 218 | unsigned int is_managed:1; |
218 | unsigned int is_pcie:1; | 219 | unsigned int is_pcie:1; |
219 | pci_dev_flags_t dev_flags; | 220 | pci_dev_flags_t dev_flags; |
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index 450684f7eaac..eb6686b88f9a 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h | |||
@@ -419,6 +419,10 @@ | |||
419 | #define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */ | 419 | #define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */ |
420 | #define PCI_EXP_RTCAP 30 /* Root Capabilities */ | 420 | #define PCI_EXP_RTCAP 30 /* Root Capabilities */ |
421 | #define PCI_EXP_RTSTA 32 /* Root Status */ | 421 | #define PCI_EXP_RTSTA 32 /* Root Status */ |
422 | #define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */ | ||
423 | #define PCI_EXP_DEVCAP2_ARI 0x20 /* Alternative Routing-ID */ | ||
424 | #define PCI_EXP_DEVCTL2 40 /* Device Control 2 */ | ||
425 | #define PCI_EXP_DEVCTL2_ARI 0x20 /* Alternative Routing-ID */ | ||
422 | 426 | ||
423 | /* Extended Capabilities (PCI-X 2.0 and Express) */ | 427 | /* Extended Capabilities (PCI-X 2.0 and Express) */ |
424 | #define PCI_EXT_CAP_ID(header) (header & 0x0000ffff) | 428 | #define PCI_EXT_CAP_ID(header) (header & 0x0000ffff) |
@@ -429,6 +433,7 @@ | |||
429 | #define PCI_EXT_CAP_ID_VC 2 | 433 | #define PCI_EXT_CAP_ID_VC 2 |
430 | #define PCI_EXT_CAP_ID_DSN 3 | 434 | #define PCI_EXT_CAP_ID_DSN 3 |
431 | #define PCI_EXT_CAP_ID_PWR 4 | 435 | #define PCI_EXT_CAP_ID_PWR 4 |
436 | #define PCI_EXT_CAP_ID_ARI 14 | ||
432 | 437 | ||
433 | /* Advanced Error Reporting */ | 438 | /* Advanced Error Reporting */ |
434 | #define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */ | 439 | #define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */ |
@@ -536,5 +541,14 @@ | |||
536 | #define HT_CAPTYPE_GEN3 0xD0 /* Generation 3 hypertransport configuration */ | 541 | #define HT_CAPTYPE_GEN3 0xD0 /* Generation 3 hypertransport configuration */ |
537 | #define HT_CAPTYPE_PM 0xE0 /* Hypertransport powermanagement configuration */ | 542 | #define HT_CAPTYPE_PM 0xE0 /* Hypertransport powermanagement configuration */ |
538 | 543 | ||
544 | /* Alternative Routing-ID Interpretation */ | ||
545 | #define PCI_ARI_CAP 0x04 /* ARI Capability Register */ | ||
546 | #define PCI_ARI_CAP_MFVC 0x0001 /* MFVC Function Groups Capability */ | ||
547 | #define PCI_ARI_CAP_ACS 0x0002 /* ACS Function Groups Capability */ | ||
548 | #define PCI_ARI_CAP_NFN(x) (((x) >> 8) & 0xff) /* Next Function Number */ | ||
549 | #define PCI_ARI_CTRL 0x06 /* ARI Control Register */ | ||
550 | #define PCI_ARI_CTRL_MFVC 0x0001 /* MFVC Function Groups Enable */ | ||
551 | #define PCI_ARI_CTRL_ACS 0x0002 /* ACS Function Groups Enable */ | ||
552 | #define PCI_ARI_CTRL_FG(x) (((x) >> 4) & 7) /* Function Group */ | ||
539 | 553 | ||
540 | #endif /* LINUX_PCI_REGS_H */ | 554 | #endif /* LINUX_PCI_REGS_H */ |