linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v8 0/7] PCI: Consolidate TLP Log reading and printing
@ 2024-12-18 14:37 Ilpo Järvinen
  2024-12-18 14:37 ` [PATCH v8 1/7] PCI: Don't expose pcie_read_tlp_log() outside of PCI subsystem Ilpo Järvinen
                   ` (7 more replies)
  0 siblings, 8 replies; 19+ messages in thread
From: Ilpo Järvinen @ 2024-12-18 14:37 UTC (permalink / raw)
  To: Bjorn Helgaas, linux-pci, Krzysztof Wilczyński, Lukas Wunner,
	Jonathan Cameron, Yazen Ghannam
  Cc: Mahesh J Salgaonkar, Oliver O'Halloran, linux-kernel,
	linuxppc-dev, Ilpo Järvinen

This series has the remaining patches of the AER & DPC TLP Log handling
consolidation and now includes a few minor improvements to the earlier
accepted TLP Logging code.

v8:
- Added missing parameter to kerneldoc.
- Dropped last patch due to conflict with the pci_printk() cleanup
  series (will move the patch into that series).

v7:
- Explain in commit message reasoning why eetlp_prefix_max stores Max
  End-End TLP Prefixes value instead of limiting it by the bridge/RP
  imposed limits
- Take account TLP Prefix Log Present flag.
- Align PCI_ERR_CAP_* flags in pci_regs.h
- Add EE_PREFIX_STR define to be able to take its sizeof() for output
  char[] sizing.

v6:
- Preserve "AER:"/"DPC:" prefix on the printed TLP line
- New patch to add "AER:" also  on other lines of the AER error dump

v5:
- Fix build with AER=y and DPC=n
- Match kerneldoc and function parameter name

v4:
- Added patches:
	- Remove EXPORT of pcie_read_tlp_log()
	- Moved code to pcie/tlp.c and build only with AER enabled
	- Match variables in prototype and function
	- int -> unsigned int conversion
	- eetlp_prefix_max into own patch
- struct pcie_tlp_log param consistently called "log" within tlp.c
- Moved function prototypes into drivers/pci/pci.h
- Describe AER/DPC differences more clearly in one commit message

v3:
- Small rewording in a commit message

v2:
- Don't add EXPORT()s
- Don't include igxbe changes
- Don't use pr_cont() as it's incompatible with pci_err() and according
  to Andy Shevchenko should not be used in the first place


Ilpo Järvinen (7):
  PCI: Don't expose pcie_read_tlp_log() outside of PCI subsystem
  PCI: Move TLP Log handling to own file
  PCI: Make pcie_read_tlp_log() signature same
  PCI: Use unsigned int i in pcie_read_tlp_log()
  PCI: Store # of supported End-End TLP Prefixes
  PCI: Add TLP Prefix reading into pcie_read_tlp_log()
  PCI: Create helper to print TLP Header and Prefix Log

 drivers/pci/ats.c             |   2 +-
 drivers/pci/pci.c             |  28 ---------
 drivers/pci/pci.h             |   9 +++
 drivers/pci/pcie/Makefile     |   2 +-
 drivers/pci/pcie/aer.c        |  15 ++---
 drivers/pci/pcie/dpc.c        |  14 ++---
 drivers/pci/pcie/tlp.c        | 113 ++++++++++++++++++++++++++++++++++
 drivers/pci/probe.c           |  14 +++--
 include/linux/aer.h           |   3 +-
 include/linux/pci.h           |   2 +-
 include/uapi/linux/pci_regs.h |  11 ++--
 11 files changed, 153 insertions(+), 60 deletions(-)
 create mode 100644 drivers/pci/pcie/tlp.c

-- 
2.39.5



^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v8 1/7] PCI: Don't expose pcie_read_tlp_log() outside of PCI subsystem
  2024-12-18 14:37 [PATCH v8 0/7] PCI: Consolidate TLP Log reading and printing Ilpo Järvinen
@ 2024-12-18 14:37 ` Ilpo Järvinen
  2025-01-08 16:05   ` Yazen Ghannam
  2024-12-18 14:37 ` [PATCH v8 2/7] PCI: Move TLP Log handling to own file Ilpo Järvinen
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 19+ messages in thread
From: Ilpo Järvinen @ 2024-12-18 14:37 UTC (permalink / raw)
  To: Bjorn Helgaas, linux-pci, Krzysztof Wilczyński, Lukas Wunner,
	Jonathan Cameron, Yazen Ghannam, linux-kernel
  Cc: Mahesh J Salgaonkar, Oliver O'Halloran, linuxppc-dev,
	Ilpo Järvinen

pcie_read_tlp_log() was exposed by the commit 0a5a46a6a61b ("PCI/AER:
Generalize TLP Header Log reading") but this is now considered a
mistake. No drivers outside of PCI subsystem should build their own
diagnostic logging but should rely on PCI core doing it for them.

There's currently one driver (ixgbe) doing it independently which was
the initial reason why the export was added but it was decided by the
PCI maintainer that it's something that should be eliminated.

Remove the unwanted EXPORT of pcie_read_tlp_log() and remove it from
include/linux/aer.h.

Link: https://lore.kernel.org/all/20240322193011.GA701027@bhelgaas/
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
 drivers/pci/pci.c   | 1 -
 drivers/pci/pci.h   | 4 ++++
 include/linux/aer.h | 2 --
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 0b29ec6e8e5e..e0fdc9d10f91 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1125,7 +1125,6 @@ int pcie_read_tlp_log(struct pci_dev *dev, int where,
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(pcie_read_tlp_log);
 
 /**
  * pci_restore_bars - restore a device's BAR values (e.g. after wake-up)
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 2e40fc63ba31..8a60fc9e7786 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -4,6 +4,8 @@
 
 #include <linux/pci.h>
 
+struct pcie_tlp_log;
+
 /* Number of possible devfns: 0.0 to 1f.7 inclusive */
 #define MAX_NR_DEVFNS 256
 
@@ -549,6 +551,8 @@ 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);
 #endif	/* CONFIG_PCIEAER */
 
+int pcie_read_tlp_log(struct pci_dev *dev, int where, struct pcie_tlp_log *log);
+
 #ifdef CONFIG_PCIEPORTBUS
 /* Cached RCEC Endpoint Association */
 struct rcec_ea {
diff --git a/include/linux/aer.h b/include/linux/aer.h
index 4b97f38f3fcf..190a0a2061cd 100644
--- a/include/linux/aer.h
+++ b/include/linux/aer.h
@@ -37,8 +37,6 @@ struct aer_capability_regs {
 	u16 uncor_err_source;
 };
 
-int pcie_read_tlp_log(struct pci_dev *dev, int where, struct pcie_tlp_log *log);
-
 #if defined(CONFIG_PCIEAER)
 int pci_aer_clear_nonfatal_status(struct pci_dev *dev);
 int pcie_aer_is_native(struct pci_dev *dev);
-- 
2.39.5



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v8 2/7] PCI: Move TLP Log handling to own file
  2024-12-18 14:37 [PATCH v8 0/7] PCI: Consolidate TLP Log reading and printing Ilpo Järvinen
  2024-12-18 14:37 ` [PATCH v8 1/7] PCI: Don't expose pcie_read_tlp_log() outside of PCI subsystem Ilpo Järvinen
