# HG changeset patch # User Yu Zhao # Date 1236909443 14400 # Node ID 313310b824c81e803a698ee3a1a8a94075096060 # Parent 66f3de153185eddae2d118d088ecfc17e96bf706 Backport: PCI: support PCIe ARI capability commit 58c3a727cb73b75a9104d295f096cca12959a5a5 Author: Yu Zhao Date: Tue Oct 14 14:02:53 2008 +0800 PCI: support PCIe ARI capability This patch adds support for PCI Express Alternative Routing-ID Interpretation (ARI) capability. The ARI capability extends the Function Number field of the PCI Express Endpoint by reusing the Device Number which is otherwise hardwired to 0. With ARI, an Endpoint can have up to 256 functions. Signed-off-by: Yu Zhao Signed-off-by: Jesse Barnes Signed-off-by: Yu Zhao diff -r 66f3de153185 -r 313310b824c8 drivers/pci/pci.c --- a/drivers/pci/pci.c Thu Mar 12 21:55:13 2009 -0400 +++ b/drivers/pci/pci.c Thu Mar 12 21:57:23 2009 -0400 @@ -629,6 +629,38 @@ return 0; } +/** + * pci_enable_ari - enable ARI forwarding if hardware support it + * @dev: the PCI device + */ +void pci_enable_ari(struct pci_dev *dev) +{ + int pos; + u32 cap; + u16 ctrl; + + if (!dev->is_pcie) + return; + + if (dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && + dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) + return; + + pos = pci_find_capability(dev, PCI_CAP_ID_EXP); + if (!pos) + return; + + pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap); + if (!(cap & PCI_EXP_DEVCAP2_ARI)) + return; + + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl); + ctrl |= PCI_EXP_DEVCTL2_ARI; + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl); + + dev->ari_enabled = 1; +} + int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge) { diff -r 66f3de153185 -r 313310b824c8 drivers/pci/pci.h --- a/drivers/pci/pci.h Thu Mar 12 21:55:13 2009 -0400 +++ b/drivers/pci/pci.h Thu Mar 12 21:57:23 2009 -0400 @@ -119,3 +119,14 @@ extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, struct resource *res, unsigned int reg); +extern void pci_enable_ari(struct pci_dev *dev); +/** + * pci_ari_enabled - query ARI forwarding status + * @dev: the PCI device + * + * Returns 1 if ARI forwarding is enabled, or 0 if not enabled; + */ +static inline int pci_ari_enabled(struct pci_dev *dev) +{ + return dev->ari_enabled; +} diff -r 66f3de153185 -r 313310b824c8 drivers/pci/probe.c --- a/drivers/pci/probe.c Thu Mar 12 21:55:13 2009 -0400 +++ b/drivers/pci/probe.c Thu Mar 12 21:57:23 2009 -0400 @@ -885,6 +885,9 @@ /* Fix up broken headers */ pci_fixup_device(pci_fixup_header, dev); + /* Alternative Routing-ID Forwarding */ + pci_enable_ari(dev); + /* * Add the device to our list of discovered devices * and the bus list for fixup functions, etc. diff -r 66f3de153185 -r 313310b824c8 include/linux/pci.h --- a/include/linux/pci.h Thu Mar 12 21:55:13 2009 -0400 +++ b/include/linux/pci.h Thu Mar 12 21:57:23 2009 -0400 @@ -172,6 +172,7 @@ struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */ int rom_attr_enabled; /* has display of the rom attribute been enabled? */ struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */ + unsigned int ari_enabled:1; /* ARI forwarding */ }; #define pci_dev_g(n) list_entry(n, struct pci_dev, global_list) diff -r 66f3de153185 -r 313310b824c8 include/linux/pci_regs.h --- a/include/linux/pci_regs.h Thu Mar 12 21:55:13 2009 -0400 +++ b/include/linux/pci_regs.h Thu Mar 12 21:57:23 2009 -0400 @@ -378,6 +378,10 @@ #define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */ #define PCI_EXP_RTCAP 30 /* Root Capabilities */ #define PCI_EXP_RTSTA 32 /* Root Status */ +#define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */ +#define PCI_EXP_DEVCAP2_ARI 0x20 /* Alternative Routing-ID */ +#define PCI_EXP_DEVCTL2 40 /* Device Control 2 */ +#define PCI_EXP_DEVCTL2_ARI 0x20 /* Alternative Routing-ID */ /* Extended Capabilities (PCI-X 2.0 and Express) */ #define PCI_EXT_CAP_ID(header) (header & 0x0000ffff) @@ -388,6 +392,7 @@ #define PCI_EXT_CAP_ID_VC 2 #define PCI_EXT_CAP_ID_DSN 3 #define PCI_EXT_CAP_ID_PWR 4 +#define PCI_EXT_CAP_ID_ARI 14 /* Advanced Error Reporting */ #define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */ @@ -463,4 +468,14 @@ #define PCI_PWR_CAP 12 /* Capability */ #define PCI_PWR_CAP_BUDGET(x) ((x) & 1) /* Included in system budget */ +/* Alternative Routing-ID Interpretation */ +#define PCI_ARI_CAP 0x04 /* ARI Capability Register */ +#define PCI_ARI_CAP_MFVC 0x0001 /* MFVC Function Groups Capability */ +#define PCI_ARI_CAP_ACS 0x0002 /* ACS Function Groups Capability */ +#define PCI_ARI_CAP_NFN(x) (((x) >> 8) & 0xff) /* Next Function Number */ +#define PCI_ARI_CTRL 0x06 /* ARI Control Register */ +#define PCI_ARI_CTRL_MFVC 0x0001 /* MFVC Function Groups Enable */ +#define PCI_ARI_CTRL_ACS 0x0002 /* ACS Function Groups Enable */ +#define PCI_ARI_CTRL_FG(x) (((x) >> 4) & 7) /* Function Group */ + #endif /* LINUX_PCI_REGS_H */