From nobody Fri Dec 19 20:55:39 2025 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.18]) (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 6A3DA13B284; Tue, 14 May 2024 11:32:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715686324; cv=none; b=uc8gNVhbTC3XdAKeqT4Oxfnc9fjWPySmEoUN+u16rNc6Nk8kE5cXSk8wjDgZk9LS9Ym5PB4cgTZSB1P5ozK48jou43mGZNuy+Bh1i/82+1UYCwQOPyYinEcEEQ8zBBV2qnI+UNxNeTVafH+MSkkVTEwROWmKjQ3vwq7M9hcRu94= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715686324; c=relaxed/simple; bh=muDPYeTDqUqXMJ0EJOzrmCFm6YAucOY0ej2xemGJzmU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=uAPuSpTsGKy9SnQwrUvbicB6Afme0LvsAHHP2onJxklmcCxJE1qG2EJYkSTNBgIBthRzHgQ2W0+BNTN8ftr2LK4GBrjE12Xk5S7KsSQasgPnguA2RMbbL6XoNcxoHYJu+DkldL3GB05wot34F/HQiuXiAu18qs4cl2jsDMu4APs= 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=KaB3V/3I; arc=none smtp.client-ip=198.175.65.18 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="KaB3V/3I" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1715686323; x=1747222323; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=muDPYeTDqUqXMJ0EJOzrmCFm6YAucOY0ej2xemGJzmU=; b=KaB3V/3I5oWfMR1hs/SuqTOUYE3oo7B6fq1oc9CwoTvt1wSpe/HGhONi tT/I8dcJKodExzFLJwa2CZv1p6VvIlBqKvFdwb59If63jEP100mGEK4Zr eykp7UcErezOLrOzN0HEJUPC/f6yrHx8ApudV7jvZxeHt9sIG3A0JpMkc 4k0xZLoccBfdf5fE+Yqr4NdxgtXgyNw9NU6UHQCM9uVL9ObEFayzK33br qpjK/1XIUUGhdjW6MvZBkWaLQSc+BOTl7N2aGib+uE0vFzU7mjn6Dp0ah XJE+OtPlrgdPCsUtDXLbpMJo/Kxg4Fy86k/kuX+xCWS1Mz1DcK9UWiO0J A==; X-CSE-ConnectionGUID: CZ4t/pN8RIygyGp8easqIw== X-CSE-MsgGUID: cCa8nw60QdGDpeD+d0yRpQ== X-IronPort-AV: E=McAfee;i="6600,9927,11072"; a="11828378" X-IronPort-AV: E=Sophos;i="6.08,159,1712646000"; d="scan'208";a="11828378" Received: from orviesa004.jf.intel.com ([10.64.159.144]) by orvoesa110.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 May 2024 04:32:03 -0700 X-CSE-ConnectionGUID: OPvY+vUWTOGolxa2EvWFXw== X-CSE-MsgGUID: Plao2HLxTf+Ix/1wfeJbUQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,159,1712646000"; d="scan'208";a="35546238" Received: from ijarvine-desk1.ger.corp.intel.com (HELO localhost) ([10.245.247.94]) by orviesa004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 May 2024 04:32:01 -0700 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= To: linux-pci@vger.kernel.org, Bjorn Helgaas , Mahesh J Salgaonkar , Oliver O'Halloran , Lukas Wunner , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Cc: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Subject: [PATCH v5 6/7] PCI: Add TLP Prefix reading into pcie_read_tlp_log() Date: Tue, 14 May 2024 14:31:08 +0300 Message-Id: <20240514113109.6690-7-ilpo.jarvinen@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240514113109.6690-1-ilpo.jarvinen@linux.intel.com> References: <20240514113109.6690-1-ilpo.jarvinen@linux.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable 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=C3=A4rvinen --- 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 0e9917f8bf3f..7afdd71f9026 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -420,7 +420,9 @@ struct aer_err_info { int aer_get_device_error_info(struct pci_dev *dev, struct aer_err_info *in= fo); void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); =20 -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 */ =20 #ifdef CONFIG_PCIEPORTBUS @@ -439,6 +441,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 ac6293c24976..ecc1dea5a208 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, st= ruct aer_err_info *info) =20 if (info->status & AER_LOG_TLP_MASKS) { info->tlp_header_valid =3D 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); } } =20 diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c index a668820696dc..5056cc6961ec 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 =3D 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; =20 @@ -217,20 +217,19 @@ static void dpc_process_rp_pio_error(struct pci_dev *= pdev) =20 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 =3D 0; i < pdev->dpc_rp_log_size - 5; i++) + pci_err(pdev, "TLP Prefix Header: dw%d, %#010x\n", i, tlp_log.prefix[i]); =20 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); =20 - for (i =3D 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 @@ =20 #include "../pci.h" =20 +/** + * 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 >=3D 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; =20 memset(log, 0, sizeof(*log)); =20 - for (i =3D 0; i < 4; i++) { - ret =3D pci_read_config_dword(dev, where + i * 4, &log->dw[i]); + for (i =3D 0; i < tlp_len; i++) { + if (i < 4) { + off =3D where + i * 4; + to =3D &log->dw[i]; + } else { + off =3D where2 + (i - 4) * 4; + to =3D &log->prefix[i - 4]; + } + + ret =3D 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; =20 struct pcie_tlp_log { u32 dw[4]; + u32 prefix[4]; }; =20 struct aer_capability_regs { diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index 09e0c300c952..cf7a07fa4a3b 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 Mess= age 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= ) */ =20 /* Virtual Channel */ #define PCI_VC_PORT_CAP1 0x04 --=20 2.39.2