@ 2024-12-18 14:37 ` Ilpo Järvinen
  2025-01-08 16:26   ` Yazen Ghannam
  2024-12-18 14:37 ` [PATCH v8 3/7] PCI: Make pcie_read_tlp_log() signature same Ilpo Järvinen
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 19+ messages in thread
From: Ilpo Järvinen @ 2024-12-18 14:37 UTC (permalink / raw)
  To: Bjorn Helgaas, linux-pci, Krzysztof Wilczyński, Lukas Wunner,
	Jonathan Cameron, Yazen Ghannam, linux-kernel
  Cc: Mahesh J Salgaonkar, Oliver O'Halloran, linuxppc-dev,
	Ilpo Järvinen

TLP Log is PCIe feature and is processed only by AER and DPC.
Configwise, DPC depends AER being enabled. In lack of better place, the
TLP Log handling code was initially placed into pci.c but it can be
easily placed in a separate file.

Move TLP Log handling code to own file under pcie/ subdirectory and
include it only when AER is enabled.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
 drivers/pci/pci.c         | 27 ---------------------------
 drivers/pci/pci.h         |  2 +-
 drivers/pci/pcie/Makefile |  2 +-
 drivers/pci/pcie/tlp.c    | 39 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 41 insertions(+), 29 deletions(-)
 create mode 100644 drivers/pci/pcie/tlp.c

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e0fdc9d10f91..02cd4c7eb80b 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1099,33 +1099,6 @@ static void pci_enable_acs(struct pci_dev *dev)
 	pci_write_config_word(dev, pos + PCI_ACS_CTRL, caps.ctrl);
 }
 
-/**
- * pcie_read_tlp_log - read TLP Header Log
- * @dev: PCIe device
- * @where: PCI Config offset of TLP Header Log
- * @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 i, ret;
-
-	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]);
-		if (ret)
-			return pcibios_err_to_errno(ret);
-	}
-
-	return 0;
-}
-
 /**
  * pci_restore_bars - restore a device's BAR values (e.g. after wake-up)
  * @dev: PCI device to have its BARs restored
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 8a60fc9e7786..55fcf3bac4f7 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -549,9 +549,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);
-#endif	/* CONFIG_PCIEAER */
 
 int pcie_read_tlp_log(struct pci_dev *dev, int where, struct pcie_tlp_log *log);
+#endif	/* CONFIG_PCIEAER */
 
 #ifdef CONFIG_PCIEPORTBUS
 /* Cached RCEC Endpoint Association */
diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile
index 53ccab62314d..173829aa02e6 100644
--- a/drivers/pci/pcie/Makefile
+++ b/drivers/pci/pcie/Makefile
@@ -7,7 +7,7 @@ pcieportdrv-y			:= portdrv.o rcec.o
 obj-$(CONFIG_PCIEPORTBUS)	+= pcieportdrv.o bwctrl.o
 
 obj-y				+= aspm.o
-obj-$(CONFIG_PCIEAER)		+= aer.o err.o
+obj-$(CONFIG_PCIEAER)		+= aer.o err.o tlp.o
 obj-$(CONFIG_PCIEAER_INJECT)	+= aer_inject.o
 obj-$(CONFIG_PCIE_PME)		+= pme.o
 obj-$(CONFIG_PCIE_DPC)		+= dpc.o
diff --git a/drivers/pci/pcie/tlp.c b/drivers/pci/pcie/tlp.c
new file mode 100644
index 000000000000..3f053cc62290
--- /dev/null
+++ b/drivers/pci/pcie/tlp.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCIe TLP Log handling
+ *
+ * Copyright (C) 2024 Intel Corporation
+ */
+
+#include <linux/aer.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+
+#include "../pci.h"
+
+/**
+ * pcie_read_tlp_log - read TLP Header Log
+ * @dev: PCIe device
+ * @where: PCI Config offset of TLP Header Log
+ * @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 i, ret;
+
+	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]);
+		if (ret)
+			return pcibios_err_to_errno(ret);
+	}
+
+	return 0;
+}
-- 
2.39.5



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v8 3/7] PCI: Make pcie_read_tlp_log() signature same
  2024-12-18 14:37 [PATCH v8 0/7] PCI: Consolidate TLP Log reading and printing Ilpo Järvinen
  2024-12-18 14:37 ` [PATCH v8 1/7] PCI: Don't expose pcie_read_tlp_log() outside of PCI subsystem Ilpo Järvinen
  2024-12-18 14:37 ` [PATCH v8 2/7] PCI: Move TLP Log handling to own file Ilpo Järvinen
@ 2024-12-18 14:37 ` Ilpo Järvinen
  2025-01-08 20:40   ` Yazen Ghannam
  2024-12-18 14:37 ` [PATCH v8 4/7] PCI: Use unsigned int i in pcie_read_tlp_log() Ilpo Järvinen
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 19+ messages in thread
From: Ilpo Järvinen @ 2024-12-18 14:37 UTC (permalink / raw)
  To: Bjorn Helgaas, linux-pci, Krzysztof Wilczyński, Lukas Wunner,
	Jonathan Cameron, Yazen Ghannam, linux-kernel
  Cc: Mahesh J Salgaonkar, Oliver O'Halloran, linuxppc-dev,
	Ilpo Järvinen

pcie_read_tlp_log()'s prototype and function signature diverged due to
changes made while applying.

Make the parameters of pcie_read_tlp_log() named identically.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
 drivers/pci/pcie/tlp.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/pcie/tlp.c b/drivers/pci/pcie/tlp.c
index 3f053cc62290..2bf15749cd31 100644
--- a/drivers/pci/pcie/tlp.c
+++ b/drivers/pci/pcie/tlp.c
@@ -15,22 +15,21 @@
  * pcie_read_tlp_log - read TLP Header Log
  * @dev: PCIe device
  * @where: PCI Config offset of TLP Header Log
- * @tlp_log: TLP Log structure to fill
+ * @log: TLP Log structure to fill
  *
- * Fill @tlp_log from TLP Header Log registers, e.g., AER or DPC.
+ * 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 *tlp_log)
+		      struct pcie_tlp_log *log)
 {
 	int i, ret;
 
-	memset(tlp_log, 0, sizeof(*tlp_log));
+	memset(log, 0, sizeof(*log));
 
 	for (i = 0; i < 4; i++) {
-		ret = pci_read_config_dword(dev, where + i * 4,
-					    &tlp_log->dw[i]);
+		ret = pci_read_config_dword(dev, where + i * 4, &log->dw[i]);
 		if (ret)
 			return pcibios_err_to_errno(ret);
 	}
-- 
2.39.5



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v8 4/7] PCI: Use unsigned int i in pcie_read_tlp_log()
  2024-12-18 14:37 [PATCH v8 0/7] PCI: Consolidate TLP Log reading and printing Ilpo Järvinen
                   ` (2 preceding siblings ...)
  2024-12-18 14:37 ` [PATCH v8 3/7] PCI: Make pcie_read_tlp_log() signature same Ilpo Järvinen
@ 2024-12-18 14:37 ` Ilpo Järvinen
  2025-01-03 16:38   ` Jonathan Cameron
  2024-12-18 14:37 ` [PATCH v8 5/7] PCI: Store # of supported End-End TLP Prefixes Ilpo Järvinen
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 19+ messages in thread
From: Ilpo Järvinen @ 2024-12-18 14:37 UTC (permalink / raw)
  To: Bjorn Helgaas, linux-pci, Krzysztof Wilczyński, Lukas Wunner,
	Jonathan Cameron, Yazen Ghannam, linux-kernel
  Cc: Mahesh J Salgaonkar, Oliver O'Halloran, linuxppc-dev,
	Ilpo Järvinen

Loop variable i counting from 0 upwards does not need to be signed so
make it unsigned int.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 drivers/pci/pcie/tlp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pcie/tlp.c b/drivers/pci/pcie/tlp.c
index 2bf15749cd31..65ac7b5d8a87 100644
--- a/drivers/pci/pcie/tlp.c
+++ b/drivers/pci/pcie/tlp.c
@@ -24,7 +24,8 @@
 int pcie_read_tlp_log(struct pci_dev *dev, int where,
 		      struct pcie_tlp_log *log)
 {
-	int i, ret;
+	unsigned int i;
+	int ret;
 
 	memset(log, 0, sizeof(*log));
 
-- 
2.39.5



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v8 5/7] PCI: Store # of supported End-End TLP Prefixes
  2024-12-18 14:37 [PATCH v8 0/7] PCI: Consolidate TLP Log reading and printing Ilpo Järvinen
                   ` (3 preceding siblings ...)
  2024-12-18 14:37 ` [PATCH v8 4/7] PCI: Use unsigned int i in pcie_read_tlp_log() Ilpo Järvinen
@ 2024-12-18 14:37 ` Ilpo Järvinen
  2025-01-03 16:36   ` Jonathan Cameron
  2025-01-08 20:56   ` Yazen Ghannam
  2024-12-18 14:37 ` [PATCH v8 6/7] PCI: Add TLP Prefix reading into pcie_read_tlp_log() Ilpo Järvinen
                   ` (2 subsequent siblings)
  7 siblings, 2 replies; 19+ messages in thread
From: Ilpo Järvinen @ 2024-12-18 14:37 UTC (permalink / raw)
  To: Bjorn Helgaas, linux-pci, Krzysztof Wilczyński, Lukas Wunner,
	Jonathan Cameron, Yazen Ghannam, linux-kernel
  Cc: Mahesh J Salgaonkar, Oliver O'Halloran, linuxppc-dev,
	Ilpo Järvinen

eetlp_prefix_path in the struct pci_dev tells if End-End TLP Prefixes
are supported by the path or not, the value is only calculated if
CONFIG_PCI_PASID is set.

The Max End-End TLP Prefixes field in the Device Capabilities Register
2 also tells how many (1-4) End-End TLP Prefixes are supported (PCIe
r6.2 sec 7.5.3.15). The number of supported End-End Prefixes is useful
for reading correct number of DWORDs from TLP Prefix Log register in AER
capability (PCIe r6.2 sec 7.8.4.12).

Replace eetlp_prefix_path with eetlp_prefix_max and determine the
number of supported End-End Prefixes regardless of CONFIG_PCI_PASID so
that an upcoming commit generalizing TLP Prefix Log register reading
does not have to read extra DWORDs for End-End Prefixes that never will
be there.

The value stored into eetlp_prefix_max is directly derived from
device's Max End-End TLP Prefixes and does not consider limitations
imposed by bridges or the Root Port beyond supported/not supported
flags. This is intentional for two reasons:

  1) PCIe r6.2 spec sections r6.1 2.2.10.4 & 6.2.4.4 indicate that TLP
  is handled malformed only if the number of prefixes exceed the number
  of Max End-End TLP Prefixes, which seems to be the case even if the
  device could never receive that many prefixes due to smaller maximum
  imposed by a bridge or the Root Port. If TLP parsing is later added,
  this distinction is significant in interpreting what is logged by the
  TLP Prefix Log registers and the value matching to the Malformed TLP
  threshold is going to be more useful.

  2) TLP Prefix handling happens autonomously on a low layer and the
  value in eetlp_prefix_max is not programmed anywhere by the kernel
  (i.e., there is no limiter OS can control to prevent sending more
  than n TLP Prefixes).

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 drivers/pci/ats.c             |  2 +-
 drivers/pci/probe.c           | 14 +++++++++-----
 include/linux/pci.h           |  2 +-
 include/uapi/linux/pci_regs.h |  1 +
 4 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
index 6afff1f1b143..c6b266c772c8 100644
--- a/drivers/pci/ats.c
+++ b/drivers/pci/ats.c
@@ -410,7 +410,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/probe.c b/drivers/pci/probe.c
index 2e81ab0f5a25..381c22e3ccdb 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2251,8 +2251,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;
 
@@ -2264,15 +2264,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/pci.h b/include/linux/pci.h
index db9b47ce3eef..21be5a1edf1a 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -407,7 +407,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-End TLP Prefixes, 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 1601c7ed5fab..14a6306c4ce1 100644
--- a/include/uapi/linux/pci_regs.h
+++ b/include/uapi/linux/pci_regs.h
@@ -665,6 +665,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 */
-- 
2.39.5



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v8 6/7] PCI: Add TLP Prefix reading into pcie_read_tlp_log()
  2024-12-18 14:37 [PATCH v8 0/7] PCI: Consolidate TLP Log reading and printing Ilpo Järvinen
                   ` (4 preceding siblings ...)
  2024-12-18 14:37 ` [PATCH v8 5/7] PCI: Store # of supported End-End TLP Prefixes Ilpo Järvinen
@ 2024-12-18 14:37 ` Ilpo Järvinen
  2025-01-08 21:33   ` Yazen Ghannam
  2024-12-18 14:37 ` [PATCH v8 7/7] PCI: Create helper to print TLP Header and Prefix Log Ilpo Järvinen
  2025-01-08 15:53 ` [PATCH v8 0/7] PCI: Consolidate TLP Log reading and printing Yazen Ghannam
  7 siblings, 1 reply; 19+ messages in thread
From: Ilpo Järvinen @ 2024-12-18 14:37 UTC (permalink / raw)
  To: Bjorn Helgaas, linux-pci, Krzysztof Wilczyński, Lukas Wunner,
	Jonathan Cameron, Yazen Ghannam, Mahesh J Salgaonkar,
	Oliver O'Halloran, linux-kernel, linuxppc-dev
  Cc: Ilpo Järvinen

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.
c) AER TLP Prefix Log Present (PCIe r6.1 sec 7.8.4.7) can indicate
   Prefix Log is not present.

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 <ilpo.jarvinen@linux.intel.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
 drivers/pci/pci.h             |  5 +++-
 drivers/pci/pcie/aer.c        |  5 +++-
 drivers/pci/pcie/dpc.c        | 13 +++++----
 drivers/pci/pcie/tlp.c        | 51 +++++++++++++++++++++++++++++++----
 include/linux/aer.h           |  1 +
 include/uapi/linux/pci_regs.h | 10 ++++---
 6 files changed, 67 insertions(+), 18 deletions(-)

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 55fcf3bac4f7..7797b2544d00 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -550,7 +550,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, u32 aercc);
 #endif	/* CONFIG_PCIEAER */
 
 #ifdef CONFIG_PCIEPORTBUS
@@ -569,6 +571,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 80c5ba8d8296..656dbf1ac45b 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -1248,7 +1248,10 @@ 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, aercc),
+					  &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..302ba99e64e6 100644
--- a/drivers/pci/pcie/tlp.c
+++ b/drivers/pci/pcie/tlp.c
@@ -11,26 +11,67 @@
 
 #include "../pci.h"
 
+/**
+ * aer_tlp_log_len - Calculates AER Capability TLP Header/Prefix Log length
+ * @dev: PCIe device
+ * @aercc: AER Capabilities and Control register value
+ *
+ * Return: TLP Header/Prefix Log length
+ */
+unsigned int aer_tlp_log_len(struct pci_dev *dev, u32 aercc)
+{
+	return 4 + (aercc & PCI_ERR_CAP_PREFIX_LOG_PRESENT) ?
+		   dev->eetlp_prefix_max : 0;
+}
+
+#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 14a6306c4ce1..82866ac0bda7 100644
--- a/include/uapi/linux/pci_regs.h
+++ b/include/uapi/linux/pci_regs.h
@@ -790,10 +790,11 @@
 	/* Same bits as above */
 #define PCI_ERR_CAP		0x18	/* Advanced Error Capabilities & Ctrl*/
 #define  PCI_ERR_CAP_FEP(x)	((x) & 0x1f)	/* First Error Pointer */
-#define  PCI_ERR_CAP_ECRC_GENC	0x00000020	/* ECRC Generation Capable */
-#define  PCI_ERR_CAP_ECRC_GENE	0x00000040	/* ECRC Generation Enable */
-#define  PCI_ERR_CAP_ECRC_CHKC	0x00000080	/* ECRC Check Capable */
-#define  PCI_ERR_CAP_ECRC_CHKE	0x00000100	/* ECRC Check Enable */
+#define  PCI_ERR_CAP_ECRC_GENC		0x00000020 /* ECRC Generation Capable */
+#define  PCI_ERR_CAP_ECRC_GENE		0x00000040 /* ECRC Generation Enable */
+#define  PCI_ERR_CAP_ECRC_CHKC		0x00000080 /* ECRC Check Capable */
+#define  PCI_ERR_CAP_ECRC_CHKE		0x00000100 /* ECRC Check Enable */
+#define  PCI_ERR_CAP_PREFIX_LOG_PRESENT	0x00000800 /* TLP Prefix Log Present */
 #define PCI_ERR_HEADER_LOG	0x1c	/* Header Log Register (16 bytes) */
 #define PCI_ERR_ROOT_COMMAND	0x2c	/* Root Error Command */
 #define  PCI_ERR_ROOT_CMD_COR_EN	0x00000001 /* Correctable Err Reporting Enable */
@@ -809,6 +810,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.5



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v8 7/7] PCI: Create helper to print TLP Header and Prefix Log
  2024-12-18 14:37 [PATCH v8 0/7] PCI: Consolidate TLP Log reading and printing Ilpo Järvinen
                   ` (5 preceding siblings ...)
  2024-12-18 14:37 ` [PATCH v8 6/7] PCI: Add TLP Prefix reading into pcie_read_tlp_log() Ilpo Järvinen
@ 2024-12-18 14:37 ` Ilpo Järvinen
  2025-01-08 15:53 ` [PATCH v8 0/7] PCI: Consolidate TLP Log reading and printing Yazen Ghannam
  7 siblings, 0 replies; 19+ messages in thread
From: Ilpo Järvinen @ 2024-12-18 14:37 UTC (permalink / raw)
  To: Bjorn Helgaas, linux-pci, Krzysztof Wilczyński, Lukas Wunner,
	Jonathan Cameron, Yazen Ghannam, Mahesh J Salgaonkar,
	Oliver O'Halloran, linux-kernel, linuxppc-dev
  Cc: Ilpo Järvinen

Add pcie_print_tlp_log() helper to print TLP Header and Prefix Log.
Print End-End Prefixes only if they are non-zero.

Consolidate the few places which currently print TLP using custom
formatting.

