Commit 93b2f7de authored by Shashank Gupta's avatar Shashank Gupta Committed by Herbert Xu

crypto: qat - add infrastructure for error reporting

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: default avatarShashank Gupta <shashank.gupta@intel.com>
Reviewed-by: default avatarGiovanni Cabiddu <giovanni.cabiddu@intel.com>
Reviewed-by: default avatarTero Kristo <tero.kristo@linux.intel.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 33fc506d
......@@ -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)
......
......@@ -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 \
......
......@@ -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;
......
// 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);
/* 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_ */
......@@ -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);
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment