aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/phb3.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/hw/phb3.c b/hw/phb3.c
index d0b5010..1796a8f 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -405,6 +405,24 @@ static void phb3_switch_port_init(struct phb *phb,
pci_cfg_write32(phb, bdfn, aercap + PCIECAP_AER_CAPCTL, val32);
}
+static inline bool phb3_endpoint_report_ecrc(struct pci_device *pd)
+{
+ if (!pd || !pd->parent)
+ return true;
+
+ /* No ECRC generation and check on Broadcom ethernet adapter
+ * when it seats behind a PMC's PCIe switch downstream port.
+ * Otherwise, the Broadcom ethernet adapter's config space
+ * can't be accessed because of frozen PE error even after
+ * the frozen PE error is cleared.
+ */
+ if (pd->vdid == 0x168a14e4 || // Broadcom bnx2x CHIP_NUM_57800
+ pd->parent->vdid == 0x854611f8)
+ return false;
+
+ return true;
+}
+
static void phb3_endpoint_init(struct phb *phb,
struct pci_device *dev,
int ecap, int aercap)
@@ -442,8 +460,12 @@ static void phb3_endpoint_init(struct phb *phb,
/* Enable ECRC generation and check */
pci_cfg_read32(phb, bdfn, aercap + PCIECAP_AER_CAPCTL, &val32);
- val32 |= (PCIECAP_AER_CAPCTL_ECRCG_EN |
- PCIECAP_AER_CAPCTL_ECRCC_EN);
+ if (phb3_endpoint_report_ecrc(dev))
+ val32 |= (PCIECAP_AER_CAPCTL_ECRCG_EN |
+ PCIECAP_AER_CAPCTL_ECRCC_EN);
+ else
+ val32 &= ~(PCIECAP_AER_CAPCTL_ECRCG_EN |
+ PCIECAP_AER_CAPCTL_ECRCC_EN);
pci_cfg_write32(phb, bdfn, aercap + PCIECAP_AER_CAPCTL, val32);
}