From patchwork Thu May 6 15:31:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 12242481 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.7 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7EC60C43460 for ; Thu, 6 May 2021 15:35:05 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E5E40610C8 for ; Thu, 6 May 2021 15:35:04 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E5E40610C8 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=XKdJc69t4jzQv5fDH/KMQIu92JKaM4kdG1DAXBX7xTU=; b=gVR2PZTXfIellg5wiL3yLbvcJ NVkfIUdKG7Hts6HJWiwRLDLGNUjK45CW1d2+va8D3IlY3ghj8zp8/YuLv1RdsyNPMKbSbGV1VEaR6 vCMzIexGZKkbB/HYnU84i4TrkgHYbqM8NFFTYcuzCqzxJXrZdgQxNa3HGKQJLTOa1GwJYhxo4//eo qvi46rexpDICswlYCV2tw51NqtqlaenmMXtnzW1Ocuz1oCeU9qgvmIWr6BLJI5TZPnKP4vJeo2zL9 Ehv/QulVat+Y9mNGZKTS+kkDyHWq7htD25pgzipVlft+wwny66OVNEZPrVu6X2kDH032qohHBbETO N3QNjRH0w==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1leg0N-004aIA-DP; Thu, 06 May 2021 15:33:35 +0000 Received: from bombadil.infradead.org ([2607:7c80:54:e::133]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lefzg-004a2p-Hi for linux-arm-kernel@desiato.infradead.org; Thu, 06 May 2021 15:32:52 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc: To:From:Sender:Reply-To:Content-ID:Content-Description; bh=XsPgc7bIvYP03GMTAo4H2GSsadfaTqDy1rGt8fB9ZbI=; b=miwFXIk0bIIpeI8wGXMUy5Pn1N 2g1/FqhMtgDkvJlSXTCVu3Hw/oskDCPakZz90yAVWxMsGw4sGDc1MZLx45h+oNcezleuUigtHwD6D GJxjqx03x0HMke36Z0WRCZd9iZsjPWkszJWBmVVYB7jTLpDjJnLZKkpW3F1jmxnO8l+JrJAXNUdy/ sweIH/JJTeR9YLS4EBsvbiSNlqkzvZz2AWHo0WkSDGIAD+cdk/VEbTIWBEk6htKFE2TJwfJDa1HKV 4Xh/IOS5KK+v3iO9/onFZEka5g35HRWNJKALwPi+vCFkZQXhYgQ5F3F3AkcZ/VYB49UNQqtq5xUD5 nvjqchFA==; Received: from mail.kernel.org ([198.145.29.99]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lefzb-0069f4-W4 for linux-arm-kernel@lists.infradead.org; Thu, 06 May 2021 15:32:51 +0000 Received: by mail.kernel.org (Postfix) with ESMTPSA id 2B80F61168; Thu, 6 May 2021 15:32:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1620315167; bh=Fu4/t9pMjXwvsBTR1oTGCXyaBjHyoagLyBJfrUrRITM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Tvv6Aru/o7L85xCaZOCy8rUW3aMkT6HCjU1p3R9hyH4Y06DgBjU6ma+WfLSk86O8C J2bzfs9PBV9RCicsRr7kyOh673+gkaNBfb4BPPuPefC5HZ4wDjVsJ3t3uBiV7zO57j CBr18OLYW4MkaFxwzGJMZqfO6cGgFVPUy0OvP4P6yQmLuSMdKcUPAf3y+Elp/qRwCd YVdiCiL4lqocEHxmysDM7b2qSP5Vl3YaIN+mDmSkKekQRQoIZn+3i61kooaL16Jtx0 0iqmdbmL+i8P4tcl6Vw8bx0Ge86s2T6bB0PnlCn/5rtMspqoMy2Jlpr6W3eO3A8HZm or+s1vmzqwNeg== Received: by pali.im (Postfix) id CBBC4BF9; Thu, 6 May 2021 17:32:44 +0200 (CEST) From: =?utf-8?q?Pali_Roh=C3=A1r?= To: Lorenzo Pieralisi , Thomas Petazzoni , Rob Herring , Bjorn Helgaas Cc: Russell King , =?utf-8?q?Marek_Beh=C3=BAn?= , Remi Pommarel , Xogium , Tomasz Maciej Nowak , Marc Zyngier , linux-pci@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH 03/42] PCI: aardvark: Fix checking for PIO status Date: Thu, 6 May 2021 17:31:14 +0200 Message-Id: <20210506153153.30454-4-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210506153153.30454-1-pali@kernel.org> References: <20210506153153.30454-1-pali@kernel.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210506_083248_176761_6C62D4DB X-CRM114-Status: GOOD ( 25.19 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Evan Wang There is an issue that when PCIe switch is connected to an Armada 3700 board, there will be lots of warnings about PIO errors when reading the config space. According to Aardvark PIO read and write sequence in HW specification, the current way to check PIO status has the following issues: 1) For PIO read operation, it reports the error message, which should be avoided according to HW specification. 2) For PIO read and write operations, it only checks PIO operation complete status, which is not enough, and error status should also be checked. This patch aligns the code with Aardvark PIO read and write sequence in HW specification on PIO status check and fix the warnings when reading config space. This patch also returns Completion Retry Status value when the read request timeout, to give the caller a chance to send the request again instead of failing. Signed-off-by: Evan Wang Reviewed-by: Victor Gu Tested-by: Victor Gu [pali: Return CRS also after timeout] Signed-off-by: Pali Rohár Reviewed-by: Marek Behún Cc: stable@vger.kernel.org # b1bd5714472c ("PCI: aardvark: Indicate error in 'val' when config read fails") --- drivers/pci/controller/pci-aardvark.c | 93 +++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 13 deletions(-) diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c index 2f8380a1f84f..a37ba86f1b2d 100644 --- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -58,6 +58,7 @@ #define PIO_COMPLETION_STATUS_CRS 2 #define PIO_COMPLETION_STATUS_CA 4 #define PIO_NON_POSTED_REQ BIT(10) +#define PIO_ERR_STATUS BIT(11) #define PIO_ADDR_LS (PIO_BASE_ADDR + 0x8) #define PIO_ADDR_MS (PIO_BASE_ADDR + 0xc) #define PIO_WR_DATA (PIO_BASE_ADDR + 0x10) @@ -176,6 +177,9 @@ #define MSI_IRQ_NUM 32 +#define CFG_RD_UR_VAL 0xffffffff +#define CFG_RD_CRS_VAL 0xffff0001 + struct advk_pcie { struct platform_device *pdev; void __iomem *base; @@ -461,7 +465,7 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie) advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG); } -static void advk_pcie_check_pio_status(struct advk_pcie *pcie) +static int advk_pcie_check_pio_status(struct advk_pcie *pcie, u32 *val) { struct device *dev = &pcie->pdev->dev; u32 reg; @@ -472,15 +476,50 @@ static void advk_pcie_check_pio_status(struct advk_pcie *pcie) status = (reg & PIO_COMPLETION_STATUS_MASK) >> PIO_COMPLETION_STATUS_SHIFT; - if (!status) - return; - + /* + * According to HW spec, the PIO status check sequence as below: + * 1) even if COMPLETION_STATUS(bit9:7) indicates successful, + * it still needs to check Error Status(bit11), only when this bit + * indicates no error happen, the operation is successful. + * 2) value Unsupported Request(1) of COMPLETION_STATUS(bit9:7) only + * means a PIO write error, and for PIO read it is successful with + * a read value of 0xFFFFFFFF. + * 3) value Completion Retry Status(CRS) of COMPLETION_STATUS(bit9:7) + * only means a PIO write error, and for PIO read it is successful + * with a read value of 0xFFFF0001. + * 4) value Completer Abort (CA) of COMPLETION_STATUS(bit9:7) means + * error for both PIO read and PIO write operation. + * 5) other errors are indicated as 'unknown'. + */ switch (status) { + case PIO_COMPLETION_STATUS_OK: + if (reg & PIO_ERR_STATUS) { + strcomp_status = "COMP_ERR"; + break; + } + /* Get the read result */ + if (val) + *val = advk_readl(pcie, PIO_RD_DATA); + /* No error */ + strcomp_status = NULL; + break; case PIO_COMPLETION_STATUS_UR: - strcomp_status = "UR"; + if (val) { + /* For reading, UR is not an error status */ + *val = CFG_RD_UR_VAL; + strcomp_status = NULL; + } else { + strcomp_status = "UR"; + } break; case PIO_COMPLETION_STATUS_CRS: - strcomp_status = "CRS"; + if (val) { + /* For reading, CRS is not an error status */ + *val = CFG_RD_CRS_VAL; + strcomp_status = NULL; + } else { + strcomp_status = "CRS"; + } break; case PIO_COMPLETION_STATUS_CA: strcomp_status = "CA"; @@ -490,6 +529,9 @@ static void advk_pcie_check_pio_status(struct advk_pcie *pcie) break; } + if (!strcomp_status) + return 0; + if (reg & PIO_NON_POSTED_REQ) str_posted = "Non-posted"; else @@ -497,6 +539,8 @@ static void advk_pcie_check_pio_status(struct advk_pcie *pcie) dev_err(dev, "%s PIO Response Status: %s, %#x @ %#x\n", str_posted, strcomp_status, reg, advk_readl(pcie, PIO_ADDR_LS)); + + return -EFAULT; } static int advk_pcie_wait_pio(struct advk_pcie *pcie) @@ -703,8 +747,17 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, size, val); if (advk_pcie_pio_is_running(pcie)) { - *val = 0xffffffff; - return PCIBIOS_SET_FAILED; + /* + * For PCI_VENDOR_ID register, return Completion Retry Status + * so caller tries to issue the request again insted of failing + */ + if (where == PCI_VENDOR_ID) { + *val = CFG_RD_CRS_VAL; + return PCIBIOS_SUCCESSFUL; + } else { + *val = 0xffffffff; + return PCIBIOS_SET_FAILED; + } } /* Program the control register */ @@ -729,15 +782,27 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, advk_writel(pcie, 1, PIO_START); ret = advk_pcie_wait_pio(pcie); + if (ret < 0) { + /* + * For PCI_VENDOR_ID register, return Completion Retry Status + * so caller tries to issue the request again instead of failing + */ + if (where == PCI_VENDOR_ID) { + *val = CFG_RD_CRS_VAL; + return PCIBIOS_SUCCESSFUL; + } else { + *val = 0xffffffff; + return PCIBIOS_SET_FAILED; + } + } + + /* Check PIO status and get the read result */ + ret = advk_pcie_check_pio_status(pcie, val); if (ret < 0) { *val = 0xffffffff; return PCIBIOS_SET_FAILED; } - advk_pcie_check_pio_status(pcie); - - /* Get the read result */ - *val = advk_readl(pcie, PIO_RD_DATA); if (size == 1) *val = (*val >> (8 * (where & 3))) & 0xff; else if (size == 2) @@ -801,7 +866,9 @@ static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn, if (ret < 0) return PCIBIOS_SET_FAILED; - advk_pcie_check_pio_status(pcie); + ret = advk_pcie_check_pio_status(pcie, NULL); + if (ret < 0) + return PCIBIOS_SET_FAILED; return PCIBIOS_SUCCESSFUL; }