Received: by 2002:ab2:7041:0:b0:1f4:bcc8:f211 with SMTP id x1csp151503lql; Fri, 12 Apr 2024 06:37:09 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVbDjvYpIAXLiGE7qW92YOna3/eky/gtn7EjmF/9Wl72obzp7jSH02ZjcU14VOywBP7lutjEwOpDIVWjyl45Z+l1SpDasES2E3+dsmsaw== X-Google-Smtp-Source: AGHT+IEgX1lz/qa/0gWvg/NQWhWDsWrBCs508c0iv2+ENU3L/iDSOBpzkwviatf6896gr7r5YtkC X-Received: by 2002:a17:906:8402:b0:a51:ae75:bca with SMTP id n2-20020a170906840200b00a51ae750bcamr1524682ejx.62.1712929029076; Fri, 12 Apr 2024 06:37:09 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1712929029; cv=pass; d=google.com; s=arc-20160816; b=rmiqCtIy0bQDM+GoZwG13+unPS6ruja3544vUhI2UBKeStYlNGHCyGi5eBf7Tnwzxp OFwk1v49Nr85YZxxTmxkVEVu9PTSx46Zi2TmH0GvrgtQNAIwWqNYswJOKsiV0PAWFynY saXmVXKwQG0i6Fsztcq7N3yOMZKcCt1msKeaoSvP1pSyqJGnrEN/aF9y6Cg+YKkr3DoM R7bwFx7N+1dk0jjChjNbvEtU86CGZ3VJD/m9r/ZLVvQB2lRLSvxcWdtyV/CQ7FGLnRwh IjaaoOGh9Y6koDAAgaiSZzKt6RI9IhJbVMW/zyji1Z/xVO6IQFrDmP0BvsJE2sbBgyVQ QJ7g== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=c8Mgs2bAwsLbeQPn67CL1zHskhAdtup7O7W6g93jHeM=; fh=oxkMSmyDN+ZfsWyXoK7AaIPyxxXdtJViCSChfVQVcUg=; b=S0iOW36dUkcdNfo2FtS5DgBSvc98CAdXGbKQ1adzAuTknL3ILpFzLwZfiPKPZz09hD CfISX2WC3HADz86PTyuymN+EFFobYnEiP+XSR8Spcpeq6Ad7Icl5XKNx04en/ZPgVEL+ 1uEmIS97vjEda0wdqzwxIaRZgZUT5mQMoqk5Uy24hvHeQIe30ACQHk8aJWOyzU2F2sM+ fOyazlHMbanQW0dfU1ZnwXwoAwah97Mfr6jRzzO0vj74W0WbWTz7pcu1l4jpssAASKqH UyfbWtC0QNCuphfPPrSKwaJfwivFUDb+l5Ciwiq2JFZNfyiF6YEkzcQInOPNgKmo76Pd ENzQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=lO9y4GVn; arc=pass (i=1 dkim=pass dkdomain=intel.com dmarc=pass fromdomain=linux.intel.com); spf=pass (google.com: domain of linux-kernel+bounces-142741-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-142741-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id a6-20020a170906368600b00a522c10bcefsi1126513ejc.47.2024.04.12.06.37.09 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 12 Apr 2024 06:37:09 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-142741-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=lO9y4GVn; arc=pass (i=1 dkim=pass dkdomain=intel.com dmarc=pass fromdomain=linux.intel.com); spf=pass (google.com: domain of linux-kernel+bounces-142741-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-142741-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 97CF01F2161B for ; Fri, 12 Apr 2024 13:37:08 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id EF59D84055; Fri, 12 Apr 2024 13:37:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="lO9y4GVn" Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.8]) (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 A41FC824AD; Fri, 12 Apr 2024 13:36:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.8 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712929020; cv=none; b=O0jQ8gwQ+FSVeiss/K2qt7A7qRuURPnPupCnNwBUlHhQOgTVVT1offwQ2NHLXKUlHZLoRug/MzChwRK1vnEz0HJinM5sToNhSzuUuG9WuGbq19la+iLBIm7agKvgS5tmfO9z17YJRF6JVxEub/NUH5TRZFcvFYtTA5QvCdxY7vU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712929020; c=relaxed/simple; bh=jFxPYMsDHicnn0s+j2hAbaa5C5BsvDA//bTohuyzYdI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=i5Q1fmFIW/PzKk6eLM09LDUAk1fZJcLaxR1Js7k/DYS9WkBF6XgiyKK/0F+4GGcRWtA6qLqdLM6kEx5Y86ejKLZkJTuaVO00e+H+U35YCIBHh89cAM+zmC76AjoJ0dfFXBWsXPZRGOdRUt7tuiG/iHfmzhYtIvM56chXw+ppBb0= 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=lO9y4GVn; arc=none smtp.client-ip=192.198.163.8 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1712929018; x=1744465018; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=jFxPYMsDHicnn0s+j2hAbaa5C5BsvDA//bTohuyzYdI=; b=lO9y4GVn9XLhBfDHs4KNkE68CxFB+k9607gA8ZGi7FZM2J56wcy3g/uG ybCkjFQqKVNymKtKU2wS52UyFLXgvhH1kQ0PzJhODr10A8e8ExJFWw1t0 DwWqv0d/IONp7p1wyDOSPO6qArZPAD3WtkWtdi6T/F+iDXbwfa94ucJa9 YweNoKJT5p3hp/rC9aBmeJm2bYDpoQqb0JAFBBXL9suRGTzGGSt8wpW5+ r1PYfPHp63mgBuorugZ4pbeddVS21HhqaM/JPQC1UdIw9Ft+GTe03eVru KItaVgAu2ZnNxspkEcJxEpENemB/5GOG3TGQqL9aXNdh3DU3kUM32yj8A A==; X-CSE-ConnectionGUID: sysfq4yOQmKJIAHSFcGtAA== X-CSE-MsgGUID: eQdTkbWGTfywdPUML6VMeA== X-IronPort-AV: E=McAfee;i="6600,9927,11041"; a="25897889" X-IronPort-AV: E=Sophos;i="6.07,196,1708416000"; d="scan'208";a="25897889" Received: from orviesa001.jf.intel.com ([10.64.159.141]) by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 06:36:57 -0700 X-CSE-ConnectionGUID: wqtLTnGORQ+Fr/sxb0+ddw== X-CSE-MsgGUID: 05AnKh1vQ+mWl4s/5cIaoQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.07,196,1708416000"; d="scan'208";a="58662889" Received: from ijarvine-desk1.ger.corp.intel.com (HELO localhost) ([10.245.247.32]) by smtpauth.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Apr 2024 06:36:54 -0700 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= To: Bjorn Helgaas , linux-pci@vger.kernel.org, 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 v3 1/2] PCI: Add TLP Prefix reading into pcie_read_tlp_log() Date: Fri, 12 Apr 2024 16:36:34 +0300 Message-Id: <20240412133635.3831-2-ilpo.jarvinen@linux.intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240412133635.3831-1-ilpo.jarvinen@linux.intel.com> References: <20240412133635.3831-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: 8bit pcie_read_tlp_log() handles only 4 TLP 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 layout of relevant registers in AER and DPC Capability is not identical because the offsets of TLP Header Log and TLP Prefix Log vary so the callers must pass the offsets to pcie_read_tlp_log(). Convert eetlp_prefix_path into integer called eetlp_prefix_max and make is available also when CONFIG_PCI_PASID is not configured to be able to determine the number of E-E Prefixes. Signed-off-by: Ilpo Järvinen --- drivers/pci/ats.c | 2 +- drivers/pci/pci.c | 34 ++++++++++++++++++++++++++++------ drivers/pci/pcie/aer.c | 4 +++- drivers/pci/pcie/dpc.c | 22 +++++++++++++++------- drivers/pci/probe.c | 14 +++++++++----- include/linux/aer.h | 5 ++++- include/linux/pci.h | 2 +- include/uapi/linux/pci_regs.h | 2 ++ 8 files changed, 63 insertions(+), 22 deletions(-) diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c index c570892b2090..e13433dcfc82 100644 --- a/drivers/pci/ats.c +++ b/drivers/pci/ats.c @@ -377,7 +377,7 @@ int pci_enable_pasid(struct pci_dev *pdev, int features) if (WARN_ON(pdev->pasid_enabled)) return -EBUSY; - if (!pdev->eetlp_prefix_path && !pdev->pasid_no_tlp) + if (!pdev->eetlp_prefix_max && !pdev->pasid_no_tlp) return -EINVAL; if (!pasid) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e5f243dd4288..af230e6e5557 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1066,26 +1066,48 @@ static void pci_enable_acs(struct pci_dev *dev) pci_disable_acs_redir(dev); } +/** + * aer_tlp_log_len - Calculates 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; +} + /** * 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 (in DWORDs) * @tlp_log: TLP Log structure to fill * * Fill @tlp_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 *tlp_log) +int pcie_read_tlp_log(struct pci_dev *dev, int where, int where2, + unsigned int tlp_len, struct pcie_tlp_log *tlp_log) { - int i, ret; + unsigned int i; + int off, ret; + u32 *to; memset(tlp_log, 0, sizeof(*tlp_log)); - for (i = 0; i < 4; i++) { - ret = pci_read_config_dword(dev, where + i * 4, - &tlp_log->dw[i]); + for (i = 0; i < tlp_len; i++) { + if (i < 4) { + to = &tlp_log->dw[i]; + off = where + i * 4; + } else { + to = &tlp_log->prefix[i - 4]; + off = where2 + (i - 4) * 4; + } + + ret = pci_read_config_dword(dev, off, to); if (ret) return pcibios_err_to_errno(ret); } 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, 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 a668820696dc..80b1456f95fe 100644 --- a/drivers/pci/pcie/dpc.c +++ b/drivers/pci/pcie/dpc.c @@ -187,10 +187,19 @@ pci_ers_result_t dpc_reset_link(struct pci_dev *pdev) return ret; } +static unsigned int dpc_tlp_log_len(struct pci_dev *pdev) +{ + /* Remove ImpSpec Log register from the count */ + if (pdev->dpc_rp_log_size >= 5) + return pdev->dpc_rp_log_size - 1; + + return pdev->dpc_rp_log_size; +} + 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 +226,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/probe.c b/drivers/pci/probe.c index 1325fbae2f28..02035b005a53 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2211,8 +2211,8 @@ static void pci_configure_relaxed_ordering(struct pci_dev *dev) static void pci_configure_eetlp_prefix(struct pci_dev *dev) { -#ifdef CONFIG_PCI_PASID struct pci_dev *bridge; + unsigned int eetlp_max; int pcie_type; u32 cap; @@ -2224,15 +2224,19 @@ static void pci_configure_eetlp_prefix(struct pci_dev *dev) return; pcie_type = pci_pcie_type(dev); + + eetlp_max = FIELD_GET(PCI_EXP_DEVCAP2_EE_PREFIX_MAX, cap); + /* 00b means 4 */ + eetlp_max = eetlp_max ?: 4; + if (pcie_type == PCI_EXP_TYPE_ROOT_PORT || pcie_type == PCI_EXP_TYPE_RC_END) - dev->eetlp_prefix_path = 1; + dev->eetlp_prefix_max = eetlp_max; else { bridge = pci_upstream_bridge(dev); - if (bridge && bridge->eetlp_prefix_path) - dev->eetlp_prefix_path = 1; + if (bridge && bridge->eetlp_prefix_max) + dev->eetlp_prefix_max = eetlp_max; } -#endif } static void pci_configure_serr(struct pci_dev *dev) diff --git a/include/linux/aer.h b/include/linux/aer.h index 4b97f38f3fcf..2484056feb8d 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 { @@ -37,7 +38,9 @@ struct aer_capability_regs { u16 uncor_err_source; }; -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); #if defined(CONFIG_PCIEAER) int pci_aer_clear_nonfatal_status(struct pci_dev *dev); diff --git a/include/linux/pci.h b/include/linux/pci.h index 16493426a04f..71f505862ef0 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -397,7 +397,7 @@ struct pci_dev { supported from root to here */ #endif unsigned int pasid_no_tlp:1; /* PASID works without TLP Prefix */ - unsigned int eetlp_prefix_path:1; /* End-to-End TLP Prefix */ + unsigned int eetlp_prefix_max:3; /* Max # of End-to-End TLP Prefix, 0=not supported */ pci_channel_state_t error_state; /* Current connectivity state */ struct device dev; /* Generic device interface */ diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index a39193213ff2..cf7a07fa4a3b 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -661,6 +661,7 @@ #define PCI_EXP_DEVCAP2_OBFF_MSG 0x00040000 /* New message signaling */ #define PCI_EXP_DEVCAP2_OBFF_WAKE 0x00080000 /* Re-use WAKE# for OBFF */ #define PCI_EXP_DEVCAP2_EE_PREFIX 0x00200000 /* End-End TLP Prefix */ +#define PCI_EXP_DEVCAP2_EE_PREFIX_MAX 0x00c00000 /* Max End-End TLP Prefixes */ #define PCI_EXP_DEVCTL2 0x28 /* Device Control 2 */ #define PCI_EXP_DEVCTL2_COMP_TIMEOUT 0x000f /* Completion Timeout Value */ #define PCI_EXP_DEVCTL2_COMP_TMOUT_DIS 0x0010 /* Completion Timeout Disable */ @@ -802,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 -- 2.39.2