mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] PCI: rcar-gen4: Limit Max_Read_Request_Size and Max_Payload_Size to 256 Bytes
@ 2026-04-25 23:38 Marek Vasut
  2026-04-28  7:00 ` Koichiro Den
  2026-05-11 14:34 ` Manivannan Sadhasivam
  0 siblings, 2 replies; 10+ messages in thread
From: Marek Vasut @ 2026-04-25 23:38 UTC (permalink / raw)
  To: linux-pci
  Cc: Marek Vasut, stable, Krzysztof Wilczyński, Bjorn Helgaas,
	Geert Uytterhoeven, Koichiro Den, Lorenzo Pieralisi, Magnus Damm,
	Manivannan Sadhasivam, Rob Herring, Yoshihiro Shimoda,
	linux-kernel, linux-renesas-soc

R-Car Gen4 PCIe controller has a hardware limitation of 256 Bytes
maximum payload size. The PCIe DMA generates requests of size up
to minimum(Max_Read_Request_Size, Max_Payload_Size). Force limit
both Max_Read_Request_Size and Max_Payload_Size to 256 Bytes and
propagate this limit to all downstream devices.

This limitation can be triggered for example by using an NVMe SSD
which does not use host memory buffer, Samsung 980 PRO is such an
SSD. Affected SSD reports 'hmpre' field as 0:
"
$ nvme id-ctrl /dev/nvme0 | grep hmpre
hmpre     : 0
"

The symptom is a read from the SSD which wraps around at 256 Byte
boundary. The test for this symptom can be implemented by writing
512 Byte of random data into the SSD and reading the data back. If
the read back data repeat after 256 Bytes, the device is affected.
"
$ dd if=/dev/urandom of=/tmp/data.bin bs=256 count=2 \
  dd if=/tmp/data.bin of=/dev/nvme0n1 bs=256 count=2 \
  dd if=/dev/nvme0n1 bs=256 count=2 of=/tmp/readback.bin
"

Expected data:
"
$ hexdump -vC /tmp/data.bin
00000000  97 81 b7 3b 0e 38 2b 4d  a7 d3 e0 47 ff c2 4b ca
00000010  c1 85 98 f0 4a ac 03 a0  3b ab f3 19 44 dd 06 8b
...
00000100  7a ce 3c b2 e1 d5 d9 11  88 63 10 59 76 3c dc 32 <-- random
00000110  72 32 2a 7d a3 e1 aa 13  7c da 58 a1 7b 21 11 50 <-- data
"

Faulty readback, collected without this change in place:
"
$ hexdump -vC /tmp/readback.bin
00000000  97 81 b7 3b 0e 38 2b 4d  a7 d3 e0 47 ff c2 4b ca <---.
00000010  c1 85 98 f0 4a ac 03 a0  3b ab f3 19 44 dd 06 8b <-. |
...                                                          | |
00000100  97 81 b7 3b 0e 38 2b 4d  a7 d3 e0 47 ff c2 4b ca <-:-+- repeated
00000110  c1 85 98 f0 4a ac 03 a0  3b ab f3 19 44 dd 06 8b <-+--- data
     ^^^
      |
      '--- Repeat starts at offset 0x100 = 256 Bytes
"

Fixes: 0d0c551011df ("PCI: rcar-gen4: Add R-Car Gen4 PCIe controller support for host mode")
Cc: stable@vger.kernel.org
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: "Krzysztof Wilczyński" <kwilczynski@kernel.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Koichiro Den <den@valinux.co.jp>
Cc: Lorenzo Pieralisi <lpieralisi@kernel.org>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Cc: Rob Herring <robh@kernel.org>
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Cc: linux-kernel@vger.kernel.org
Cc: linux-pci@vger.kernel.org
Cc: linux-renesas-soc@vger.kernel.org
---
 drivers/pci/controller/dwc/pcie-rcar-gen4.c | 56 +++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
index 8b03c42f8c84c..82f0a074a71da 100644
--- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
+++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
@@ -576,6 +576,7 @@ static int r8a779f0_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable)
 static void rcar_gen4_pcie_additional_common_init(struct rcar_gen4_pcie *rcar)
 {
 	struct dw_pcie *dw = &rcar->dw;
+	u16 offset = dw_pcie_find_capability(dw, PCI_CAP_ID_EXP);
 	u32 val;
 
 	val = dw_pcie_readl_dbi(dw, PCIE_PORT_LANE_SKEW);
@@ -584,11 +585,66 @@ static void rcar_gen4_pcie_additional_common_init(struct rcar_gen4_pcie *rcar)
 		val |= BIT(6);
 	dw_pcie_writel_dbi(dw, PCIE_PORT_LANE_SKEW, val);
 
+	val = dw_pcie_readl_dbi(dw, offset + PCI_EXP_DEVCTL);
+	val &= ~(PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ);
+	val |= PCI_EXP_DEVCTL_PAYLOAD_256B | PCI_EXP_DEVCTL_READRQ_256B;
+	dw_pcie_writel_dbi(dw, offset + PCI_EXP_DEVCTL, val);
+
 	val = readl(rcar->base + PCIEPWRMNGCTRL);
 	val |= APP_CLK_REQ_N | APP_CLK_PM_EN;
 	writel(val, rcar->base + PCIEPWRMNGCTRL);
 }
 
