From patchwork Thu May 17 17:21:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ray Jui X-Patchwork-Id: 10407345 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BF0B6602C2 for ; Thu, 17 May 2018 17:22:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AC75728592 for ; Thu, 17 May 2018 17:22:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9F5BC285A5; Thu, 17 May 2018 17:22:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3318A28592 for ; Thu, 17 May 2018 17:22:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752519AbeEQRWt (ORCPT ); Thu, 17 May 2018 13:22:49 -0400 Received: from mail-qk0-f195.google.com ([209.85.220.195]:45068 "EHLO mail-qk0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752276AbeEQRVz (ORCPT ); Thu, 17 May 2018 13:21:55 -0400 Received: by mail-qk0-f195.google.com with SMTP id a8-v6so4232216qkj.12 for ; Thu, 17 May 2018 10:21:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=EGsGzE8s9MH5WTWV8E76h1YyRrL8Gew2PH0Uxz3vclw=; b=YnIud8OyZX3oFv1ANZL4mWAIYZ8IVO4cI6PdIJSQvqM3pcSIOu04yI+p9IJbI+OD8A cstvBspdpdQglnlUM/DpTZI4+jXVFfmOmtJD90GRrb9bV90Wkvy1TvroO2KgZa4yz6St icaURHGpVXRbodEhfu2z8YDaEG4FrqGz4d8p0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=EGsGzE8s9MH5WTWV8E76h1YyRrL8Gew2PH0Uxz3vclw=; b=rPkixjquL0yaTXjQVro9F0K/tQA5/0m0kYqrk20JqDwANC44htw4n4mf2+ucSIllYY Y1KKJJWfoLRRQHMvSzKGnZKmRhDSu4FDpxXYoX8/xYCNKGvacAkxJLi2YUBcmu7S0NYC SPA7CGle3Yo4UBbMuRlyXO0Uev/G1HUE4s/OvTJOvHo8XLa6+U1meF4OsKXqH1oXNTru g8L3Nb0QVDPp5XIIZQu6Mauvr0bFO39EzCPIcL22J3V2nlrubV3STCee+P3Zp73pHaci d2hiYrARu5SnH7JiLs5aGCkMkddXp5qGfB2G5VkVZ5+znc0Xcp7GAZmPu5EkJoy+okej PG3w== X-Gm-Message-State: ALKqPwdsWL6uCnEtfagTQmA1hEOY+P4Hy4IQ+Q/GmwlHD5GVYDXZAU2H QEFPBIvyqBOyqH0xK96gqYPqPw== X-Google-Smtp-Source: AB8JxZqAW3r+j4eaji98Y1Q8ZLC3wA4WNU44WoVuPUqumTU9AJfGig+X1otltDE0b09/I2ZJPTeEZA== X-Received: by 2002:a37:8c05:: with SMTP id o5-v6mr5843105qkd.155.1526577714400; Thu, 17 May 2018 10:21:54 -0700 (PDT) Received: from lbrmn-lnxub44-1.ric.broadcom.com ([192.19.228.250]) by smtp.gmail.com with ESMTPSA id 26-v6sm4459261qtm.16.2018.05.17.10.21.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 17 May 2018 10:21:53 -0700 (PDT) From: Ray Jui To: Bjorn Helgaas , Lorenzo Pieralisi Cc: Bjorn Helgaas , linux-kernel@vger.kernel.org, bcm-kernel-feedback-list@broadcom.com, linux-pci@vger.kernel.org, Ray Jui , Ray Jui Subject: [PATCH INTERNAL 2/3] PCI: iproc: Fix up corrupted PAXC root complex config registers Date: Thu, 17 May 2018 10:21:31 -0700 Message-Id: <1526577692-21104-3-git-send-email-ray.jui@broadcom.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1526577692-21104-1-git-send-email-ray.jui@broadcom.com> References: <1526577692-21104-1-git-send-email-ray.jui@broadcom.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On certain versions of Broadcom PAXC based root complexes, certain regions of the configuration space are corrupted. As a result, it prevents the Linux PCIe stack from traversing the linked list of the capability registers completely and therefore the root complex is not advertised as "PCIe capable". This prevents the correct PCIe RID from being parsed in the kernel PCIe stack. A correct RID is required for mapping to a stream ID from the SMMU or the device ID from the GICv3 ITS This patch fixes up the issue by manually populating the related PCIe capabilities based on readings from the PCIe capability structure Signed-off-by: Ray Jui Reviewed-by: Anup Patel Reviewed-by: Scott Branden --- drivers/pci/quirks.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 47dfea0..0cdbd0a 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2198,6 +2198,101 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16f0, quirk_paxc_bridge); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd750, quirk_paxc_bridge); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd802, quirk_paxc_bridge); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd804, quirk_paxc_bridge); + +/* + * The PCI capabilities list for certain revisions of Broadcom PAXC root + * complexes is incorrectly terminated due to corrupted configuration space + * registers in the range of 0x50 - 0x5f + * + * As a result, the capability list becomes broken and prevent standard PCI + * stack from being able to traverse to the PCIe capability structure + */ +static void quirk_paxc_pcie_capability(struct pci_dev *pdev) +{ + int pos, i = 0; + u8 next_cap; + u16 reg16, *cap; + struct pci_cap_saved_state *state; + + /* bail out if PCIe capability can be found */ + if (pdev->pcie_cap || pci_find_capability(pdev, PCI_CAP_ID_EXP)) + return; + + /* locate the power management capability */ + pos = pci_find_capability(pdev, PCI_CAP_ID_PM); + if (!pos) + return; + + /* bail out if the next capability pointer is not 0x50/0x58 */ + pci_read_config_byte(pdev, pos + 1, &next_cap); + if (next_cap != 0x50 && next_cap != 0x58) + return; + + /* bail out if we do not terminate at 0x50/0x58 */ + pos = next_cap; + pci_read_config_byte(pdev, pos + 1, &next_cap); + if (next_cap != 0x00) + return; + + /* + * On these buggy HW, PCIe capability structure is expected to be at + * 0xac and should terminate the list + * + * Borrow the similar logic from theIntel DH895xCC VFs fixup to save + * the PCIe capability list + */ + pos = 0xac; + pci_read_config_word(pdev, pos, ®16); + if (reg16 == (0x0000 | PCI_CAP_ID_EXP)) { + u32 status; + +#ifndef PCI_EXP_SAVE_REGS +#define PCI_EXP_SAVE_REGS 7 +#endif + int size = PCI_EXP_SAVE_REGS * sizeof(u16); + + pdev->pcie_cap = pos; + pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); + pdev->pcie_flags_reg = reg16; + pci_read_config_word(pdev, pos + PCI_EXP_DEVCAP, ®16); + pdev->pcie_mpss = reg16 & PCI_EXP_DEVCAP_PAYLOAD; + + pdev->cfg_size = PCI_CFG_SPACE_EXP_SIZE; + if (pci_read_config_dword(pdev, PCI_CFG_SPACE_SIZE, &status) != + PCIBIOS_SUCCESSFUL || (status == 0xffffffff)) + pdev->cfg_size = PCI_CFG_SPACE_SIZE; + + if (pci_find_saved_cap(pdev, PCI_CAP_ID_EXP)) + return; + + state = kzalloc(sizeof(*state) + size, GFP_KERNEL); + if (!state) + return; + + state->cap.cap_nr = PCI_CAP_ID_EXP; + state->cap.cap_extended = 0; + state->cap.size = size; + cap = (u16 *)&state->cap.data[0]; + pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &cap[i++]); + pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &cap[i++]); + pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &cap[i++]); + pcie_capability_read_word(pdev, PCI_EXP_RTCTL, &cap[i++]); + pcie_capability_read_word(pdev, PCI_EXP_DEVCTL2, &cap[i++]); + pcie_capability_read_word(pdev, PCI_EXP_LNKCTL2, &cap[i++]); + pcie_capability_read_word(pdev, PCI_EXP_SLTCTL2, &cap[i++]); + hlist_add_head(&state->next, &pdev->saved_cap_space); + } +} +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57810, + quirk_paxc_pcie_capability); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16cd, + quirk_paxc_pcie_capability); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16f0, + quirk_paxc_pcie_capability); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd802, + quirk_paxc_pcie_capability); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd804, + quirk_paxc_pcie_capability); #endif /* Originally in EDAC sources for i82875P: