[Skiboot] [PATCH] PCI: Clear error bits after changing MPS

Gavin Shan gwshan at linux.vnet.ibm.com
Fri Sep 11 14:36:34 AEST 2015


Chaning MPS on PCI upstream bridge might cause error bits set on
downstream endpoints when system boots into Linux as below case
shows:

host# lspci -vvs 0001:06:00.0
0001:06:00.0 Ethernet controller: Broadcom Corporation \
             NetXtreme II BCM57810 10 Gigabit Ethernet (rev 10)
    :
DevSta:	CorrErr+ UncorrErr- FatalErr- UnsuppReq+ AuxPwr- TransPend-
    :
CESta:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+

This clears those error bits in AER and PCIe capability after MPS
is changed. With the patch applied, no more error bits are seen.

Reported-by: John Walthour <jwalthour at us.ibm.com>
Signed-off-by: Gavin Shan <gwshan at linux.vnet.ibm.com>
---
 core/pci.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/core/pci.c b/core/pci.c
index 26ed48c..6cfb3cb 100644
--- a/core/pci.c
+++ b/core/pci.c
@@ -609,20 +609,23 @@ static int pci_configure_mps(struct phb *phb,
 			     struct pci_device *pd,
 			     void *userdata __unused)
 {
-	uint32_t ecap, mps;
+	uint32_t ecap, aercap, mps;
 	uint16_t val;
 
 	assert(phb);
 	assert(pd);
 
-	mps = phb->mps;
 	/* If the MPS isn't acceptable one, bail immediately */
+	mps = phb->mps;
 	if (mps < 128 || mps > 4096)
 		return 1;
 
+	/* Retrieve PCIe and AER capability */
+	ecap = pci_cap(pd, PCI_CFG_CAP_ID_EXP, false);
+	aercap = pci_cap(pd, PCIECAP_ID_AER, true);
+
 	/* PCIe device always has MPS capacity */
 	if (pd->mps) {
-		ecap = pci_cap(pd, PCI_CFG_CAP_ID_EXP, false);
 		mps = ilog2(mps) - 7;
 
 		pci_cfg_read16(phb, pd->bdfn, ecap + PCICAP_EXP_DEVCTL, &val);
@@ -630,6 +633,19 @@ static int pci_configure_mps(struct phb *phb,
 		pci_cfg_write16(phb, pd->bdfn, ecap + PCICAP_EXP_DEVCTL, val);
 	}
 
+	/* Changing MPS on upstream PCI bridge might cause some error
+	 * bits in PCIe and AER capability. To clear them to avoid
+	 * confusion.
+	 */
+	if (aercap) {
+		pci_cfg_write32(phb, pd->bdfn, aercap + PCIECAP_AER_UE_STATUS,
+				0xffffffff);
+		pci_cfg_write32(phb, pd->bdfn, aercap + PCIECAP_AER_CE_STATUS,
+				0xffffffff);
+	}
+	if (ecap)
+		pci_cfg_write16(phb, pd->bdfn, ecap + PCICAP_EXP_DEVSTAT, 0xf);
+
 	return 0;
 }
 
-- 
2.1.0



More information about the Skiboot mailing list