The first attempt used pr_cont() instead of building a string first but
it turns out pr_cont() is not compatible with pci_err() and prints on a
separate line. When I asked about this, Andy Shevchenko suggested
pr_cont() should not be used in the first place (to eventually get rid
of it) so pr_cont() is now replaced with building the string first.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
 drivers/pci/pci.h      |  2 ++
 drivers/pci/pcie/aer.c | 10 ++--------
 drivers/pci/pcie/dpc.c |  5 +----
 drivers/pci/pcie/tlp.c | 33 +++++++++++++++++++++++++++++++++
 4 files changed, 38 insertions(+), 12 deletions(-)

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 7797b2544d00..797ad43a7683 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -553,6 +553,8 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
 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, u32 aercc);
+void pcie_print_tlp_log(const struct pci_dev *dev,
+			const struct pcie_tlp_log *log, const char *pfx);
 #endif	/* CONFIG_PCIEAER */
 
 #ifdef CONFIG_PCIEPORTBUS
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index 656dbf1ac45b..ece8cb88d110 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -665,12 +665,6 @@ static void pci_rootport_aer_stats_incr(struct pci_dev *pdev,
 	}
 }
 
-static void __print_tlp_header(struct pci_dev *dev, struct pcie_tlp_log *t)
-{
-	pci_err(dev, "  TLP Header: %08x %08x %08x %08x\n",
-		t->dw[0], t->dw[1], t->dw[2], t->dw[3]);
-}
-
 static void __aer_print_error(struct pci_dev *dev,
 			      struct aer_err_info *info)
 {
@@ -725,7 +719,7 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
 	__aer_print_error(dev, info);
 
 	if (info->tlp_header_valid)
-		__print_tlp_header(dev, &info->tlp);
+		pcie_print_tlp_log(dev, &info->tlp, dev_fmt("  "));
 
 out:
 	if (info->id && info->error_dev_num > 1 && info->id == id)
@@ -797,7 +791,7 @@ void pci_print_aer(struct pci_dev *dev, int aer_severity,
 			aer->uncor_severity);
 
 	if (tlp_header_valid)
-		__print_tlp_header(dev, &aer->header_log);
+		pcie_print_tlp_log(dev, &aer->header_log, dev_fmt("  "));
 
 	trace_aer_event(dev_name(&dev->dev), (status & ~mask),
 			aer_severity, tlp_header_valid, &aer->header_log);
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index 7933b3cedb59..86ae1cf88787 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -220,10 +220,7 @@ static void dpc_process_rp_pio_error(struct pci_dev *pdev)
 	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]);
+	pcie_print_tlp_log(pdev, &tlp_log, dev_fmt(""));
 
 	if (pdev->dpc_rp_log_size < 5)
 		goto clear_status;
diff --git a/drivers/pci/pcie/tlp.c b/drivers/pci/pcie/tlp.c
index 302ba99e64e6..6171cb3a682b 100644
--- a/drivers/pci/pcie/tlp.c
+++ b/drivers/pci/pcie/tlp.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/aer.h>
+#include <linux/array_size.h>
 #include <linux/pci.h>
 #include <linux/string.h>
 
@@ -78,3 +79,35 @@ int pcie_read_tlp_log(struct pci_dev *dev, int where, int where2,
 
 	return 0;
 }
+
+#define EE_PREFIX_STR " E-E Prefixes:"
+
+/**
+ * pcie_print_tlp_log - Print TLP Header / Prefix Log contents
+ * @dev: PCIe device
+ * @log: TLP Log structure
+ * @pfx: String prefix
+ *
+ * Prints TLP Header and Prefix Log information held by @log.
+ */
+void pcie_print_tlp_log(const struct pci_dev *dev,
+			const struct pcie_tlp_log *log, const char *pfx)
+{
+	char buf[11 * (4 + ARRAY_SIZE(log->prefix)) + sizeof(EE_PREFIX_STR)];
+	unsigned int i;
+	int len;
+
+	len = scnprintf(buf, sizeof(buf), "%#010x %#010x %#010x %#010x",
+			log->dw[0], log->dw[1], log->dw[2], log->dw[3]);
+
+	if (log->prefix[0])
+		len += scnprintf(buf + len, sizeof(buf) - len, EE_PREFIX_STR);
+	for (i = 0; i < ARRAY_SIZE(log->prefix); i++) {
+		if (!log->prefix[i])
+			break;
+		len += scnprintf(buf + len, sizeof(buf) - len,
+				 " %#010x", log->prefix[i]);
+	}
+
+	pci_err(dev, "%sTLP Header: %s\n", pfx, buf);
+}
-- 
2.39.5



^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 5/7] PCI: Store # of supported End-End TLP Prefixes
  2024-12-18 14:37 ` [PATCH v8 5/7] PCI: Store # of supported End-End TLP Prefixes Ilpo Järvinen
@ 2025-01-03 16:36   ` Jonathan Cameron
  2025-01-08 20:56   ` Yazen Ghannam
  1 sibling, 0 replies; 19+ messages in thread
From: Jonathan Cameron @ 2025-01-03 16:36 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: Bjorn Helgaas, linux-pci, Krzysztof Wilczyński, Lukas Wunner,
	Yazen Ghannam, linux-kernel, Mahesh J Salgaonkar,
	Oliver O'Halloran, linuxppc-dev

On Wed, 18 Dec 2024 16:37:45 +0200
Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> wrote:

> eetlp_prefix_path in the struct pci_dev tells if End-End TLP Prefixes
> are supported by the path or not, the value is only calculated if
> CONFIG_PCI_PASID is set.
> 
> The Max End-End TLP Prefixes field in the Device Capabilities Register
> 2 also tells how many (1-4) End-End TLP Prefixes are supported (PCIe
> r6.2 sec 7.5.3.15). The number of supported End-End Prefixes is useful
> for reading correct number of DWORDs from TLP Prefix Log register in AER
> capability (PCIe r6.2 sec 7.8.4.12).
> 
> Replace eetlp_prefix_path with eetlp_prefix_max and determine the
> number of supported End-End Prefixes regardless of CONFIG_PCI_PASID so
> that an upcoming commit generalizing TLP Prefix Log register reading
> does not have to read extra DWORDs for End-End Prefixes that never will
> be there.
> 
> The value stored into eetlp_prefix_max is directly derived from
> device's Max End-End TLP Prefixes and does not consider limitations
> imposed by bridges or the Root Port beyond supported/not supported
> flags. This is intentional for two reasons:
> 
>   1) PCIe r6.2 spec sections r6.1 2.2.10.4 & 6.2.4.4 indicate that TLP
>   is handled malformed only if the number of prefixes exceed the number
>   of Max End-End TLP Prefixes, which seems to be the case even if the
>   device could never receive that many prefixes due to smaller maximum
>   imposed by a bridge or the Root Port. If TLP parsing is later added,
>   this distinction is significant in interpreting what is logged by the
>   TLP Prefix Log registers and the value matching to the Malformed TLP
>   threshold is going to be more useful.
> 
>   2) TLP Prefix handling happens autonomously on a low layer and the
>   value in eetlp_prefix_max is not programmed anywhere by the kernel
>   (i.e., there is no limiter OS can control to prevent sending more
>   than n TLP Prefixes).
> 
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Extra explanation looks good to me.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 4/7] PCI: Use unsigned int i in pcie_read_tlp_log()
  2024-12-18 14:37 ` [PATCH v8 4/7] PCI: Use unsigned int i in pcie_read_tlp_log() Ilpo Järvinen
@ 2025-01-03 16:38   ` Jonathan Cameron
  0 siblings, 0 replies; 19+ messages in thread
From: Jonathan Cameron @ 2025-01-03 16:38 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: Bjorn Helgaas, linux-pci, Krzysztof Wilczyński, Lukas Wunner,
	Yazen Ghannam, linux-kernel, Mahesh J Salgaonkar,
	Oliver O'Halloran, linuxppc-dev

On Wed, 18 Dec 2024 16:37:44 +0200
Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> wrote:

> Loop variable i counting from 0 upwards does not need to be signed so
> make it unsigned int.
> 
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

Whilst I find it hard to care, it is harmless so up to Bjorn if he
wants the churn or not.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> ---
>  drivers/pci/pcie/tlp.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/pcie/tlp.c b/drivers/pci/pcie/tlp.c
> index 2bf15749cd31..65ac7b5d8a87 100644
> --- a/drivers/pci/pcie/tlp.c
> +++ b/drivers/pci/pcie/tlp.c
> @@ -24,7 +24,8 @@
>  int pcie_read_tlp_log(struct pci_dev *dev, int where,
>  		      struct pcie_tlp_log *log)
>  {
> -	int i, ret;
> +	unsigned int i;
> +	int ret;
>  
>  	memset(log, 0, sizeof(*log));
>  



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 0/7] PCI: Consolidate TLP Log reading and printing
  2024-12-18 14:37 [PATCH v8 0/7] PCI: Consolidate TLP Log reading and printing Ilpo Järvinen
                   ` (6 preceding siblings ...)
  2024-12-18 14:37 ` [PATCH v8 7/7] PCI: Create helper to print TLP Header and Prefix Log Ilpo Järvinen
@ 2025-01-08 15:53 ` Yazen Ghannam
  7 siblings, 0 replies; 19+ messages in thread
