Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp3545841imm; Thu, 17 May 2018 10:23:49 -0700 (PDT) X-Google-Smtp-Source: AB8JxZrGZrLSXERxcdIznPqwHVv0rvyTbZzzQ5QtmGfDCrwuqo1oQyN121IDwep9VtYj1e4CW6hu X-Received: by 2002:a62:a65c:: with SMTP id t89-v6mr5980944pfe.27.1526577829761; Thu, 17 May 2018 10:23:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526577829; cv=none; d=google.com; s=arc-20160816; b=IAoWrFmkl9t8W07a4m6fEknisfKrqnhm/uvFWl6T2hnbWK0ctSfgpG3YgMXQH+btos jgGpgq2KLlM1sythR0edrbrd9exlahmZ2dtUmRjPNOy1lU3qO7+kjopzectMidQ/KdWO FsZ45oxcyRZFLp9wREx7QoXe9ViuUwq1NF9bQ4U/mu5je2heZd1eh8LkPrZUfTsWbiPt hl7ARSBjkTrov+0rxZbIjzKLFUw0Kzrzw/2Xx9twQTZwwtc52F8wYfgBOtb8501pBH8J v94xEzYGO1MvnuKiNfZZQXSBC5wHqILkwSpv48exy9697o6q7mwZBJAvOnSEEHVyHWZ5 YG3w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=EGsGzE8s9MH5WTWV8E76h1YyRrL8Gew2PH0Uxz3vclw=; b=IsgMLUZkOd+anXnYjbPSGVAOpAWa4nYax6gbWf08dQayXFeTqwayFxkppYGsl2whtB D49kUsDsMO9+77ClGsb6uDSgG9Wip6G8d8WvunFYvmLMntoCEjKK0IOjZziggvuDldWD IglyvGe/29LnLA0Bunn0EFPaRO3j9s77XvElk4feu8ZN8yDyWFygNzuivUUR6W7gNWBV iJrn31zL9op9HsBUbynoYhoCIbuJZUVp0hJRZn4sJeNQRqqjms7j83Gj3cWfNCEOKw4U m5CJRAf4nK/aP1git+LB/Z8FUna5H2GwhJTyYXPqBfeZFYgJeT60Dr1S0Z4zf7j/4qRh Cchw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@broadcom.com header.s=google header.b=YnIud8Oy; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=broadcom.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j14-v6si4288937pgc.627.2018.05.17.10.23.35; Thu, 17 May 2018 10:23:49 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@broadcom.com header.s=google header.b=YnIud8Oy; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=broadcom.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752524AbeEQRWt (ORCPT + 99 others); Thu, 17 May 2018 13:22:49 -0400 Received: from mail-qk0-f193.google.com ([209.85.220.193]:42971 "EHLO mail-qk0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751898AbeEQRVz (ORCPT ); Thu, 17 May 2018 13:21:55 -0400 Received: by mail-qk0-f193.google.com with SMTP id b22-v6so4225540qkj.9 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=kD/s7/DOPIWHHe0RuiNxRZeKyICtTSCg2jVg8gCiiDeisGxNPCl7eMF1XW06g7jNzr Yyvs5yuzwtdY2BpFuphg02pK5o60KnKXwbxUAVSCNtjaPbnuEbq3Ge2ac6HF3LGZQpLn d8UtEhU2tTO4JfXQ8TA3tuKeUT/Az18fLRD7KaU63akj/wiNcjCVWcIFXMKLNISm+uZP 8H++f3FjqPK0jl85XA4vTaYPg1CmuUQvbTXAnU416w+0CNiI1QLR+DE4gRkaPs/0zR5q PRBr9kPGwIzvZvCA2vtV2chpPmPYa6tnJZU1tDsiWrnTljhUCSt9hIQ97EEwWnU3mCFl HdFQ== X-Gm-Message-State: ALKqPwegTrgp35YHOwVOF3+rYo7wepwTPVQuSMolr3Wv5/+vuw7BAfb9 mk/AU4P1RHVmQm3cvesNoMHiYA== 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-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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: -- 2.1.4