mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 00:53:34 +02:00
Merge branch 'pci/enumeration'
- Skip enabling ExtTag on VFs since that bit is Reserved and causes misleading log messages (Håkon Bugge) - Mark 3ware-9650SA Root Port Extended Tags as broken since 9650SA can't handle 8-bit tags (Jörg Wedekind) - Release domain number from the correct IDA when a PCI host bridge has no parent device (Sergey Shtylyov) - Initialize endpoint Read Completion Boundary to match Root Port, regardless of ACPI _HPX (Håkon Bugge) - Apply _HPX PCIe Setting Record only to AER configuration, and only when OS owns PCIe hotplug but not AER, to avoid clobbering Extended Tag and Relaxed Ordering settings (Håkon Bugge) - Clear PCIe Root Status register with a write, not a read/modify/write (Lukas Wunner) * pci/enumeration: PCI/PME: Replace RMW of Root Status register with direct write PCI/ACPI: Restrict program_hpx_type2() to AER bits PCI: Initialize RCB from pci_configure_device() PCI: Check parent for NULL in of_pci_bus_release_domain_nr() PCI: Mark 3ware-9650SA Root Port Extended Tags as broken PCI: Do not attempt to set ExtTag for VFs
This commit is contained in:
commit
2304eeaf2f
|
|
@ -271,21 +271,6 @@ static acpi_status decode_type1_hpx_record(union acpi_object *record,
|
|||
return AE_OK;
|
||||
}
|
||||
|
||||
static bool pcie_root_rcb_set(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_dev *rp = pcie_find_root_port(dev);
|
||||
u16 lnkctl;
|
||||
|
||||
if (!rp)
|
||||
return false;
|
||||
|
||||
pcie_capability_read_word(rp, PCI_EXP_LNKCTL, &lnkctl);
|
||||
if (lnkctl & PCI_EXP_LNKCTL_RCB)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* _HPX PCI Express Setting Record (Type 2) */
|
||||
struct hpx_type2 {
|
||||
u32 revision;
|
||||
|
|
@ -311,6 +296,7 @@ static void program_hpx_type2(struct pci_dev *dev, struct hpx_type2 *hpx)
|
|||
{
|
||||
int pos;
|
||||
u32 reg32;
|
||||
const struct pci_host_bridge *host;
|
||||
|
||||
if (!hpx)
|
||||
return;
|
||||
|
|
@ -318,6 +304,15 @@ static void program_hpx_type2(struct pci_dev *dev, struct hpx_type2 *hpx)
|
|||
if (!pci_is_pcie(dev))
|
||||
return;
|
||||
|
||||
host = pci_find_host_bridge(dev->bus);
|
||||
|
||||
/*
|
||||
* Only do the _HPX Type 2 programming if OS owns PCIe native
|
||||
* hotplug but not AER.
|
||||
*/
|
||||
if (!host->native_pcie_hotplug || host->native_aer)
|
||||
return;
|
||||
|
||||
if (hpx->revision > 1) {
|
||||
pci_warn(dev, "PCIe settings rev %d not supported\n",
|
||||
hpx->revision);
|
||||
|
|
@ -325,33 +320,27 @@ static void program_hpx_type2(struct pci_dev *dev, struct hpx_type2 *hpx)
|
|||
}
|
||||
|
||||
/*
|
||||
* Don't allow _HPX to change MPS or MRRS settings. We manage
|
||||
* those to make sure they're consistent with the rest of the
|
||||
* platform.
|
||||
* We only allow _HPX to program DEVCTL bits related to AER, namely
|
||||
* PCI_EXP_DEVCTL_CERE, PCI_EXP_DEVCTL_NFERE, PCI_EXP_DEVCTL_FERE,
|
||||
* and PCI_EXP_DEVCTL_URRE.
|
||||
*
|
||||
* The rest of DEVCTL is managed by the OS to make sure it's
|
||||
* consistent with the rest of the platform.
|
||||
*/
|
||||
hpx->pci_exp_devctl_and |= PCI_EXP_DEVCTL_PAYLOAD |
|
||||
PCI_EXP_DEVCTL_READRQ;
|
||||
hpx->pci_exp_devctl_or &= ~(PCI_EXP_DEVCTL_PAYLOAD |
|
||||
PCI_EXP_DEVCTL_READRQ);
|
||||
hpx->pci_exp_devctl_and |= ~PCI_EXP_AER_FLAGS;
|
||||
hpx->pci_exp_devctl_or &= PCI_EXP_AER_FLAGS;
|
||||
|
||||
/* Initialize Device Control Register */
|
||||
pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL,
|
||||
~hpx->pci_exp_devctl_and, hpx->pci_exp_devctl_or);
|
||||
|
||||
/* Initialize Link Control Register */
|
||||
/* Log if _HPX attempts to modify Link Control Register */
|
||||
if (pcie_cap_has_lnkctl(dev)) {
|
||||
|
||||
/*
|
||||
* If the Root Port supports Read Completion Boundary of
|
||||
* 128, set RCB to 128. Otherwise, clear it.
|
||||
*/
|
||||
hpx->pci_exp_lnkctl_and |= PCI_EXP_LNKCTL_RCB;
|
||||
hpx->pci_exp_lnkctl_or &= ~PCI_EXP_LNKCTL_RCB;
|
||||
if (pcie_root_rcb_set(dev))
|
||||
hpx->pci_exp_lnkctl_or |= PCI_EXP_LNKCTL_RCB;
|
||||
|
||||
pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL,
|
||||
~hpx->pci_exp_lnkctl_and, hpx->pci_exp_lnkctl_or);
|
||||
if (hpx->pci_exp_lnkctl_and != 0xffff ||
|
||||
hpx->pci_exp_lnkctl_or != 0)
|
||||
pci_info(dev, "_HPX attempts Link Control setting (AND %#06x OR %#06x)\n",
|
||||
hpx->pci_exp_lnkctl_and,
|
||||
hpx->pci_exp_lnkctl_or);
|
||||
}
|
||||
|
||||
/* Find Advanced Error Reporting Enhanced Capability */
|
||||
|
|
|
|||
|
|
@ -2256,7 +2256,7 @@ void pcie_clear_device_status(struct pci_dev *dev)
|
|||
*/
|
||||
void pcie_clear_root_pme_status(struct pci_dev *dev)
|
||||
{
|
||||
pcie_capability_set_dword(dev, PCI_EXP_RTSTA, PCI_EXP_RTSTA_PME);
|
||||
pcie_capability_write_dword(dev, PCI_EXP_RTSTA, PCI_EXP_RTSTA_PME);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -6591,7 +6591,7 @@ static void of_pci_bus_release_domain_nr(struct device *parent, int domain_nr)
|
|||
return;
|
||||
|
||||
/* Release domain from IDA where it was allocated. */
|
||||
if (of_get_pci_domain_nr(parent->of_node) == domain_nr)
|
||||
if (parent && of_get_pci_domain_nr(parent->of_node) == domain_nr)
|
||||
ida_free(&pci_domain_nr_static_ida, domain_nr);
|
||||
else
|
||||
ida_free(&pci_domain_nr_dynamic_ida, domain_nr);
|
||||
|
|
|
|||
|
|
@ -88,6 +88,9 @@ struct pcie_tlp_log;
|
|||
#define PCI_BUS_BRIDGE_MEM_WINDOW 1
|
||||
#define PCI_BUS_BRIDGE_PREF_MEM_WINDOW 2
|
||||
|
||||
#define PCI_EXP_AER_FLAGS (PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | \
|
||||
PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE)
|
||||
|
||||
extern const unsigned char pcie_link_speed[];
|
||||
extern bool pci_early_dump;
|
||||
|
||||
|
|
|
|||
|
|
@ -239,9 +239,6 @@ void pcie_ecrc_get_policy(char *str)
|
|||
}
|
||||
#endif /* CONFIG_PCIE_ECRC */
|
||||
|
||||
#define PCI_EXP_AER_FLAGS (PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | \
|
||||
PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE)
|
||||
|
||||
int pcie_aer_is_native(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_host_bridge *host = pci_find_host_bridge(dev->bus);
|
||||
|
|
|
|||
|
|
@ -2270,7 +2270,8 @@ int pci_configure_extended_tags(struct pci_dev *dev, void *ign)
|
|||
u16 ctl;
|
||||
int ret;
|
||||
|
||||
if (!pci_is_pcie(dev))
|
||||
/* PCI_EXP_DEVCTL_EXT_TAG is RsvdP in VFs */
|
||||
if (!pci_is_pcie(dev) || dev->is_virtfn)
|
||||
return 0;
|
||||
|
||||
ret = pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap);
|
||||
|
|
@ -2410,6 +2411,37 @@ static void pci_configure_serr(struct pci_dev *dev)
|
|||
}
|
||||
}
|
||||
|
||||
static void pci_configure_rcb(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_dev *rp;
|
||||
u16 rp_lnkctl;
|
||||
|
||||
/*
|
||||
* Per PCIe r7.0, sec 7.5.3.7, RCB is only meaningful in Root Ports
|
||||
* (where it is read-only), Endpoints, and Bridges. It may only be
|
||||
* set for Endpoints and Bridges if it is set in the Root Port. For
|
||||
* Endpoints, it is 'RsvdP' for Virtual Functions.
|
||||
*/
|
||||
if (!pci_is_pcie(dev) ||
|
||||
pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
|
||||
pci_pcie_type(dev) == PCI_EXP_TYPE_UPSTREAM ||
|
||||
pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM ||
|
||||
pci_pcie_type(dev) == PCI_EXP_TYPE_RC_EC ||
|
||||
dev->is_virtfn)
|
||||
return;
|
||||
|
||||
/* Root Port often not visible to virtualized guests */
|
||||
rp = pcie_find_root_port(dev);
|
||||
if (!rp)
|
||||
return;
|
||||
|
||||
pcie_capability_read_word(rp, PCI_EXP_LNKCTL, &rp_lnkctl);
|
||||
pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL,
|
||||
PCI_EXP_LNKCTL_RCB,
|
||||
(rp_lnkctl & PCI_EXP_LNKCTL_RCB) ?
|
||||
PCI_EXP_LNKCTL_RCB : 0);
|
||||
}
|
||||
|
||||
static void pci_configure_device(struct pci_dev *dev)
|
||||
{
|
||||
pci_configure_mps(dev);
|
||||
|
|
@ -2419,6 +2451,7 @@ static void pci_configure_device(struct pci_dev *dev)
|
|||
pci_configure_aspm_l1ss(dev);
|
||||
pci_configure_eetlp_prefix(dev);
|
||||
pci_configure_serr(dev);
|
||||
pci_configure_rcb(dev);
|
||||
|
||||
pci_acpi_program_hp_params(dev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5591,6 +5591,7 @@ static void quirk_no_ext_tags(struct pci_dev *pdev)
|
|||
pci_walk_bus(bridge->bus, pci_configure_extended_tags, NULL);
|
||||
}
|
||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_3WARE, 0x1004, quirk_no_ext_tags);
|
||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_3WARE, 0x1005, quirk_no_ext_tags);
|
||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0132, quirk_no_ext_tags);
|
||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0140, quirk_no_ext_tags);
|
||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0141, quirk_no_ext_tags);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user