From: Yazen Ghannam @ 2025-01-08 15:53 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: Bjorn Helgaas, linux-pci, Krzysztof Wilczyński, Lukas Wunner,
	Jonathan Cameron, Mahesh J Salgaonkar, Oliver O'Halloran,
	linux-kernel, linuxppc-dev

On Wed, Dec 18, 2024 at 04:37:40PM +0200, Ilpo Järvinen wrote:
> This series has the remaining patches of the AER & DPC TLP Log handling
> consolidation and now includes a few minor improvements to the earlier
> accepted TLP Logging code.
> 
> v8:
> - Added missing parameter to kerneldoc.
> - Dropped last patch due to conflict with the pci_printk() cleanup
>   series (will move the patch into that series).
> 
> v7:
> - Explain in commit message reasoning why eetlp_prefix_max stores Max
>   End-End TLP Prefixes value instead of limiting it by the bridge/RP
>   imposed limits
> - Take account TLP Prefix Log Present flag.
> - Align PCI_ERR_CAP_* flags in pci_regs.h
> - Add EE_PREFIX_STR define to be able to take its sizeof() for output
>   char[] sizing.
> 
> v6:
> - Preserve "AER:"/"DPC:" prefix on the printed TLP line
> - New patch to add "AER:" also  on other lines of the AER error dump
> 
> v5:
> - Fix build with AER=y and DPC=n
> - Match kerneldoc and function parameter name
> 
> v4:
> - Added patches:
> 	- Remove EXPORT of pcie_read_tlp_log()
> 	- Moved code to pcie/tlp.c and build only with AER enabled
> 	- Match variables in prototype and function
> 	- int -> unsigned int conversion
> 	- eetlp_prefix_max into own patch
> - struct pcie_tlp_log param consistently called "log" within tlp.c
> - Moved function prototypes into drivers/pci/pci.h
> - Describe AER/DPC differences more clearly in one commit message
> 
> v3:
> - Small rewording in a commit message
> 
> v2:
> - Don't add EXPORT()s
> - Don't include igxbe changes
> - Don't use pr_cont() as it's incompatible with pci_err() and according
>   to Andy Shevchenko should not be used in the first place
> 
> 
> Ilpo Järvinen (7):
>   PCI: Don't expose pcie_read_tlp_log() outside of PCI subsystem
>   PCI: Move TLP Log handling to own file
>   PCI: Make pcie_read_tlp_log() signature same
>   PCI: Use unsigned int i in pcie_read_tlp_log()
>   PCI: Store # of supported End-End TLP Prefixes
>   PCI: Add TLP Prefix reading into pcie_read_tlp_log()
>   PCI: Create helper to print TLP Header and Prefix Log
> 
>  drivers/pci/ats.c             |   2 +-
>  drivers/pci/pci.c             |  28 ---------
>  drivers/pci/pci.h             |   9 +++
>  drivers/pci/pcie/Makefile     |   2 +-
>  drivers/pci/pcie/aer.c        |  15 ++---
>  drivers/pci/pcie/dpc.c        |  14 ++---
>  drivers/pci/pcie/tlp.c        | 113 ++++++++++++++++++++++++++++++++++
>  drivers/pci/probe.c           |  14 +++--
>  include/linux/aer.h           |   3 +-
>  include/linux/pci.h           |   2 +-
>  include/uapi/linux/pci_regs.h |  11 ++--
>  11 files changed, 153 insertions(+), 60 deletions(-)
>  create mode 100644 drivers/pci/pcie/tlp.c
> 
> -- 

Can you please include a base commit in future revisions?

I was able to apply the set to v6.13-rc6, but I was trying a couple of
the PCI repo branches before which didn't apply.

Thanks,
Yazen


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 1/7] PCI: Don't expose pcie_read_tlp_log() outside of PCI subsystem
  2024-12-18 14:37 ` [PATCH v8 1/7] PCI: Don't expose pcie_read_tlp_log() outside of PCI subsystem Ilpo Järvinen
@ 2025-01-08 16:05   ` Yazen Ghannam
  0 siblings, 0 replies; 19+ messages in thread
From: Yazen Ghannam @ 2025-01-08 16:05 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: Bjorn Helgaas, linux-pci, Krzysztof Wilczyński, Lukas Wunner,
	Jonathan Cameron, linux-kernel, Mahesh J Salgaonkar,
	Oliver O'Halloran, linuxppc-dev

On Wed, Dec 18, 2024 at 04:37:41PM +0200, Ilpo Järvinen wrote:
> pcie_read_tlp_log() was exposed by the commit 0a5a46a6a61b ("PCI/AER:
> Generalize TLP Header Log reading") but this is now considered a
> mistake. No drivers outside of PCI subsystem should build their own
> diagnostic logging but should rely on PCI core doing it for them.
> 
> There's currently one driver (ixgbe) doing it independently which was
> the initial reason why the export was added but it was decided by the
> PCI maintainer that it's something that should be eliminated.
> 
> Remove the unwanted EXPORT of pcie_read_tlp_log() and remove it from
> include/linux/aer.h.
> 
> Link: https://lore.kernel.org/all/20240322193011.GA701027@bhelgaas/
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

Reviewed-by: Yazen Ghannam <yazen.ghannam@amd.com>

Thanks,
Yazen


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 2/7] PCI: Move TLP Log handling to own file
  2024-12-18 14:37 ` [PATCH v8 2/7] PCI: Move TLP Log handling to own file Ilpo Järvinen
@ 2025-01-08 16:26   ` Yazen Ghannam
  0 siblings, 0 replies; 19+ messages in thread
From: Yazen Ghannam @ 2025-01-08 16:26 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: Bjorn Helgaas, linux-pci, Krzysztof Wilczyński, Lukas Wunner,
	Jonathan Cameron, linux-kernel, Mahesh J Salgaonkar,
	Oliver O'Halloran, linuxppc-dev

On Wed, Dec 18, 2024 at 04:37:42PM +0200, Ilpo Järvinen wrote:
> TLP Log is PCIe feature and is processed only by AER and DPC.
> Configwise, DPC depends AER being enabled. In lack of better place, the
> TLP Log handling code was initially placed into pci.c but it can be
> easily placed in a separate file.
> 
> Move TLP Log handling code to own file under pcie/ subdirectory and
> include it only when AER is enabled.
> 
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> ---

Reviewed-by: Yazen Ghannam <yazen.ghannam@amd.com>

Overall, looks good to me, but I have one idea below.

