提交 f3eb83cf 编写于 作者: S Subbaraya Sundeep 提交者: Caspar Zhang

PCI: Assign bus numbers present in EA capability for bridges

task #29600094

commit 2dbce590117981196fe355efc0569bc6f949ae9b upstream.
Backport summary: for 4.19 kernel ICX PCIe Gen4 support.

The "Enhanced Allocation (EA) for Memory and I/O Resources" ECN, approved
23 October 2014, sec 6.9.1.2, specifies a second DW in the capability for
type 1 (bridge) functions to describe fixed secondary and subordinate bus
numbers.  This ECN was included in the PCIe r4.0 spec, but sec 6.9.1.2 was
omitted, presumably by mistake.

Read fixed bus numbers from the EA capability for bridges.
Signed-off-by: NSubbaraya Sundeep <sbhatta@marvell.com>
[bhelgaas: add pci_ea_fixed_busnrs() return value]
Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>

(cherry picked from commit 2dbce590117981196fe355efc0569bc6f949ae9b)
Signed-off-by: NEthan Zhao <haifeng.zhao@intel.com>
Signed-off-by: NArtie Ding <artie.ding@linux.alibaba.com>
Acked-by: NCaspar Zhang <caspar@linux.alibaba.com>
上级 1ae19f9b
...@@ -1034,6 +1034,36 @@ static void pci_enable_crs(struct pci_dev *pdev) ...@@ -1034,6 +1034,36 @@ static void pci_enable_crs(struct pci_dev *pdev)
static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus, static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus,
unsigned int available_buses); unsigned int available_buses);
/**
* pci_ea_fixed_busnrs() - Read fixed Secondary and Subordinate bus
* numbers from EA capability.
* @dev: Bridge
* @sec: updated with secondary bus number from EA
* @sub: updated with subordinate bus number from EA
*
* If @dev is a bridge with EA capability, update @sec and @sub with
* fixed bus numbers from the capability and return true. Otherwise,
* return false.
*/
static bool pci_ea_fixed_busnrs(struct pci_dev *dev, u8 *sec, u8 *sub)
{
int ea, offset;
u32 dw;
if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE)
return false;
/* find PCI EA capability in list */
ea = pci_find_capability(dev, PCI_CAP_ID_EA);
if (!ea)
return false;
offset = ea + PCI_EA_FIRST_ENT;
pci_read_config_dword(dev, offset, &dw);
*sec = dw & PCI_EA_SEC_BUS_MASK;
*sub = (dw & PCI_EA_SUB_BUS_MASK) >> PCI_EA_SUB_BUS_SHIFT;
return true;
}
/* /*
* pci_scan_bridge_extend() - Scan buses behind a bridge * pci_scan_bridge_extend() - Scan buses behind a bridge
...@@ -1068,6 +1098,9 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev, ...@@ -1068,6 +1098,9 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
u16 bctl; u16 bctl;
u8 primary, secondary, subordinate; u8 primary, secondary, subordinate;
int broken = 0; int broken = 0;
bool fixed_buses;
u8 fixed_sec, fixed_sub;
int next_busnr;
/* /*
* Make sure the bridge is powered on to be able to access config * Make sure the bridge is powered on to be able to access config
...@@ -1167,17 +1200,24 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev, ...@@ -1167,17 +1200,24 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
/* Clear errors */ /* Clear errors */
pci_write_config_word(dev, PCI_STATUS, 0xffff); pci_write_config_word(dev, PCI_STATUS, 0xffff);
/* Read bus numbers from EA Capability (if present) */
fixed_buses = pci_ea_fixed_busnrs(dev, &fixed_sec, &fixed_sub);
if (fixed_buses)
next_busnr = fixed_sec;
else
next_busnr = max + 1;
/* /*
* Prevent assigning a bus number that already exists. * Prevent assigning a bus number that already exists.
* This can happen when a bridge is hot-plugged, so in this * This can happen when a bridge is hot-plugged, so in this
* case we only re-scan this bus. * case we only re-scan this bus.
*/ */
child = pci_find_bus(pci_domain_nr(bus), max+1); child = pci_find_bus(pci_domain_nr(bus), next_busnr);
if (!child) { if (!child) {
child = pci_add_new_bus(bus, dev, max+1); child = pci_add_new_bus(bus, dev, next_busnr);
if (!child) if (!child)
goto out; goto out;
pci_bus_insert_busn_res(child, max+1, pci_bus_insert_busn_res(child, next_busnr,
bus->busn_res.end); bus->busn_res.end);
} }
max++; max++;
...@@ -1238,7 +1278,13 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev, ...@@ -1238,7 +1278,13 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
max += i; max += i;
} }
/* Set subordinate bus number to its real value */ /*
* Set subordinate bus number to its real value.
* If fixed subordinate bus number exists from EA
* capability then use it.
*/
if (fixed_buses)
max = fixed_sub;
pci_bus_update_busn_res_end(child, max); pci_bus_update_busn_res_end(child, max);
pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max); pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max);
} }
......
...@@ -372,6 +372,12 @@ ...@@ -372,6 +372,12 @@
#define PCI_EA_FIRST_ENT_BRIDGE 8 /* First EA Entry for Bridges */ #define PCI_EA_FIRST_ENT_BRIDGE 8 /* First EA Entry for Bridges */
#define PCI_EA_ES 0x00000007 /* Entry Size */ #define PCI_EA_ES 0x00000007 /* Entry Size */
#define PCI_EA_BEI 0x000000f0 /* BAR Equivalent Indicator */ #define PCI_EA_BEI 0x000000f0 /* BAR Equivalent Indicator */
/* EA fixed Secondary and Subordinate bus numbers for Bridge */
#define PCI_EA_SEC_BUS_MASK 0xff
#define PCI_EA_SUB_BUS_MASK 0xff00
#define PCI_EA_SUB_BUS_SHIFT 8
/* 0-5 map to BARs 0-5 respectively */ /* 0-5 map to BARs 0-5 respectively */
#define PCI_EA_BEI_BAR0 0 #define PCI_EA_BEI_BAR0 0
#define PCI_EA_BEI_BAR5 5 #define PCI_EA_BEI_BAR5 5
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册