diff mbox series

[v11,14/20] cxl/pci: Map RCH downstream AER registers for logging protocol errors

Message ID 20230927154339.1600738-15-rrichter@amd.com
State Superseded
Headers show
Series cxl/pci: Add support for RCH RAS error handling | expand

Commit Message

Robert Richter Sept. 27, 2023, 3:43 p.m. UTC
From: Terry Bowman <terry.bowman@amd.com>

The restricted CXL host (RCH) error handler will log protocol errors
using AER and RAS status registers. The AER and RAS registers need to
be virtually memory mapped before enabling interrupts. Create the
initializer function devm_cxl_setup_parent_dport() for this when the
endpoint is connected with the dport. The initialization sets up the
RCH RAS and AER mappings.

Add 'struct cxl_regs' to 'struct cxl_dport' for saving a pointer to
the RCH downstream port's AER and RAS registers.

Co-developed-by: Robert Richter <rrichter@amd.com>
Signed-off-by: Terry Bowman <terry.bowman@amd.com>
Signed-off-by: Robert Richter <rrichter@amd.com>
---
 drivers/cxl/core/pci.c | 36 ++++++++++++++++++++++++++++++++++++
 drivers/cxl/cxl.h      | 10 ++++++++++
 2 files changed, 46 insertions(+)

Comments

Jonathan Cameron Oct. 2, 2023, 2:56 p.m. UTC | #1
On Wed, 27 Sep 2023 17:43:33 +0200
Robert Richter <rrichter@amd.com> wrote:

> From: Terry Bowman <terry.bowman@amd.com>
> 
> The restricted CXL host (RCH) error handler will log protocol errors
> using AER and RAS status registers. The AER and RAS registers need to
> be virtually memory mapped before enabling interrupts. Create the
> initializer function devm_cxl_setup_parent_dport() for this when the
> endpoint is connected with the dport. The initialization sets up the
> RCH RAS and AER mappings.
> 
> Add 'struct cxl_regs' to 'struct cxl_dport' for saving a pointer to
> the RCH downstream port's AER and RAS registers.
> 
> Co-developed-by: Robert Richter <rrichter@amd.com>
> Signed-off-by: Terry Bowman <terry.bowman@amd.com>
As before. Co-dev just before SoB. 

https://elixir.bootlin.com/linux/latest/source/Documentation/process/submitting-patches.rst#L521
This example looks like what you have here.

> Signed-off-by: Robert Richter <rrichter@amd.com>
Otherwise, LGTM

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