>  drivers/pci/pci.c         | 27 ---------------------------
>  drivers/pci/pci.h         |  2 +-
>  drivers/pci/pcie/Makefile |  2 +-
>  drivers/pci/pcie/tlp.c    | 39 +++++++++++++++++++++++++++++++++++++++
>  4 files changed, 41 insertions(+), 29 deletions(-)
>  create mode 100644 drivers/pci/pcie/tlp.c
> 
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index e0fdc9d10f91..02cd4c7eb80b 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -1099,33 +1099,6 @@ static void pci_enable_acs(struct pci_dev *dev)
>  	pci_write_config_word(dev, pos + PCI_ACS_CTRL, caps.ctrl);
>  }
>  
> -/**
> - * pcie_read_tlp_log - read TLP Header Log
> - * @dev: PCIe device
> - * @where: PCI Config offset of TLP Header Log
> - * @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 i, ret;
> -
> -	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]);
> -		if (ret)
> -			return pcibios_err_to_errno(ret);
> -	}
> -
> -	return 0;
> -}
> -
>  /**
>   * pci_restore_bars - restore a device's BAR values (e.g. after wake-up)
>   * @dev: PCI device to have its BARs restored
> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> index 8a60fc9e7786..55fcf3bac4f7 100644
> --- a/drivers/pci/pci.h
> +++ b/drivers/pci/pci.h
> @@ -549,9 +549,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);
> -#endif	/* CONFIG_PCIEAER */
>  
>  int pcie_read_tlp_log(struct pci_dev *dev, int where, struct pcie_tlp_log *log);
> +#endif	/* CONFIG_PCIEAER */
>  
>  #ifdef CONFIG_PCIEPORTBUS
>  /* Cached RCEC Endpoint Association */
> diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile
> index 53ccab62314d..173829aa02e6 100644
> --- a/drivers/pci/pcie/Makefile
> +++ b/drivers/pci/pcie/Makefile
> @@ -7,7 +7,7 @@ pcieportdrv-y			:= portdrv.o rcec.o
>  obj-$(CONFIG_PCIEPORTBUS)	+= pcieportdrv.o bwctrl.o
>  
>  obj-y				+= aspm.o
> -obj-$(CONFIG_PCIEAER)		+= aer.o err.o
> +obj-$(CONFIG_PCIEAER)		+= aer.o err.o tlp.o
>  obj-$(CONFIG_PCIEAER_INJECT)	+= aer_inject.o
>  obj-$(CONFIG_PCIE_PME)		+= pme.o
>  obj-$(CONFIG_PCIE_DPC)		+= dpc.o
> diff --git a/drivers/pci/pcie/tlp.c b/drivers/pci/pcie/tlp.c
> new file mode 100644
> index 000000000000..3f053cc62290
> --- /dev/null
> +++ b/drivers/pci/pcie/tlp.c
> @@ -0,0 +1,39 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * PCIe TLP Log handling
> + *
> + * Copyright (C) 2024 Intel Corporation
> + */
> +
> +#include <linux/aer.h>
> +#include <linux/pci.h>
> +#include <linux/string.h>
> +
> +#include "../pci.h"
> +
> +/**
> + * pcie_read_tlp_log - read TLP Header Log
> + * @dev: PCIe device
> + * @where: PCI Config offset of TLP Header Log
> + * @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 i, ret;
> +
> +	memset(tlp_log, 0, sizeof(*tlp_log));
> +

Can we include a define for the number of registers? 

> +	for (i = 0; i < 4; i++) {

This '4' is "MIN_TLP_REGS" or something similar.

> +		ret = pci_read_config_dword(dev, where + i * 4,

This '4' is the register offset factor.

Another thought is to make the offset a variable and adjust it in the
for-loop conditions.

	int i, ret, offset = where;

	for (i = 0; i < MIN_TLP_REGS; i++, offset += 4) {
		ret = pci_read_config_dword(dev, offset, &tlp_log->dw[i]);

I think this will help as variable-size TLP logs are added in later
patches.

> +					    &tlp_log->dw[i]);
> +		if (ret)
> +			return pcibios_err_to_errno(ret);
> +	}
> +
> +	return 0;
> +}

Thanks,
Yazen


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 3/7] PCI: Make pcie_read_tlp_log() signature same
  2024-12-18 14:37 ` [PATCH v8 3/7] PCI: Make pcie_read_tlp_log() signature same Ilpo Järvinen
@ 2025-01-08 20:40   ` Yazen Ghannam
  2025-01-08 22:13     ` Bjorn Helgaas
  0 siblings, 1 reply; 19+ messages in thread
From: Yazen Ghannam @ 2025-01-08 20:40 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: Bjorn Helgaas, linux-pci, Krzysztof Wilczyński, Lukas Wunner,
	Jonathan Cameron, linux-kernel, Mahesh J Salgaonkar,
	Oliver O'Halloran, linuxppc-dev

On Wed, Dec 18, 2024 at 04:37:43PM +0200, Ilpo Järvinen wrote:
> pcie_read_tlp_log()'s prototype and function signature diverged due to
> changes made while applying.
> 
> Make the parameters of pcie_read_tlp_log() named identically.
> 
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

Reviewed-by: Yazen Ghannam <yazen.ghannam@amd.com>

Just wondering, could this be squashed into the previous patch? Or is
the goal to be strict with one logical change per patch?

Thanks,
Yazen


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 5/7] PCI: Store # of supported End-End TLP Prefixes
  2024-12-18 14:37 ` [PATCH v8 5/7] PCI: Store # of supported End-End TLP Prefixes Ilpo Järvinen
  2025-01-03 16:36   ` Jonathan Cameron
@ 2025-01-08 20:56   ` Yazen Ghannam
  1 sibling, 0 replies; 19+ messages in thread
From: Yazen Ghannam @ 2025-01-08 20:56 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: Bjorn Helgaas, linux-pci, Krzysztof Wilczyński, Lukas Wunner,
	Jonathan Cameron, linux-kernel, Mahesh J Salgaonkar,
	Oliver O'Halloran, linuxppc-dev

On Wed, Dec 18, 2024 at 04:37:45PM +0200, Ilpo Järvinen wrote:
> eetlp_prefix_path in the struct pci_dev tells if End-End TLP Prefixes
> are supported by the path or not, the value is only calculated if
> CONFIG_PCI_PASID is set.
> 
> The Max End-End TLP Prefixes field in the Device Capabilities Register
> 2 also tells how many (1-4) End-End TLP Prefixes are supported (PCIe
> r6.2 sec 7.5.3.15). The number of supported End-End Prefixes is useful
> for reading correct number of DWORDs from TLP Prefix Log register in AER
> capability (PCIe r6.2 sec 7.8.4.12).
> 
> Replace eetlp_prefix_path with eetlp_prefix_max and determine the
> number of supported End-End Prefixes regardless of CONFIG_PCI_PASID so
> that an upcoming commit generalizing TLP Prefix Log register reading
> does not have to read extra DWORDs for End-End Prefixes that never will
> be there.
> 
> The value stored into eetlp_prefix_max is directly derived from
> device's Max End-End TLP Prefixes and does not consider limitations
> imposed by bridges or the Root Port beyond supported/not supported
> flags. This is intentional for two reasons:
> 
>   1) PCIe r6.2 spec sections r6.1 2.2.10.4 & 6.2.4.4 indicate that TLP
>   is handled malformed only if the number of prefixes exceed the number
>   of Max End-End TLP Prefixes, which seems to be the case even if the
>   device could never receive that many prefixes due to smaller maximum
>   imposed by a bridge or the Root Port. If TLP parsing is later added,
>   this distinction is significant in interpreting what is logged by the
>   TLP Prefix Log registers and the value matching to the Malformed TLP
>   threshold is going to be more useful.
> 
>   2) TLP Prefix handling happens autonomously on a low layer and the
>   value in eetlp_prefix_max is not programmed anywhere by the kernel
>   (i.e., there is no limiter OS can control to prevent sending more
>   than n TLP Prefixes).
> 
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

Reviewed-by: Yazen Ghannam <yazen.ghannam@amd.com>

Thanks,
Yazen


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 6/7] PCI: Add TLP Prefix reading into pcie_read_tlp_log()
  2024-12-18 14:37 ` [PATCH v8 6/7] PCI: Add TLP Prefix reading into pcie_read_tlp_log() Ilpo Järvinen
@ 2025-01-08 21:33   ` Yazen Ghannam
  2025-01-09  9:36     ` Ilpo Järvinen
  0 siblings, 1 reply; 19+ messages in thread
From: Yazen Ghannam @ 2025-01-08 21:33 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: Bjorn Helgaas, linux-pci, Krzysztof Wilczyński, Lukas Wunner,
	Jonathan Cameron, Mahesh J Salgaonkar, Oliver O'Halloran,
	linux-kernel, linuxppc-dev

On Wed, Dec 18, 2024 at 04:37:46PM +0200, Ilpo Järvinen wrote:
> 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.
> c) AER TLP Prefix Log Present (PCIe r6.1 sec 7.8.4.7) can indicate
>    Prefix Log is not present.
> 
> 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 <ilpo.jarvinen@linux.intel.com>
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> ---
>  drivers/pci/pci.h             |  5 +++-
>  drivers/pci/pcie/aer.c        |  5 +++-
>  drivers/pci/pcie/dpc.c        | 13 +++++----
>  drivers/pci/pcie/tlp.c        | 51 +++++++++++++++++++++++++++++++----
>  include/linux/aer.h           |  1 +
>  include/uapi/linux/pci_regs.h | 10 ++++---
>  6 files changed, 67 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> index 55fcf3bac4f7..7797b2544d00 100644
> --- a/drivers/pci/pci.h
> +++ b/drivers/pci/pci.h
> @@ -550,7 +550,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, u32 aercc);
>  #endif	/* CONFIG_PCIEAER */
>  
>  #ifdef CONFIG_PCIEPORTBUS
> @@ -569,6 +571,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 80c5ba8d8296..656dbf1ac45b 100644
> --- a/drivers/pci/pcie/aer.c
> +++ b/drivers/pci/pcie/aer.c
> @@ -1248,7 +1248,10 @@ 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, aercc),
> +					  &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..302ba99e64e6 100644
> --- a/drivers/pci/pcie/tlp.c
> +++ b/drivers/pci/pcie/tlp.c
> @@ -11,26 +11,67 @@
>  
>  #include "../pci.h"
>  
> +/**
> + * aer_tlp_log_len - Calculates AER Capability TLP Header/Prefix Log length
> + * @dev: PCIe device
> + * @aercc: AER Capabilities and Control register value
> + *
> + * Return: TLP Header/Prefix Log length
> + */
> +unsigned int aer_tlp_log_len(struct pci_dev *dev, u32 aercc)
> +{
> +	return 4 + (aercc & PCI_ERR_CAP_PREFIX_LOG_PRESENT) ?

Another place for a "BASE_NR_*" define. I incorrectly said "MAX_NR_*" in
a previous patch. But "BASE" or "STD" seems more appropriate.

> +		   dev->eetlp_prefix_max : 0;
> +}
> +
> +#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);