+static void rcar_gen4_rc_pcie_quirk(struct pci_dev *dev)
+{
+	static const struct pci_device_id rcar_gen4_pcie_rc_devid = {
+		PCI_DEVICE(PCI_VENDOR_ID_RENESAS, 0x0030),
+		.class = PCI_CLASS_BRIDGE_PCI_NORMAL, .class_mask = ~0
+	};
+	struct pci_bus *bus = dev->bus;
+	struct pci_dev *bridge;
+
+	if (pci_is_root_bus(bus))
+		bridge = dev;
+
+	/* Look for the host bridge */
+	while (!pci_is_root_bus(bus)) {
+		bridge = bus->self;
+		bus = bus->parent;
+	}
+
+	if (!bridge)
+		return;
+
+	if (!pci_match_one_device(&rcar_gen4_pcie_rc_devid, bridge))
+		return;
+
+	/*
+	 * R-Car Gen4 PCIe controller has a hardware limitation of 256 Bytes
+	 * maximum payload size. The PCIe DMA generates requests of size up
+	 * to minimum(Max_Read_Request_Size, Max_Payload_Size). Force limit
+	 * both Max_Read_Request_Size and Max_Payload_Size to 256 Bytes and
+	 * propagate this limit to all downstream devices.
+	 *
+	 * For details, refer to:
+	 * R-Car S4 R19UH0161EJ0130 Rev.1.30 Jun. 16, 2025 or
+	 * R-Car V4H R19UH0186EJ0130 Rev.1.30 Apr. 21, 2025 or
+	 * R-Car V4M R19UH0217EJ0100 Rev.1.00 Dec. 12, 2025,
+	 * chapters 104.1.1 Features and 104.3.9 DMA Transfer
+	 * section DMA Read Transfer.
+	 */
+	if (pcie_get_readrq(dev) > 256) {
+		dev_info(&dev->dev, "Limiting MRRS to 256 bytes\n");
+		pcie_set_readrq(dev, 256);
+	}
+
+	if (pcie_get_mps(dev) > 256) {
+		dev_info(&dev->dev, "Limiting MPS to 256 bytes\n");
+		pcie_set_mps(dev, 256);
+	}
+}
+DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, rcar_gen4_rc_pcie_quirk);
+
 static void rcar_gen4_pcie_phy_reg_update_bits(struct rcar_gen4_pcie *rcar,
 					       u32 offset, u32 mask, u32 val)
 {
-- 
2.53.0


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

* Re: [PATCH] PCI: rcar-gen4: Limit Max_Read_Request_Size and Max_Payload_Size to 256 Bytes
  2026-04-25 23:38 [PATCH] PCI: rcar-gen4: Limit Max_Read_Request_Size and Max_Payload_Size to 256 Bytes Marek Vasut
@ 2026-04-28  7:00 ` Koichiro Den
  2026-05-03 23:54   ` Marek Vasut
  2026-05-11 14:34 ` Manivannan Sadhasivam
  1 sibling, 1 reply; 10+ messages in thread
From: Koichiro Den @ 2026-04-28  7:00 UTC (permalink / raw)
  To: Marek Vasut
  Cc: linux-pci, stable, Krzysztof Wilczyński, Bjorn Helgaas,
	Geert Uytterhoeven, Lorenzo Pieralisi, Magnus Damm,
	Manivannan Sadhasivam, Rob Herring, Yoshihiro Shimoda,
	linux-kernel, linux-renesas-soc

On Sun, Apr 26, 2026 at 01:38:28AM +0200, Marek Vasut wrote:
> R-Car Gen4 PCIe controller has a hardware limitation of 256 Bytes
> maximum payload size. The PCIe DMA generates requests of size up
> to minimum(Max_Read_Request_Size, Max_Payload_Size). Force limit
> both Max_Read_Request_Size and Max_Payload_Size to 256 Bytes and
> propagate this limit to all downstream devices.
> 
> This limitation can be triggered for example by using an NVMe SSD
> which does not use host memory buffer, Samsung 980 PRO is such an
> SSD. Affected SSD reports 'hmpre' field as 0:
> "
> $ nvme id-ctrl /dev/nvme0 | grep hmpre
> hmpre     : 0
> "
> 
> The symptom is a read from the SSD which wraps around at 256 Byte
> boundary. The test for this symptom can be implemented by writing
> 512 Byte of random data into the SSD and reading the data back. If
> the read back data repeat after 256 Bytes, the device is affected.
> "
> $ dd if=/dev/urandom of=/tmp/data.bin bs=256 count=2 \
>   dd if=/tmp/data.bin of=/dev/nvme0n1 bs=256 count=2 \
>   dd if=/dev/nvme0n1 bs=256 count=2 of=/tmp/readback.bin
> "
> 
> Expected data:
> "
> $ hexdump -vC /tmp/data.bin
> 00000000  97 81 b7 3b 0e 38 2b 4d  a7 d3 e0 47 ff c2 4b ca
> 00000010  c1 85 98 f0 4a ac 03 a0  3b ab f3 19 44 dd 06 8b
> ...
> 00000100  7a ce 3c b2 e1 d5 d9 11  88 63 10 59 76 3c dc 32 <-- random
> 00000110  72 32 2a 7d a3 e1 aa 13  7c da 58 a1 7b 21 11 50 <-- data
> "
> 
> Faulty readback, collected without this change in place:
> "
> $ hexdump -vC /tmp/readback.bin
> 00000000  97 81 b7 3b 0e 38 2b 4d  a7 d3 e0 47 ff c2 4b ca <---.
> 00000010  c1 85 98 f0 4a ac 03 a0  3b ab f3 19 44 dd 06 8b <-. |
> ...                                                          | |
> 00000100  97 81 b7 3b 0e 38 2b 4d  a7 d3 e0 47 ff c2 4b ca <-:-+- repeated
> 00000110  c1 85 98 f0 4a ac 03 a0  3b ab f3 19 44 dd 06 8b <-+--- data
>      ^^^
>       |
>       '--- Repeat starts at offset 0x100 = 256 Bytes
> "
> 
> Fixes: 0d0c551011df ("PCI: rcar-gen4: Add R-Car Gen4 PCIe controller support for host mode")
> Cc: stable@vger.kernel.org
> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
> ---
> Cc: "Krzysztof Wilczyński" <kwilczynski@kernel.org>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Geert Uytterhoeven <geert+renesas@glider.be>
> Cc: Koichiro Den <den@valinux.co.jp>
> Cc: Lorenzo Pieralisi <lpieralisi@kernel.org>
> Cc: Magnus Damm <magnus.damm@gmail.com>
> Cc: Manivannan Sadhasivam <mani@kernel.org>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-pci@vger.kernel.org
> Cc: linux-renesas-soc@vger.kernel.org
> ---
>  drivers/pci/controller/dwc/pcie-rcar-gen4.c | 56 +++++++++++++++++++++
>  1 file changed, 56 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> index 8b03c42f8c84c..82f0a074a71da 100644
> --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> @@ -576,6 +576,7 @@ static int r8a779f0_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable)
>  static void rcar_gen4_pcie_additional_common_init(struct rcar_gen4_pcie *rcar)
>  {
>  	struct dw_pcie *dw = &rcar->dw;
> +	u16 offset = dw_pcie_find_capability(dw, PCI_CAP_ID_EXP);
>  	u32 val;
>  
>  	val = dw_pcie_readl_dbi(dw, PCIE_PORT_LANE_SKEW);
> @@ -584,11 +585,66 @@ static void rcar_gen4_pcie_additional_common_init(struct rcar_gen4_pcie *rcar)
>  		val |= BIT(6);
>  	dw_pcie_writel_dbi(dw, PCIE_PORT_LANE_SKEW, val);
>  
> +	val = dw_pcie_readl_dbi(dw, offset + PCI_EXP_DEVCTL);
> +	val &= ~(PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ);
> +	val |= PCI_EXP_DEVCTL_PAYLOAD_256B | PCI_EXP_DEVCTL_READRQ_256B;
> +	dw_pcie_writel_dbi(dw, offset + PCI_EXP_DEVCTL, val);
> +
>  	val = readl(rcar->base + PCIEPWRMNGCTRL);
>  	val |= APP_CLK_REQ_N | APP_CLK_PM_EN;
>  	writel(val, rcar->base + PCIEPWRMNGCTRL);
>  }

Hello Marek,

The patch makes sense to me. Let me ask two questions:

1. Could r8a779f0 (R-Car S4-8) be handled as well, perhaps by adding a separate
   .additional_common_init() implementation for it?

   As far as I can see, the r8a779f0 match data currently does not use
   rcar_gen4_pcie_additional_common_init().

2. Did you also happen to test V4H/V4M in endpoint (EP) mode, with the local
   eDMA engine issuing MRd requests toward host memory? Your commit message
   describes an NVMe device as the requester, but I'm wondering whether the same
   256B limit was also verified for the R-Car EP DMA requester path.



(*) The background for my question 2:

   I only have access to S4 Spider boards. In my RC <-> EP setup, where the EP
   side uses the local eDMA engine to issue MRd requests toward the RC, 256-byte
   MRd requests still appear to corrupt the transferred data. With the following
   change on top of your patch, my DMA-read tests become stable:

   ---8<-----8<---

   diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
   index 82f0a074a71d..6910b9cd9d7b 100644
   --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
   +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
   @@ -595,6 +595,18 @@ static void rcar_gen4_pcie_additional_common_init(struct rcar_gen4_pcie *rcar)
           writel(val, rcar->base + PCIEPWRMNGCTRL);
    }
   
   +static void r8a779f0_additional_common_init(struct rcar_gen4_pcie *rcar)
   +{
   +       struct dw_pcie *dw = &rcar->dw;
   +       u16 offset = dw_pcie_find_capability(dw, PCI_CAP_ID_EXP);
   +       u32 val;
   +
   +       val = dw_pcie_readl_dbi(dw, offset + PCI_EXP_DEVCTL);
   +       val &= ~(PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ);
   +       val |= PCI_EXP_DEVCTL_PAYLOAD_128B | PCI_EXP_DEVCTL_READRQ_128B;
   +       dw_pcie_writel_dbi(dw, offset + PCI_EXP_DEVCTL, val);
   +}
   +
    static void rcar_gen4_rc_pcie_quirk(struct pci_dev *dev)
    {
           static const struct pci_device_id rcar_gen4_pcie_rc_devid = {
   @@ -796,11 +808,13 @@ static int rcar_gen4_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable
    }
   
    static struct rcar_gen4_pcie_drvdata drvdata_r8a779f0_pcie = {
   +       .additional_common_init = r8a779f0_additional_common_init,
           .ltssm_control = r8a779f0_pcie_ltssm_control,
           .mode = DW_PCIE_RC_TYPE,
    };
   
    static struct rcar_gen4_pcie_drvdata drvdata_r8a779f0_pcie_ep = {
   +       .additional_common_init = r8a779f0_additional_common_init,
           .ltssm_control = r8a779f0_pcie_ltssm_control,
           .mode = DW_PCIE_EP_TYPE,
    };

   ---8<-----8<---

   One detail which might be important is that limiting only MPS does not appear
   to be sufficient in my setup. MPS=128B with MRRS=256B still seems broken,
   while MPS=128B with MRRS=128B works fine. I wonder whether this is because
   the "MPS" term in the min(MRRS, MPS) limit for DMA read transfers may
   effectively be tied to the DMA read buffer segment size / MPSS rather than
   only to DevCtl.MPS. I'm not sure about this yet though.

   One more thing I noticed in the manuals:

     R-Car S4 R19UH0161EJ0130 Rev.1.30 Jun. 16, 2025:
       Type00 MPSS initial = 256B, PCI R, Internal R/W
       Type01 MPSS initial = 128B, PCI R, Internal R

     R-Car V4H R19UH0186EJ0130 Rev.1.30 Apr. 21, 2025
       Type00 MPSS initial = 256B, PCI R, Internal R
       Type01 MPSS initial = 128B, PCI R, Internal R/W

   I'm still unsure, but this difference might be relevant. In particular, in
   V4H/V4M RC mode your patch programs DevCtl.MPS to 256B, but does not change
   Type01 MPSS. I wonder if the Type01 MPSS should also be updated to 256B first
   on SoCs where the manual says it is writable from the internal bus, or if I'm
   missing something here.



Best regards,
Koichiro

>  
> +static void rcar_gen4_rc_pcie_quirk(struct pci_dev *dev)
> +{
> +	static const struct pci_device_id rcar_gen4_pcie_rc_devid = {
> +		PCI_DEVICE(PCI_VENDOR_ID_RENESAS, 0x0030),
> +		.class = PCI_CLASS_BRIDGE_PCI_NORMAL, .class_mask = ~0
> +	};
> +	struct pci_bus *bus = dev->bus;
> +	struct pci_dev *bridge;
> +
> +	if (pci_is_root_bus(bus))
> +		bridge = dev;
> +
> +	/* Look for the host bridge */
> +	while (!pci_is_root_bus(bus)) {
> +		bridge = bus->self;
> +		bus = bus->parent;
> +	}
> +
> +	if (!bridge)
> +		return;
> +
> +	if (!pci_match_one_device(&rcar_gen4_pcie_rc_devid, bridge))
> +		return;
> +
> +	/*
> +	 * R-Car Gen4 PCIe controller has a hardware limitation of 256 Bytes
> +	 * maximum payload size. The PCIe DMA generates requests of size up
> +	 * to minimum(Max_Read_Request_Size, Max_Payload_Size). Force limit
> +	 * both Max_Read_Request_Size and Max_Payload_Size to 256 Bytes and
> +	 * propagate this limit to all downstream devices.
> +	 *
> +	 * For details, refer to:
> +	 * R-Car S4 R19UH0161EJ0130 Rev.1.30 Jun. 16, 2025 or
> +	 * R-Car V4H R19UH0186EJ0130 Rev.1.30 Apr. 21, 2025 or
> +	 * R-Car V4M R19UH0217EJ0100 Rev.1.00 Dec. 12, 2025,
> +	 * chapters 104.1.1 Features and 104.3.9 DMA Transfer
> +	 * section DMA Read Transfer.
> +	 */
> +	if (pcie_get_readrq(dev) > 256) {
> +		dev_info(&dev->dev, "Limiting MRRS to 256 bytes\n");
> +		pcie_set_readrq(dev, 256);
> +	}
> +
> +	if (pcie_get_mps(dev) > 256) {
> +		dev_info(&dev->dev, "Limiting MPS to 256 bytes\n");
> +		pcie_set_mps(dev, 256);
> +	}
> +}
> +DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, rcar_gen4_rc_pcie_quirk);
> +
>  static void rcar_gen4_pcie_phy_reg_update_bits(struct rcar_gen4_pcie *rcar,
>  					       u32 offset, u32 mask, u32 val)
>  {
> -- 
> 2.53.0
> 

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

* Re: [PATCH] PCI: rcar-gen4: Limit Max_Read_Request_Size and Max_Payload_Size to 256 Bytes
  2026-04-28  7:00 ` Koichiro Den
@ 2026-05-03 23:54   ` Marek Vasut
  2026-05-11 14:20     ` Koichiro Den
  0 siblings, 1 reply; 10+ messages in thread
From: Marek Vasut @ 2026-05-03 23:54 UTC (permalink / raw)
  To: Koichiro Den
  Cc: linux-pci, stable, Krzysztof Wilczyński, Bjorn Helgaas,
	Geert Uytterhoeven, Lorenzo Pieralisi, Magnus Damm,
	Manivannan Sadhasivam, Rob Herring, Yoshihiro Shimoda,
	linux-kernel, linux-renesas-soc

On 4/28/26 9:00 AM, Koichiro Den wrote:

Hello Den-san,

> The patch makes sense to me. Let me ask two questions:
> 
> 1. Could r8a779f0 (R-Car S4-8) be handled as well, perhaps by adding a separate
>     .additional_common_init() implementation for it?
> 
>     As far as I can see, the r8a779f0 match data currently does not use
>     rcar_gen4_pcie_additional_common_init().

I will address this one in V2, thank you for pointing that out.

> 2. Did you also happen to test V4H/V4M in endpoint (EP) mode, with the local
>     eDMA engine issuing MRd requests toward host memory?

I was not able to test this configuration.

Is it possible to perform this test with a single device, by having the 
eDMA do local-memory-read-to-local-memory-write transfers, maybe using 
PIPE_LOOPBACK/LOOPBACK_ENABLE bits, or do I need two devices with NTB 
connection between them ?

In case it is the later, could you please briefly describe the S4 NTB 
setup you use, so I could try to replicate it locally ?

> Your commit message
>     describes an NVMe device as the requester, but I'm wondering whether the same
>     256B limit was also verified for the R-Car EP DMA requester path.

This part I currently can not answer, I'm sorry.

...

I made the following two observations in the meantime.

First, I wrote two SSDs, Crucial P5 Plus SSD without HMPRE (without host 
memory buffer) and XPG GAMMIX P55 with HMPRE (with host memory buffer) 
with 4 GiB of random data on another system (iMX8M Plus, ARM64 with DWC 
PCIe controller too), then I did a read back and compared the data, the 
writen and read-back data matched.

Then I plugged both SSDs into V4H Sparrow Hawk _without_ this patch, and 
I did read back of data:

- Crucial P5 Plus SSD without HMPRE (without host memory buffer)
   -> Data read back match data written on iMX8M Plus, OK
- XPG GAMMIX P55 with HMPRE (with host memory buffer)
   -> Data read back match data written on iMX8M Plus, OK

Then I wrote 512 Byte of data into the Crucial P5 Plus SSD without HMPRE 
on V4H Sparrow Hawk and did read back again.
   -> Data read back does NOT match data written, NG

That would indicate that:
- WRITE transfers from SSD to DRAM are OK
- READ transfers from DRAM to SSD are corrupted at 256 Bytes boundary

That would indicate that we need _at_least_ the 256 Bytes limit, likely 
on both MPS and MRRS.

Second, I got a report of another SSD for which this patch is not 
sufficient. I currently do not have access to that SSD, but I will ask 
for access and investigate. That may shed some light on the 128 Byte 
limit below.

> (*) The background for my question 2:
> 
>     I only have access to S4 Spider boards. In my RC <-> EP setup, where the EP
>     side uses the local eDMA engine to issue MRd requests toward the RC, 256-byte
>     MRd requests still appear to corrupt the transferred data.

Is the corruption deterministic in some way, i.e. are the same bytes of 
the transferred data corrupted every time, or is the corruption "random" ?

Does the corruption happen even on singular MRd transfer, or does it 
happen only when a lot of traffic is sent across the NTB link? I wonder 
if this corruption might be DRAM bandwidth related, i.e. whether the DMA 
does possibly saturate the DRAM controller with write requests and make 
the system run out of DRAM bandwidth.

> With the following
>     change on top of your patch, my DMA-read tests become stable:

[...]

>     One detail which might be important is that limiting only MPS does not appear
>     to be sufficient in my setup. MPS=128B with MRRS=256B still seems broken,
>     while MPS=128B with MRRS=128B works fine. I wonder whether this is because
>     the "MPS" term in the min(MRRS, MPS) limit for DMA read transfers may
>     effectively be tied to the DMA read buffer segment size / MPSS rather than
>     only to DevCtl.MPS. I'm not sure about this yet though.

I think setting MPS=128B MRRS=256B only leads to the transfer being 
split into 2 x 128B TLPs sent across the PCIe link, but in the end, 2 x 
128 Bytes of data are received (in some order) into the read segment 
buffer and reordered, and 1 x 256 Bytes are written from read segment 
buffer into the memory as a single write.

In case of MPS=256B MRRS=256B, only one 256B TLP is sent across the 
link, 1 x 256 Bytes of data are received into the read segment buffer 
with no reordering necessary, and 1 x 256 Bytes are still written from 
read segment buffer into the memory as a single write.

=> For MPS=128B/MPS=256B and MRRS=256B, there is difference in the
    transfer format between PCIe and DMA, but there is no difference
    between DMA and DRAM .

But in case of MRRS=128B and transfer of 256 Bytes, 2 x 128 Bytes of 
data are received into (separate? (*)) entries in read segment buffer, 
and 2 x 128 Bytes are written from (separate?) entries in read segment 
buffer into the memory as two separate writes . Could this different 
memory write pattern be responsible for the (lack of) corruption ?

Do you know whether the data are corrupted on the PCIe-to-DMA side (when 
the data are received from the PCIe side and written into the read 
buffer segment) or on the DMA-to-DRAM side (on read from read segment 
buffer or on write into DRAM) ?

(*) Since the read segment buffer has 16 x 256 Byte segments, with 16 
DMA tags and never more than 16 MRd requests in flight, I think it is 
likely that each MRd data land in separate read segment buffer segment. 
But this information comes from another datasheet, not V4H one.

>     One more thing I noticed in the manuals:
> 
>       R-Car S4 R19UH0161EJ0130 Rev.1.30 Jun. 16, 2025:
>         Type00 MPSS initial = 256B, PCI R, Internal R/W
>         Type01 MPSS initial = 128B, PCI R, Internal R
> 
>       R-Car V4H R19UH0186EJ0130 Rev.1.30 Apr. 21, 2025
>         Type00 MPSS initial = 256B, PCI R, Internal R
>         Type01 MPSS initial = 128B, PCI R, Internal R/W
> 
>     I'm still unsure, but this difference might be relevant. In particular, in
>     V4H/V4M RC mode your patch programs DevCtl.MPS to 256B, but does not change
>     Type01 MPSS. I wonder if the Type01 MPSS should also be updated to 256B first
>     on SoCs where the manual says it is writable from the internal bus, or if I'm
>     missing something here.

This is a very good point.

The R-Car S4 RM Rev.1.20 lists Type00 MPSS as Internal R and Type01 MPSS 
as Internal R/W. This was updated in RM Rev.1.30 to Type 00 Internal R/W 
and Type 01 Internal R. It is possible this change is going to be added 
into the V4H RM in the future too. That would likely imply, that Type01 
MPSS is not programmable.

I don't think Type1 affects RC operation, but does it affect NTB ?

[...]

Thank you for your help!

-- 
Best regards,
Marek Vasut

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

* Re: [PATCH] PCI: rcar-gen4: Limit Max_Read_Request_Size and Max_Payload_Size to 256 Bytes
  2026-05-03 23:54   ` Marek Vasut
@ 2026-05-11 14:20     ` Koichiro Den
  2026-05-13  3:01       ` Marek Vasut
  0 siblings, 1 reply; 10+ messages in thread
From: Koichiro Den @ 2026-05-11 14:20 UTC (permalink / raw)
  To: Marek Vasut
  Cc: linux-pci, stable, Krzysztof Wilczyński, Bjorn Helgaas,
	Geert Uytterhoeven, Lorenzo Pieralisi, Magnus Damm,
	Manivannan Sadhasivam, Rob Herring, Yoshihiro Shimoda,
	linux-kernel, linux-renesas-soc

On Mon, May 04, 2026 at 01:54:01AM +0200, Marek Vasut wrote:
> On 4/28/26 9:00 AM, Koichiro Den wrote:
> 
> Hello Den-san,
> 
> > The patch makes sense to me. Let me ask two questions:
> > 
> > 1. Could r8a779f0 (R-Car S4-8) be handled as well, perhaps by adding a separate
> >     .additional_common_init() implementation for it?
> > 
> >     As far as I can see, the r8a779f0 match data currently does not use
> >     rcar_gen4_pcie_additional_common_init().

Hi Marek,

Thank you for the detailed analysis. I'm sorry for the late reply.

> 
> I will address this one in V2, thank you for pointing that out.

Thanks!

> 
> > 2. Did you also happen to test V4H/V4M in endpoint (EP) mode, with the local
> >     eDMA engine issuing MRd requests toward host memory?
> 
> I was not able to test this configuration.
> 
> Is it possible to perform this test with a single device, by having the eDMA
> do local-memory-read-to-local-memory-write transfers, maybe using
> PIPE_LOOPBACK/LOOPBACK_ENABLE bits, or do I need two devices with NTB
> connection between them ?
> 
> In case it is the later, could you please briefly describe the S4 NTB setup
> you use, so I could try to replicate it locally ?

My setup was a two-board setup:

  S4 Spider as RC <-> S4 Spider as EP, connected with OCuLink.

It is unfortunately not a small standalone reproducer. The setup was based on
the following RFC v4 series:

  [RFC PATCH v4 00/38] NTB transport backed by PCI EP embedded DMA
  https://lore.kernel.org/all/20260118135440.1958279-1-den@valinux.co.jp/

In particular, the workaround patch I used in the RFC series was:

  [RFC PATCH v4 31/38] NTB: epf: Add per-SoC quirk to cap MRRS for DWC eDMA (128B for R-Car)
  https://lore.kernel.org/all/20260118135440.1958279-32-den@valinux.co.jp/

Note that in that workaround I only capped MRRS (i.e. I did not add an MPS cap).
At least in that setup, avoiding 256B MRd requests was enough to make the
visible corruption disappear.

At a high level, the EP side exposes the vNTB endpoint function, and the RC side
uses the NTB data path which is backed by the EP-local eDMA through that vNTB
function. For the RC-to-EP data path, the EP-local eDMA acts as the requester:
it issues MRd requests toward remote RC memory, receives the CplD payloads, and
writes the data into EP-side memory. In other words, this is a DMA read transfer
from the point of view of the EP-local eDMA.

I have not tried PIPE_LOOPBACK/LOOPBACK_ENABLE. Given how heavy the setup
described above is, I am not asking you to reproduce the whole thing just for
this patch. Also, I do not want this NTB/eDMA observation to block your v2. For
now, please treat it as a separate observation from the RC/NVMe issue. I will
continue the investigation on my side and let you know if I can narrow down
where the corruption occurs.

> 
> > Your commit message
> >     describes an NVMe device as the requester, but I'm wondering whether the same
> >     256B limit was also verified for the R-Car EP DMA requester path.
> 
> This part I currently can not answer, I'm sorry.
> 
> ...
> 
> I made the following two observations in the meantime.
> 
> First, I wrote two SSDs, Crucial P5 Plus SSD without HMPRE (without host
> memory buffer) and XPG GAMMIX P55 with HMPRE (with host memory buffer) with
> 4 GiB of random data on another system (iMX8M Plus, ARM64 with DWC PCIe
> controller too), then I did a read back and compared the data, the writen
> and read-back data matched.
> 
> Then I plugged both SSDs into V4H Sparrow Hawk _without_ this patch, and I
> did read back of data:
> 
> - Crucial P5 Plus SSD without HMPRE (without host memory buffer)
>   -> Data read back match data written on iMX8M Plus, OK
> - XPG GAMMIX P55 with HMPRE (with host memory buffer)
>   -> Data read back match data written on iMX8M Plus, OK
> 
> Then I wrote 512 Byte of data into the Crucial P5 Plus SSD without HMPRE on
> V4H Sparrow Hawk and did read back again.
>   -> Data read back does NOT match data written, NG
> 
> That would indicate that:
> - WRITE transfers from SSD to DRAM are OK
> - READ transfers from DRAM to SSD are corrupted at 256 Bytes boundary
> 
> That would indicate that we need _at_least_ the 256 Bytes limit, likely on
> both MPS and MRRS.
> 
> Second, I got a report of another SSD for which this patch is not
> sufficient. I currently do not have access to that SSD, but I will ask for
> access and investigate. That may shed some light on the 128 Byte limit
> below.

Thank you for sharing these observations.
Interesting, that second point may indeed help determine whether my 128B
observation in the past is related to the same underlying issue, or is a purely
eDMA/NTB-specific one.

> 
> > (*) The background for my question 2:
> > 
> >     I only have access to S4 Spider boards. In my RC <-> EP setup, where the EP
> >     side uses the local eDMA engine to issue MRd requests toward the RC, 256-byte
> >     MRd requests still appear to corrupt the transferred data.
> 
> Is the corruption deterministic in some way, i.e. are the same bytes of the
> transferred data corrupted every time, or is the corruption "random" ?

The exact corrupted values were not deterministic, but the offsets where the
corruption occurred were fairly consistent.

Let me quote from my earlier RFC patch:
(https://lore.kernel.org/all/20260118135440.1958279-32-den@valinux.co.jp/)

  [...]
  * On some R-Car platforms using the Synopsys DWC PCIe + eDMA we
  * observe data corruption on RC->EP Remote DMA Read paths whenever
  * the EP issues large MRd requests. The corruption consistently
  * hits the tail of each 256-byte segment (e.g. offsets
  * 0x00E0..0x00FF within a 256B block, and again at 0x01E0..0x01FF
  * for larger transfers).
  [...]

> 
> Does the corruption happen even on singular MRd transfer, or does it happen
> only when a lot of traffic is sent across the NTB link? I wonder if this
> corruption might be DRAM bandwidth related, i.e. whether the DMA does
> possibly saturate the DRAM controller with write requests and make the
> system run out of DRAM bandwidth.

It occurred even with a single eDMA read transfer. It was not a symptom only
observable under high load.

> 
> > With the following
> >     change on top of your patch, my DMA-read tests become stable:
> 
> [...]
> 
> >     One detail which might be important is that limiting only MPS does not appear
> >     to be sufficient in my setup. MPS=128B with MRRS=256B still seems broken,
> >     while MPS=128B with MRRS=128B works fine. I wonder whether this is because
> >     the "MPS" term in the min(MRRS, MPS) limit for DMA read transfers may
> >     effectively be tied to the DMA read buffer segment size / MPSS rather than
> >     only to DevCtl.MPS. I'm not sure about this yet though.
> 
> I think setting MPS=128B MRRS=256B only leads to the transfer being split
> into 2 x 128B TLPs sent across the PCIe link, but in the end, 2 x 128 Bytes
> of data are received (in some order) into the read segment buffer and
> reordered, and 1 x 256 Bytes are written from read segment buffer into the
> memory as a single write.
> 
> In case of MPS=256B MRRS=256B, only one 256B TLP is sent across the link, 1
> x 256 Bytes of data are received into the read segment buffer with no
> reordering necessary, and 1 x 256 Bytes are still written from read segment
> buffer into the memory as a single write.
> 
> => For MPS=128B/MPS=256B and MRRS=256B, there is difference in the
>    transfer format between PCIe and DMA, but there is no difference
>    between DMA and DRAM .
> 
> But in case of MRRS=128B and transfer of 256 Bytes, 2 x 128 Bytes of data
> are received into (separate? (*)) entries in read segment buffer, and 2 x
> 128 Bytes are written from (separate?) entries in read segment buffer into
> the memory as two separate writes . Could this different memory write
> pattern be responsible for the (lack of) corruption ?
> 
> Do you know whether the data are corrupted on the PCIe-to-DMA side (when the
> data are received from the PCIe side and written into the read buffer
> segment) or on the DMA-to-DRAM side (on read from read segment buffer or on
> write into DRAM) ?

Unfortunately I cannot distinguish these from software alone. I only observed
the final destination buffer contents after the eDMA read transfer completed.

> 
> (*) Since the read segment buffer has 16 x 256 Byte segments, with 16 DMA
> tags and never more than 16 MRd requests in flight, I think it is likely
> that each MRd data land in separate read segment buffer segment. But this
> information comes from another datasheet, not V4H one.
> 
> >     One more thing I noticed in the manuals:
> > 
> >       R-Car S4 R19UH0161EJ0130 Rev.1.30 Jun. 16, 2025:
> >         Type00 MPSS initial = 256B, PCI R, Internal R/W
> >         Type01 MPSS initial = 128B, PCI R, Internal R
> > 
> >       R-Car V4H R19UH0186EJ0130 Rev.1.30 Apr. 21, 2025
> >         Type00 MPSS initial = 256B, PCI R, Internal R
> >         Type01 MPSS initial = 128B, PCI R, Internal R/W
> > 
> >     I'm still unsure, but this difference might be relevant. In particular, in
> >     V4H/V4M RC mode your patch programs DevCtl.MPS to 256B, but does not change
> >     Type01 MPSS. I wonder if the Type01 MPSS should also be updated to 256B first
> >     on SoCs where the manual says it is writable from the internal bus, or if I'm
> >     missing something here.
> 
> This is a very good point.
> 
> The R-Car S4 RM Rev.1.20 lists Type00 MPSS as Internal R and Type01 MPSS as
> Internal R/W. This was updated in RM Rev.1.30 to Type 00 Internal R/W and
> Type 01 Internal R. It is possible this change is going to be added into the
> V4H RM in the future too. That would likely imply, that Type01 MPSS is not
> programmable.
> 
> I don't think Type1 affects RC operation, but does it affect NTB ?

I have no evidence that Type1 affects NTB either. It was just a speculative idea
based on the difference I saw in the manuals.

Your inference, i.e. that the S4 RM Rev.1.30 may reflect the intended access
attributes and the V4H RM may later get a similar correction, sounds reasonable
to me.

I had not checked the S4 RM Rev.1.20, so I missed that change. Thanks for
pointing it out.

> 
> [...]
> 
> Thank you for your help!

Thank you for investigating this and for the very helpful analysis.
I will let you know if I find anything more.

Best regards,
Koichiro

> 
> -- 
> Best regards,
> Marek Vasut

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

* Re: [PATCH] PCI: rcar-gen4: Limit Max_Read_Request_Size and Max_Payload_Size to 256 Bytes
  2026-04-25 23:38 [PATCH] PCI: rcar-gen4: Limit Max_Read_Request_Size and Max_Payload_Size to 256 Bytes Marek Vasut
  2026-04-28  7:00 ` Koichiro Den
@ 2026-05-11 14:34 ` Manivannan Sadhasivam
  2026-05-12 22:57   ` Marek Vasut
  1 sibling, 1 reply; 10+ messages in thread
From: Manivannan Sadhasivam @ 2026-05-11 14:34 UTC (permalink / raw)
  To: Marek Vasut
  Cc: linux-pci, stable, Krzysztof Wilczyński, Bjorn Helgaas,
	Geert Uytterhoeven, Koichiro Den, Lorenzo Pieralisi, Magnus Damm,
	Rob Herring, Yoshihiro Shimoda, linux-kernel, linux-renesas-soc

On Sun, Apr 26, 2026 at 01:38:28AM +0200, Marek Vasut wrote:
> R-Car Gen4 PCIe controller has a hardware limitation of 256 Bytes
> maximum payload size. The PCIe DMA generates requests of size up
> to minimum(Max_Read_Request_Size, Max_Payload_Size). Force limit
> both Max_Read_Request_Size and Max_Payload_Size to 256 Bytes and
> propagate this limit to all downstream devices.
> 
> This limitation can be triggered for example by using an NVMe SSD
> which does not use host memory buffer, Samsung 980 PRO is such an
> SSD. Affected SSD reports 'hmpre' field as 0:
> "
> $ nvme id-ctrl /dev/nvme0 | grep hmpre
> hmpre     : 0
> "
> 
> The symptom is a read from the SSD which wraps around at 256 Byte
> boundary. The test for this symptom can be implemented by writing
> 512 Byte of random data into the SSD and reading the data back. If
> the read back data repeat after 256 Bytes, the device is affected.
> "
> $ dd if=/dev/urandom of=/tmp/data.bin bs=256 count=2 \
>   dd if=/tmp/data.bin of=/dev/nvme0n1 bs=256 count=2 \
>   dd if=/dev/nvme0n1 bs=256 count=2 of=/tmp/readback.bin
> "
> 
> Expected data:
> "
> $ hexdump -vC /tmp/data.bin
> 00000000  97 81 b7 3b 0e 38 2b 4d  a7 d3 e0 47 ff c2 4b ca
> 00000010  c1 85 98 f0 4a ac 03 a0  3b ab f3 19 44 dd 06 8b
> ...
> 00000100  7a ce 3c b2 e1 d5 d9 11  88 63 10 59 76 3c dc 32 <-- random
> 00000110  72 32 2a 7d a3 e1 aa 13  7c da 58 a1 7b 21 11 50 <-- data
> "
> 
> Faulty readback, collected without this change in place:
> "
> $ hexdump -vC /tmp/readback.bin
> 00000000  97 81 b7 3b 0e 38 2b 4d  a7 d3 e0 47 ff c2 4b ca <---.
> 00000010  c1 85 98 f0 4a ac 03 a0  3b ab f3 19 44 dd 06 8b <-. |
> ...                                                          | |
> 00000100  97 81 b7 3b 0e 38 2b 4d  a7 d3 e0 47 ff c2 4b ca <-:-+- repeated
> 00000110  c1 85 98 f0 4a ac 03 a0  3b ab f3 19 44 dd 06 8b <-+--- data
>      ^^^
>       |
>       '--- Repeat starts at offset 0x100 = 256 Bytes
> "
> 
> Fixes: 0d0c551011df ("PCI: rcar-gen4: Add R-Car Gen4 PCIe controller support for host mode")
> Cc: stable@vger.kernel.org
> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
> ---
> Cc: "Krzysztof Wilczyński" <kwilczynski@kernel.org>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Geert Uytterhoeven <geert+renesas@glider.be>
> Cc: Koichiro Den <den@valinux.co.jp>
> Cc: Lorenzo Pieralisi <lpieralisi@kernel.org>
> Cc: Magnus Damm <magnus.damm@gmail.com>
> Cc: Manivannan Sadhasivam <mani@kernel.org>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-pci@vger.kernel.org
> Cc: linux-renesas-soc@vger.kernel.org
> ---
>  drivers/pci/controller/dwc/pcie-rcar-gen4.c | 56 +++++++++++++++++++++
>  1 file changed, 56 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> index 8b03c42f8c84c..82f0a074a71da 100644
> --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> @@ -576,6 +576,7 @@ static int r8a779f0_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable)
>  static void rcar_gen4_pcie_additional_common_init(struct rcar_gen4_pcie *rcar)
>  {
>  	struct dw_pcie *dw = &rcar->dw;
> +	u16 offset = dw_pcie_find_capability(dw, PCI_CAP_ID_EXP);
>  	u32 val;
>  
>  	val = dw_pcie_readl_dbi(dw, PCIE_PORT_LANE_SKEW);
> @@ -584,11 +585,66 @@ static void rcar_gen4_pcie_additional_common_init(struct rcar_gen4_pcie *rcar)
>  		val |= BIT(6);
>  	dw_pcie_writel_dbi(dw, PCIE_PORT_LANE_SKEW, val);
>  
> +	val = dw_pcie_readl_dbi(dw, offset + PCI_EXP_DEVCTL);
> +	val &= ~(PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ);
> +	val |= PCI_EXP_DEVCTL_PAYLOAD_256B | PCI_EXP_DEVCTL_READRQ_256B;
> +	dw_pcie_writel_dbi(dw, offset + PCI_EXP_DEVCTL, val);

Instead of limiting the MRRS/MPS values for all devices through quirks, why
can't you just limit the Root Port's MPSS value in PCI_EXP_DEVCAP?

- Mani

> +
>  	val = readl(rcar->base + PCIEPWRMNGCTRL);
>  	val |= APP_CLK_REQ_N | APP_CLK_PM_EN;
>  	writel(val, rcar->base + PCIEPWRMNGCTRL);
>  }
>  
> +static void rcar_gen4_rc_pcie_quirk(struct pci_dev *dev)
> +{
> +	static const struct pci_device_id rcar_gen4_pcie_rc_devid = {
> +		PCI_DEVICE(PCI_VENDOR_ID_RENESAS, 0x0030),
> +		.class = PCI_CLASS_BRIDGE_PCI_NORMAL, .class_mask = ~0
> +	};
> +	struct pci_bus *bus = dev->bus;
> +	struct pci_dev *bridge;
> +
> +	if (pci_is_root_bus(bus))
> +		bridge = dev;
> +
> +	/* Look for the host bridge */
> +	while (!pci_is_root_bus(bus)) {
> +		bridge = bus->self;
> +		bus = bus->parent;
> +	}
> +
> +	if (!bridge)
> +		return;
> +
> +	if (!pci_match_one_device(&rcar_gen4_pcie_rc_devid, bridge))
> +		return;
> +
> +	/*
> +	 * R-Car Gen4 PCIe controller has a hardware limitation of 256 Bytes
> +	 * maximum payload size. The PCIe DMA generates requests of size up
> +	 * to minimum(Max_Read_Request_Size, Max_Payload_Size). Force limit
> +	 * both Max_Read_Request_Size and Max_Payload_Size to 256 Bytes and
> +	 * propagate this limit to all downstream devices.
> +	 *
> +	 * For details, refer to:
> +	 * R-Car S4 R19UH0161EJ0130 Rev.1.30 Jun. 16, 2025 or
> +	 * R-Car V4H R19UH0186EJ0130 Rev.1.30 Apr. 21, 2025 or
> +	 * R-Car V4M R19UH0217EJ0100 Rev.1.00 Dec. 12, 2025,
> +	 * chapters 104.1.1 Features and 104.3.9 DMA Transfer
> +	 * section DMA Read Transfer.
> +	 */
> +	if (pcie_get_readrq(dev) > 256) {
> +		dev_info(&dev->dev, "Limiting MRRS to 256 bytes\n");
> +		pcie_set_readrq(dev, 256);
> +	}
> +
> +	if (pcie_get_mps(dev) > 256) {
> +		dev_info(&dev->dev, "Limiting MPS to 256 bytes\n");
> +		pcie_set_mps(dev, 256);
> +	}
> +}
> +DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, rcar_gen4_rc_pcie_quirk);
> +
>  static void rcar_gen4_pcie_phy_reg_update_bits(struct rcar_gen4_pcie *rcar,
>  					       u32 offset, u32 mask, u32 val)
>  {
> -- 
> 2.53.0
> 
> 

-- 
மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH] PCI: rcar-gen4: Limit Max_Read_Request_Size and Max_Payload_Size to 256 Bytes
  2026-05-11 14:34 ` Manivannan Sadhasivam
@ 2026-05-12 22:57   ` Marek Vasut
  2026-05-12 23:08     ` Marek Vasut
  2026-05-20  7:52     ` Manivannan Sadhasivam
  0 siblings, 2 replies; 10+ messages in thread
From: Marek Vasut @ 2026-05-12 22:57 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: linux-pci, stable, Krzysztof Wilczyński, Bjorn Helgaas,
	Geert Uytterhoeven, Koichiro Den, Lorenzo Pieralisi, Magnus Damm,
	Rob Herring, Yoshihiro Shimoda, linux-kernel, linux-renesas-soc

On 5/11/26 4:34 PM, Manivannan Sadhasivam wrote:

Hello Manivannan,

>>   drivers/pci/controller/dwc/pcie-rcar-gen4.c | 56 +++++++++++++++++++++
>>   1 file changed, 56 insertions(+)
>>
>> diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
>> index 8b03c42f8c84c..82f0a074a71da 100644
>> --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
>> +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
>> @@ -576,6 +576,7 @@ static int r8a779f0_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable)
>>   static void rcar_gen4_pcie_additional_common_init(struct rcar_gen4_pcie *rcar)
>>   {
>>   	struct dw_pcie *dw = &rcar->dw;
>> +	u16 offset = dw_pcie_find_capability(dw, PCI_CAP_ID_EXP);
>>   	u32 val;
>>   
>>   	val = dw_pcie_readl_dbi(dw, PCIE_PORT_LANE_SKEW);
>> @@ -584,11 +585,66 @@ static void rcar_gen4_pcie_additional_common_init(struct rcar_gen4_pcie *rcar)
>>   		val |= BIT(6);
>>   	dw_pcie_writel_dbi(dw, PCIE_PORT_LANE_SKEW, val);
>>   
>> +	val = dw_pcie_readl_dbi(dw, offset + PCI_EXP_DEVCTL);
>> +	val &= ~(PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ);
>> +	val |= PCI_EXP_DEVCTL_PAYLOAD_256B | PCI_EXP_DEVCTL_READRQ_256B;
>> +	dw_pcie_writel_dbi(dw, offset + PCI_EXP_DEVCTL, val);
> 
> Instead of limiting the MRRS/MPS values for all devices through quirks, why
> can't you just limit the Root Port's MPSS value in PCI_EXP_DEVCAP?
The root port MPSS is already 3'b001 = 256 Bytes and is read-only for 
EXPCAP1F0 (PCI_EXP_DEVCAP) .

The controller is limited to MPS 256 Bytes according to V4H rev.1.30 
documentation. There is no explicitly spelled out MRRS limitation in the 
documentation to my knowledge, except for the DMA hint, but please read on.

The root port EXPCAP2F0 MPS is 128 Bytes and MRRS is 512 Bytes .

I now noticed that in V4H rev.1.30 documentation, the EXPCAP2F0 MRRS 
field is default set to 3'b010 = 512 Bytes, but that value is "Reserved" 
and only two non-reserved values are 3'b000 and 3'b001 which are MRRS 
128 Bytes and 256 Bytes respectively. That means MRRS has to be trimmed 
to maximum 256 Bytes in software to avoid "Reserved" settings. I will 
also ask the hardware and documentation team about this.

As a result, I adjust EXPCAP2F0:

- I raise MPS from 128 Bytes to 256 Bytes
- I reduce MRRS from 512 Bytes to 256 Bytes (this is important to 
prevent data corruption)

However, the downstream devices (in my case, PCIe SSD) can still be 
configured with MRRS > 256 (in my case, Crucial P5 Plus 1 TiB has 
MRRS=512 and MPS=128), which is where the quirk kicks in and 
reconfigures MRRS for those downstream devices.

The pci_configure_mps() does propagate MPS from root port EXPCAP2F0 to 
downstream devices, but there is no equivalent for MRRS as far as I can 
find ?

Thank you for your help!

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

* Re: [PATCH] PCI: rcar-gen4: Limit Max_Read_Request_Size and Max_Payload_Size to 256 Bytes
  2026-05-12 22:57   ` Marek Vasut
@ 2026-05-12 23:08     ` Marek Vasut
  2026-05-20  7:52     ` Manivannan Sadhasivam
  1 sibling, 0 replies; 10+ messages in thread
From: Marek Vasut @ 2026-05-12 23:08 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: linux-pci, stable, Krzysztof Wilczyński, Bjorn Helgaas,
	Geert Uytterhoeven, Koichiro Den, Lorenzo Pieralisi, Magnus Damm,
	Rob Herring, Yoshihiro Shimoda, linux-kernel, linux-renesas-soc

On 5/13/26 12:57 AM, Marek Vasut wrote:
> On 5/11/26 4:34 PM, Manivannan Sadhasivam wrote:
> 
> Hello Manivannan,
> 
>>>   drivers/pci/controller/dwc/pcie-rcar-gen4.c | 56 +++++++++++++++++++++
>>>   1 file changed, 56 insertions(+)
>>>
>>> diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/ 
>>> pci/controller/dwc/pcie-rcar-gen4.c
>>> index 8b03c42f8c84c..82f0a074a71da 100644
>>> --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
>>> +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
>>> @@ -576,6 +576,7 @@ static int r8a779f0_pcie_ltssm_control(struct 
>>> rcar_gen4_pcie *rcar, bool enable)
>>>   static void rcar_gen4_pcie_additional_common_init(struct 
>>> rcar_gen4_pcie *rcar)
>>>   {
>>>       struct dw_pcie *dw = &rcar->dw;
>>> +    u16 offset = dw_pcie_find_capability(dw, PCI_CAP_ID_EXP);
>>>       u32 val;
>>>       val = dw_pcie_readl_dbi(dw, PCIE_PORT_LANE_SKEW);
>>> @@ -584,11 +585,66 @@ static void 
>>> rcar_gen4_pcie_additional_common_init(struct rcar_gen4_pcie *rcar)
>>>           val |= BIT(6);
>>>       dw_pcie_writel_dbi(dw, PCIE_PORT_LANE_SKEW, val);
>>> +    val = dw_pcie_readl_dbi(dw, offset + PCI_EXP_DEVCTL);
>>> +    val &= ~(PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ);
>>> +    val |= PCI_EXP_DEVCTL_PAYLOAD_256B | PCI_EXP_DEVCTL_READRQ_256B;
>>> +    dw_pcie_writel_dbi(dw, offset + PCI_EXP_DEVCTL, val);
>>
>> Instead of limiting the MRRS/MPS values for all devices through 
>> quirks, why
>> can't you just limit the Root Port's MPSS value in PCI_EXP_DEVCAP?
> The root port MPSS is already 3'b001 = 256 Bytes and is read-only for 
> EXPCAP1F0 (PCI_EXP_DEVCAP) .

I have to correct myself here -- EXPCAP1F0 Type 0 MPSS is 256 Bytes and 
Read-Only, Type 1 MPSS is 128 Bytes and Read-Write . I will now try to 
increase the later, but the MRRS topic below remains.

> The controller is limited to MPS 256 Bytes according to V4H rev.1.30 
> documentation. There is no explicitly spelled out MRRS limitation in the 
> documentation to my knowledge, except for the DMA hint, but please read on.
> 
> The root port EXPCAP2F0 MPS is 128 Bytes and MRRS is 512 Bytes .
> 
> I now noticed that in V4H rev.1.30 documentation, the EXPCAP2F0 MRRS 
> field is default set to 3'b010 = 512 Bytes, but that value is "Reserved" 
> and only two non-reserved values are 3'b000 and 3'b001 which are MRRS 
> 128 Bytes and 256 Bytes respectively. That means MRRS has to be trimmed 
> to maximum 256 Bytes in software to avoid "Reserved" settings. I will 
> also ask the hardware and documentation team about this.
> 
> As a result, I adjust EXPCAP2F0:
> 
> - I raise MPS from 128 Bytes to 256 Bytes
> - I reduce MRRS from 512 Bytes to 256 Bytes (this is important to 
> prevent data corruption)
> 
> However, the downstream devices (in my case, PCIe SSD) can still be 
> configured with MRRS > 256 (in my case, Crucial P5 Plus 1 TiB has 
> MRRS=512 and MPS=128), which is where the quirk kicks in and 
> reconfigures MRRS for those downstream devices.
> 
> The pci_configure_mps() does propagate MPS from root port EXPCAP2F0 to 
> downstream devices, but there is no equivalent for MRRS as far as I can 
> find ?
> 
> Thank you for your help!


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

* Re: [PATCH] PCI: rcar-gen4: Limit Max_Read_Request_Size and Max_Payload_Size to 256 Bytes
  2026-05-11 14:20     ` Koichiro Den
@ 2026-05-13  3:01       ` Marek Vasut
  0 siblings, 0 replies; 10+ messages in thread
From: Marek Vasut @ 2026-05-13  3:01 UTC (permalink / raw)
  To: Koichiro Den
  Cc: linux-pci, stable, Krzysztof Wilczyński, Bjorn Helgaas,
	Geert Uytterhoeven, Lorenzo Pieralisi, Magnus Damm,
	Manivannan Sadhasivam, Rob Herring, Yoshihiro Shimoda,
	linux-kernel, linux-renesas-soc

On 5/11/26 4:20 PM, Koichiro Den wrote:

Hello Den-san,

>>> 2. Did you also happen to test V4H/V4M in endpoint (EP) mode, with the local
>>>      eDMA engine issuing MRd requests toward host memory?
>>
>> I was not able to test this configuration.
>>
>> Is it possible to perform this test with a single device, by having the eDMA
>> do local-memory-read-to-local-memory-write transfers, maybe using
>> PIPE_LOOPBACK/LOOPBACK_ENABLE bits, or do I need two devices with NTB
>> connection between them ?
>>
>> In case it is the later, could you please briefly describe the S4 NTB setup
>> you use, so I could try to replicate it locally ?
> 
> My setup was a two-board setup:
> 
>    S4 Spider as RC <-> S4 Spider as EP, connected with OCuLink.
> 
> It is unfortunately not a small standalone reproducer. The setup was based on
> the following RFC v4 series:
> 
>    [RFC PATCH v4 00/38] NTB transport backed by PCI EP embedded DMA
>    https://lore.kernel.org/all/20260118135440.1958279-1-den@valinux.co.jp/
> 
> In particular, the workaround patch I used in the RFC series was:
> 
>    [RFC PATCH v4 31/38] NTB: epf: Add per-SoC quirk to cap MRRS for DWC eDMA (128B for R-Car)
>    https://lore.kernel.org/all/20260118135440.1958279-32-den@valinux.co.jp/
> 
> Note that in that workaround I only capped MRRS (i.e. I did not add an MPS cap).
> At least in that setup, avoiding 256B MRd requests was enough to make the
> visible corruption disappear.

I have been investigating the MPSS/MPS/MRRS a bit deeper. I did not make 
the connection between your last observation in your previous email, 
which already hinted at what the issue might be, the MPSS bitfield, 
TYPE00 and TYPE01 accesses until today and one more nudge from 
Manivannan in the MPSS direction. Thank you both for those two items.

It seems that for S4, the latest documentation rev.1.30 indicates 
EXPCAP1F MPSS as read-write and configurable between 128B and 256B for 
TYPE00 (EP) access , but read-only and set to fixed 128B for TYPE01 (RC) 
access .

If the S4 PCIe in RC mode is only capable of 128B long TLPs and in EP 
mode is capable of 128B or 256B long TLPs, this might explain why you 
observe corruption with 256B long TLPs between two S4 Spiders. The S4 
Spider in EP mode might work just fine with another RC which can do 256B 
long TLPs.

I still do not understand one more observation -- if I configure V4H 
PCIe as RC, and read out EXPCAP1F register MPSS field, it reads as 256B 
(value 3'b001). I would expect EXPCAP1F register MPSS field to read out 
as (default) 128B in this RC case. The V4H documentation indicates 
EXPCAP1F MPSS as read-ONLY and set to fixed 256B for TYPE00 (EP) access, 
but read-WRITE and set to 128B for TYPE01 (RC) access , which I think 
might be a documentation issue. I also do not rewrite the EXPCAP1F MPSS 
in any way.

If the V4H is also capable of only 128B TLPs in RC mode, then this patch 
would require additional adjustment and would have to limit TLP length 
based on configuration -- 128B for RC, 256B for EP.

I will now ask for documentation clarification.

> At a high level, the EP side exposes the vNTB endpoint function, and the RC side
> uses the NTB data path which is backed by the EP-local eDMA through that vNTB
> function. For the RC-to-EP data path, the EP-local eDMA acts as the requester:
> it issues MRd requests toward remote RC memory, receives the CplD payloads, and
> writes the data into EP-side memory. In other words, this is a DMA read transfer
> from the point of view of the EP-local eDMA.

I understand. If the S4 EP has MPSS set to 256 Bytes (and possibly also 
MPS), but the S4 RC may (*) be limited to MPSS and MPS 128 Bytes, I 
wonder if the MRd from the EP-local DMA sent to RC might be causing 
malfunction on the RC side.

(*) to be determined, I will ask.

> I have not tried PIPE_LOOPBACK/LOOPBACK_ENABLE. Given how heavy the setup
> described above is, I am not asking you to reproduce the whole thing just for
> this patch. Also, I do not want this NTB/eDMA observation to block your v2. For
> now, please treat it as a separate observation from the RC/NVMe issue. I will
> continue the investigation on my side and let you know if I can narrow down
> where the corruption occurs.

I very much appreciate your input, and in light of it, I believe this 
patch does need an update.

As for local Oculink setup options, I already had a closer look as well.

>>> Your commit message
>>>      describes an NVMe device as the requester, but I'm wondering whether the same
>>>      256B limit was also verified for the R-Car EP DMA requester path.
>>
>> This part I currently can not answer, I'm sorry.
>>
>> ...
>>
>> I made the following two observations in the meantime.
>>
>> First, I wrote two SSDs, Crucial P5 Plus SSD without HMPRE (without host
>> memory buffer) and XPG GAMMIX P55 with HMPRE (with host memory buffer) with
>> 4 GiB of random data on another system (iMX8M Plus, ARM64 with DWC PCIe
>> controller too), then I did a read back and compared the data, the writen
>> and read-back data matched.
>>
>> Then I plugged both SSDs into V4H Sparrow Hawk _without_ this patch, and I
>> did read back of data:
>>
>> - Crucial P5 Plus SSD without HMPRE (without host memory buffer)
>>    -> Data read back match data written on iMX8M Plus, OK
>> - XPG GAMMIX P55 with HMPRE (with host memory buffer)
>>    -> Data read back match data written on iMX8M Plus, OK
>>
>> Then I wrote 512 Byte of data into the Crucial P5 Plus SSD without HMPRE on
>> V4H Sparrow Hawk and did read back again.
>>    -> Data read back does NOT match data written, NG
>>
>> That would indicate that:
>> - WRITE transfers from SSD to DRAM are OK
>> - READ transfers from DRAM to SSD are corrupted at 256 Bytes boundary
>>
>> That would indicate that we need _at_least_ the 256 Bytes limit, likely on
>> both MPS and MRRS.
>>
>> Second, I got a report of another SSD for which this patch is not
>> sufficient. I currently do not have access to that SSD, but I will ask for
>> access and investigate. That may shed some light on the 128 Byte limit
>> below.
> 
> Thank you for sharing these observations.
> Interesting, that second point may indeed help determine whether my 128B
> observation in the past is related to the same underlying issue, or is a purely
> eDMA/NTB-specific one.

Could you please have a look at the beginning of this email too ? I 
wonder if the TYPE00/TYPE01 accesses might have different TLP size 
limitations.

>>> (*) The background for my question 2:
>>>
>>>      I only have access to S4 Spider boards. In my RC <-> EP setup, where the EP
>>>      side uses the local eDMA engine to issue MRd requests toward the RC, 256-byte
>>>      MRd requests still appear to corrupt the transferred data.
>>
>> Is the corruption deterministic in some way, i.e. are the same bytes of the
>> transferred data corrupted every time, or is the corruption "random" ?
> 
> The exact corrupted values were not deterministic, but the offsets where the
> corruption occurred were fairly consistent.
> 
> Let me quote from my earlier RFC patch:
> (https://lore.kernel.org/all/20260118135440.1958279-32-den@valinux.co.jp/)
> 
>    [...]
>    * On some R-Car platforms using the Synopsys DWC PCIe + eDMA we
>    * observe data corruption on RC->EP Remote DMA Read paths whenever
>    * the EP issues large MRd requests. The corruption consistently
>    * hits the tail of each 256-byte segment (e.g. offsets
>    * 0x00E0..0x00FF within a 256B block, and again at 0x01E0..0x01FF
>    * for larger transfers).
>    [...]

I see.

>> Does the corruption happen even on singular MRd transfer, or does it happen
>> only when a lot of traffic is sent across the NTB link? I wonder if this
>> corruption might be DRAM bandwidth related, i.e. whether the DMA does
>> possibly saturate the DRAM controller with write requests and make the
>> system run out of DRAM bandwidth.
> 
> It occurred even with a single eDMA read transfer. It was not a symptom only
> observable under high load.

That rules out my hypothesis that this might be link stability related, 
or memory or interconnect pressure related. Thank you for this input.

>>> With the following
>>>      change on top of your patch, my DMA-read tests become stable:
>>
>> [...]
>>
>>>      One detail which might be important is that limiting only MPS does not appear
>>>      to be sufficient in my setup. MPS=128B with MRRS=256B still seems broken,
>>>      while MPS=128B with MRRS=128B works fine. I wonder whether this is because
>>>      the "MPS" term in the min(MRRS, MPS) limit for DMA read transfers may
>>>      effectively be tied to the DMA read buffer segment size / MPSS rather than
>>>      only to DevCtl.MPS. I'm not sure about this yet though.
>>
>> I think setting MPS=128B MRRS=256B only leads to the transfer being split
>> into 2 x 128B TLPs sent across the PCIe link, but in the end, 2 x 128 Bytes
>> of data are received (in some order) into the read segment buffer and
>> reordered, and 1 x 256 Bytes are written from read segment buffer into the
>> memory as a single write.
>>
>> In case of MPS=256B MRRS=256B, only one 256B TLP is sent across the link, 1
>> x 256 Bytes of data are received into the read segment buffer with no
>> reordering necessary, and 1 x 256 Bytes are still written from read segment
>> buffer into the memory as a single write.
>>
>> => For MPS=128B/MPS=256B and MRRS=256B, there is difference in the
>>     transfer format between PCIe and DMA, but there is no difference
>>     between DMA and DRAM .
>>
>> But in case of MRRS=128B and transfer of 256 Bytes, 2 x 128 Bytes of data
>> are received into (separate? (*)) entries in read segment buffer, and 2 x
>> 128 Bytes are written from (separate?) entries in read segment buffer into
>> the memory as two separate writes . Could this different memory write
>> pattern be responsible for the (lack of) corruption ?
>>
>> Do you know whether the data are corrupted on the PCIe-to-DMA side (when the
>> data are received from the PCIe side and written into the read buffer
>> segment) or on the DMA-to-DRAM side (on read from read segment buffer or on
>> write into DRAM) ?
> 
> Unfortunately I cannot distinguish these from software alone. I only observed
> the final destination buffer contents after the eDMA read transfer completed.

I understand.

>> (*) Since the read segment buffer has 16 x 256 Byte segments, with 16 DMA
>> tags and never more than 16 MRd requests in flight, I think it is likely
>> that each MRd data land in separate read segment buffer segment. But this
>> information comes from another datasheet, not V4H one.
>>
>>>      One more thing I noticed in the manuals:
>>>
>>>        R-Car S4 R19UH0161EJ0130 Rev.1.30 Jun. 16, 2025:
>>>          Type00 MPSS initial = 256B, PCI R, Internal R/W
>>>          Type01 MPSS initial = 128B, PCI R, Internal R
>>>
>>>        R-Car V4H R19UH0186EJ0130 Rev.1.30 Apr. 21, 2025
>>>          Type00 MPSS initial = 256B, PCI R, Internal R
>>>          Type01 MPSS initial = 128B, PCI R, Internal R/W
>>>
>>>      I'm still unsure, but this difference might be relevant. In particular, in
>>>      V4H/V4M RC mode your patch programs DevCtl.MPS to 256B, but does not change
>>>      Type01 MPSS. I wonder if the Type01 MPSS should also be updated to 256B first
>>>      on SoCs where the manual says it is writable from the internal bus, or if I'm
>>>      missing something here.
>>
>> This is a very good point.
>>
>> The R-Car S4 RM Rev.1.20 lists Type00 MPSS as Internal R and Type01 MPSS as
>> Internal R/W. This was updated in RM Rev.1.30 to Type 00 Internal R/W and
>> Type 01 Internal R. It is possible this change is going to be added into the
>> V4H RM in the future too. That would likely imply, that Type01 MPSS is not
>> programmable.
>>
>> I don't think Type1 affects RC operation, but does it affect NTB ?
> 
> I have no evidence that Type1 affects NTB either. It was just a speculative idea
> based on the difference I saw in the manuals.
> 
> Your inference, i.e. that the S4 RM Rev.1.30 may reflect the intended access
> attributes and the V4H RM may later get a similar correction, sounds reasonable
> to me.
> 
> I had not checked the S4 RM Rev.1.20, so I missed that change. Thanks for
> pointing it out.

I have now checked 4 S4, 10 V4H, 6 V4M reference manual versions and 
there are subtle changes. I asked for clarification. If I learn 
anything, I will let you know.

I did not make the connection between your aforementioned observation, 
MPSS, and TYPE00 and TYPE01 accesses until today, now I realized there 
might be different TLP size limits for RC and EP modes.

>> [...]
>>
>> Thank you for your help!
> 
> Thank you for investigating this and for the very helpful analysis.
> I will let you know if I find anything more.

Likewise, thank you for your help !

-- 
Best regards,
Marek Vasut

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

* Re: [PATCH] PCI: rcar-gen4: Limit Max_Read_Request_Size and Max_Payload_Size to 256 Bytes
  2026-05-12 22:57   ` Marek Vasut
  2026-05-12 23:08     ` Marek Vasut
@ 2026-05-20  7:52     ` Manivannan Sadhasivam
  2026-05-20 14:18       ` Marek Vasut
  1 sibling, 1 reply; 10+ messages in thread
From: Manivannan Sadhasivam @ 2026-05-20  7:52 UTC (permalink / raw)
  To: Marek Vasut
  Cc: linux-pci, stable, Krzysztof Wilczyński, Bjorn Helgaas,
	Geert Uytterhoeven, Koichiro Den, Lorenzo Pieralisi, Magnus Damm,
	Rob Herring, Yoshihiro Shimoda, linux-kernel, linux-renesas-soc

On Wed, May 13, 2026 at 12:57:18AM +0200, Marek Vasut wrote:
> On 5/11/26 4:34 PM, Manivannan Sadhasivam wrote:
> 
> Hello Manivannan,
> 
> > >   drivers/pci/controller/dwc/pcie-rcar-gen4.c | 56 +++++++++++++++++++++
> > >   1 file changed, 56 insertions(+)
> > > 
> > > diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> > > index 8b03c42f8c84c..82f0a074a71da 100644
> > > --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> > > +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
> > > @@ -576,6 +576,7 @@ static int r8a779f0_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable)
> > >   static void rcar_gen4_pcie_additional_common_init(struct rcar_gen4_pcie *rcar)
> > >   {
> > >   	struct dw_pcie *dw = &rcar->dw;
> > > +	u16 offset = dw_pcie_find_capability(dw, PCI_CAP_ID_EXP);
> > >   	u32 val;
> > >   	val = dw_pcie_readl_dbi(dw, PCIE_PORT_LANE_SKEW);
> > > @@ -584,11 +585,66 @@ static void rcar_gen4_pcie_additional_common_init(struct rcar_gen4_pcie *rcar)
> > >   		val |= BIT(6);
> > >   	dw_pcie_writel_dbi(dw, PCIE_PORT_LANE_SKEW, val);
> > > +	val = dw_pcie_readl_dbi(dw, offset + PCI_EXP_DEVCTL);
> > > +	val &= ~(PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ);
> > > +	val |= PCI_EXP_DEVCTL_PAYLOAD_256B | PCI_EXP_DEVCTL_READRQ_256B;
> > > +	dw_pcie_writel_dbi(dw, offset + PCI_EXP_DEVCTL, val);
> > 
> > Instead of limiting the MRRS/MPS values for all devices through quirks, why
> > can't you just limit the Root Port's MPSS value in PCI_EXP_DEVCAP?
> The root port MPSS is already 3'b001 = 256 Bytes and is read-only for
> EXPCAP1F0 (PCI_EXP_DEVCAP) .
> 
> The controller is limited to MPS 256 Bytes according to V4H rev.1.30
> documentation. There is no explicitly spelled out MRRS limitation in the
> documentation to my knowledge, except for the DMA hint, but please read on.
> 
> The root port EXPCAP2F0 MPS is 128 Bytes and MRRS is 512 Bytes .
> 
> I now noticed that in V4H rev.1.30 documentation, the EXPCAP2F0 MRRS field
> is default set to 3'b010 = 512 Bytes, but that value is "Reserved" and only
> two non-reserved values are 3'b000 and 3'b001 which are MRRS 128 Bytes and
> 256 Bytes respectively. That means MRRS has to be trimmed to maximum 256
> Bytes in software to avoid "Reserved" settings. I will also ask the hardware
> and documentation team about this.
> 
> As a result, I adjust EXPCAP2F0:
> 
> - I raise MPS from 128 Bytes to 256 Bytes
> - I reduce MRRS from 512 Bytes to 256 Bytes (this is important to prevent
> data corruption)
> 
> However, the downstream devices (in my case, PCIe SSD) can still be
> configured with MRRS > 256 (in my case, Crucial P5 Plus 1 TiB has MRRS=512
> and MPS=128), which is where the quirk kicks in and reconfigures MRRS for
> those downstream devices.
> 
> The pci_configure_mps() does propagate MPS from root port EXPCAP2F0 to
> downstream devices, but there is no equivalent for MRRS as far as I can find
> ?

Sorry for the late reply!

I'm now confused about the issue itself. In your v1 patch you said:

"R-Car Gen4 PCIe controller has a hardware limitation of 256 Bytes
maximum payload size. The PCIe DMA generates requests of size up
to minimum(Max_Read_Request_Size, Max_Payload_Size). Force limit
both Max_Read_Request_Size and Max_Payload_Size to 256 Bytes and
propagate this limit to all downstream devices."

The 256B limitation of Root Port MPS is clear. And you said, Root Port's MPSS is
already 256B. So this will prevent the endpoints from sending > 256B payload.

Also, the DMA calculation of min(MRRS,MPS) will also satisfy with 256B MPS even
if MRRS is higher i.e, 512B.

If MRRS is 512B, the endpoint should send two 256B TLPs based on MPS and that
shouldn't be a problem on the host. So I'm not sure how the higher MRRS value
induces data corruption here. And why you want to limit MRRS on all downstream
devices and not just the Root Port? Since you are using NVMe, the host will be
the one sending MRd TLP to the device. So I'm not sure how the endpoint MRRS
comes into play.

Am I missing something?

- Mani

-- 
மணிவண்ணன் சதாசிவம்

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

* Re: [PATCH] PCI: rcar-gen4: Limit Max_Read_Request_Size and Max_Payload_Size to 256 Bytes
  2026-05-20  7:52     ` Manivannan Sadhasivam
@ 2026-05-20 14:18       ` Marek Vasut
  0 siblings, 0 replies; 10+ messages in thread
From: Marek Vasut @ 2026-05-20 14:18 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: linux-pci, stable, Krzysztof Wilczyński, Bjorn Helgaas,
	Geert Uytterhoeven, Koichiro Den, Lorenzo Pieralisi, Magnus Damm,
	Rob Herring, Yoshihiro Shimoda, linux-kernel, linux-renesas-soc

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

On 5/20/26 9:52 AM, Manivannan Sadhasivam wrote:
> On Wed, May 13, 2026 at 12:57:18AM +0200, Marek Vasut wrote:
>> On 5/11/26 4:34 PM, Manivannan Sadhasivam wrote:
>>
>> Hello Manivannan,
>>
>>>>    drivers/pci/controller/dwc/pcie-rcar-gen4.c | 56 +++++++++++++++++++++
>>>>    1 file changed, 56 insertions(+)
>>>>
>>>> diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
>>>> index 8b03c42f8c84c..82f0a074a71da 100644
>>>> --- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
>>>> +++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
>>>> @@ -576,6 +576,7 @@ static int r8a779f0_pcie_ltssm_control(struct rcar_gen4_pcie *rcar, bool enable)
>>>>    static void rcar_gen4_pcie_additional_common_init(struct rcar_gen4_pcie *rcar)
>>>>    {
>>>>    	struct dw_pcie *dw = &rcar->dw;
>>>> +	u16 offset = dw_pcie_find_capability(dw, PCI_CAP_ID_EXP);
>>>>    	u32 val;
>>>>    	val = dw_pcie_readl_dbi(dw, PCIE_PORT_LANE_SKEW);
>>>> @@ -584,11 +585,66 @@ static void rcar_gen4_pcie_additional_common_init(struct rcar_gen4_pcie *rcar)
>>>>    		val |= BIT(6);
>>>>    	dw_pcie_writel_dbi(dw, PCIE_PORT_LANE_SKEW, val);
>>>> +	val = dw_pcie_readl_dbi(dw, offset + PCI_EXP_DEVCTL);
>>>> +	val &= ~(PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ);
>>>> +	val |= PCI_EXP_DEVCTL_PAYLOAD_256B | PCI_EXP_DEVCTL_READRQ_256B;
>>>> +	dw_pcie_writel_dbi(dw, offset + PCI_EXP_DEVCTL, val);
>>>
>>> Instead of limiting the MRRS/MPS values for all devices through quirks, why
>>> can't you just limit the Root Port's MPSS value in PCI_EXP_DEVCAP?
>> The root port MPSS is already 3'b001 = 256 Bytes and is read-only for
>> EXPCAP1F0 (PCI_EXP_DEVCAP) .
>>
>> The controller is limited to MPS 256 Bytes according to V4H rev.1.30
>> documentation. There is no explicitly spelled out MRRS limitation in the
>> documentation to my knowledge, except for the DMA hint, but please read on.
>>
>> The root port EXPCAP2F0 MPS is 128 Bytes and MRRS is 512 Bytes .
>>
>> I now noticed that in V4H rev.1.30 documentation, the EXPCAP2F0 MRRS field
>> is default set to 3'b010 = 512 Bytes, but that value is "Reserved" and only
>> two non-reserved values are 3'b000 and 3'b001 which are MRRS 128 Bytes and
>> 256 Bytes respectively. That means MRRS has to be trimmed to maximum 256
>> Bytes in software to avoid "Reserved" settings. I will also ask the hardware
>> and documentation team about this.
>>
>> As a result, I adjust EXPCAP2F0:
>>
>> - I raise MPS from 128 Bytes to 256 Bytes
>> - I reduce MRRS from 512 Bytes to 256 Bytes (this is important to prevent
>> data corruption)
>>
>> However, the downstream devices (in my case, PCIe SSD) can still be
>> configured with MRRS > 256 (in my case, Crucial P5 Plus 1 TiB has MRRS=512
>> and MPS=128), which is where the quirk kicks in and reconfigures MRRS for
>> those downstream devices.
>>
>> The pci_configure_mps() does propagate MPS from root port EXPCAP2F0 to
>> downstream devices, but there is no equivalent for MRRS as far as I can find
>> ?
> 
> Sorry for the late reply!
> 
> I'm now confused about the issue itself. In your v1 patch you said:
> 
> "R-Car Gen4 PCIe controller has a hardware limitation of 256 Bytes
> maximum payload size. The PCIe DMA generates requests of size up
> to minimum(Max_Read_Request_Size, Max_Payload_Size). Force limit
> both Max_Read_Request_Size and Max_Payload_Size to 256 Bytes and
> propagate this limit to all downstream devices."
> 
> The 256B limitation of Root Port MPS is clear. And you said, Root Port's MPSS is
> already 256B. So this will prevent the endpoints from sending > 256B payload.

I can leave the MPS configuration out of the V3, in its current state, 
this is only a safeguard.

> Also, the DMA calculation of min(MRRS,MPS) will also satisfy with 256B MPS even
> if MRRS is higher i.e, 512B.

I think we can leave the DMA part out of this too.

> If MRRS is 512B, the endpoint should send two 256B TLPs based on MPS and that
> shouldn't be a problem on the host.

This seems to be the main problem here.

> So I'm not sure how the higher MRRS value
> induces data corruption here. And why you want to limit MRRS on all downstream
> devices and not just the Root Port? Since you are using NVMe, the host will be
> the one sending MRd TLP to the device. So I'm not sure how the endpoint MRRS
> comes into play.

I did further tests:
- Set root bus MRRS to 128 B , NVMe SSD MRRS to 128 B => Pass
- Set root bus MRRS to 128 B , NVMe SSD MRRS to 256 B => Pass
- Set root bus MRRS to 128 B , NVMe SSD MRRS to 512 B => Fail !
- Set root bus MRRS to 256 B , NVMe SSD MRRS to 128 B => Pass
- Set root bus MRRS to 256 B , NVMe SSD MRRS to 256 B => Pass
- Set root bus MRRS to 256 B , NVMe SSD MRRS to 512 B => Fail !

I also tried to reconfigure only the RC MRRS to 256 B, but the default 
for the NVMe SSD is MRRS = 512 B, so that fails.

The corruption (=wraparound) always occurs at 256 B boundary, and it 
happens on WRITE into the NVMe SSD , not on READ from the NVMe SSD. (I 
am attaching the full logs without=fail.log and with=pass.log this 
patch, compare esp. the readback/data hexdump at offset 0x0 and 0x100 
and capabilities in lspci output for MRRS settings)

My understanding is, that WRITE into the NVMe SSD makes the NVMe SSD 
issue MRd toward the RC to fetch the data from host DRAM behind the RC. 
READ from the NVMe SSD makes the NVMe SSD issue MWr toward the RC to 
store data into the host DRAM behind the RC. That leads me to believe, 
that if an MRd which is longer than 256 B is sent by the NVMe SSD to the 
RC, the RC cannot handle it correctly and responds with 2 TLPs with the 
same data instead of two TLPs with expected data in sequence. And that 
is why we have to limit the MRRS of all devices on the bus, not only RC 
MRRS.

I also do not think this is an NVMe SSD quirk, since this occurs with 
NVMe SSDs from different vendors.

The behavior here strongly resembles 86f271f22bbb ("PCI: keystone: Add 
workaround for Errata #i2037 (AM65x SR 1.0)"), except for 256 B MRRS .

[-- Attachment #2: fail.log --]
[-- Type: text/x-log, Size: 18388 bytes --]

$ lspci -vvv
...
0001:00:00.0 PCI bridge: Renesas Electronics Corp. Device 0030 (prog-if 00 [Normal decode])
        Device tree node: /sys/firmware/devicetree/base/soc/pcie@e65d0000/pci@0,0
        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Latency: 0
        Interrupts: pin B disabled, MSI(X) routed to IRQ 99
        Bus: primary=00, secondary=01, subordinate=ff, sec-latency=0
        I/O behind bridge: f000-0fff [disabled] [16-bit]
        Memory behind bridge: 30000000-300fffff [size=1M] [32-bit]
        Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff [disabled] [64-bit]
        Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
        BridgeCtl: Parity- SERR+ NoISA- VGA- VGA16- MAbort- >Reset- FastB2B-
                PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
        Capabilities: [40] Power Management version 3
                Flags: PMEClk- DSI- D1+ D2- AuxCurrent=0mA PME(D0+,D1+,D2-,D3hot+,D3cold+)
                Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
        Capabilities: [50] MSI: Enable+ Count=1/32 Maskable+ 64bit+
                Address: 00000000f1050040  Data: 0001
                Masking: fffffffe  Pending: 00000000
        Capabilities: [70] Express (v2) Root Port (Slot-), IntMsgNum 0
                DevCap: MaxPayload 256 bytes, PhantFunc 0
                        ExtTag+ RBE+ TEE-IO-
                DevCtl: CorrErr+ NonFatalErr+ FatalErr+ UnsupReq+
                        RlxdOrd+ ExtTag+ PhantFunc- AuxPwr- NoSnoop+
                        MaxPayload 128 bytes, MaxReadReq 512 bytes
                DevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr+ TransPend-
                LnkCap: Port #0, Speed 16GT/s, Width x2, ASPM L0s L1, Exit Latency L0s <4us, L1 <64us
                        ClockPM- Surprise+ LLActRep+ BwNot+ ASPMOptComp+
                LnkCtl: ASPM Disabled; RCB 64 bytes, LnkDisable- CommClk-
                        ExtSynch- ClockPM- AutWidDis- BWInt+ AutBWInt+ FltModeDis-
                LnkSta: Speed 16GT/s, Width x2
                        TrErr- Train- SlotClk- DLActive+ BWMgmt- ABWMgmt-
                RootCap: CRSVisible+
                RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible+
                RootSta: PME ReqID 0000, PMEStatus- PMEPending-
                DevCap2: Completion Timeout: Not Supported, TimeoutDis+ NROPrPrP+ LTR+
                         10BitTagComp+ 10BitTagReq- OBFF Not Supported, ExtFmt- EETLPPrefix-
                         EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
                         FRS- LN System CLS Not Supported, TPHComp- ExtTPHComp- ARIFwd-
                         AtomicOpsCap: Routing- 32bit- 64bit- 128bitCAS-
                DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- ARIFwd-
                         AtomicOpsCtl: ReqEn- EgressBlck-
                         IDOReq- IDOCompl- LTR+ EmergencyPowerReductionReq-
                         10BitTagReq- OBFF Disabled, EETLPPrefixBlk-
                LnkCap2: Supported Link Speeds: 2.5-16GT/s, Crosslink+ Retimer+ 2Retimers+ DRS-
                LnkCtl2: Target Link Speed: 16GT/s, EnterCompliance- SpeedDis-
                         Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
                         Compliance Preset/De-emphasis: -6dB de-emphasis, 0dB preshoot
                LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete+ EqualizationPhase1+
                         EqualizationPhase2+ EqualizationPhase3+ LinkEqualizationRequest-
                         Retimer- 2Retimers- CrosslinkRes: Downstream Port, FltMode-
        Capabilities: [100 v2] Advanced Error Reporting
                UESta:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
                        ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
                        PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
                UEMsk:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
                        ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
                        PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
                UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
                        ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
                        PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
                CESta:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr- CorrIntErr- HeaderOF-
                CEMsk:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+ CorrIntErr+ HeaderOF+
                AERCap: First Error Pointer: 00, ECRCGenCap- ECRCGenEn- ECRCChkCap- ECRCChkEn-
                        MultHdrRecCap+ MultHdrRecEn- TLPPfxPres- HdrLogCap-
                HeaderLog: 00000000 00000000 00000000 00000000
                RootCmd: CERptEn+ NFERptEn+ FERptEn+
                RootSta: CERcvd- MultCERcvd- UERcvd- MultUERcvd-
                         FirstFatal- NonFatalMsg- FatalMsg- IntMsgNum 0
                ErrorSrc: ERR_COR: 0000 ERR_FATAL/NONFATAL: 0000
        Capabilities: [148 v1] Device Serial Number 00-00-00-00-00-00-00-00
        Capabilities: [158 v1] Secondary PCI Express
                LnkCtl3: LnkEquIntrruptEn- PerformEqu-
                LaneErrStat: 0
        Capabilities: [178 v1] Physical Layer 16.0 GT/s
                Phy16Sta: EquComplete+ EquPhase1+ EquPhase2+ EquPhase3+ LinkEquRequest-
        Capabilities: [19c v1] Lane Margining at the Receiver
                PortCap: Uses Driver-
                PortSta: MargReady- MargSoftReady-
        Capabilities: [1bc v1] L1 PM Substates
                L1SubCap: PCI-PM_L1.2- PCI-PM_L1.1- ASPM_L1.2- ASPM_L1.1- L1_PM_Substates-
                L1SubCtl1: PCI-PM_L1.2- PCI-PM_L1.1- ASPM_L1.2- ASPM_L1.1-
                L1SubCtl2:
        Capabilities: [1cc v1] Vendor Specific Information: ID=0002 Rev=4 Len=100 <?>
        Capabilities: [2cc v1] Vendor Specific Information: ID=0001 Rev=1 Len=038 <?>
        Capabilities: [304 v1] Data Link Feature <?>
        Capabilities: [310 v1] Precision Time Measurement
                PTMCap: Requester+ Responder+ Root+
                PTMClockGranularity: 16ns
                PTMControl: Enabled- RootSelected-
                PTMEffectiveGranularity: Unknown
        Capabilities: [31c v1] Vendor Specific Information: ID=0004 Rev=1 Len=054 <?>
        Capabilities: [384 v1] Vendor Specific Information: ID=0006 Rev=0 Len=018 <?>
        Kernel driver in use: pcieport

0001:01:00.0 Non-Volatile memory controller: Micron/Crucial Technology P5 Plus NVMe PCIe SSD (prog-if 02 [NVM Express])
        Subsystem: Micron/Crucial Technology Device 0100
        Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Latency: 0
        Interrupts: pin B disabled, MSI(X) routed to IRQ 100-104
        Region 0: Memory at 30000000 (64-bit, non-prefetchable) [size=16K]
        Capabilities: [40] Power Management version 3
                Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
                Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
        Capabilities: [50] MSI-X: Enable+ Count=32 Masked-
                Vector table: BAR=0 offset=00003000
                PBA: BAR=0 offset=00002000
        Capabilities: [60] Express (v2) Endpoint, IntMsgNum 0
                DevCap: MaxPayload 512 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimited
                        ExtTag+ AttnBtn- AttnInd- PwrInd- RBE+ FLReset+ SlotPowerLimit 0W TEE-IO-
                DevCtl: CorrErr+ NonFatalErr+ FatalErr+ UnsupReq+
                        RlxdOrd+ ExtTag+ PhantFunc- AuxPwr- NoSnoop+ FLReset-
                        MaxPayload 128 bytes, MaxReadReq 512 bytes
                DevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr- TransPend-
                LnkCap: Port #0, Speed 16GT/s, Width x4, ASPM L1, Exit Latency L1 <8us
                        ClockPM+ Surprise- LLActRep- BwNot- ASPMOptComp+
                LnkCtl: ASPM Disabled; RCB 64 bytes, LnkDisable- CommClk-
                        ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- FltModeDis-
                LnkSta: Speed 16GT/s, Width x2 (downgraded)
                        TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
                DevCap2: Completion Timeout: Range BCD, TimeoutDis+ NROPrPrP- LTR+
                         10BitTagComp+ 10BitTagReq- OBFF Via message, ExtFmt- EETLPPrefix-
                         EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
                         FRS- TPHComp- ExtTPHComp-
                         AtomicOpsCap: 32bit- 64bit- 128bitCAS-
                DevCtl2: Completion Timeout: 17s to 64s, TimeoutDis-
                         AtomicOpsCtl: ReqEn-
                         IDOReq- IDOCompl- LTR+ EmergencyPowerReductionReq-
                         10BitTagReq- OBFF Disabled, EETLPPrefixBlk-
                LnkCap2: Supported Link Speeds: 2.5-16GT/s, Crosslink- Retimer+ 2Retimers+ DRS-
                LnkCtl2: Target Link Speed: 16GT/s, EnterCompliance- SpeedDis-
                         Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
                         Compliance Preset/De-emphasis: -6dB de-emphasis, 0dB preshoot
                LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete+ EqualizationPhase1+
                         EqualizationPhase2+ EqualizationPhase3+ LinkEqualizationRequest-
                         Retimer- 2Retimers- CrosslinkRes: unsupported, FltMode-
        Capabilities: [100 v1] Advanced Error Reporting
                UESta:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
                        ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
                        PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
                UEMsk:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
                        ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
                        PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
                UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
                        ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
                        PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
                CESta:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr- CorrIntErr- HeaderOF-
                CEMsk:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+ CorrIntErr- HeaderOF-
                AERCap: First Error Pointer: 00, ECRCGenCap+ ECRCGenEn- ECRCChkCap+ ECRCChkEn-
                        MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
                HeaderLog: 00000000 00000000 00000000 00000000
        Capabilities: [2a0 v1] Secondary PCI Express
                LnkCtl3: LnkEquIntrruptEn- PerformEqu-
                LaneErrStat: 0
        Capabilities: [2d0 v1] Latency Tolerance Reporting
                Max snoop latency: 0ns
                Max no snoop latency: 0ns
        Capabilities: [320 v1] Data Link Feature <?>
        Capabilities: [330 v1] Physical Layer 16.0 GT/s
                Phy16Sta: EquComplete+ EquPhase1+ EquPhase2+ EquPhase3+ LinkEquRequest-
        Capabilities: [360 v1] Lane Margining at the Receiver
                PortCap: Uses Driver-
                PortSta: MargReady+ MargSoftReady-
        Capabilities: [700 v1] L1 PM Substates
                L1SubCap: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1- L1_PM_Substates+
                          PortCommonModeRestoreTime=32us PortTPowerOnTime=20us
                L1SubCtl1: PCI-PM_L1.2- PCI-PM_L1.1- ASPM_L1.2- ASPM_L1.1-
                           T_CommonMode=0us LTR1.2_Threshold=0ns
                L1SubCtl2: T_PwrOn=10us
        Kernel driver in use: nvme

$ dd if=/dev/urandom of=/tmp/data.bin bs=256 count=2 ; dd if=/tmp/data.bin of=/dev/nvme0n1 bs=256 count=2 ; dd if=/dev/nvme0n1 bs=256 count=2 of=/tmp/readback.bin ; sha256sum /tmp/data.bin /tmp/readback.bin
2+0 records in
2+0 records out
512 bytes copied, 0.568777 s, 0.9 kB/s
2+0 records in
2+0 records out
512 bytes copied, 0.00180474 s, 284 kB/s
2+0 records in
2+0 records out
512 bytes copied, 0.00106782 s, 479 kB/s
cf4f1b4e480f22f8a22d4aa322f13df3523e7a4483c3c3809d1c657b6c36df67  /tmp/data.bin
79d89cec4285ab36deb4f272a670d39ffdbfdcb132df2e859e818a2181fa8ef1  /tmp/readback.bin

$ hexdump -vC /tmp/data.bin
00000000  a3 3f b0 9b 78 d5 90 59  82 40 39 d7 19 1a c7 ae  |.?..x..Y.@9.....|
00000010  79 00 e5 dd e7 c1 d0 9f  cb c8 34 d3 ff 5e 63 f2  |y.........4..^c.|
00000020  09 16 f5 25 e3 83 76 91  99 78 74 b6 b8 c0 90 77  |...%..v..xt....w|
00000030  6c a3 df 0d d8 b6 e5 5c  d3 b1 a4 1e 71 ac 1a 62  |l......\....q..b|
00000040  c6 00 8e 9a 93 89 6a 25  40 85 aa bf 57 3d ca f7  |......j%@...W=..|
00000050  cc d1 ae 3c ab 4b 57 87  c2 f9 d0 b4 31 98 01 53  |...<.KW.....1..S|
00000060  3a 9f 52 e1 9b 34 85 a2  1e ae 4a 42 c3 82 3c 92  |:.R..4....JB..<.|
00000070  08 b7 aa ed 2c fa 3e ed  18 8d a4 46 24 de e5 25  |....,.>....F$..%|
00000080  c5 3f cf 24 1b 41 dd 67  65 8d e6 94 b0 89 98 07  |.?.$.A.ge.......|
00000090  29 e6 c7 b8 7a fd e7 d5  07 61 58 74 a3 0f 81 6a  |)...z....aXt...j|
000000a0  b1 ad be 59 b9 7b e9 13  8a b7 14 ef 54 b0 33 84  |...Y.{......T.3.|
000000b0  0c bd 74 bd 96 9f 23 47  4c ea 20 39 e2 cf ee a2  |..t...#GL. 9....|
000000c0  c4 f1 a6 43 8c f1 7b 20  57 c8 07 c3 f9 4b d7 20  |...C..{ W....K. |
000000d0  40 24 e9 9a 8b bd 05 b4  21 7e 64 fc 4f 69 b9 f7  |@$......!~d.Oi..|
000000e0  e1 03 77 51 10 27 55 70  de fd a3 03 79 63 68 b0  |..wQ.'Up....ych.|
000000f0  bf 63 a3 9c 40 e7 c8 00  bd ed a9 69 38 85 4d 61  |.c..@......i8.Ma|
00000100  d4 4a 19 af bf 55 b9 56  b0 70 e7 b5 20 3f 58 35  |.J...U.V.p.. ?X5|
00000110  cf 05 0f 83 c8 18 19 3f  51 10 1d 12 60 f3 d8 44  |.......?Q...`..D|
00000120  7d ae 2f 16 ec e8 7c 5d  3c e6 1e 77 be 2c 09 3a  |}./...|]<..w.,.:|
00000130  6d 5b e4 d9 71 d7 cf 01  51 3f d1 91 b7 73 0e a7  |m[..q...Q?...s..|
00000140  dc 33 c3 1f b2 b8 f7 75  c0 f2 35 05 9b d5 9f 25  |.3.....u..5....%|
00000150  3d 5b 47 43 0d 9b 20 cf  de ed fa 9f dd 46 17 e5  |=[GC.. ......F..|
00000160  37 2a be e8 bb 70 32 17  0b ff 9d 5f 91 8c 55 84  |7*...p2...._..U.|
00000170  8d ab b4 36 19 58 4f 50  fc 82 89 50 06 de d6 79  |...6.XOP...P...y|
00000180  51 b5 0c a6 4a 18 a9 e1  f3 1d 1d 17 bf 84 e6 a5  |Q...J...........|
00000190  b5 f1 80 6a 20 67 22 97  d4 a6 a8 1f f8 27 1b 80  |...j g"......'..|
000001a0  dc ca 51 ac bb 06 72 f7  ab fe 47 40 af 57 ec 62  |..Q...r...G@.W.b|
000001b0  9b 6b e6 b7 2a ba 6c bf  8d 5b db 5c 8f ec 8c d4  |.k..*.l..[.\....|
000001c0  b3 67 b5 b4 6b 52 df 75  da be e8 7c 4c 3a d8 37  |.g..kR.u...|L:.7|
000001d0  90 55 f8 c2 cc 54 26 2f  89 06 b5 d3 7b ea 74 01  |.U...T&/....{.t.|
000001e0  74 28 63 a3 73 14 4f 7b  72 ea 06 62 0f 08 ec 2b  |t(c.s.O{r..b...+|
000001f0  b3 e2 74 9e 01 56 4b 77  19 5c ee 8e 92 f9 11 e4  |..t..VKw.\......|
00000200

$ hexdump -vC /tmp/readback.bin 
00000000  a3 3f b0 9b 78 d5 90 59  82 40 39 d7 19 1a c7 ae  |.?..x..Y.@9.....|
00000010  79 00 e5 dd e7 c1 d0 9f  cb c8 34 d3 ff 5e 63 f2  |y.........4..^c.|
00000020  09 16 f5 25 e3 83 76 91  99 78 74 b6 b8 c0 90 77  |...%..v..xt....w|
00000030  6c a3 df 0d d8 b6 e5 5c  d3 b1 a4 1e 71 ac 1a 62  |l......\....q..b|
00000040  c6 00 8e 9a 93 89 6a 25  40 85 aa bf 57 3d ca f7  |......j%@...W=..|
00000050  cc d1 ae 3c ab 4b 57 87  c2 f9 d0 b4 31 98 01 53  |...<.KW.....1..S|
00000060  3a 9f 52 e1 9b 34 85 a2  1e ae 4a 42 c3 82 3c 92  |:.R..4....JB..<.|
00000070  08 b7 aa ed 2c fa 3e ed  18 8d a4 46 24 de e5 25  |....,.>....F$..%|
00000080  c5 3f cf 24 1b 41 dd 67  65 8d e6 94 b0 89 98 07  |.?.$.A.ge.......|
00000090  29 e6 c7 b8 7a fd e7 d5  07 61 58 74 a3 0f 81 6a  |)...z....aXt...j|
000000a0  b1 ad be 59 b9 7b e9 13  8a b7 14 ef 54 b0 33 84  |...Y.{......T.3.|
000000b0  0c bd 74 bd 96 9f 23 47  4c ea 20 39 e2 cf ee a2  |..t...#GL. 9....|
000000c0  c4 f1 a6 43 8c f1 7b 20  57 c8 07 c3 f9 4b d7 20  |...C..{ W....K. |
000000d0  40 24 e9 9a 8b bd 05 b4  21 7e 64 fc 4f 69 b9 f7  |@$......!~d.Oi..|
000000e0  e1 03 77 51 10 27 55 70  de fd a3 03 79 63 68 b0  |..wQ.'Up....ych.|
000000f0  bf 63 a3 9c 40 e7 c8 00  bd ed a9 69 38 85 4d 61  |.c..@......i8.Ma|
00000100  a3 3f b0 9b 78 d5 90 59  82 40 39 d7 19 1a c7 ae  |.?..x..Y.@9.....|
00000110  79 00 e5 dd e7 c1 d0 9f  cb c8 34 d3 ff 5e 63 f2  |y.........4..^c.|
00000120  09 16 f5 25 e3 83 76 91  99 78 74 b6 b8 c0 90 77  |...%..v..xt....w|
00000130  6c a3 df 0d d8 b6 e5 5c  d3 b1 a4 1e 71 ac 1a 62  |l......\....q..b|
00000140  c6 00 8e 9a 93 89 6a 25  40 85 aa bf 57 3d ca f7  |......j%@...W=..|
00000150  cc d1 ae 3c ab 4b 57 87  c2 f9 d0 b4 31 98 01 53  |...<.KW.....1..S|
00000160  3a 9f 52 e1 9b 34 85 a2  1e ae 4a 42 c3 82 3c 92  |:.R..4....JB..<.|
00000170  08 b7 aa ed 2c fa 3e ed  18 8d a4 46 24 de e5 25  |....,.>....F$..%|
00000180  c5 3f cf 24 1b 41 dd 67  65 8d e6 94 b0 89 98 07  |.?.$.A.ge.......|
00000190  29 e6 c7 b8 7a fd e7 d5  07 61 58 74 a3 0f 81 6a  |)...z....aXt...j|
000001a0  b1 ad be 59 b9 7b e9 13  8a b7 14 ef 54 b0 33 84  |...Y.{......T.3.|
000001b0  0c bd 74 bd 96 9f 23 47  4c ea 20 39 e2 cf ee a2  |..t...#GL. 9....|
000001c0  c4 f1 a6 43 8c f1 7b 20  57 c8 07 c3 f9 4b d7 20  |...C..{ W....K. |
000001d0  40 24 e9 9a 8b bd 05 b4  21 7e 64 fc 4f 69 b9 f7  |@$......!~d.Oi..|
000001e0  e1 03 77 51 10 27 55 70  de fd a3 03 79 63 68 b0  |..wQ.'Up....ych.|
000001f0  bf 63 a3 9c 40 e7 c8 00  bd ed a9 69 38 85 4d 61  |.c..@......i8.Ma|
00000200

[-- Attachment #3: pass.log --]
[-- Type: text/x-log, Size: 15816 bytes --]

$ lspci -vvv
...
0001:00:00.0 PCI bridge: Renesas Electronics Corp. Device 0030 (prog-if 00 [Normal decode])
        Device tree node: /sys/firmware/devicetree/base/soc/pcie@e65d0000/pci@0,0
        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Latency: 0
        Interrupts: pin B disabled, MSI(X) routed to IRQ 99
        Bus: primary=00, secondary=01, subordinate=ff, sec-latency=0
        I/O behind bridge: f000-0fff [disabled] [16-bit]
        Memory behind bridge: 30000000-300fffff [size=1M] [32-bit]
        Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff [disabled] [64-bit]
        Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
        BridgeCtl: Parity- SERR+ NoISA- VGA- VGA16- MAbort- >Reset- FastB2B-
                PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
        Capabilities: [40] Power Management version 3
                Flags: PMEClk- DSI- D1+ D2- AuxCurrent=0mA PME(D0+,D1+,D2-,D3hot+,D3cold+)
                Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
        Capabilities: [50] MSI: Enable+ Count=1/32 Maskable+ 64bit+
                Address: 00000000f1050040  Data: 0001
                Masking: fffffffe  Pending: 00000000
        Capabilities: [70] Express (v2) Root Port (Slot-), IntMsgNum 0
                DevCap: MaxPayload 256 bytes, PhantFunc 0
                        ExtTag+ RBE+ TEE-IO-
                DevCtl: CorrErr+ NonFatalErr+ FatalErr+ UnsupReq+
                        RlxdOrd+ ExtTag+ PhantFunc- AuxPwr- NoSnoop+
                        MaxPayload 128 bytes, MaxReadReq 256 bytes
                DevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr+ TransPend-
                LnkCap: Port #0, Speed 16GT/s, Width x2, ASPM L0s L1, Exit Latency L0s <4us, L1 <64us
                        ClockPM- Surprise+ LLActRep+ BwNot+ ASPMOptComp+
                LnkCtl: ASPM Disabled; RCB 64 bytes, LnkDisable- CommClk-
                        ExtSynch- ClockPM- AutWidDis- BWInt+ AutBWInt+ FltModeDis-
                LnkSta: Speed 16GT/s, Width x2
                        TrErr- Train- SlotClk- DLActive+ BWMgmt- ABWMgmt-
                RootCap: CRSVisible+
                RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna+ CRSVisible+
                RootSta: PME ReqID 0000, PMEStatus- PMEPending-
                DevCap2: Completion Timeout: Not Supported, TimeoutDis+ NROPrPrP+ LTR+
                         10BitTagComp+ 10BitTagReq- OBFF Not Supported, ExtFmt- EETLPPrefix-
                         EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
                         FRS- LN System CLS Not Supported, TPHComp- ExtTPHComp- ARIFwd-
                         AtomicOpsCap: Routing- 32bit- 64bit- 128bitCAS-
                DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis- ARIFwd-
                         AtomicOpsCtl: ReqEn- EgressBlck-
                         IDOReq- IDOCompl- LTR+ EmergencyPowerReductionReq-
                         10BitTagReq- OBFF Disabled, EETLPPrefixBlk-
                LnkCap2: Supported Link Speeds: 2.5-16GT/s, Crosslink+ Retimer+ 2Retimers+ DRS-
                LnkCtl2: Target Link Speed: 16GT/s, EnterCompliance- SpeedDis-
                         Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
                         Compliance Preset/De-emphasis: -6dB de-emphasis, 0dB preshoot
                LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete+ EqualizationPhase1+
                         EqualizationPhase2+ EqualizationPhase3+ LinkEqualizationRequest-
                         Retimer- 2Retimers- CrosslinkRes: Downstream Port, FltMode-
        Capabilities: [100 v2] Advanced Error Reporting
                UESta:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
                        ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
                        PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
                UEMsk:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
                        ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
                        PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
                UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
                        ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
                        PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
                CESta:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr- CorrIntErr- HeaderOF-
                CEMsk:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+ CorrIntErr+ HeaderOF+
                AERCap: First Error Pointer: 00, ECRCGenCap- ECRCGenEn- ECRCChkCap- ECRCChkEn-
                        MultHdrRecCap+ MultHdrRecEn- TLPPfxPres- HdrLogCap-
                HeaderLog: 00000000 00000000 00000000 00000000
                RootCmd: CERptEn+ NFERptEn+ FERptEn+
                RootSta: CERcvd- MultCERcvd- UERcvd- MultUERcvd-
                         FirstFatal- NonFatalMsg- FatalMsg- IntMsgNum 0
                ErrorSrc: ERR_COR: 0000 ERR_FATAL/NONFATAL: 0000
        Capabilities: [148 v1] Device Serial Number 00-00-00-00-00-00-00-00
        Capabilities: [158 v1] Secondary PCI Express
                LnkCtl3: LnkEquIntrruptEn- PerformEqu-
                LaneErrStat: 0
        Capabilities: [178 v1] Physical Layer 16.0 GT/s
                Phy16Sta: EquComplete+ EquPhase1+ EquPhase2+ EquPhase3+ LinkEquRequest-
        Capabilities: [19c v1] Lane Margining at the Receiver
                PortCap: Uses Driver-
                PortSta: MargReady- MargSoftReady-
        Capabilities: [1bc v1] L1 PM Substates
                L1SubCap: PCI-PM_L1.2- PCI-PM_L1.1- ASPM_L1.2- ASPM_L1.1- L1_PM_Substates-
                L1SubCtl1: PCI-PM_L1.2- PCI-PM_L1.1- ASPM_L1.2- ASPM_L1.1-
                L1SubCtl2:
        Capabilities: [1cc v1] Vendor Specific Information: ID=0002 Rev=4 Len=100 <?>
        Capabilities: [2cc v1] Vendor Specific Information: ID=0001 Rev=1 Len=038 <?>
        Capabilities: [304 v1] Data Link Feature <?>
        Capabilities: [310 v1] Precision Time Measurement
                PTMCap: Requester+ Responder+ Root+
                PTMClockGranularity: 16ns
                PTMControl: Enabled- RootSelected-
                PTMEffectiveGranularity: Unknown
        Capabilities: [31c v1] Vendor Specific Information: ID=0004 Rev=1 Len=054 <?>
        Capabilities: [384 v1] Vendor Specific Information: ID=0006 Rev=0 Len=018 <?>
        Kernel driver in use: pcieport

0001:01:00.0 Non-Volatile memory controller: Micron/Crucial Technology P5 Plus NVMe PCIe SSD (prog-if 02 [NVM Express])
        Subsystem: Micron/Crucial Technology Device 0100
        Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Latency: 0
        Interrupts: pin B disabled, MSI(X) routed to IRQ 100-104
        Region 0: Memory at 30000000 (64-bit, non-prefetchable) [size=16K]
        Capabilities: [40] Power Management version 3
                Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
                Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
        Capabilities: [50] MSI-X: Enable+ Count=32 Masked-
                Vector table: BAR=0 offset=00003000
                PBA: BAR=0 offset=00002000
        Capabilities: [60] Express (v2) Endpoint, IntMsgNum 0
                DevCap: MaxPayload 512 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimited
                        ExtTag+ AttnBtn- AttnInd- PwrInd- RBE+ FLReset+ SlotPowerLimit 0W TEE-IO-
                DevCtl: CorrErr+ NonFatalErr+ FatalErr+ UnsupReq+
                        RlxdOrd+ ExtTag+ PhantFunc- AuxPwr- NoSnoop+ FLReset-
                        MaxPayload 128 bytes, MaxReadReq 256 bytes
                DevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr- TransPend-
                LnkCap: Port #0, Speed 16GT/s, Width x4, ASPM L1, Exit Latency L1 <8us
                        ClockPM+ Surprise- LLActRep- BwNot- ASPMOptComp+
                LnkCtl: ASPM Disabled; RCB 64 bytes, LnkDisable- CommClk-
                        ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- FltModeDis-
                LnkSta: Speed 16GT/s, Width x2 (downgraded)
                        TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
                DevCap2: Completion Timeout: Range BCD, TimeoutDis+ NROPrPrP- LTR+
                         10BitTagComp+ 10BitTagReq- OBFF Via message, ExtFmt- EETLPPrefix-
                         EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
                         FRS- TPHComp- ExtTPHComp-
                         AtomicOpsCap: 32bit- 64bit- 128bitCAS-
                DevCtl2: Completion Timeout: 17s to 64s, TimeoutDis-
                         AtomicOpsCtl: ReqEn-
                         IDOReq- IDOCompl- LTR+ EmergencyPowerReductionReq-
                         10BitTagReq- OBFF Disabled, EETLPPrefixBlk-
                LnkCap2: Supported Link Speeds: 2.5-16GT/s, Crosslink- Retimer+ 2Retimers+ DRS-
                LnkCtl2: Target Link Speed: 16GT/s, EnterCompliance- SpeedDis-
                         Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
                         Compliance Preset/De-emphasis: -6dB de-emphasis, 0dB preshoot
                LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete+ EqualizationPhase1+
                         EqualizationPhase2+ EqualizationPhase3+ LinkEqualizationRequest-
                         Retimer- 2Retimers- CrosslinkRes: unsupported, FltMode-
        Capabilities: [100 v1] Advanced Error Reporting
                UESta:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
                        ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
                        PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
                UEMsk:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
                        ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
                        PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
                UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
                        ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
                        PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
                CESta:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr- CorrIntErr- HeaderOF-
                CEMsk:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+ CorrIntErr- HeaderOF-
                AERCap: First Error Pointer: 00, ECRCGenCap+ ECRCGenEn- ECRCChkCap+ ECRCChkEn-
                        MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
                HeaderLog: 00000000 00000000 00000000 00000000
        Capabilities: [2a0 v1] Secondary PCI Express
                LnkCtl3: LnkEquIntrruptEn- PerformEqu-
                LaneErrStat: 0
        Capabilities: [2d0 v1] Latency Tolerance Reporting
                Max snoop latency: 0ns
                Max no snoop latency: 0ns
        Capabilities: [320 v1] Data Link Feature <?>
        Capabilities: [330 v1] Physical Layer 16.0 GT/s
                Phy16Sta: EquComplete+ EquPhase1+ EquPhase2+ EquPhase3+ LinkEquRequest-
        Capabilities: [360 v1] Lane Margining at the Receiver
                PortCap: Uses Driver-
                PortSta: MargReady+ MargSoftReady-
        Capabilities: [700 v1] L1 PM Substates
                L1SubCap: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1- L1_PM_Substates+
                          PortCommonModeRestoreTime=32us PortTPowerOnTime=20us
                L1SubCtl1: PCI-PM_L1.2- PCI-PM_L1.1- ASPM_L1.2- ASPM_L1.1-
                           T_CommonMode=0us LTR1.2_Threshold=0ns
                L1SubCtl2: T_PwrOn=10us
        Kernel driver in use: nvme

$ dd if=/dev/urandom of=/tmp/data.bin bs=256 count=2 ; dd if=/tmp/data.bin of=/dev/nvme0n1 bs=256 count=2 ; dd if=/dev/nvme0n1 bs=256 count=2 of=/tmp/readback.bin ; sha256sum /tmp/data.bin /tmp/readback.bin
2+0 records in
2+0 records out
512 bytes copied, 0.679513 s, 0.8 kB/s
2+0 records in
2+0 records out
512 bytes copied, 0.00173286 s, 295 kB/s
2+0 records in
2+0 records out
512 bytes copied, 0.0009876 s, 518 kB/s
121f0f010736d802f76e7d9ea8ab874edee39549cbd0c3dce7b77a22b0fda76c  /tmp/data.bin
121f0f010736d802f76e7d9ea8ab874edee39549cbd0c3dce7b77a22b0fda76c  /tmp/readback.bin

$ hexdump -vC /tmp/data.bin
00000000  fa b6 e5 1a 13 20 8c b2  07 84 ec ec 6d 7b 51 c9  |..... ......m{Q.|
00000010  80 59 ea 60 fb 95 fa e3  cb 2f 19 06 a4 e1 46 40  |.Y.`...../....F@|
00000020  9d 3e d4 a7 a4 56 7d 34  9f 6c a2 96 66 4b 37 4d  |.>...V}4.l..fK7M|
00000030  41 6c 2e 04 fb bd e9 6e  3c fd 41 36 1c ac 75 4e  |Al.....n<.A6..uN|
00000040  62 86 a6 a2 b8 aa 8c ee  d2 6e 10 a5 2f 11 85 0a  |b........n../...|
00000050  69 3b 6a 4b a5 06 f3 85  58 fa c1 eb 73 35 95 34  |i;jK....X...s5.4|
00000060  19 a6 3f 7f a3 d9 51 3f  cf 48 de 4c 29 7f 4e 67  |..?...Q?.H.L).Ng|
00000070  f9 49 26 30 be 84 67 19  f7 d0 99 13 dc b6 0d a1  |.I&0..g.........|
00000080  69 c5 6a cf c2 a3 9a 54  de 5f bd 2b b0 91 1c 73  |i.j....T._.+...s|
00000090  f1 7e bc 16 75 13 24 93  44 76 32 87 66 77 06 0f  |.~..u.$.Dv2.fw..|
000000a0  0c cf 40 eb 39 fc 62 93  e5 4c c6 a8 b3 b8 6b bd  |..@.9.b..L....k.|
000000b0  09 19 12 9d 8d c0 d8 8c  70 2e d4 5e 61 6e cd c2  |........p..^an..|
000000c0  6a 5d 5c 9e 29 3b a6 a6  ca 34 a6 e4 46 88 2c bb  |j]\.);...4..F.,.|
000000d0  a9 68 24 53 ab e3 1b 10  6f 3a da 3f 5e b7 69 10  |.h$S....o:.?^.i.|
000000e0  71 c3 fc 10 04 b7 74 b6  b6 2d bc 75 e9 9c 78 d9  |q.....t..-.u..x.|
000000f0  db 6c ba e7 7e a0 91 c6  57 87 87 c5 e3 4c d8 ac  |.l..~...W....L..|
00000100  ae de d9 d7 88 ad ec 6f  d6 5c 29 51 bb b1 5e 41  |.......o.\)Q..^A|
00000110  0b 99 6d 06 7e f5 d1 fa  19 06 f4 9a e0 fd fb 9c  |..m.~...........|
00000120  6d 80 17 3a ce 8e 71 05  02 18 d3 81 c0 4a 89 89  |m..:..q......J..|
00000130  84 83 88 e0 35 13 8c 82  27 9f bd f5 80 f4 0e 71  |....5...'......q|
00000140  91 69 2a 63 bf 61 df 7a  de b9 a8 93 79 7b 22 d1  |.i*c.a.z....y{".|
00000150  74 a8 a6 ea b7 bb e9 6f  53 24 02 bf 66 d6 ae 2a  |t......oS$..f..*|
00000160  66 63 03 42 03 8f 0c d3  7a c3 30 b0 dd f6 57 c3  |fc.B....z.0...W.|
00000170  37 0e 3b ea a2 f0 54 ef  9f b5 74 bd cd 48 20 bf  |7.;...T...t..H .|
00000180  96 19 a4 e2 17 ae 0e 39  10 5a e3 69 6b e6 b9 ae  |.......9.Z.ik...|
00000190  d4 9b c0 da d8 54 99 a3  6f cd 58 46 3f 32 7f 3f  |.....T..o.XF?2.?|
000001a0  b0 08 45 42 66 b3 f8 0d  f0 71 a8 0e b1 62 f5 81  |..EBf....q...b..|
000001b0  13 be 95 ca 59 3e 46 d3  f6 27 5c c6 1f 8e b9 f5  |....Y>F..'\.....|
000001c0  f5 49 24 b6 04 19 90 1f  ac 75 a4 a0 19 e1 4d f9  |.I$......u....M.|
000001d0  08 a3 57 fd f4 8d dd 4b  71 dd 71 2f bb ee 5f e5  |..W....Kq.q/.._.|
000001e0  a9 60 66 f8 4f 5b b2 f1  ef d0 ac 5b f7 fa 6d 1d  |.`f.O[.....[..m.|
000001f0  f4 2d 24 ec 6f 9f e4 d5  74 67 e4 f7 61 91 a2 66  |.-$.o...tg..a..f|
00000200

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

end of thread, other threads:[~2026-05-20 14:19 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-04-25 23:38 [PATCH] PCI: rcar-gen4: Limit Max_Read_Request_Size and Max_Payload_Size to 256 Bytes Marek Vasut
2026-04-28  7:00 ` Koichiro Den
2026-05-03 23:54   ` Marek Vasut
2026-05-11 14:20     ` Koichiro Den
2026-05-13  3:01       ` Marek Vasut
2026-05-11 14:34 ` Manivannan Sadhasivam
2026-05-12 22:57   ` Marek Vasut
2026-05-12 23:08     ` Marek Vasut
2026-05-20  7:52     ` Manivannan Sadhasivam
2026-05-20 14:18       ` Marek Vasut

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®