> ---
>  drivers/cxl/core/pci.c | 36 ++++++++++++++++++++++++++++++++++++
>  drivers/cxl/cxl.h      | 10 ++++++++++
>  2 files changed, 46 insertions(+)
> 
> diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
> index 2b8883288539..2af7ad77b273 100644
> --- a/drivers/cxl/core/pci.c
> +++ b/drivers/cxl/core/pci.c
> @@ -5,6 +5,7 @@
>  #include <linux/delay.h>
>  #include <linux/pci.h>
>  #include <linux/pci-doe.h>
> +#include <linux/aer.h>
>  #include <cxlpci.h>
>  #include <cxlmem.h>
>  #include <cxl.h>
> @@ -730,6 +731,38 @@ static bool cxl_handle_endpoint_ras(struct cxl_dev_state *cxlds)
>  
>  #ifdef CONFIG_PCIEAER_CXL
>  
> +static void cxl_dport_map_rch_aer(struct cxl_dport *dport)
> +{
> +	struct cxl_rcrb_info *ri = &dport->rcrb;
> +	void __iomem *dport_aer = NULL;
> +	resource_size_t aer_phys;
> +	struct device *host;
> +
> +	if (dport->rch && ri->aer_cap) {
> +		host = dport->reg_map.host;
> +		aer_phys = ri->aer_cap + ri->base;
> +		dport_aer = devm_cxl_iomap_block(host, aer_phys,
> +				sizeof(struct aer_capability_regs));
> +	}
> +
> +	dport->regs.dport_aer = dport_aer;
> +}
> +
> +static void cxl_dport_map_regs(struct cxl_dport *dport)
> +{
> +	struct cxl_register_map *map = &dport->reg_map;
> +	struct device *dev = dport->dport_dev;
> +
> +	if (!map->component_map.ras.valid)
> +		dev_dbg(dev, "RAS registers not found\n");
> +	else if (cxl_map_component_regs(map, &dport->regs.component,
> +					BIT(CXL_CM_CAP_CAP_ID_RAS)))
> +		dev_dbg(dev, "Failed to map RAS capability.\n");
> +
> +	if (dport->rch)
> +		cxl_dport_map_rch_aer(dport);
> +}
> +
>  void devm_cxl_setup_parent_dport(struct device *host, struct cxl_dport *dport)
>  {
>  	struct device *dport_dev = dport->dport_dev;
> @@ -738,6 +771,9 @@ void devm_cxl_setup_parent_dport(struct device *host, struct cxl_dport *dport)
>  	host_bridge = to_pci_host_bridge(dport_dev);
>  	if (host_bridge->native_cxl_error)
>  		dport->rcrb.aer_cap = cxl_rcrb_to_aer(dport_dev, dport->rcrb.base);
> +
> +	dport->reg_map.host = host;
> +	cxl_dport_map_regs(dport);
>  }
>  EXPORT_SYMBOL_NS_GPL(devm_cxl_setup_parent_dport, CXL);
>  
> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
> index cfa2f6bede41..7c2c195592d6 100644
> --- a/drivers/cxl/cxl.h
> +++ b/drivers/cxl/cxl.h
> @@ -221,6 +221,14 @@ struct cxl_regs {
>  	struct_group_tagged(cxl_pmu_regs, pmu_regs,
>  		void __iomem *pmu;
>  	);
> +
> +	/*
> +	 * RCH downstream port specific RAS register
> +	 * @aer: CXL 3.0 8.2.1.1 RCH Downstream Port RCRB
> +	 */
> +	struct_group_tagged(cxl_rch_regs, rch_regs,
> +		void __iomem *dport_aer;
> +	);
>  };
>  
>  struct cxl_reg_map {
> @@ -623,6 +631,7 @@ struct cxl_rcrb_info {
>   * @rcrb: Data about the Root Complex Register Block layout
>   * @rch: Indicate whether this dport was enumerated in RCH or VH mode
>   * @port: reference to cxl_port that contains this downstream port
> + * @regs: Dport parsed register blocks
>   */
>  struct cxl_dport {
>  	struct device *dport_dev;
> @@ -631,6 +640,7 @@ struct cxl_dport {
>  	struct cxl_rcrb_info rcrb;
>  	bool rch;
>  	struct cxl_port *port;
> +	struct cxl_regs regs;
>  };
>  
>  /**
Terry Bowman Oct. 9, 2023, 2:56 p.m. UTC | #2
On 10/2/23 09:56, Jonathan Cameron wrote:
> On Wed, 27 Sep 2023 17:43:33 +0200
> Robert Richter <rrichter@amd.com> wrote:
> 
>> From: Terry Bowman <terry.bowman@amd.com>
>>
>> The restricted CXL host (RCH) error handler will log protocol errors
>> using AER and RAS status registers. The AER and RAS registers need to
>> be virtually memory mapped before enabling interrupts. Create the
>> initializer function devm_cxl_setup_parent_dport() for this when the
>> endpoint is connected with the dport. The initialization sets up the
>> RCH RAS and AER mappings.
>>
>> Add 'struct cxl_regs' to 'struct cxl_dport' for saving a pointer to
>> the RCH downstream port's AER and RAS registers.
>>
>> Co-developed-by: Robert Richter <rrichter@amd.com>
>> Signed-off-by: Terry Bowman <terry.bowman@amd.com>
> As before. Co-dev just before SoB. 
> 
> https://elixir.bootlin.com/linux/latest/source/Documentation/process/submitting-patches.rst#L521
> This example looks like what you have here.
> 
>> Signed-off-by: Robert Richter <rrichter@amd.com>
> Otherwise, LGTM
> 
> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

Yes, we will fix.

Regards,
Terry
diff mbox series

Patch

diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
index 2b8883288539..2af7ad77b273 100644
--- a/drivers/cxl/core/pci.c
+++ b/drivers/cxl/core/pci.c
@@ -5,6 +5,7 @@ 
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/pci-doe.h>
+#include <linux/aer.h>
 #include <cxlpci.h>
 #include <cxlmem.h>
 #include <cxl.h>
@@ -730,6 +731,38 @@  static bool cxl_handle_endpoint_ras(struct cxl_dev_state *cxlds)
 
 #ifdef CONFIG_PCIEAER_CXL
 
+static void cxl_dport_map_rch_aer(struct cxl_dport *dport)
+{
+	struct cxl_rcrb_info *ri = &dport->rcrb;
+	void __iomem *dport_aer = NULL;
+	resource_size_t aer_phys;
+	struct device *host;
+
+	if (dport->rch && ri->aer_cap) {
+		host = dport->reg_map.host;
+		aer_phys = ri->aer_cap + ri->base;
+		dport_aer = devm_cxl_iomap_block(host, aer_phys,
+				sizeof(struct aer_capability_regs));
+	}
+
+	dport->regs.dport_aer = dport_aer;
+}
+
+static void cxl_dport_map_regs(struct cxl_dport *dport)
+{
+	struct cxl_register_map *map = &dport->reg_map;
+	struct device *dev = dport->dport_dev;
+
+	if (!map->component_map.ras.valid)
+		dev_dbg(dev, "RAS registers not found\n");
+	else if (cxl_map_component_regs(map, &dport->regs.component,
+					BIT(CXL_CM_CAP_CAP_ID_RAS)))
+		dev_dbg(dev, "Failed to map RAS capability.\n");
+
+	if (dport->rch)
+		cxl_dport_map_rch_aer(dport);
+}
+
 void devm_cxl_setup_parent_dport(struct device *host, struct cxl_dport *dport)
 {
 	struct device *dport_dev = dport->dport_dev;
@@ -738,6 +771,9 @@  void devm_cxl_setup_parent_dport(struct device *host, struct cxl_dport *dport)
 	host_bridge = to_pci_host_bridge(dport_dev);
 	if (host_bridge->native_cxl_error)
 		dport->rcrb.aer_cap = cxl_rcrb_to_aer(dport_dev, dport->rcrb.base);
+
+	dport->reg_map.host = host;
+	cxl_dport_map_regs(dport);
 }
 EXPORT_SYMBOL_NS_GPL(devm_cxl_setup_parent_dport, CXL);
 
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index cfa2f6bede41..7c2c195592d6 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -221,6 +221,14 @@  struct cxl_regs {
 	struct_group_tagged(cxl_pmu_regs, pmu_regs,
 		void __iomem *pmu;
 	);
+
+	/*
+	 * RCH downstream port specific RAS register
+	 * @aer: CXL 3.0 8.2.1.1 RCH Downstream Port RCRB
+	 */
+	struct_group_tagged(cxl_rch_regs, rch_regs,
+		void __iomem *dport_aer;
+	);
 };
 
 struct cxl_reg_map {
@@ -623,6 +631,7 @@  struct cxl_rcrb_info {
  * @rcrb: Data about the Root Complex Register Block layout
  * @rch: Indicate whether this dport was enumerated in RCH or VH mode
  * @port: reference to cxl_port that contains this downstream port
+ * @regs: Dport parsed register blocks
  */
 struct cxl_dport {
 	struct device *dport_dev;
@@ -631,6 +640,7 @@  struct cxl_dport {
 	struct cxl_rcrb_info rcrb;
 	bool rch;
 	struct cxl_port *port;
+	struct cxl_regs regs;
 };
 
 /**