Could we do two loops? Sorry if this was already discussed.

	for (i = 0; i < min(tlp_len, BASE_NR_TLP); i++, where += 4, tlp_len--) {
		ret = pci_read_config_dword(dev, where, &log->dw[i]);
		if (ret)
			return pcibios_err_to_errno(ret);
	}

	for (i = 0; i < tlp_len; i++, where2 += 4) {
		ret = pci_read_config_dword(dev, where2, &log->prefix[i]);
		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];

Another place for "BASE_NR_*".

>  };
>  
>  struct aer_capability_regs {
> diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
> index 14a6306c4ce1..82866ac0bda7 100644
> --- a/include/uapi/linux/pci_regs.h
> +++ b/include/uapi/linux/pci_regs.h
> @@ -790,10 +790,11 @@
>  	/* Same bits as above */
>  #define PCI_ERR_CAP		0x18	/* Advanced Error Capabilities & Ctrl*/
>  #define  PCI_ERR_CAP_FEP(x)	((x) & 0x1f)	/* First Error Pointer */
> -#define  PCI_ERR_CAP_ECRC_GENC	0x00000020	/* ECRC Generation Capable */
> -#define  PCI_ERR_CAP_ECRC_GENE	0x00000040	/* ECRC Generation Enable */
> -#define  PCI_ERR_CAP_ECRC_CHKC	0x00000080	/* ECRC Check Capable */
> -#define  PCI_ERR_CAP_ECRC_CHKE	0x00000100	/* ECRC Check Enable */
> +#define  PCI_ERR_CAP_ECRC_GENC		0x00000020 /* ECRC Generation Capable */
> +#define  PCI_ERR_CAP_ECRC_GENE		0x00000040 /* ECRC Generation Enable */
> +#define  PCI_ERR_CAP_ECRC_CHKC		0x00000080 /* ECRC Check Capable */
> +#define  PCI_ERR_CAP_ECRC_CHKE		0x00000100 /* ECRC Check Enable */
> +#define  PCI_ERR_CAP_PREFIX_LOG_PRESENT	0x00000800 /* TLP Prefix Log Present */

I didn't think to mention this in a previous patch, but could/should we
use GENMASK() for bitmasks updates? I know it's a break from the current
style though.

>  #define PCI_ERR_HEADER_LOG	0x1c	/* Header Log Register (16 bytes) */
>  #define PCI_ERR_ROOT_COMMAND	0x2c	/* Root Error Command */
>  #define  PCI_ERR_ROOT_CMD_COR_EN	0x00000001 /* Correctable Err Reporting Enable */
> @@ -809,6 +810,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
> -- 

Thanks,
Yazen


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 3/7] PCI: Make pcie_read_tlp_log() signature same
  2025-01-08 20:40   ` Yazen Ghannam
@ 2025-01-08 22:13     ` Bjorn Helgaas
  0 siblings, 0 replies; 19+ messages in thread
From: Bjorn Helgaas @ 2025-01-08 22:13 UTC (permalink / raw)
  To: Yazen Ghannam
  Cc: Ilpo Järvinen, Bjorn Helgaas, linux-pci,
	Krzysztof Wilczyński, Lukas Wunner, Jonathan Cameron,
	linux-kernel, Mahesh J Salgaonkar, Oliver O'Halloran,
	linuxppc-dev

On Wed, Jan 08, 2025 at 03:40:11PM -0500, Yazen Ghannam wrote:
> On Wed, Dec 18, 2024 at 04:37:43PM +0200, Ilpo Järvinen wrote:
> > pcie_read_tlp_log()'s prototype and function signature diverged due to
> > changes made while applying.
> > 
> > Make the parameters of pcie_read_tlp_log() named identically.
> > 
> > Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> 
> Reviewed-by: Yazen Ghannam <yazen.ghannam@amd.com>
> 
> Just wondering, could this be squashed into the previous patch? Or is
> the goal to be strict with one logical change per patch?

I haven't looked closely enough to opine on whether this should be
squashed, but I generally do prefer one logical change per patch.

It's much easier for me to squash things when merging than it is to
untangle things that should be separate patches.

Bjorn


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 6/7] PCI: Add TLP Prefix reading into pcie_read_tlp_log()
  2025-01-08 21:33   ` Yazen Ghannam
@ 2025-01-09  9:36     ` Ilpo Järvinen
  2025-01-10 14:54       ` Yazen Ghannam
  0 siblings, 1 reply; 19+ messages in thread
From: Ilpo Järvinen @ 2025-01-09  9:36 UTC (permalink / raw)
  To: Yazen Ghannam
  Cc: Bjorn Helgaas, linux-pci, Krzysztof Wilczyński, Lukas Wunner,
	Jonathan Cameron, Mahesh J Salgaonkar, Oliver O'Halloran,
	LKML, linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 10970 bytes --]

On Wed, 8 Jan 2025, Yazen Ghannam wrote:

> On Wed, Dec 18, 2024 at 04:37:46PM +0200, Ilpo Järvinen wrote:
> > 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.
> > c) AER TLP Prefix Log Present (PCIe r6.1 sec 7.8.4.7) can indicate
> >    Prefix Log is not present.
> > 
> > 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 <ilpo.jarvinen@linux.intel.com>
> > Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> > ---
> >  drivers/pci/pci.h             |  5 +++-
> >  drivers/pci/pcie/aer.c        |  5 +++-
> >  drivers/pci/pcie/dpc.c        | 13 +++++----
> >  drivers/pci/pcie/tlp.c        | 51 +++++++++++++++++++++++++++++++----
> >  include/linux/aer.h           |  1 +
> >  include/uapi/linux/pci_regs.h | 10 ++++---
> >  6 files changed, 67 insertions(+), 18 deletions(-)
> > 
> > diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> > index 55fcf3bac4f7..7797b2544d00 100644
> > --- a/drivers/pci/pci.h
> > +++ b/drivers/pci/pci.h
> > @@ -550,7 +550,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, u32 aercc);
> >  #endif	/* CONFIG_PCIEAER */
> >  
> >  #ifdef CONFIG_PCIEPORTBUS
> > @@ -569,6 +571,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 80c5ba8d8296..656dbf1ac45b 100644
> > --- a/drivers/pci/pcie/aer.c
> > +++ b/drivers/pci/pcie/aer.c
> > @@ -1248,7 +1248,10 @@ 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, aercc),
> > +					  &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..302ba99e64e6 100644
> > --- a/drivers/pci/pcie/tlp.c
> > +++ b/drivers/pci/pcie/tlp.c
> > @@ -11,26 +11,67 @@
> >  
> >  #include "../pci.h"
> >  
> > +/**
> > + * aer_tlp_log_len - Calculates AER Capability TLP Header/Prefix Log length
> > + * @dev: PCIe device
> > + * @aercc: AER Capabilities and Control register value
> > + *
> > + * Return: TLP Header/Prefix Log length
> > + */
> > +unsigned int aer_tlp_log_len(struct pci_dev *dev, u32 aercc)
> > +{
> > +	return 4 + (aercc & PCI_ERR_CAP_PREFIX_LOG_PRESENT) ?
> 
> Another place for a "BASE_NR_*" define. I incorrectly said "MAX_NR_*" in
> a previous patch. But "BASE" or "STD" seems more appropriate.

Thanks for the reviews!

I don't know why I didn't realize I was adding a literal 4 in many places. 
I'll surely add a define for it now that you pointed it out, thanks.

> > +		   dev->eetlp_prefix_max : 0;
> > +}
> > +
> > +#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);
> 
> Could we do two loops? Sorry if this was already discussed.
> 
> 	for (i = 0; i < min(tlp_len, BASE_NR_TLP); i++, where += 4, tlp_len--) {
> 		ret = pci_read_config_dword(dev, where, &log->dw[i]);
> 		if (ret)
> 			return pcibios_err_to_errno(ret);
> 	}
> 
> 	for (i = 0; i < tlp_len; i++, where2 += 4) {
> 		ret = pci_read_config_dword(dev, where2, &log->prefix[i]);
> 		if (ret)
> 			return pcibios_err_to_errno(ret);
> 	}

I'm not convinced splitting it would be clearly better. After the flit 
mode patch, only variation that will remain is the offset calculation 
(extended ->dw[] entires will be overlapping with ->prefix[] using union 
trickery so I can just use ->dw[i] in the loop).

> >  	}
> > 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];
> 
> Another place for "BASE_NR_*".
> 
> >  };
> >  
> >  struct aer_capability_regs {
> > diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
> > index 14a6306c4ce1..82866ac0bda7 100644
> > --- a/include/uapi/linux/pci_regs.h
> > +++ b/include/uapi/linux/pci_regs.h
> > @@ -790,10 +790,11 @@
> >  	/* Same bits as above */
> >  #define PCI_ERR_CAP		0x18	/* Advanced Error Capabilities & Ctrl*/
> >  #define  PCI_ERR_CAP_FEP(x)	((x) & 0x1f)	/* First Error Pointer */
> > -#define  PCI_ERR_CAP_ECRC_GENC	0x00000020	/* ECRC Generation Capable */
> > -#define  PCI_ERR_CAP_ECRC_GENE	0x00000040	/* ECRC Generation Enable */
> > -#define  PCI_ERR_CAP_ECRC_CHKC	0x00000080	/* ECRC Check Capable */
> > -#define  PCI_ERR_CAP_ECRC_CHKE	0x00000100	/* ECRC Check Enable */
> > +#define  PCI_ERR_CAP_ECRC_GENC		0x00000020 /* ECRC Generation Capable */
> > +#define  PCI_ERR_CAP_ECRC_GENE		0x00000040 /* ECRC Generation Enable */
> > +#define  PCI_ERR_CAP_ECRC_CHKC		0x00000080 /* ECRC Check Capable */
> > +#define  PCI_ERR_CAP_ECRC_CHKE		0x00000100 /* ECRC Check Enable */
> > +#define  PCI_ERR_CAP_PREFIX_LOG_PRESENT	0x00000800 /* TLP Prefix Log Present */
> 
> I didn't think to mention this in a previous patch, but could/should we
> use GENMASK() for bitmasks updates? I know it's a break from the current
> style though.

Bjorn called himself "a dinosaur" when it comes to GENMASK() :-):

https://lore.kernel.org/linux-pci/20231031200312.GA25127@bhelgaas/

> >  #define PCI_ERR_HEADER_LOG	0x1c	/* Header Log Register (16 bytes) */
> >  #define PCI_ERR_ROOT_COMMAND	0x2c	/* Root Error Command */
> >  #define  PCI_ERR_ROOT_CMD_COR_EN	0x00000001 /* Correctable Err Reporting Enable */
> > @@ -809,6 +810,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

-- 
 i.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 6/7] PCI: Add TLP Prefix reading into pcie_read_tlp_log()
  2025-01-09  9:36     ` Ilpo Järvinen
