2014-06-05 13:42:39 -07:00
/*
This file is provided under a dual BSD / GPLv2 license . When using or
redistributing this file , you may do so under either license .
GPL LICENSE SUMMARY
Copyright ( c ) 2014 Intel Corporation .
This program is free software ; you can redistribute it and / or modify
it under the terms of version 2 of the GNU General Public License as
published by the Free Software Foundation .
This program is distributed in the hope that it will be useful , but
WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
General Public License for more details .
Contact Information :
qat - linux @ intel . com
BSD LICENSE
Copyright ( c ) 2014 Intel Corporation .
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions
are met :
* Redistributions of source code must retain the above copyright
notice , this list of conditions and the following disclaimer .
* Redistributions in binary form must reproduce the above copyright
notice , this list of conditions and the following disclaimer in
the documentation and / or other materials provided with the
distribution .
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
" AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT
LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
# ifndef ADF_ACCEL_DEVICES_H_
# define ADF_ACCEL_DEVICES_H_
2015-08-07 11:34:25 -07:00
# include <linux/interrupt.h>
2014-06-05 13:42:39 -07:00
# include <linux/module.h>
# include <linux/list.h>
2014-06-24 15:19:24 -07:00
# include <linux/io.h>
2015-08-07 11:34:25 -07:00
# include <linux/ratelimit.h>
2014-06-05 13:42:39 -07:00
# include "adf_cfg_common.h"
# define ADF_DH895XCC_DEVICE_NAME "dh895xcc"
2015-08-07 11:34:25 -07:00
# define ADF_DH895XCCVF_DEVICE_NAME "dh895xccvf"
2016-01-05 11:14:55 -08:00
# define ADF_C62X_DEVICE_NAME "c6xx"
# define ADF_C62XVF_DEVICE_NAME "c6xxvf"
2015-12-04 16:56:17 -08:00
# define ADF_C3XXX_DEVICE_NAME "c3xxx"
# define ADF_C3XXXVF_DEVICE_NAME "c3xxxvf"
2014-06-05 13:42:39 -07:00
# define ADF_DH895XCC_PCI_DEVICE_ID 0x435
2015-08-07 11:34:25 -07:00
# define ADF_DH895XCCIOV_PCI_DEVICE_ID 0x443
2015-12-04 16:56:17 -08:00
# define ADF_C62X_PCI_DEVICE_ID 0x37c8
# define ADF_C62XIOV_PCI_DEVICE_ID 0x37c9
# define ADF_C3XXX_PCI_DEVICE_ID 0x19e2
# define ADF_C3XXXIOV_PCI_DEVICE_ID 0x19e3
# define ADF_ERRSOU3 (0x3A000 + 0x0C)
# define ADF_ERRSOU5 (0x3A000 + 0xD8)
2015-12-04 16:56:28 -08:00
# define ADF_DEVICE_FUSECTL_OFFSET 0x40
# define ADF_DEVICE_LEGFUSE_OFFSET 0x4C
2014-06-05 13:42:39 -07:00
# define ADF_PCI_MAX_BARS 3
# define ADF_DEVICE_NAME_LENGTH 32
# define ADF_ETR_MAX_RINGS_PER_BANK 16
# define ADF_MAX_MSIX_VECTOR_NAME 16
# define ADF_DEVICE_NAME_PREFIX "qat_"
enum adf_accel_capabilities {
ADF_ACCEL_CAPABILITIES_NULL = 0 ,
ADF_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC = 1 ,
ADF_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC = 2 ,
ADF_ACCEL_CAPABILITIES_CIPHER = 4 ,
ADF_ACCEL_CAPABILITIES_AUTHENTICATION = 8 ,
ADF_ACCEL_CAPABILITIES_COMPRESSION = 32 ,
ADF_ACCEL_CAPABILITIES_LZS_COMPRESSION = 64 ,
ADF_ACCEL_CAPABILITIES_RANDOM_NUMBER = 128
} ;
struct adf_bar {
resource_size_t base_addr ;
void __iomem * virt_addr ;
resource_size_t size ;
} __packed ;
struct adf_accel_msix {
struct msix_entry * entries ;
char * * names ;
2015-08-07 11:34:25 -07:00
u32 num_entries ;
2014-06-05 13:42:39 -07:00
} __packed ;
struct adf_accel_pci {
struct pci_dev * pci_dev ;
struct adf_accel_msix msix_entries ;
struct adf_bar pci_bars [ ADF_PCI_MAX_BARS ] ;
uint8_t revid ;
uint8_t sku ;
} __packed ;
enum dev_state {
DEV_DOWN = 0 ,
DEV_UP
} ;
enum dev_sku_info {
DEV_SKU_1 = 0 ,
DEV_SKU_2 ,
DEV_SKU_3 ,
DEV_SKU_4 ,
2015-08-07 11:34:25 -07:00
DEV_SKU_VF ,
2014-06-05 13:42:39 -07:00
DEV_SKU_UNKNOWN ,
} ;
static inline const char * get_sku_info ( enum dev_sku_info info )
{
switch ( info ) {
case DEV_SKU_1 :
return " SKU1 " ;
case DEV_SKU_2 :
return " SKU2 " ;
case DEV_SKU_3 :
return " SKU3 " ;
case DEV_SKU_4 :
return " SKU4 " ;
2015-08-07 11:34:25 -07:00
case DEV_SKU_VF :
return " SKUVF " ;
2014-06-05 13:42:39 -07:00
case DEV_SKU_UNKNOWN :
default :
break ;
}
return " Unknown SKU " ;
}
struct adf_hw_device_class {
const char * name ;
const enum adf_device_type type ;
uint32_t instances ;
} __packed ;
struct adf_cfg_device_data ;
struct adf_accel_dev ;
struct adf_etr_data ;
struct adf_etr_ring_data ;
struct adf_hw_device_data {
struct adf_hw_device_class * dev_class ;
uint32_t ( * get_accel_mask ) ( uint32_t fuse ) ;
uint32_t ( * get_ae_mask ) ( uint32_t fuse ) ;
2015-07-15 15:28:26 -07:00
uint32_t ( * get_sram_bar_id ) ( struct adf_hw_device_data * self ) ;
2014-06-05 13:42:39 -07:00
uint32_t ( * get_misc_bar_id ) ( struct adf_hw_device_data * self ) ;
uint32_t ( * get_etr_bar_id ) ( struct adf_hw_device_data * self ) ;
uint32_t ( * get_num_aes ) ( struct adf_hw_device_data * self ) ;
uint32_t ( * get_num_accels ) ( struct adf_hw_device_data * self ) ;
2015-08-07 11:34:25 -07:00
uint32_t ( * get_pf2vf_offset ) ( uint32_t i ) ;
uint32_t ( * get_vintmsk_offset ) ( uint32_t i ) ;
2014-06-05 13:42:39 -07:00
enum dev_sku_info ( * get_sku ) ( struct adf_hw_device_data * self ) ;
int ( * alloc_irq ) ( struct adf_accel_dev * accel_dev ) ;
void ( * free_irq ) ( struct adf_accel_dev * accel_dev ) ;
void ( * enable_error_correction ) ( struct adf_accel_dev * 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
int ( * init_admin_comms ) ( struct adf_accel_dev * accel_dev ) ;
void ( * exit_admin_comms ) ( struct adf_accel_dev * accel_dev ) ;
2015-08-07 11:34:20 -07:00
int ( * send_admin_init ) ( struct adf_accel_dev * 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
int ( * init_arb ) ( struct adf_accel_dev * accel_dev ) ;
void ( * exit_arb ) ( struct adf_accel_dev * accel_dev ) ;
2015-08-07 11:34:20 -07:00
void ( * get_arb_mapping ) ( struct adf_accel_dev * accel_dev ,
const uint32_t * * cfg ) ;
2015-08-07 11:34:25 -07:00
void ( * disable_iov ) ( struct adf_accel_dev * 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
void ( * enable_ints ) ( struct adf_accel_dev * accel_dev ) ;
2015-08-07 11:34:25 -07:00
int ( * enable_vf2pf_comms ) ( struct adf_accel_dev * accel_dev ) ;
2016-07-04 16:26:00 +01:00
void ( * reset_device ) ( struct adf_accel_dev * accel_dev ) ;
2014-06-05 13:42:39 -07:00
const char * fw_name ;
2015-07-15 15:28:32 -07:00
const char * fw_mmp_name ;
2014-06-05 13:42:39 -07:00
uint32_t fuses ;
uint32_t accel_capabilities_mask ;
2015-12-04 16:56:28 -08:00
uint32_t instance_id ;
2014-06-05 13:42:39 -07:00
uint16_t accel_mask ;
uint16_t ae_mask ;
uint16_t tx_rings_mask ;
uint8_t tx_rx_gap ;
uint8_t num_banks ;
uint8_t num_accel ;
uint8_t num_logical_accel ;
uint8_t num_engines ;
2015-08-07 11:34:25 -07:00
uint8_t min_iov_compat_ver ;
2014-06-05 13:42:39 -07:00
} __packed ;
/* CSR write macro */
# define ADF_CSR_WR(csr_base, csr_offset, val) \
__raw_writel ( val , csr_base + csr_offset )
/* CSR read macro */
# define ADF_CSR_RD(csr_base, csr_offset) __raw_readl(csr_base + csr_offset)
# define GET_DEV(accel_dev) ((accel_dev)->accel_pci_dev.pci_dev->dev)
# define GET_BARS(accel_dev) ((accel_dev)->accel_pci_dev.pci_bars)
# define GET_HW_DATA(accel_dev) (accel_dev->hw_device)
# define GET_MAX_BANKS(accel_dev) (GET_HW_DATA(accel_dev)->num_banks)
# define GET_MAX_ACCELENGINES(accel_dev) (GET_HW_DATA(accel_dev)->num_engines)
# define accel_to_pci_dev(accel_ptr) accel_ptr->accel_pci_dev.pci_dev
struct adf_admin_comms ;
struct icp_qat_fw_loader_handle ;
struct adf_fw_loader_data {
struct icp_qat_fw_loader_handle * fw_loader ;
const struct firmware * uof_fw ;
2015-07-15 15:28:32 -07:00
const struct firmware * mmp_fw ;
2014-06-05 13:42:39 -07:00
} ;
2015-08-07 11:34:25 -07:00
struct adf_accel_vf_info {
struct adf_accel_dev * accel_dev ;
struct tasklet_struct vf2pf_bh_tasklet ;
struct mutex pf2vf_lock ; /* protect CSR access for PF2VF messages */
struct ratelimit_state vf2pf_ratelimit ;
u32 vf_nr ;
bool init ;
} ;
2014-06-05 13:42:39 -07:00
struct adf_accel_dev {
struct adf_etr_data * transport ;
struct adf_hw_device_data * hw_device ;
struct adf_cfg_device_data * cfg ;
struct adf_fw_loader_data * fw_loader ;
struct adf_admin_comms * admin ;
struct list_head crypto_list ;
unsigned long status ;
atomic_t ref_count ;
struct dentry * debugfs_dir ;
struct list_head list ;
struct module * owner ;
struct adf_accel_pci accel_pci_dev ;
2015-08-07 11:34:25 -07:00
union {
struct {
/* vf_info is non-zero when SR-IOV is init'ed */
struct adf_accel_vf_info * vf_info ;
} pf ;
struct {
char * irq_name ;
struct tasklet_struct pf2vf_bh_tasklet ;
struct mutex vf2pf_lock ; /* protect CSR access */
struct completion iov_msg_completion ;
uint8_t compatible ;
uint8_t pf_version ;
} vf ;
} ;
bool is_vf ;
2015-12-10 14:23:03 -08:00
u32 accel_id ;
2014-06-05 13:42:39 -07:00
} __packed ;
# endif