From patchwork Fri Sep 13 14:36:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ilpo_J=C3=A4rvinen?= X-Patchwork-Id: 13803563 X-Patchwork-Delegate: bhelgaas@google.com Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 40DC529CEF; Fri, 13 Sep 2024 14:38:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.20 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726238281; cv=none; b=RuW8Xqtazfp3GEha09NfUbHtwNJsTNMYfZJn42b6IAEyA+bmGuguIPbp7KXrTq3RiuZH6DmYwNHmmhMC8pm3S4mnBRaH7B2gjAWXaK7bDMUroL3ooRWBi8mCwcf4av/3fdJEvGZsfoYerILRjJEKj5tnUOSlyLQuE2j6Gl39OWs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1726238281; c=relaxed/simple; bh=BQmnVJb14Jy4hYknmKumrCK5be389oT5bY8zdV22lKo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=McIMw4AVzW3CCg0CCrjwSnYdeZXEwidjhS5057FURboCaIH5kUvTKlisgL/5YsExsTxeuhPiwmOGLsje53xh1jAQEbCNlL5OwK4HfsZEMkK9CZVfIFCBdL6jpR21+63/UrawUhKizSNiZisFiMLSjhDG3cOz7sUy43JbFuG3FA0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=F8FvHgV7; arc=none smtp.client-ip=198.175.65.20 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="F8FvHgV7" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1726238280; x=1757774280; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=BQmnVJb14Jy4hYknmKumrCK5be389oT5bY8zdV22lKo=; b=F8FvHgV7vdURTAdDSCdUX4z13dQ0S6d9ozz2HL65y196i+5MtQh9bQ8I c+YF/ZKJh8eC/7LBlBuNnnrqrENP4wayaLlRO2q9inIOGpgy1KMJ7n/JK fUJ2ig4RlQy/XPWXha6338HhKX/NT83Upi5O604zMUWxejPm7Vi4l+cKM qPiULwemcc/KiO+dxzxVMxTnZHO4fgn4ubKK0qe1hb68Wu8fQ1gdSivNR aQBYxXbhWOPjw+BrAfo689b8qM21pKQoHNWyoZ4dqXM2G1e6Pqv6SZcPO CZT5OhqmO0ObOYYb/enF5uPMQGErLxP15zHvPpUj1T/pQSCcQiv6hdLpZ Q==; X-CSE-ConnectionGUID: PVofmB0fQLiW9m0Q4dTXWw== X-CSE-MsgGUID: T5+9PmGbQl+FzQcRNlJb6g== X-IronPort-AV: E=McAfee;i="6700,10204,11194"; a="24962994" X-IronPort-AV: E=Sophos;i="6.10,226,1719903600"; d="scan'208";a="24962994" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by orvoesa112.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Sep 2024 07:38:00 -0700 X-CSE-ConnectionGUID: z6R0qocRRB6j+lg9XXxTbA== X-CSE-MsgGUID: v5AP44CBQrOpoVvW6dJ1LA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.10,226,1719903600"; d="scan'208";a="98764506" Received: from ijarvine-mobl1.ger.corp.intel.com (HELO localhost) ([10.245.245.154]) by orviesa002-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Sep 2024 07:37:57 -0700 From: =?utf-8?q?Ilpo_J=C3=A4rvinen?= To: linux-pci@vger.kernel.org, Bjorn Helgaas , Mahesh J Salgaonkar , Oliver O'Halloran , Lukas Wunner , =?utf-8?q?Krzysztof_Wilczy=C5=84ski?= , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Cc: =?utf-8?q?Ilpo_J=C3=A4rvinen?= Subject: [PATCH v6 6/8] PCI: Add TLP Prefix reading into pcie_read_tlp_log() Date: Fri, 13 Sep 2024 17:36:30 +0300 Message-Id: <20240913143632.5277-7-ilpo.jarvinen@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240913143632.5277-1-ilpo.jarvinen@linux.intel.com> References: <20240913143632.5277-1-ilpo.jarvinen@linux.intel.com> Precedence: bulk X-Mailing-List: linux-pci@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 pcie_read_tlp_log() handles only 4 Header Log DWORDs but TLP Prefix Log (PCIe r6.1 secs 7.8.4.12 & 7.9.14.13) may also be present. Generalize pcie_read_tlp_log() and struct pcie_tlp_log to handle also TLP Prefix Log. The relevant registers are formatted identically in AER and DPC Capability, but has these variations: a) The offsets of TLP Prefix Log registers vary. b) DPC RP PIO TLP Prefix Log register can be < 4 DWORDs. Therefore callers must pass the offset of the TLP Prefix Log register and the entire length to pcie_read_tlp_log() to be able to read the correct number of TLP Prefix DWORDs from the correct offset. Signed-off-by: Ilpo Järvinen --- drivers/pci/pci.h | 5 +++- drivers/pci/pcie/aer.c | 4 ++- drivers/pci/pcie/dpc.c | 13 +++++----- drivers/pci/pcie/tlp.c | 49 +++++++++++++++++++++++++++++++---- include/linux/aer.h | 1 + include/uapi/linux/pci_regs.h | 1 + 6 files changed, 59 insertions(+), 14 deletions(-) diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 532bb05a0411..b47844b97428 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -483,7 +483,9 @@ struct aer_err_info { int aer_get_device_error_info(struct pci_dev *dev, struct aer_err_info *info); void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); -int pcie_read_tlp_log(struct pci_dev *dev, int where, struct pcie_tlp_log *log); +int pcie_read_tlp_log(struct pci_dev *dev, int where, int where2, + unsigned int tlp_len, struct pcie_tlp_log *log); +unsigned int aer_tlp_log_len(struct pci_dev *dev); #endif /* CONFIG_PCIEAER */ #ifdef CONFIG_PCIEPORTBUS @@ -502,6 +504,7 @@ void pci_dpc_init(struct pci_dev *pdev); void dpc_process_error(struct pci_dev *pdev); pci_ers_result_t dpc_reset_link(struct pci_dev *pdev); bool pci_dpc_recovered(struct pci_dev *pdev); +unsigned int dpc_tlp_log_len(struct pci_dev *dev); #else static inline void pci_save_dpc_state(struct pci_dev *dev) { } static inline void pci_restore_dpc_state(struct pci_dev *dev) { } diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c index 13b8586924ea..651d0c72802a 100644 --- a/drivers/pci/pcie/aer.c +++ b/drivers/pci/pcie/aer.c @@ -1245,7 +1245,9 @@ int aer_get_device_error_info(struct pci_dev *dev, struct aer_err_info *info) if (info->status & AER_LOG_TLP_MASKS) { info->tlp_header_valid = 1; - pcie_read_tlp_log(dev, aer + PCI_ERR_HEADER_LOG, &info->tlp); + pcie_read_tlp_log(dev, aer + PCI_ERR_HEADER_LOG, + aer + PCI_ERR_PREFIX_LOG, + aer_tlp_log_len(dev), &info->tlp); } } diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c index 2b6ef7efa3c1..7933b3cedb59 100644 --- a/drivers/pci/pcie/dpc.c +++ b/drivers/pci/pcie/dpc.c @@ -190,7 +190,7 @@ pci_ers_result_t dpc_reset_link(struct pci_dev *pdev) static void dpc_process_rp_pio_error(struct pci_dev *pdev) { u16 cap = pdev->dpc_cap, dpc_status, first_error; - u32 status, mask, sev, syserr, exc, log, prefix; + u32 status, mask, sev, syserr, exc, log; struct pcie_tlp_log tlp_log; int i; @@ -217,20 +217,19 @@ static void dpc_process_rp_pio_error(struct pci_dev *pdev) if (pdev->dpc_rp_log_size < 4) goto clear_status; - pcie_read_tlp_log(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG, &tlp_log); + pcie_read_tlp_log(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG, + cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG, + dpc_tlp_log_len(pdev), &tlp_log); pci_err(pdev, "TLP Header: %#010x %#010x %#010x %#010x\n", tlp_log.dw[0], tlp_log.dw[1], tlp_log.dw[2], tlp_log.dw[3]); + for (i = 0; i < pdev->dpc_rp_log_size - 5; i++) + pci_err(pdev, "TLP Prefix Header: dw%d, %#010x\n", i, tlp_log.prefix[i]); if (pdev->dpc_rp_log_size < 5) goto clear_status; pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_IMPSPEC_LOG, &log); pci_err(pdev, "RP PIO ImpSpec Log %#010x\n", log); - for (i = 0; i < pdev->dpc_rp_log_size - 5; i++) { - pci_read_config_dword(pdev, - cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG + i * 4, &prefix); - pci_err(pdev, "TLP Prefix Header: dw%d, %#010x\n", i, prefix); - } clear_status: pci_write_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_STATUS, status); } diff --git a/drivers/pci/pcie/tlp.c b/drivers/pci/pcie/tlp.c index 65ac7b5d8a87..def9dd7b73e8 100644 --- a/drivers/pci/pcie/tlp.c +++ b/drivers/pci/pcie/tlp.c @@ -11,26 +11,65 @@ #include "../pci.h" +/** + * aer_tlp_log_len - Calculates AER Capability TLP Header/Prefix Log length + * @dev: PCIe device + * + * Return: TLP Header/Prefix Log length + */ +unsigned int aer_tlp_log_len(struct pci_dev *dev) +{ + return 4 + dev->eetlp_prefix_max; +} + +#ifdef CONFIG_PCIE_DPC +/** + * dpc_tlp_log_len - Calculates DPC RP PIO TLP Header/Prefix Log length + * @dev: PCIe device + * + * Return: TLP Header/Prefix Log length + */ +unsigned int dpc_tlp_log_len(struct pci_dev *dev) +{ + /* Remove ImpSpec Log register from the count */ + if (dev->dpc_rp_log_size >= 5) + return dev->dpc_rp_log_size - 1; + + return dev->dpc_rp_log_size; +} +#endif + /** * pcie_read_tlp_log - read TLP Header Log * @dev: PCIe device * @where: PCI Config offset of TLP Header Log + * @where2: PCI Config offset of TLP Prefix Log + * @tlp_len: TLP Log length (Header Log + TLP Prefix Log in DWORDs) * @log: TLP Log structure to fill * * Fill @log from TLP Header Log registers, e.g., AER or DPC. * * Return: 0 on success and filled TLP Log structure, <0 on error. */ -int pcie_read_tlp_log(struct pci_dev *dev, int where, - struct pcie_tlp_log *log) +int pcie_read_tlp_log(struct pci_dev *dev, int where, int where2, + unsigned int tlp_len, struct pcie_tlp_log *log) { unsigned int i; - int ret; + int off, ret; + u32 *to; memset(log, 0, sizeof(*log)); - for (i = 0; i < 4; i++) { - ret = pci_read_config_dword(dev, where + i * 4, &log->dw[i]); + for (i = 0; i < tlp_len; i++) { + if (i < 4) { + off = where + i * 4; + to = &log->dw[i]; + } else { + off = where2 + (i - 4) * 4; + to = &log->prefix[i - 4]; + } + + ret = pci_read_config_dword(dev, off, to); if (ret) return pcibios_err_to_errno(ret); } diff --git a/include/linux/aer.h b/include/linux/aer.h index 190a0a2061cd..dc498adaa1c8 100644 --- a/include/linux/aer.h +++ b/include/linux/aer.h @@ -20,6 +20,7 @@ struct pci_dev; struct pcie_tlp_log { u32 dw[4]; + u32 prefix[4]; }; struct aer_capability_regs { diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index b297bc30ddcb..b6f9012a3fc4 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -803,6 +803,7 @@ #define PCI_ERR_ROOT_FATAL_RCV 0x00000040 /* Fatal Received */ #define PCI_ERR_ROOT_AER_IRQ 0xf8000000 /* Advanced Error Interrupt Message Number */ #define PCI_ERR_ROOT_ERR_SRC 0x34 /* Error Source Identification */ +#define PCI_ERR_PREFIX_LOG 0x38 /* TLP Prefix LOG Register (up to 16 bytes) */ /* Virtual Channel */ #define PCI_VC_PORT_CAP1 0x04