crypto: qat - add infrastructure for error reporting
authorShashank Gupta <shashank.gupta@intel.com>
Fri, 20 Oct 2023 10:32:45 +0000 (11:32 +0100)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 27 Oct 2023 10:04:27 +0000 (18:04 +0800)
Add infrastructure for enabling, disabling and reporting errors in the QAT
driver. This adds a new structure, adf_ras_ops, to adf_hw_device_data that
contains the following methods:
  - enable_ras_errors(): allows to enable RAS errors at device
    initialization.
  - disable_ras_errors(): allows to disable RAS errors at device shutdown.
  - handle_interrupt(): allows to detect if there is an error and report if
    a reset is required. This is executed immediately after the error is
    reported, in the context of an ISR.

An initial, empty, implementation of the methods above is provided
for QAT GEN4.

Signed-off-by: Shashank Gupta <shashank.gupta@intel.com>
Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Reviewed-by: Tero Kristo <tero.kristo@linux.intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c
drivers/crypto/intel/qat/qat_common/Makefile
drivers/crypto/intel/qat/qat_common/adf_accel_devices.h
drivers/crypto/intel/qat/qat_common/adf_gen4_ras.c [new file with mode: 0644]
drivers/crypto/intel/qat/qat_common/adf_gen4_ras.h [new file with mode: 0644]
drivers/crypto/intel/qat/qat_common/adf_init.c
drivers/crypto/intel/qat/qat_common/adf_isr.c

index 12b5d18..671e32c 100644 (file)
@@ -9,6 +9,7 @@
 #include <adf_gen4_hw_data.h>
 #include <adf_gen4_pfvf.h>
 #include <adf_gen4_pm.h>
+#include "adf_gen4_ras.h"
 #include <adf_gen4_timer.h>
 #include "adf_4xxx_hw_data.h"
 #include "adf_cfg_services.h"
@@ -541,6 +542,7 @@ void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data, u32 dev_id)
        adf_gen4_init_hw_csr_ops(&hw_data->csr_ops);
        adf_gen4_init_pf_pfvf_ops(&hw_data->pfvf_ops);
        adf_gen4_init_dc_ops(&hw_data->dc_ops);
+       adf_gen4_init_ras_ops(&hw_data->ras_ops);
 }
 
 void adf_clean_hw_data_4xxx(struct adf_hw_device_data *hw_data)
index 204c7d0..151fd3c 100644 (file)
@@ -18,6 +18,7 @@ intel_qat-objs := adf_cfg.o \
        adf_gen4_pm.o \
        adf_gen2_dc.o \
        adf_gen4_dc.o \
+       adf_gen4_ras.o \
        adf_gen4_timer.o \
        adf_clock.o \
        qat_crypto.o \
index 9677c8e..a624194 100644 (file)
@@ -152,6 +152,13 @@ struct adf_accel_dev;
 struct adf_etr_data;
 struct adf_etr_ring_data;
 
+struct adf_ras_ops {
+       void (*enable_ras_errors)(struct adf_accel_dev *accel_dev);
+       void (*disable_ras_errors)(struct adf_accel_dev *accel_dev);
+       bool (*handle_interrupt)(struct adf_accel_dev *accel_dev,
+                                bool *reset_required);
+};
+
 struct adf_pfvf_ops {
        int (*enable_comms)(struct adf_accel_dev *accel_dev);
        u32 (*get_pf2vf_offset)(u32 i);
@@ -214,6 +221,7 @@ struct adf_hw_device_data {
        struct adf_pfvf_ops pfvf_ops;
        struct adf_hw_csr_ops csr_ops;
        struct adf_dc_ops dc_ops;
+       struct adf_ras_ops ras_ops;
        const char *fw_name;
        const char *fw_mmp_name;
        u32 fuses;
diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen4_ras.c b/drivers/crypto/intel/qat/qat_common/adf_gen4_ras.c
new file mode 100644 (file)
index 0000000..0bf243a
--- /dev/null
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2023 Intel Corporation */
+#include "adf_common_drv.h"
+#include "adf_gen4_ras.h"
+
+static void adf_gen4_enable_ras(struct adf_accel_dev *accel_dev)
+{
+}
+
+static void adf_gen4_disable_ras(struct adf_accel_dev *accel_dev)
+{
+}
+
+static bool adf_gen4_handle_interrupt(struct adf_accel_dev *accel_dev,
+                                     bool *reset_required)
+{
+       return false;
+}
+
+void adf_gen4_init_ras_ops(struct adf_ras_ops *ras_ops)
+{
+       ras_ops->enable_ras_errors = adf_gen4_enable_ras;
+       ras_ops->disable_ras_errors = adf_gen4_disable_ras;
+       ras_ops->handle_interrupt = adf_gen4_handle_interrupt;
+}
+EXPORT_SYMBOL_GPL(adf_gen4_init_ras_ops);
diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen4_ras.h b/drivers/crypto/intel/qat/qat_common/adf_gen4_ras.h
new file mode 100644 (file)
index 0000000..2765d35
--- /dev/null
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright(c) 2023 Intel Corporation */
+#ifndef ADF_GEN4_RAS_H_
+#define ADF_GEN4_RAS_H_
+
+struct adf_ras_ops;
+
+void adf_gen4_init_ras_ops(struct adf_ras_ops *ras_ops);
+
+#endif /* ADF_GEN4_RAS_H_ */
index bccd6bf..b3cf072 100644 (file)
@@ -116,6 +116,9 @@ static int adf_dev_init(struct adf_accel_dev *accel_dev)
        }
        set_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status);
 
+       if (hw_data->ras_ops.enable_ras_errors)
+               hw_data->ras_ops.enable_ras_errors(accel_dev);
+
        hw_data->enable_ints(accel_dev);
        hw_data->enable_error_correction(accel_dev);
 
@@ -350,6 +353,9 @@ static void adf_dev_shutdown(struct adf_accel_dev *accel_dev)
                        clear_bit(accel_dev->accel_id, service->init_status);
        }
 
+       if (hw_data->ras_ops.disable_ras_errors)
+               hw_data->ras_ops.disable_ras_errors(accel_dev);
+
        adf_heartbeat_shutdown(accel_dev);
 
        hw_data->disable_iov(accel_dev);
index 2aba194..3557a0d 100644 (file)
@@ -132,6 +132,21 @@ static bool adf_handle_pm_int(struct adf_accel_dev *accel_dev)
        return false;
 }
 
+static bool adf_handle_ras_int(struct adf_accel_dev *accel_dev)
+{
+       struct adf_ras_ops *ras_ops = &accel_dev->hw_device->ras_ops;
+       bool reset_required;
+
+       if (ras_ops->handle_interrupt &&
+           ras_ops->handle_interrupt(accel_dev, &reset_required)) {
+               if (reset_required)
+                       dev_err(&GET_DEV(accel_dev), "Fatal error, reset required\n");
+               return true;
+       }
+
+       return false;
+}
+
 static irqreturn_t adf_msix_isr_ae(int irq, void *dev_ptr)
 {
        struct adf_accel_dev *accel_dev = dev_ptr;
@@ -145,6 +160,9 @@ static irqreturn_t adf_msix_isr_ae(int irq, void *dev_ptr)
        if (adf_handle_pm_int(accel_dev))
                return IRQ_HANDLED;
 
+       if (adf_handle_ras_int(accel_dev))
+               return IRQ_HANDLED;
+
        dev_dbg(&GET_DEV(accel_dev), "qat_dev%d spurious AE interrupt\n",
                accel_dev->accel_id);