2020-05-27 16:21:28 +01:00
// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
/* Copyright(c) 2014 - 2020 Intel Corporation */
2014-06-05 13:42:39 -07:00
# include <linux/mutex.h>
# include <linux/list.h>
# include <linux/bitops.h>
# include <linux/delay.h>
# include "adf_accel_devices.h"
# include "adf_cfg.h"
# include "adf_common_drv.h"
static LIST_HEAD ( service_table ) ;
static DEFINE_MUTEX ( service_lock ) ;
static void adf_service_add ( struct service_hndl * service )
{
mutex_lock ( & service_lock ) ;
list_add ( & service - > list , & service_table ) ;
mutex_unlock ( & service_lock ) ;
}
int adf_service_register ( struct service_hndl * service )
{
2016-12-22 15:01:02 +00:00
memset ( service - > init_status , 0 , sizeof ( service - > init_status ) ) ;
memset ( service - > start_status , 0 , sizeof ( service - > start_status ) ) ;
2014-06-05 13:42:39 -07:00
adf_service_add ( service ) ;
return 0 ;
}
static void adf_service_remove ( struct service_hndl * service )
{
mutex_lock ( & service_lock ) ;
list_del ( & service - > list ) ;
mutex_unlock ( & service_lock ) ;
}
int adf_service_unregister ( struct service_hndl * service )
{
2016-12-22 15:01:02 +00:00
int i ;
for ( i = 0 ; i < ARRAY_SIZE ( service - > init_status ) ; i + + ) {
if ( service - > init_status [ i ] | | service - > start_status [ i ] ) {
pr_err ( " QAT: Could not remove active service \n " ) ;
return - EFAULT ;
}
2014-06-05 13:42:39 -07:00
}
adf_service_remove ( service ) ;
return 0 ;
}
/**
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
* adf_dev_init ( ) - Init data structures and services for the given accel device
* @ accel_dev : Pointer to acceleration device .
2014-06-05 13:42:39 -07:00
*
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
* Initialize the ring data structures and the admin comms and arbitration
* services .
2014-06-05 13:42:39 -07:00
*
2015-07-24 13:18:26 -07:00
* Return : 0 on success , error code otherwise .
2014-06-05 13:42:39 -07:00
*/
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
int adf_dev_init ( struct adf_accel_dev * accel_dev )
2014-06-05 13:42:39 -07:00
{
struct service_hndl * service ;
struct list_head * list_itr ;
struct adf_hw_device_data * hw_data = accel_dev - > hw_device ;
2021-08-12 21:21:13 +01:00
int ret ;
2014-06-05 13:42:39 -07:00
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
if ( ! hw_data ) {
dev_err ( & GET_DEV ( accel_dev ) ,
2015-03-19 16:03:44 -07:00
" Failed to init device - hw_data not set \n " ) ;
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
return - EFAULT ;
}
2021-12-16 09:13:30 +00:00
if ( ! test_bit ( ADF_STATUS_CONFIGURED , & accel_dev - > status ) & &
! accel_dev - > is_vf ) {
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) , " Device not configured \n " ) ;
2014-06-05 13:42:39 -07:00
return - EFAULT ;
}
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
if ( adf_init_etr_data ( accel_dev ) ) {
dev_err ( & GET_DEV ( accel_dev ) , " Failed initialize etr \n " ) ;
return - EFAULT ;
}
2021-09-16 15:45:41 +01:00
if ( hw_data - > init_device & & hw_data - > init_device ( accel_dev ) ) {
dev_err ( & GET_DEV ( accel_dev ) , " Failed to initialize device \n " ) ;
return - EFAULT ;
}
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
if ( hw_data - > init_admin_comms & & hw_data - > init_admin_comms ( accel_dev ) ) {
dev_err ( & GET_DEV ( accel_dev ) , " Failed initialize admin comms \n " ) ;
return - EFAULT ;
}
if ( hw_data - > init_arb & & hw_data - > init_arb ( accel_dev ) ) {
dev_err ( & GET_DEV ( accel_dev ) , " Failed initialize hw arbiter \n " ) ;
return - EFAULT ;
}
2014-06-05 13:42:39 -07:00
if ( adf_ae_init ( accel_dev ) ) {
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) ,
" Failed to initialise Acceleration Engine \n " ) ;
2014-06-05 13:42:39 -07:00
return - EFAULT ;
}
set_bit ( ADF_STATUS_AE_INITIALISED , & accel_dev - > status ) ;
if ( adf_ae_fw_load ( accel_dev ) ) {
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) ,
" Failed to load acceleration FW \n " ) ;
2014-06-05 13:42:39 -07:00
return - EFAULT ;
}
set_bit ( ADF_STATUS_AE_UCODE_LOADED , & accel_dev - > status ) ;
if ( hw_data - > alloc_irq ( accel_dev ) ) {
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) , " Failed to allocate interrupts \n " ) ;
2014-06-05 13:42:39 -07:00
return - EFAULT ;
}
set_bit ( ADF_STATUS_IRQ_ALLOCATED , & accel_dev - > status ) ;
2021-08-12 21:21:12 +01:00
hw_data - > enable_ints ( accel_dev ) ;
2021-08-12 21:21:24 +01:00
hw_data - > enable_error_correction ( accel_dev ) ;
2021-11-17 14:30:47 +00:00
ret = hw_data - > pfvf_ops . enable_comms ( accel_dev ) ;
2021-08-12 21:21:24 +01:00
if ( ret )
return ret ;
2021-08-12 21:21:12 +01:00
2021-12-16 09:13:30 +00:00
if ( ! test_bit ( ADF_STATUS_CONFIGURED , & accel_dev - > status ) & &
accel_dev - > is_vf ) {
if ( qat_crypto_vf_dev_config ( accel_dev ) )
return - EFAULT ;
}
2014-06-05 13:42:39 -07:00
/*
* Subservice initialisation is divided into two stages : init and start .
* This is to facilitate any ordering dependencies between services
* prior to starting any of the accelerators .
*/
list_for_each ( list_itr , & service_table ) {
service = list_entry ( list_itr , struct service_hndl , list ) ;
if ( service - > event_hld ( accel_dev , ADF_EVENT_INIT ) ) {
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) ,
" Failed to initialise service %s \n " ,
service - > name ) ;
2014-06-05 13:42:39 -07:00
return - EFAULT ;
}
2016-12-22 15:01:02 +00:00
set_bit ( accel_dev - > accel_id , service - > init_status ) ;
2014-06-05 13:42:39 -07:00
}
2021-08-12 21:21:24 +01:00
return 0 ;
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
}
EXPORT_SYMBOL_GPL ( adf_dev_init ) ;
/**
* adf_dev_start ( ) - Start acceleration service for the given accel device
* @ accel_dev : Pointer to acceleration device .
*
* Function notifies all the registered services that the acceleration device
* is ready to be used .
* To be used by QAT device specific drivers .
*
2015-07-24 13:18:26 -07:00
* Return : 0 on success , error code otherwise .
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
*/
int adf_dev_start ( struct adf_accel_dev * accel_dev )
{
2015-08-07 11:34:20 -07:00
struct adf_hw_device_data * hw_data = accel_dev - > hw_device ;
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
struct service_hndl * service ;
struct list_head * list_itr ;
set_bit ( ADF_STATUS_STARTING , & accel_dev - > status ) ;
2014-06-05 13:42:39 -07:00
if ( adf_ae_start ( accel_dev ) ) {
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) , " AE Start Failed \n " ) ;
2014-06-05 13:42:39 -07:00
return - EFAULT ;
}
set_bit ( ADF_STATUS_AE_STARTED , & accel_dev - > status ) ;
2015-08-07 11:34:20 -07:00
if ( hw_data - > send_admin_init ( accel_dev ) ) {
dev_err ( & GET_DEV ( accel_dev ) , " Failed to send init message \n " ) ;
return - EFAULT ;
2014-06-05 13:42:39 -07:00
}
2015-08-07 11:34:20 -07:00
2021-04-09 14:56:19 +01:00
/* Set ssm watch dog timer */
if ( hw_data - > set_ssm_wdtimer )
hw_data - > set_ssm_wdtimer ( accel_dev ) ;
2022-02-10 13:38:27 +00:00
/* Enable Power Management */
if ( hw_data - > enable_pm & & hw_data - > enable_pm ( accel_dev ) ) {
dev_err ( & GET_DEV ( accel_dev ) , " Failed to configure Power Management \n " ) ;
return - EFAULT ;
}
2014-06-05 13:42:39 -07:00
list_for_each ( list_itr , & service_table ) {
service = list_entry ( list_itr , struct service_hndl , list ) ;
if ( service - > event_hld ( accel_dev , ADF_EVENT_START ) ) {
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) ,
" Failed to start service %s \n " ,
service - > name ) ;
2014-06-05 13:42:39 -07:00
return - EFAULT ;
}
2016-12-22 15:01:02 +00:00
set_bit ( accel_dev - > accel_id , service - > start_status ) ;
2014-06-05 13:42:39 -07:00
}
clear_bit ( ADF_STATUS_STARTING , & accel_dev - > status ) ;
set_bit ( ADF_STATUS_STARTED , & accel_dev - > status ) ;
2015-08-07 11:34:25 -07:00
if ( ! list_empty ( & accel_dev - > crypto_list ) & &
( qat_algs_register ( ) | | qat_asym_algs_register ( ) ) ) {
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) ,
" Failed to register crypto algs \n " ) ;
2014-06-05 13:42:39 -07:00
set_bit ( ADF_STATUS_STARTING , & accel_dev - > status ) ;
clear_bit ( ADF_STATUS_STARTED , & accel_dev - > status ) ;
return - EFAULT ;
}
return 0 ;
}
EXPORT_SYMBOL_GPL ( adf_dev_start ) ;
/**
* adf_dev_stop ( ) - Stop acceleration service for the given accel device
* @ accel_dev : Pointer to acceleration device .
*
* Function notifies all the registered services that the acceleration device
* is shuting down .
* To be used by QAT device specific drivers .
*
2016-03-29 10:21:07 -07:00
* Return : void
2014-06-05 13:42:39 -07:00
*/
2016-03-29 10:21:07 -07:00
void adf_dev_stop ( struct adf_accel_dev * accel_dev )
2014-06-05 13:42:39 -07:00
{
struct service_hndl * service ;
struct list_head * list_itr ;
2015-01-09 11:55:04 -08:00
bool wait = false ;
int ret ;
2014-06-05 13:42:39 -07:00
if ( ! adf_dev_started ( accel_dev ) & &
2016-03-29 10:21:07 -07:00
! test_bit ( ADF_STATUS_STARTING , & accel_dev - > status ) )
return ;
2014-06-05 13:42:39 -07:00
clear_bit ( ADF_STATUS_STARTING , & accel_dev - > status ) ;
clear_bit ( ADF_STATUS_STARTED , & accel_dev - > status ) ;
2015-09-22 11:57:47 -07:00
if ( ! list_empty ( & accel_dev - > crypto_list ) ) {
qat_algs_unregister ( ) ;
2015-08-07 11:34:25 -07:00
qat_asym_algs_unregister ( ) ;
2015-09-22 11:57:47 -07:00
}
2015-07-15 15:28:38 -07:00
2014-06-05 13:42:39 -07:00
list_for_each ( list_itr , & service_table ) {
service = list_entry ( list_itr , struct service_hndl , list ) ;
2016-12-22 15:01:02 +00:00
if ( ! test_bit ( accel_dev - > accel_id , service - > start_status ) )
2014-06-05 13:42:39 -07:00
continue ;
ret = service - > event_hld ( accel_dev , ADF_EVENT_STOP ) ;
if ( ! ret ) {
2016-12-22 15:01:02 +00:00
clear_bit ( accel_dev - > accel_id , service - > start_status ) ;
2014-06-05 13:42:39 -07:00
} else if ( ret = = - EAGAIN ) {
2015-01-09 11:55:04 -08:00
wait = true ;
2016-12-22 15:01:02 +00:00
clear_bit ( accel_dev - > accel_id , service - > start_status ) ;
2014-06-05 13:42:39 -07:00
}
}
if ( wait )
msleep ( 100 ) ;
2015-01-09 11:55:09 -08:00
if ( test_bit ( ADF_STATUS_AE_STARTED , & accel_dev - > status ) ) {
2014-06-05 13:42:39 -07:00
if ( adf_ae_stop ( accel_dev ) )
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) , " failed to stop AE \n " ) ;
2014-06-05 13:42:39 -07:00
else
clear_bit ( ADF_STATUS_AE_STARTED , & accel_dev - > status ) ;
}
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
}
EXPORT_SYMBOL_GPL ( adf_dev_stop ) ;
/**
* adf_dev_shutdown ( ) - shutdown acceleration services and data strucutures
* @ accel_dev : Pointer to acceleration device
*
* Cleanup the ring data structures and the admin comms and arbitration
* services .
*/
void adf_dev_shutdown ( struct adf_accel_dev * accel_dev )
{
struct adf_hw_device_data * hw_data = accel_dev - > hw_device ;
struct service_hndl * service ;
struct list_head * list_itr ;
if ( ! hw_data ) {
dev_err ( & GET_DEV ( accel_dev ) ,
" QAT: Failed to shutdown device - hw_data not set \n " ) ;
return ;
}
2014-06-05 13:42:39 -07:00
if ( test_bit ( ADF_STATUS_AE_UCODE_LOADED , & accel_dev - > status ) ) {
2015-04-03 08:41:17 -07:00
adf_ae_fw_release ( accel_dev ) ;
clear_bit ( ADF_STATUS_AE_UCODE_LOADED , & accel_dev - > status ) ;
2014-06-05 13:42:39 -07:00
}
if ( test_bit ( ADF_STATUS_AE_INITIALISED , & accel_dev - > status ) ) {
if ( adf_ae_shutdown ( accel_dev ) )
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) ,
" Failed to shutdown Accel Engine \n " ) ;
2014-06-05 13:42:39 -07:00
else
clear_bit ( ADF_STATUS_AE_INITIALISED ,
& accel_dev - > status ) ;
}
list_for_each ( list_itr , & service_table ) {
service = list_entry ( list_itr , struct service_hndl , list ) ;
2016-12-22 15:01:02 +00:00
if ( ! test_bit ( accel_dev - > accel_id , service - > init_status ) )
2014-06-05 13:42:39 -07:00
continue ;
if ( service - > event_hld ( accel_dev , ADF_EVENT_SHUTDOWN ) )
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) ,
" Failed to shutdown service %s \n " ,
service - > name ) ;
2014-06-05 13:42:39 -07:00
else
2016-12-22 15:01:02 +00:00
clear_bit ( accel_dev - > accel_id , service - > init_status ) ;
2014-06-05 13:42:39 -07:00
}
2016-04-15 10:38:00 -07:00
hw_data - > disable_iov ( accel_dev ) ;
2014-06-05 13:42:39 -07:00
if ( test_bit ( ADF_STATUS_IRQ_ALLOCATED , & accel_dev - > status ) ) {
hw_data - > free_irq ( accel_dev ) ;
clear_bit ( ADF_STATUS_IRQ_ALLOCATED , & accel_dev - > status ) ;
}
/* Delete configuration only if not restarting */
if ( ! test_bit ( ADF_STATUS_RESTARTING , & accel_dev - > status ) )
adf_cfg_del_all ( accel_dev ) ;
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
if ( hw_data - > exit_arb )
hw_data - > exit_arb ( accel_dev ) ;
if ( hw_data - > exit_admin_comms )
hw_data - > exit_admin_comms ( accel_dev ) ;
adf_cleanup_etr_data ( accel_dev ) ;
2015-12-04 16:56:28 -08:00
adf_dev_restore ( accel_dev ) ;
2014-06-05 13:42:39 -07:00
}
crypto: qat - fix device reset flow
When the device needs a reset, e.g. when an uncorrectable PCIe AER event
occurs, various services/data structures need to be cleaned up, the
hardware reset and the services/data structures initialized and started.
The code to perform the cleanup and initialization was not performed when
a device reset was done.
This patch moves some of the initialization code out of the .probe entry-
point into a separate function that is now called during probe as well as
after the hardware has been reset. Similarly, a new function is added for
first cleaning up these services/data structures prior to resetting. The
new functions are adf_dev_init() and adf_dev_shutdown(), respectively, for
which there are already prototypes but no actual functions just yet and are
now called when the device is reset and during probe/cleanup of the driver.
The down and up flows via ioctl calls has similarly been updated.
In addition, there are two other bugs in the reset flow - one in the logic
for determining whether to schedule a device reset upon receiving an
uncorrectable AER event which prevents the reset flow from being initiated,
and another with clearing the status bit indicating a device is configured
(when resetting the device the configuration remains across the reset so
the bit should not be cleared, otherwise, the necessary services will not
be re-started in adf_dev_start() after the reset - clear the bit only when
actually deleting the configuration).
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-01-09 11:54:58 -08:00
EXPORT_SYMBOL_GPL ( adf_dev_shutdown ) ;
2014-06-05 13:42:39 -07:00
int adf_dev_restarting_notify ( struct adf_accel_dev * accel_dev )
{
struct service_hndl * service ;
struct list_head * list_itr ;
list_for_each ( list_itr , & service_table ) {
service = list_entry ( list_itr , struct service_hndl , list ) ;
if ( service - > event_hld ( accel_dev , ADF_EVENT_RESTARTING ) )
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) ,
" Failed to restart service %s. \n " ,
service - > name ) ;
2014-06-05 13:42:39 -07:00
}
return 0 ;
}
int adf_dev_restarted_notify ( struct adf_accel_dev * accel_dev )
{
struct service_hndl * service ;
struct list_head * list_itr ;
list_for_each ( list_itr , & service_table ) {
service = list_entry ( list_itr , struct service_hndl , list ) ;
if ( service - > event_hld ( accel_dev , ADF_EVENT_RESTARTED ) )
2015-03-19 16:03:44 -07:00
dev_err ( & GET_DEV ( accel_dev ) ,
" Failed to restart service %s. \n " ,
service - > name ) ;
2014-06-05 13:42:39 -07:00
}
return 0 ;
}
2022-06-27 09:36:51 +01:00
int adf_dev_shutdown_cache_cfg ( struct adf_accel_dev * accel_dev )
{
char services [ ADF_CFG_MAX_VAL_LEN_IN_BYTES ] = { 0 } ;
int ret ;
ret = adf_cfg_get_param_value ( accel_dev , ADF_GENERAL_SEC ,
ADF_SERVICES_ENABLED , services ) ;
adf_dev_stop ( accel_dev ) ;
adf_dev_shutdown ( accel_dev ) ;
if ( ! ret ) {
ret = adf_cfg_section_add ( accel_dev , ADF_GENERAL_SEC ) ;
if ( ret )
return ret ;
ret = adf_cfg_add_key_value_param ( accel_dev , ADF_GENERAL_SEC ,
ADF_SERVICES_ENABLED ,
services , ADF_STR ) ;
if ( ret )
return ret ;
}
return 0 ;
}