@ 2025-01-10 14:54       ` Yazen Ghannam
  0 siblings, 0 replies; 19+ messages in thread
From: Yazen Ghannam @ 2025-01-10 14:54 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: Bjorn Helgaas, linux-pci, Krzysztof Wilczyński, Lukas Wunner,
	Jonathan Cameron, Mahesh J Salgaonkar, Oliver O'Halloran,
	LKML, linuxppc-dev

On Thu, Jan 09, 2025 at 11:36:17AM +0200, Ilpo Järvinen wrote:

[...]

> > > -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);
> > 
> > Could we do two loops? Sorry if this was already discussed.
> > 
> > 	for (i = 0; i < min(tlp_len, BASE_NR_TLP); i++, where += 4, tlp_len--) {
> > 		ret = pci_read_config_dword(dev, where, &log->dw[i]);
> > 		if (ret)
> > 			return pcibios_err_to_errno(ret);
> > 	}
> > 
> > 	for (i = 0; i < tlp_len; i++, where2 += 4) {
> > 		ret = pci_read_config_dword(dev, where2, &log->prefix[i]);
> > 		if (ret)
> > 			return pcibios_err_to_errno(ret);
> > 	}
> 
> I'm not convinced splitting it would be clearly better. After the flit 
> mode patch, only variation that will remain is the offset calculation 
> (extended ->dw[] entires will be overlapping with ->prefix[] using union 
> trickery so I can just use ->dw[i] in the loop).
>

Ah okay, no problem.

> > >  	}
> > > 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];
> > 
> > Another place for "BASE_NR_*".
> > 
> > >  };
> > >  
> > >  struct aer_capability_regs {
> > > diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
> > > index 14a6306c4ce1..82866ac0bda7 100644
> > > --- a/include/uapi/linux/pci_regs.h
> > > +++ b/include/uapi/linux/pci_regs.h
> > > @@ -790,10 +790,11 @@
> > >  	/* Same bits as above */
> > >  #define PCI_ERR_CAP		0x18	/* Advanced Error Capabilities & Ctrl*/
> > >  #define  PCI_ERR_CAP_FEP(x)	((x) & 0x1f)	/* First Error Pointer */
> > > -#define  PCI_ERR_CAP_ECRC_GENC	0x00000020	/* ECRC Generation Capable */
> > > -#define  PCI_ERR_CAP_ECRC_GENE	0x00000040	/* ECRC Generation Enable */
> > > -#define  PCI_ERR_CAP_ECRC_CHKC	0x00000080	/* ECRC Check Capable */
> > > -#define  PCI_ERR_CAP_ECRC_CHKE	0x00000100	/* ECRC Check Enable */
> > > +#define  PCI_ERR_CAP_ECRC_GENC		0x00000020 /* ECRC Generation Capable */
> > > +#define  PCI_ERR_CAP_ECRC_GENE		0x00000040 /* ECRC Generation Enable */
> > > +#define  PCI_ERR_CAP_ECRC_CHKC		0x00000080 /* ECRC Check Capable */
> > > +#define  PCI_ERR_CAP_ECRC_CHKE		0x00000100 /* ECRC Check Enable */
> > > +#define  PCI_ERR_CAP_PREFIX_LOG_PRESENT	0x00000800 /* TLP Prefix Log Present */
> > 
> > I didn't think to mention this in a previous patch, but could/should we
> > use GENMASK() for bitmasks updates? I know it's a break from the current
> > style though.
> 
> Bjorn called himself "a dinosaur" when it comes to GENMASK() :-):
> 
> https://lore.kernel.org/linux-pci/20231031200312.GA25127@bhelgaas/
> 

I'll try to remember. :)

Thanks,
Yazen


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2025-01-10 14:55 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-18 14:37 [PATCH v8 0/7] PCI: Consolidate TLP Log reading and printing Ilpo Järvinen
2024-12-18 14:37 ` [PATCH v8 1/7] PCI: Don't expose pcie_read_tlp_log() outside of PCI subsystem Ilpo Järvinen
2025-01-08 16:05   ` Yazen Ghannam
2024-12-18 14:37 ` [PATCH v8 2/7] PCI: Move TLP Log handling to own file Ilpo Järvinen
2025-01-08 16:26   ` Yazen Ghannam
2024-12-18 14:37 ` [PATCH v8 3/7] PCI: Make pcie_read_tlp_log() signature same Ilpo Järvinen
2025-01-08 20:40   ` Yazen Ghannam
2025-01-08 22:13     ` Bjorn Helgaas
2024-12-18 14:37 ` [PATCH v8 4/7] PCI: Use unsigned int i in pcie_read_tlp_log() Ilpo Järvinen
2025-01-03 16:38   ` Jonathan Cameron
2024-12-18 14:37 ` [PATCH v8 5/7] PCI: Store # of supported End-End TLP Prefixes Ilpo Järvinen
2025-01-03 16:36   ` Jonathan Cameron
2025-01-08 20:56   ` Yazen Ghannam
2024-12-18 14:37 ` [PATCH v8 6/7] PCI: Add TLP Prefix reading into pcie_read_tlp_log() Ilpo Järvinen
2025-01-08 21:33   ` Yazen Ghannam
2025-01-09  9:36     ` Ilpo Järvinen
2025-01-10 14:54       ` Yazen Ghannam
2024-12-18 14:37 ` [PATCH v8 7/7] PCI: Create helper to print TLP Header and Prefix Log Ilpo Järvinen
2025-01-08 15:53 ` [PATCH v8 0/7] PCI: Consolidate TLP Log reading and printing Yazen Ghannam

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).