aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTadeusz Struk <tadeusz.struk@intel.com>2014-06-05 16:42:39 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2014-06-20 09:26:15 -0400
commitd8cba25d2c68992a6e7c1d329b690a9ebe01167d (patch)
treeaf71c6b9fc92678d4ab6cf60cfd46b1bda99b5aa
parentc4f4b325e9c885b11901174158d5e1ff4b19a189 (diff)
crypto: qat - Intel(R) QAT driver framework
This patch adds a common infractructure that will be used by all Intel(R) QuickAssist Technology (QAT) devices. v2 - added ./drivers/crypto/qat/Kconfig and ./drivers/crypto/qat/Makefile v4 - splits common part into more, smaller patches Acked-by: John Griffin <john.griffin@intel.com> Reviewed-by: Bruce W. Allan <bruce.w.allan@intel.com> Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--drivers/crypto/qat/Kconfig22
-rw-r--r--drivers/crypto/qat/Makefile2
-rw-r--r--drivers/crypto/qat/qat_common/Makefile14
-rw-r--r--drivers/crypto/qat/qat_common/adf_accel_devices.h204
-rw-r--r--drivers/crypto/qat/qat_common/adf_accel_engine.c168
-rw-r--r--drivers/crypto/qat/qat_common/adf_aer.c258
-rw-r--r--drivers/crypto/qat/qat_common/adf_cfg.c359
-rw-r--r--drivers/crypto/qat/qat_common/adf_cfg.h87
-rw-r--r--drivers/crypto/qat/qat_common/adf_cfg_common.h100
-rw-r--r--drivers/crypto/qat/qat_common/adf_cfg_strings.h83
-rw-r--r--drivers/crypto/qat/qat_common/adf_cfg_user.h94
-rw-r--r--drivers/crypto/qat/qat_common/adf_common_drv.h192
-rw-r--r--drivers/crypto/qat/qat_common/adf_ctl_drv.c490
-rw-r--r--drivers/crypto/qat/qat_common/adf_dev_mgr.c215
-rw-r--r--drivers/crypto/qat/qat_common/adf_init.c388
15 files changed, 2676 insertions, 0 deletions
diff --git a/drivers/crypto/qat/Kconfig b/drivers/crypto/qat/Kconfig
new file mode 100644
index 000000000000..3bd3fd968de1
--- /dev/null
+++ b/drivers/crypto/qat/Kconfig
@@ -0,0 +1,22 @@
1config CRYPTO_DEV_QAT
2 tristate
3 select CRYPTO_AEAD
4 select CRYPTO_AUTHENC
5 select CRYPTO_ALGAPI
6 select CRYPTO_AES
7 select CRYPTO_CBC
8 select CRYPTO_SHA1
9 select CRYPTO_SHA256
10 select CRYPTO_SHA512
11
12config CRYPTO_DEV_QAT_DH895xCC
13 tristate "Support for Intel(R) DH895xCC"
14 depends on X86 && PCI
15 default n
16 select CRYPTO_DEV_QAT
17 help
18 Support for Intel(R) DH895xcc with Intel(R) QuickAssist Technology
19 for accelerating crypto and compression workloads.
20
21 To compile this as a module, choose M here: the module
22 will be called qat_dh895xcc.
diff --git a/drivers/crypto/qat/Makefile b/drivers/crypto/qat/Makefile
new file mode 100644
index 000000000000..d11481be225e
--- /dev/null
+++ b/drivers/crypto/qat/Makefile
@@ -0,0 +1,2 @@
1obj-$(CONFIG_CRYPTO_DEV_QAT) += qat_common/
2obj-$(CONFIG_CRYPTO_DEV_QAT_DH895xCC) += qat_dh895xcc/
diff --git a/drivers/crypto/qat/qat_common/Makefile b/drivers/crypto/qat/qat_common/Makefile
new file mode 100644
index 000000000000..e0424dc382fe
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/Makefile
@@ -0,0 +1,14 @@
1obj-$(CONFIG_CRYPTO_DEV_QAT) += intel_qat.o
2intel_qat-objs := adf_cfg.o \
3 adf_ctl_drv.o \
4 adf_dev_mgr.o \
5 adf_init.o \
6 adf_accel_engine.o \
7 adf_aer.o \
8 adf_transport.o \
9 qat_crypto.o \
10 qat_algs.o \
11 qat_uclo.o \
12 qat_hal.o
13
14intel_qat-$(CONFIG_DEBUG_FS) += adf_transport_debug.o
diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h
new file mode 100644
index 000000000000..f3206d9a41ab
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
@@ -0,0 +1,204 @@
1/*
2 This file is provided under a dual BSD/GPLv2 license. When using or
3 redistributing this file, you may do so under either license.
4
5 GPL LICENSE SUMMARY
6 Copyright(c) 2014 Intel Corporation.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as
9 published by the Free Software Foundation.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 Contact Information:
17 qat-linux@intel.com
18
19 BSD LICENSE
20 Copyright(c) 2014 Intel Corporation.
21 Redistribution and use in source and binary forms, with or without
22 modification, are permitted provided that the following conditions
23 are met:
24
25 * Redistributions of source code must retain the above copyright
26 notice, this list of conditions and the following disclaimer.
27 * Redistributions in binary form must reproduce the above copyright
28 notice, this list of conditions and the following disclaimer in
29 the documentation and/or other materials provided with the
30 distribution.
31 * Neither the name of Intel Corporation nor the names of its
32 contributors may be used to endorse or promote products derived
33 from this software without specific prior written permission.
34
35 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46*/
47#ifndef ADF_ACCEL_DEVICES_H_
48#define ADF_ACCEL_DEVICES_H_
49#include <linux/module.h>
50#include <linux/atomic.h>
51#include <linux/list.h>
52#include <linux/proc_fs.h>
53#include "adf_cfg_common.h"
54
55#define PCI_VENDOR_ID_INTEL 0x8086
56#define ADF_DH895XCC_DEVICE_NAME "dh895xcc"
57#define ADF_DH895XCC_PCI_DEVICE_ID 0x435
58#define ADF_DH895XCC_PMISC_BAR 1
59#define ADF_DH895XCC_ETR_BAR 2
60#define ADF_PCI_MAX_BARS 3
61#define ADF_DEVICE_NAME_LENGTH 32
62#define ADF_ETR_MAX_RINGS_PER_BANK 16
63#define ADF_MAX_MSIX_VECTOR_NAME 16
64#define ADF_DEVICE_NAME_PREFIX "qat_"
65
66enum adf_accel_capabilities {
67 ADF_ACCEL_CAPABILITIES_NULL = 0,
68 ADF_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC = 1,
69 ADF_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC = 2,
70 ADF_ACCEL_CAPABILITIES_CIPHER = 4,
71 ADF_ACCEL_CAPABILITIES_AUTHENTICATION = 8,
72 ADF_ACCEL_CAPABILITIES_COMPRESSION = 32,
73 ADF_ACCEL_CAPABILITIES_LZS_COMPRESSION = 64,
74 ADF_ACCEL_CAPABILITIES_RANDOM_NUMBER = 128
75};
76
77struct adf_bar {
78 resource_size_t base_addr;
79 void __iomem *virt_addr;
80 resource_size_t size;
81} __packed;
82
83struct adf_accel_msix {
84 struct msix_entry *entries;
85 char **names;
86} __packed;
87
88struct adf_accel_pci {
89 struct pci_dev *pci_dev;
90 struct adf_accel_msix msix_entries;
91 struct adf_bar pci_bars[ADF_PCI_MAX_BARS];
92 uint8_t revid;
93 uint8_t sku;
94} __packed;
95
96enum dev_state {
97 DEV_DOWN = 0,
98 DEV_UP
99};
100
101enum dev_sku_info {
102 DEV_SKU_1 = 0,
103 DEV_SKU_2,
104 DEV_SKU_3,
105 DEV_SKU_4,
106 DEV_SKU_UNKNOWN,
107};
108
109static inline const char *get_sku_info(enum dev_sku_info info)
110{
111 switch (info) {
112 case DEV_SKU_1:
113 return "SKU1";
114 case DEV_SKU_2:
115 return "SKU2";
116 case DEV_SKU_3:
117 return "SKU3";
118 case DEV_SKU_4:
119 return "SKU4";
120 case DEV_SKU_UNKNOWN:
121 default:
122 break;
123 }
124 return "Unknown SKU";
125}
126
127struct adf_hw_device_class {
128 const char *name;
129 const enum adf_device_type type;
130 uint32_t instances;
131} __packed;
132
133struct adf_cfg_device_data;
134struct adf_accel_dev;
135struct adf_etr_data;
136struct adf_etr_ring_data;
137
138struct adf_hw_device_data {
139 struct adf_hw_device_class *dev_class;
140 uint32_t (*get_accel_mask)(uint32_t fuse);
141 uint32_t (*get_ae_mask)(uint32_t fuse);
142 uint32_t (*get_misc_bar_id)(struct adf_hw_device_data *self);
143 uint32_t (*get_etr_bar_id)(struct adf_hw_device_data *self);
144 uint32_t (*get_num_aes)(struct adf_hw_device_data *self);
145 uint32_t (*get_num_accels)(struct adf_hw_device_data *self);
146 enum dev_sku_info (*get_sku)(struct adf_hw_device_data *self);
147 void (*hw_arb_ring_enable)(struct adf_etr_ring_data *ring);
148 void (*hw_arb_ring_disable)(struct adf_etr_ring_data *ring);
149 int (*alloc_irq)(struct adf_accel_dev *accel_dev);
150 void (*free_irq)(struct adf_accel_dev *accel_dev);
151 void (*enable_error_correction)(struct adf_accel_dev *accel_dev);
152 const char *fw_name;
153 uint32_t pci_dev_id;
154 uint32_t fuses;
155 uint32_t accel_capabilities_mask;
156 uint16_t accel_mask;
157 uint16_t ae_mask;
158 uint16_t tx_rings_mask;
159 uint8_t tx_rx_gap;
160 uint8_t instance_id;
161 uint8_t num_banks;
162 uint8_t num_accel;
163 uint8_t num_logical_accel;
164 uint8_t num_engines;
165} __packed;
166
167/* CSR write macro */
168#define ADF_CSR_WR(csr_base, csr_offset, val) \
169 __raw_writel(val, csr_base + csr_offset)
170
171/* CSR read macro */
172#define ADF_CSR_RD(csr_base, csr_offset) __raw_readl(csr_base + csr_offset)
173
174#define GET_DEV(accel_dev) ((accel_dev)->accel_pci_dev.pci_dev->dev)
175#define GET_BARS(accel_dev) ((accel_dev)->accel_pci_dev.pci_bars)
176#define GET_HW_DATA(accel_dev) (accel_dev->hw_device)
177#define GET_MAX_BANKS(accel_dev) (GET_HW_DATA(accel_dev)->num_banks)
178#define GET_MAX_ACCELENGINES(accel_dev) (GET_HW_DATA(accel_dev)->num_engines)
179#define accel_to_pci_dev(accel_ptr) accel_ptr->accel_pci_dev.pci_dev
180
181struct adf_admin_comms;
182struct icp_qat_fw_loader_handle;
183struct adf_fw_loader_data {
184 struct icp_qat_fw_loader_handle *fw_loader;
185 const struct firmware *uof_fw;
186};
187
188struct adf_accel_dev {
189 struct adf_etr_data *transport;
190 struct adf_hw_device_data *hw_device;
191 struct adf_cfg_device_data *cfg;
192 struct adf_fw_loader_data *fw_loader;
193 struct adf_admin_comms *admin;
194 struct list_head crypto_list;
195 unsigned long status;
196 atomic_t ref_count;
197 struct dentry *debugfs_dir;
198 struct list_head list;
199 struct module *owner;
200 uint8_t accel_id;
201 uint8_t numa_node;
202 struct adf_accel_pci accel_pci_dev;
203} __packed;
204#endif
diff --git a/drivers/crypto/qat/qat_common/adf_accel_engine.c b/drivers/crypto/qat/qat_common/adf_accel_engine.c
new file mode 100644
index 000000000000..25801fe3c375
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_accel_engine.c
@@ -0,0 +1,168 @@
1/*
2 This file is provided under a dual BSD/GPLv2 license. When using or
3 redistributing this file, you may do so under either license.
4
5 GPL LICENSE SUMMARY
6 Copyright(c) 2014 Intel Corporation.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as
9 published by the Free Software Foundation.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 Contact Information:
17 qat-linux@intel.com
18
19 BSD LICENSE
20 Copyright(c) 2014 Intel Corporation.
21 Redistribution and use in source and binary forms, with or without
22 modification, are permitted provided that the following conditions
23 are met:
24
25 * Redistributions of source code must retain the above copyright
26 notice, this list of conditions and the following disclaimer.
27 * Redistributions in binary form must reproduce the above copyright
28 notice, this list of conditions and the following disclaimer in
29 the documentation and/or other materials provided with the
30 distribution.
31 * Neither the name of Intel Corporation nor the names of its
32 contributors may be used to endorse or promote products derived
33 from this software without specific prior written permission.
34
35 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46*/
47#include <linux/firmware.h>
48#include <linux/pci.h>
49#include "adf_cfg.h"
50#include "adf_accel_devices.h"
51#include "adf_common_drv.h"
52#include "icp_qat_uclo.h"
53
54int adf_ae_fw_load(struct adf_accel_dev *accel_dev)
55{
56 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
57 struct adf_hw_device_data *hw_device = accel_dev->hw_device;
58 void *uof_addr;
59 uint32_t uof_size;
60
61 if (request_firmware(&loader_data->uof_fw, hw_device->fw_name,
62 &accel_dev->accel_pci_dev.pci_dev->dev)) {
63 pr_err("QAT: Failed to load firmware %s\n", hw_device->fw_name);
64 return -EFAULT;
65 }
66
67 uof_size = loader_data->uof_fw->size;
68 uof_addr = (void *)loader_data->uof_fw->data;
69 if (qat_uclo_map_uof_obj(loader_data->fw_loader, uof_addr, uof_size)) {
70 pr_err("QAT: Failed to map uof\n");
71 goto out_err;
72 }
73 if (qat_uclo_wr_all_uimage(loader_data->fw_loader)) {
74 pr_err("QAT: Failed to map uof\n");
75 goto out_err;
76 }
77 return 0;
78
79out_err:
80 release_firmware(loader_data->uof_fw);
81 return -EFAULT;
82}
83
84int adf_ae_fw_release(struct adf_accel_dev *accel_dev)
85{
86 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
87
88 release_firmware(loader_data->uof_fw);
89 qat_uclo_del_uof_obj(loader_data->fw_loader);
90 qat_hal_deinit(loader_data->fw_loader);
91 loader_data->fw_loader = NULL;
92 return 0;
93}
94
95int adf_ae_start(struct adf_accel_dev *accel_dev)
96{
97 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
98 struct adf_hw_device_data *hw_data = accel_dev->hw_device;
99 uint32_t ae_ctr, ae, max_aes = GET_MAX_ACCELENGINES(accel_dev);
100
101 for (ae = 0, ae_ctr = 0; ae < max_aes; ae++) {
102 if (hw_data->ae_mask & (1 << ae)) {
103 qat_hal_start(loader_data->fw_loader, ae, 0xFF);
104 ae_ctr++;
105 }
106 }
107 pr_info("QAT: qat_dev%d started %d acceleration engines\n",
108 accel_dev->accel_id, ae_ctr);
109 return 0;
110}
111
112int adf_ae_stop(struct adf_accel_dev *accel_dev)
113{
114 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
115 struct adf_hw_device_data *hw_data = accel_dev->hw_device;
116 uint32_t ae_ctr, ae, max_aes = GET_MAX_ACCELENGINES(accel_dev);
117
118 for (ae = 0, ae_ctr = 0; ae < max_aes; ae++) {
119 if (hw_data->ae_mask & (1 << ae)) {
120 qat_hal_stop(loader_data->fw_loader, ae, 0xFF);
121 ae_ctr++;
122 }
123 }
124 pr_info("QAT: qat_dev%d stopped %d acceleration engines\n",
125 accel_dev->accel_id, ae_ctr);
126 return 0;
127}
128
129static int adf_ae_reset(struct adf_accel_dev *accel_dev, int ae)
130{
131 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
132
133 qat_hal_reset(loader_data->fw_loader);
134 if (qat_hal_clr_reset(loader_data->fw_loader))
135 return -EFAULT;
136
137 return 0;
138}
139
140int adf_ae_init(struct adf_accel_dev *accel_dev)
141{
142 struct adf_fw_loader_data *loader_data;
143
144 loader_data = kzalloc(sizeof(*loader_data), GFP_KERNEL);
145 if (!loader_data)
146 return -ENOMEM;
147
148 accel_dev->fw_loader = loader_data;
149 if (qat_hal_init(accel_dev)) {
150 pr_err("QAT: Failed to init the AEs\n");
151 kfree(loader_data);
152 return -EFAULT;
153 }
154 if (adf_ae_reset(accel_dev, 0)) {
155 pr_err("QAT: Failed to reset the AEs\n");
156 qat_hal_deinit(loader_data->fw_loader);
157 kfree(loader_data);
158 return -EFAULT;
159 }
160 return 0;
161}
162
163int adf_ae_shutdown(struct adf_accel_dev *accel_dev)
164{
165 kfree(accel_dev->fw_loader);
166 accel_dev->fw_loader = NULL;
167 return 0;
168}
diff --git a/drivers/crypto/qat/qat_common/adf_aer.c b/drivers/crypto/qat/qat_common/adf_aer.c
new file mode 100644
index 000000000000..0651678e2345
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_aer.c
@@ -0,0 +1,258 @@
1/*
2 This file is provided under a dual BSD/GPLv2 license. When using or
3 redistributing this file, you may do so under either license.
4
5 GPL LICENSE SUMMARY
6 Copyright(c) 2014 Intel Corporation.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as
9 published by the Free Software Foundation.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 Contact Information:
17 qat-linux@intel.com
18
19 BSD LICENSE
20 Copyright(c) 2014 Intel Corporation.
21 Redistribution and use in source and binary forms, with or without
22 modification, are permitted provided that the following conditions
23 are met:
24
25 * Redistributions of source code must retain the above copyright
26 notice, this list of conditions and the following disclaimer.
27 * Redistributions in binary form must reproduce the above copyright
28 notice, this list of conditions and the following disclaimer in
29 the documentation and/or other materials provided with the
30 distribution.
31 * Neither the name of Intel Corporation nor the names of its
32 contributors may be used to endorse or promote products derived
33 from this software without specific prior written permission.
34
35 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46*/
47#include <linux/kernel.h>
48#include <linux/pci.h>
49#include <linux/aer.h>
50#include <linux/completion.h>
51#include <linux/workqueue.h>
52#include <linux/delay.h>
53#include "adf_accel_devices.h"
54#include "adf_common_drv.h"
55
56static struct workqueue_struct *device_reset_wq;
57
58static pci_ers_result_t adf_error_detected(struct pci_dev *pdev,
59 pci_channel_state_t state)
60{
61 struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev);
62
63 pr_info("QAT: Acceleration driver hardware error detected.\n");
64 if (!accel_dev) {
65 pr_err("QAT: Can't find acceleration device\n");
66 return PCI_ERS_RESULT_DISCONNECT;
67 }
68
69 if (state == pci_channel_io_perm_failure) {
70 pr_err("QAT: Can't recover from device error\n");
71 return PCI_ERS_RESULT_DISCONNECT;
72 }
73
74 return PCI_ERS_RESULT_NEED_RESET;
75}
76
77/* reset dev data */
78struct adf_reset_dev_data {
79 int mode;
80 struct adf_accel_dev *accel_dev;
81 struct completion compl;
82 struct work_struct reset_work;
83};
84
85#define PPDSTAT_OFFSET 0x7E
86static void adf_dev_restore(struct adf_accel_dev *accel_dev)
87{
88 struct pci_dev *pdev = accel_to_pci_dev(accel_dev);
89 struct pci_dev *parent = pdev->bus->self;
90 uint16_t ppdstat = 0, bridge_ctl = 0;
91 int pending = 0;
92
93 pr_info("QAT: Reseting device qat_dev%d\n", accel_dev->accel_id);
94 pci_read_config_word(pdev, PPDSTAT_OFFSET, &ppdstat);
95 pending = ppdstat & PCI_EXP_DEVSTA_TRPND;
96 if (pending) {
97 int ctr = 0;
98 do {
99 msleep(100);
100 pci_read_config_word(pdev, PPDSTAT_OFFSET, &ppdstat);
101 pending = ppdstat & PCI_EXP_DEVSTA_TRPND;
102 } while (pending && ctr++ < 10);
103 }
104
105 if (pending)
106 pr_info("QAT: Transaction still in progress. Proceeding\n");
107
108 pci_read_config_word(parent, PCI_BRIDGE_CONTROL, &bridge_ctl);
109 bridge_ctl |= PCI_BRIDGE_CTL_BUS_RESET;
110 pci_write_config_word(parent, PCI_BRIDGE_CONTROL, bridge_ctl);
111 msleep(100);
112 bridge_ctl &= ~PCI_BRIDGE_CTL_BUS_RESET;
113 pci_write_config_word(parent, PCI_BRIDGE_CONTROL, bridge_ctl);
114 msleep(100);
115 pci_restore_state(pdev);
116 pci_save_state(pdev);
117}
118
119static void adf_device_reset_worker(struct work_struct *work)
120{
121 struct adf_reset_dev_data *reset_data =
122 container_of(work, struct adf_reset_dev_data, reset_work);
123 struct adf_accel_dev *accel_dev = reset_data->accel_dev;
124
125 adf_dev_restarting_notify(accel_dev);
126 adf_dev_stop(accel_dev);
127 adf_dev_restore(accel_dev);
128 if (adf_dev_start(accel_dev)) {
129 /* The device hanged and we can't restart it so stop here */
130 dev_err(&GET_DEV(accel_dev), "Restart device failed\n");
131 kfree(reset_data);
132 WARN(1, "QAT: device restart failed. Device is unusable\n");
133 return;
134 }
135 adf_dev_restarted_notify(accel_dev);
136 clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
137
138 /* The dev is back alive. Notify the caller if in sync mode */
139 if (reset_data->mode == ADF_DEV_RESET_SYNC)
140 complete(&reset_data->compl);
141 else
142 kfree(reset_data);
143}
144
145static int adf_dev_aer_schedule_reset(struct adf_accel_dev *accel_dev,
146 enum adf_dev_reset_mode mode)
147{
148 struct adf_reset_dev_data *reset_data;
149
150 if (adf_dev_started(accel_dev) &&
151 !test_bit(ADF_STATUS_RESTARTING, &accel_dev->status))
152 return 0;
153
154 set_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
155 reset_data = kzalloc(sizeof(*reset_data), GFP_ATOMIC);
156 if (!reset_data)
157 return -ENOMEM;
158 reset_data->accel_dev = accel_dev;
159 init_completion(&reset_data->compl);
160 reset_data->mode = mode;
161 INIT_WORK(&reset_data->reset_work, adf_device_reset_worker);
162 queue_work(device_reset_wq, &reset_data->reset_work);
163
164 /* If in sync mode wait for the result */
165 if (mode == ADF_DEV_RESET_SYNC) {
166 int ret = 0;
167 /* Maximum device reset time is 10 seconds */
168 unsigned long wait_jiffies = msecs_to_jiffies(10000);
169 unsigned long timeout = wait_for_completion_timeout(
170 &reset_data->compl, wait_jiffies);
171 if (!timeout) {
172 pr_err("QAT: Reset device timeout expired\n");
173 ret = -EFAULT;
174 }
175 kfree(reset_data);
176 return ret;
177 }
178 return 0;
179}
180
181static pci_ers_result_t adf_slot_reset(struct pci_dev *pdev)
182{
183 struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev);
184
185 if (!accel_dev) {
186 pr_err("QAT: Can't find acceleration device\n");
187 return PCI_ERS_RESULT_DISCONNECT;
188 }
189 pci_cleanup_aer_uncorrect_error_status(pdev);
190 if (adf_dev_aer_schedule_reset(accel_dev, ADF_DEV_RESET_SYNC))
191 return PCI_ERS_RESULT_DISCONNECT;
192
193 return PCI_ERS_RESULT_RECOVERED;
194}
195
196static void adf_resume(struct pci_dev *pdev)
197{
198 pr_info("QAT: Acceleration driver reset completed\n");
199 pr_info("QAT: Device is up and runnig\n");
200}
201
202static struct pci_error_handlers adf_err_handler = {
203 .error_detected = adf_error_detected,
204 .slot_reset = adf_slot_reset,
205 .resume = adf_resume,
206};
207
208/**
209 * adf_enable_aer() - Enable Advance Error Reporting for acceleration device
210 * @accel_dev: Pointer to acceleration device.
211 * @adf: PCI device driver owning the given acceleration device.
212 *
213 * Function enables PCI Advance Error Reporting for the
214 * QAT acceleration device accel_dev.
215 * To be used by QAT device specific drivers.
216 *
217 * Return: 0 on success, error code othewise.
218 */
219int adf_enable_aer(struct adf_accel_dev *accel_dev, struct pci_driver *adf)
220{
221 struct pci_dev *pdev = accel_to_pci_dev(accel_dev);
222
223 adf->err_handler = &adf_err_handler;
224 pci_enable_pcie_error_reporting(pdev);
225 return 0;
226}
227EXPORT_SYMBOL_GPL(adf_enable_aer);
228
229/**
230 * adf_disable_aer() - Enable Advance Error Reporting for acceleration device
231 * @accel_dev: Pointer to acceleration device.
232 *
233 * Function disables PCI Advance Error Reporting for the
234 * QAT acceleration device accel_dev.
235 * To be used by QAT device specific drivers.
236 *
237 * Return: void
238 */
239void adf_disable_aer(struct adf_accel_dev *accel_dev)
240{
241 struct pci_dev *pdev = accel_to_pci_dev(accel_dev);
242
243 pci_disable_pcie_error_reporting(pdev);
244}
245EXPORT_SYMBOL_GPL(adf_disable_aer);
246
247int adf_init_aer(void)
248{
249 device_reset_wq = create_workqueue("qat_device_reset_wq");
250 return (device_reset_wq == NULL) ? -EFAULT : 0;
251}
252
253void adf_exit_aer(void)
254{
255 if (device_reset_wq)
256 destroy_workqueue(device_reset_wq);
257 device_reset_wq = NULL;
258}
diff --git a/drivers/crypto/qat/qat_common/adf_cfg.c b/drivers/crypto/qat/qat_common/adf_cfg.c
new file mode 100644
index 000000000000..389c0cf28e70
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_cfg.c
@@ -0,0 +1,359 @@
1/*
2 This file is provided under a dual BSD/GPLv2 license. When using or
3 redistributing this file, you may do so under either license.
4
5 GPL LICENSE SUMMARY
6 Copyright(c) 2014 Intel Corporation.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as
9 published by the Free Software Foundation.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 Contact Information:
17 qat-linux@intel.com
18
19 BSD LICENSE
20 Copyright(c) 2014 Intel Corporation.
21 Redistribution and use in source and binary forms, with or without
22 modification, are permitted provided that the following conditions
23 are met:
24
25 * Redistributions of source code must retain the above copyright
26 notice, this list of conditions and the following disclaimer.
27 * Redistributions in binary form must reproduce the above copyright
28 notice, this list of conditions and the following disclaimer in
29 the documentation and/or other materials provided with the
30 distribution.
31 * Neither the name of Intel Corporation nor the names of its
32 contributors may be used to endorse or promote products derived
33 from this software without specific prior written permission.
34
35 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46*/
47#include <linux/mutex.h>
48#include <linux/slab.h>
49#include <linux/list.h>
50#include <linux/seq_file.h>
51#include "adf_accel_devices.h"
52#include "adf_common_drv.h"
53#include "adf_cfg.h"
54
55static DEFINE_MUTEX(qat_cfg_read_lock);
56
57static void *qat_dev_cfg_start(struct seq_file *sfile, loff_t *pos)
58{
59 struct adf_cfg_device_data *dev_cfg = sfile->private;
60 mutex_lock(&qat_cfg_read_lock);
61 return seq_list_start(&dev_cfg->sec_list, *pos);
62}
63
64static int qat_dev_cfg_show(struct seq_file *sfile, void *v)
65{
66 struct list_head *list;
67 struct adf_cfg_section *sec =
68 list_entry(v, struct adf_cfg_section, list);
69
70 seq_printf(sfile, "[%s]\n", sec->name);
71 list_for_each(list, &sec->param_head) {
72 struct adf_cfg_key_val *ptr =
73 list_entry(list, struct adf_cfg_key_val, list);
74 seq_printf(sfile, "%s = %s\n", ptr->key, ptr->val);
75 }
76 return 0;
77}
78
79static void *qat_dev_cfg_next(struct seq_file *sfile, void *v, loff_t *pos)
80{
81 struct adf_cfg_device_data *dev_cfg = sfile->private;
82 return seq_list_next(v, &dev_cfg->sec_list, pos);
83}
84
85static void qat_dev_cfg_stop(struct seq_file *sfile, void *v)
86{
87 mutex_unlock(&qat_cfg_read_lock);
88}
89
90static const struct seq_operations qat_dev_cfg_sops = {
91 .start = qat_dev_cfg_start,
92 .next = qat_dev_cfg_next,
93 .stop = qat_dev_cfg_stop,
94 .show = qat_dev_cfg_show
95};
96
97static int qat_dev_cfg_open(struct inode *inode, struct file *file)
98{
99 int ret = seq_open(file, &qat_dev_cfg_sops);
100
101 if (!ret) {
102 struct seq_file *seq_f = file->private_data;
103 seq_f->private = inode->i_private;
104 }
105 return ret;
106}
107
108static const struct file_operations qat_dev_cfg_fops = {
109 .open = qat_dev_cfg_open,
110 .read = seq_read,
111 .llseek = seq_lseek,
112 .release = seq_release
113};
114
115/**
116 * adf_cfg_dev_add() - Create an acceleration device configuration table.
117 * @accel_dev: Pointer to acceleration device.
118 *
119 * Function creates a configuration table for the given acceleration device.
120 * The table stores device specific config values.
121 * To be used by QAT device specific drivers.
122 *
123 * Return: 0 on success, error code othewise.
124 */
125int adf_cfg_dev_add(struct adf_accel_dev *accel_dev)
126{
127 struct adf_cfg_device_data *dev_cfg_data;
128
129 dev_cfg_data = kzalloc(sizeof(*dev_cfg_data), GFP_KERNEL);
130 if (!dev_cfg_data)
131 return -ENOMEM;
132 INIT_LIST_HEAD(&dev_cfg_data->sec_list);
133 init_rwsem(&dev_cfg_data->lock);
134 accel_dev->cfg = dev_cfg_data;
135
136 /* accel_dev->debugfs_dir should always be non-NULL here */
137 dev_cfg_data->debug = debugfs_create_file("dev_cfg", S_IRUSR,
138 accel_dev->debugfs_dir,
139 dev_cfg_data,
140 &qat_dev_cfg_fops);
141 if (!dev_cfg_data->debug) {
142 pr_err("QAT: Failed to create qat cfg debugfs entry.\n");
143 kfree(dev_cfg_data);
144 accel_dev->cfg = NULL;
145 return -EFAULT;
146 }
147 return 0;
148}
149EXPORT_SYMBOL_GPL(adf_cfg_dev_add);
150
151static void adf_cfg_section_del_all(struct list_head *head);
152
153void adf_cfg_del_all(struct adf_accel_dev *accel_dev)
154{
155 struct adf_cfg_device_data *dev_cfg_data = accel_dev->cfg;
156
157 down_write(&dev_cfg_data->lock);
158 adf_cfg_section_del_all(&dev_cfg_data->sec_list);
159 up_write(&dev_cfg_data->lock);
160}
161
162/**
163 * adf_cfg_dev_remove() - Clears acceleration device configuration table.
164 * @accel_dev: Pointer to acceleration device.
165 *
166 * Function removes configuration table from the given acceleration device
167 * and frees all allocated memory.
168 * To be used by QAT device specific drivers.
169 *
170 * Return: void
171 */
172void adf_cfg_dev_remove(struct adf_accel_dev *accel_dev)
173{
174 struct adf_cfg_device_data *dev_cfg_data = accel_dev->cfg;
175
176 down_write(&dev_cfg_data->lock);
177 adf_cfg_section_del_all(&dev_cfg_data->sec_list);
178 up_write(&dev_cfg_data->lock);
179 debugfs_remove(dev_cfg_data->debug);
180 kfree(dev_cfg_data);
181 accel_dev->cfg = NULL;
182}
183EXPORT_SYMBOL_GPL(adf_cfg_dev_remove);
184
185static void adf_cfg_keyval_add(struct adf_cfg_key_val *new,
186 struct adf_cfg_section *sec)
187{
188 list_add_tail(&new->list, &sec->param_head);
189}
190
191static void adf_cfg_keyval_del_all(struct list_head *head)
192{
193 struct list_head *list_ptr, *tmp;
194
195 list_for_each_prev_safe(list_ptr, tmp, head) {
196 struct adf_cfg_key_val *ptr =
197 list_entry(list_ptr, struct adf_cfg_key_val, list);
198 list_del(list_ptr);
199 kfree(ptr);
200 }
201}
202
203static void adf_cfg_section_del_all(struct list_head *head)
204{
205 struct adf_cfg_section *ptr;
206 struct list_head *list, *tmp;
207
208 list_for_each_prev_safe(list, tmp, head) {
209 ptr = list_entry(list, struct adf_cfg_section, list);
210 adf_cfg_keyval_del_all(&ptr->param_head);
211 list_del(list);
212 kfree(ptr);
213 }
214}
215
216static struct adf_cfg_key_val *adf_cfg_key_value_find(struct adf_cfg_section *s,
217 const char *key)
218{
219 struct list_head *list;
220
221 list_for_each(list, &s->param_head) {
222 struct adf_cfg_key_val *ptr =
223 list_entry(list, struct adf_cfg_key_val, list);
224 if (!strcmp(ptr->key, key))
225 return ptr;
226 }
227 return NULL;
228}
229
230static struct adf_cfg_section *adf_cfg_sec_find(struct adf_accel_dev *accel_dev,
231 const char *sec_name)
232{
233 struct adf_cfg_device_data *cfg = accel_dev->cfg;
234 struct list_head *list;
235
236 list_for_each(list, &cfg->sec_list) {
237 struct adf_cfg_section *ptr =
238 list_entry(list, struct adf_cfg_section, list);
239 if (!strcmp(ptr->name, sec_name))
240 return ptr;
241 }
242 return NULL;
243}
244
245static int adf_cfg_key_val_get(struct adf_accel_dev *accel_dev,
246 const char *sec_name,
247 const char *key_name,
248 char *val)
249{
250 struct adf_cfg_section *sec = adf_cfg_sec_find(accel_dev, sec_name);
251 struct adf_cfg_key_val *keyval = NULL;
252
253 if (sec)
254 keyval = adf_cfg_key_value_find(sec, key_name);
255 if (keyval) {
256 memcpy(val, keyval->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES);
257 return 0;
258 }
259 return -1;
260}
261
262/**
263 * adf_cfg_add_key_value_param() - Add key-value config entry to config table.
264 * @accel_dev: Pointer to acceleration device.
265 * @section_name: Name of the section where the param will be added
266 * @key: The key string
267 * @val: Value pain for the given @key
268 * @type: Type - string, int or address
269 *
270 * Function adds configuration key - value entry in the appropriate section
271 * in the given acceleration device
272 * To be used by QAT device specific drivers.
273 *
274 * Return: 0 on success, error code othewise.
275 */
276int adf_cfg_add_key_value_param(struct adf_accel_dev *accel_dev,
277 const char *section_name,
278 const char *key, const void *val,
279 enum adf_cfg_val_type type)
280{
281 struct adf_cfg_device_data *cfg = accel_dev->cfg;
282 struct adf_cfg_key_val *key_val;
283 struct adf_cfg_section *section = adf_cfg_sec_find(accel_dev,
284 section_name);
285 if (!section)
286 return -EFAULT;
287
288 key_val = kzalloc(sizeof(*key_val), GFP_KERNEL);
289 if (!key_val)
290 return -ENOMEM;
291
292 INIT_LIST_HEAD(&key_val->list);
293 strlcpy(key_val->key, key, sizeof(key_val->key));
294
295 if (type == ADF_DEC) {
296 snprintf(key_val->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES,
297 "%ld", (*((long *)val)));
298 } else if (type == ADF_STR) {
299 strlcpy(key_val->val, (char *)val, sizeof(key_val->val));
300 } else if (type == ADF_HEX) {
301 snprintf(key_val->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES,
302 "0x%lx", (unsigned long)val);
303 } else {
304 pr_err("QAT: Unknown type given.\n");
305 kfree(key_val);
306 return -1;
307 }
308 key_val->type = type;
309 down_write(&cfg->lock);
310 adf_cfg_keyval_add(key_val, section);
311 up_write(&cfg->lock);
312 return 0;
313}
314EXPORT_SYMBOL_GPL(adf_cfg_add_key_value_param);
315
316/**
317 * adf_cfg_section_add() - Add config section entry to config table.
318 * @accel_dev: Pointer to acceleration device.
319 * @name: Name of the section
320 *
321 * Function adds configuration section where key - value entries
322 * will be stored.
323 * To be used by QAT device specific drivers.
324 *
325 * Return: 0 on success, error code othewise.
326 */
327int adf_cfg_section_add(struct adf_accel_dev *accel_dev, const char *name)
328{
329 struct adf_cfg_device_data *cfg = accel_dev->cfg;
330 struct adf_cfg_section *sec = adf_cfg_sec_find(accel_dev, name);
331
332 if (sec)
333 return 0;
334
335 sec = kzalloc(sizeof(*sec), GFP_KERNEL);
336 if (!sec)
337 return -ENOMEM;
338
339 strlcpy(sec->name, name, sizeof(sec->name));
340 INIT_LIST_HEAD(&sec->param_head);
341 down_write(&cfg->lock);
342 list_add_tail(&sec->list, &cfg->sec_list);
343 up_write(&cfg->lock);
344 return 0;
345}
346EXPORT_SYMBOL_GPL(adf_cfg_section_add);
347
348int adf_cfg_get_param_value(struct adf_accel_dev *accel_dev,
349 const char *section, const char *name,
350 char *value)
351{
352 struct adf_cfg_device_data *cfg = accel_dev->cfg;
353 int ret;
354
355 down_read(&cfg->lock);
356 ret = adf_cfg_key_val_get(accel_dev, section, name, value);
357 up_read(&cfg->lock);
358 return ret;
359}
diff --git a/drivers/crypto/qat/qat_common/adf_cfg.h b/drivers/crypto/qat/qat_common/adf_cfg.h
new file mode 100644
index 000000000000..6a9c6f6b5ec9
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_cfg.h
@@ -0,0 +1,87 @@
1/*
2 This file is provided under a dual BSD/GPLv2 license. When using or
3 redistributing this file, you may do so under either license.
4
5 GPL LICENSE SUMMARY
6 Copyright(c) 2014 Intel Corporation.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as
9 published by the Free Software Foundation.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 Contact Information:
17 qat-linux@intel.com
18
19 BSD LICENSE
20 Copyright(c) 2014 Intel Corporation.
21 Redistribution and use in source and binary forms, with or without
22 modification, are permitted provided that the following conditions
23 are met:
24
25 * Redistributions of source code must retain the above copyright
26 notice, this list of conditions and the following disclaimer.
27 * Redistributions in binary form must reproduce the above copyright
28 notice, this list of conditions and the following disclaimer in
29 the documentation and/or other materials provided with the
30 distribution.
31 * Neither the name of Intel Corporation nor the names of its
32 contributors may be used to endorse or promote products derived
33 from this software without specific prior written permission.
34
35 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46*/
47#ifndef ADF_CFG_H_
48#define ADF_CFG_H_
49
50#include <linux/list.h>
51#include <linux/rwsem.h>
52#include <linux/debugfs.h>
53#include "adf_accel_devices.h"
54#include "adf_cfg_common.h"
55#include "adf_cfg_strings.h"
56
57struct adf_cfg_key_val {
58 char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
59 char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
60 enum adf_cfg_val_type type;
61 struct list_head list;
62};
63
64struct adf_cfg_section {
65 char name[ADF_CFG_MAX_SECTION_LEN_IN_BYTES];
66 struct list_head list;
67 struct list_head param_head;
68};
69
70struct adf_cfg_device_data {
71 struct list_head sec_list;
72 struct dentry *debug;
73 struct rw_semaphore lock;
74};
75
76int adf_cfg_dev_add(struct adf_accel_dev *accel_dev);
77void adf_cfg_dev_remove(struct adf_accel_dev *accel_dev);
78int adf_cfg_section_add(struct adf_accel_dev *accel_dev, const char *name);
79void adf_cfg_del_all(struct adf_accel_dev *accel_dev);
80int adf_cfg_add_key_value_param(struct adf_accel_dev *accel_dev,
81 const char *section_name,
82 const char *key, const void *val,
83 enum adf_cfg_val_type type);
84int adf_cfg_get_param_value(struct adf_accel_dev *accel_dev,
85 const char *section, const char *name, char *value);
86
87#endif
diff --git a/drivers/crypto/qat/qat_common/adf_cfg_common.h b/drivers/crypto/qat/qat_common/adf_cfg_common.h
new file mode 100644
index 000000000000..88b82187ac35
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_cfg_common.h
@@ -0,0 +1,100 @@
1/*
2 This file is provided under a dual BSD/GPLv2 license. When using or
3 redistributing this file, you may do so under either license.
4
5 GPL LICENSE SUMMARY
6 Copyright(c) 2014 Intel Corporation.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as
9 published by the Free Software Foundation.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 Contact Information:
17 qat-linux@intel.com
18
19 BSD LICENSE
20 Copyright(c) 2014 Intel Corporation.
21 Redistribution and use in source and binary forms, with or without
22 modification, are permitted provided that the following conditions
23 are met:
24
25 * Redistributions of source code must retain the above copyright
26 notice, this list of conditions and the following disclaimer.
27 * Redistributions in binary form must reproduce the above copyright
28 notice, this list of conditions and the following disclaimer in
29 the documentation and/or other materials provided with the
30 distribution.
31 * Neither the name of Intel Corporation nor the names of its
32 contributors may be used to endorse or promote products derived
33 from this software without specific prior written permission.
34
35 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46*/
47#ifndef ADF_CFG_COMMON_H_
48#define ADF_CFG_COMMON_H_
49
50#include <linux/types.h>
51#include <linux/ioctl.h>
52
53#define ADF_CFG_MAX_STR_LEN 64
54#define ADF_CFG_MAX_KEY_LEN_IN_BYTES ADF_CFG_MAX_STR_LEN
55#define ADF_CFG_MAX_VAL_LEN_IN_BYTES ADF_CFG_MAX_STR_LEN
56#define ADF_CFG_MAX_SECTION_LEN_IN_BYTES ADF_CFG_MAX_STR_LEN
57#define ADF_CFG_BASE_DEC 10
58#define ADF_CFG_BASE_HEX 16
59#define ADF_CFG_ALL_DEVICES 0xFE
60#define ADF_CFG_NO_DEVICE 0xFF
61#define ADF_CFG_AFFINITY_WHATEVER 0xFF
62#define MAX_DEVICE_NAME_SIZE 32
63#define ADF_MAX_DEVICES 32
64
65enum adf_cfg_val_type {
66 ADF_DEC,
67 ADF_HEX,
68 ADF_STR
69};
70
71enum adf_device_type {
72 DEV_UNKNOWN = 0,
73 DEV_DH895XCC,
74};
75
76struct adf_dev_status_info {
77 enum adf_device_type type;
78 uint8_t accel_id;
79 uint8_t instance_id;
80 uint8_t num_ae;
81 uint8_t num_accel;
82 uint8_t num_logical_accel;
83 uint8_t banks_per_accel;
84 uint8_t state;
85 uint8_t bus;
86 uint8_t dev;
87 uint8_t fun;
88 char name[MAX_DEVICE_NAME_SIZE];
89};
90
91#define ADF_CTL_IOC_MAGIC 'a'
92#define IOCTL_CONFIG_SYS_RESOURCE_PARAMETERS _IOW(ADF_CTL_IOC_MAGIC, 0, \
93 struct adf_user_cfg_ctl_data)
94#define IOCTL_STOP_ACCEL_DEV _IOW(ADF_CTL_IOC_MAGIC, 1, \
95 struct adf_user_cfg_ctl_data)
96#define IOCTL_START_ACCEL_DEV _IOW(ADF_CTL_IOC_MAGIC, 2, \
97 struct adf_user_cfg_ctl_data)
98#define IOCTL_STATUS_ACCEL_DEV _IOW(ADF_CTL_IOC_MAGIC, 3, uint32_t)
99#define IOCTL_GET_NUM_DEVICES _IOW(ADF_CTL_IOC_MAGIC, 4, int32_t)
100#endif
diff --git a/drivers/crypto/qat/qat_common/adf_cfg_strings.h b/drivers/crypto/qat/qat_common/adf_cfg_strings.h
new file mode 100644
index 000000000000..c7ac758ebc90
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_cfg_strings.h
@@ -0,0 +1,83 @@
1/*
2 This file is provided under a dual BSD/GPLv2 license. When using or
3 redistributing this file, you may do so under either license.
4
5 GPL LICENSE SUMMARY
6 Copyright(c) 2014 Intel Corporation.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as
9 published by the Free Software Foundation.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 Contact Information:
17 qat-linux@intel.com
18
19 BSD LICENSE
20 Copyright(c) 2014 Intel Corporation.
21 Redistribution and use in source and binary forms, with or without
22 modification, are permitted provided that the following conditions
23 are met:
24
25 * Redistributions of source code must retain the above copyright
26 notice, this list of conditions and the following disclaimer.
27 * Redistributions in binary form must reproduce the above copyright
28 notice, this list of conditions and the following disclaimer in
29 the documentation and/or other materials provided with the
30 distribution.
31 * Neither the name of Intel Corporation nor the names of its
32 contributors may be used to endorse or promote products derived
33 from this software without specific prior written permission.
34
35 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46*/
47#ifndef ADF_CFG_STRINGS_H_
48#define ADF_CFG_STRINGS_H_
49
50#define ADF_GENERAL_SEC "GENERAL"
51#define ADF_KERNEL_SEC "KERNEL"
52#define ADF_ACCEL_SEC "Accelerator"
53#define ADF_NUM_CY "NumberCyInstances"
54#define ADF_NUM_DC "NumberDcInstances"
55#define ADF_RING_SYM_SIZE "NumConcurrentSymRequests"
56#define ADF_RING_ASYM_SIZE "NumConcurrentAsymRequests"
57#define ADF_RING_DC_SIZE "NumConcurrentRequests"
58#define ADF_RING_ASYM_TX "RingAsymTx"
59#define ADF_RING_SYM_TX "RingSymTx"
60#define ADF_RING_RND_TX "RingNrbgTx"
61#define ADF_RING_ASYM_RX "RingAsymRx"
62#define ADF_RING_SYM_RX "RinSymRx"
63#define ADF_RING_RND_RX "RingNrbgRx"
64#define ADF_RING_DC_TX "RingTx"
65#define ADF_RING_DC_RX "RingRx"
66#define ADF_ETRMGR_BANK "Bank"
67#define ADF_RING_BANK_NUM "BankNumber"
68#define ADF_CY "Cy"
69#define ADF_DC "Dc"
70#define ADF_ETRMGR_COALESCING_ENABLED "InterruptCoalescingEnabled"
71#define ADF_ETRMGR_COALESCING_ENABLED_FORMAT \
72 ADF_ETRMGR_BANK"%d"ADF_ETRMGR_COALESCING_ENABLED
73#define ADF_ETRMGR_COALESCE_TIMER "InterruptCoalescingTimerNs"
74#define ADF_ETRMGR_COALESCE_TIMER_FORMAT \
75 ADF_ETRMGR_BANK"%d"ADF_ETRMGR_COALESCE_TIMER
76#define ADF_ETRMGR_COALESCING_MSG_ENABLED "InterruptCoalescingNumResponses"
77#define ADF_ETRMGR_COALESCING_MSG_ENABLED_FORMAT \
78 ADF_ETRMGR_BANK"%d"ADF_ETRMGR_COALESCING_MSG_ENABLED
79#define ADF_ETRMGR_CORE_AFFINITY "CoreAffinity"
80#define ADF_ETRMGR_CORE_AFFINITY_FORMAT \
81 ADF_ETRMGR_BANK"%d"ADF_ETRMGR_CORE_AFFINITY
82#define ADF_ACCEL_STR "Accelerator%d"
83#endif
diff --git a/drivers/crypto/qat/qat_common/adf_cfg_user.h b/drivers/crypto/qat/qat_common/adf_cfg_user.h
new file mode 100644
index 000000000000..0c38a155a865
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_cfg_user.h
@@ -0,0 +1,94 @@
1/*
2 This file is provided under a dual BSD/GPLv2 license. When using or
3 redistributing this file, you may do so under either license.
4
5 GPL LICENSE SUMMARY
6 Copyright(c) 2014 Intel Corporation.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as
9 published by the Free Software Foundation.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 Contact Information:
17 qat-linux@intel.com
18
19 BSD LICENSE
20 Copyright(c) 2014 Intel Corporation.
21 Redistribution and use in source and binary forms, with or without
22 modification, are permitted provided that the following conditions
23 are met:
24
25 * Redistributions of source code must retain the above copyright
26 notice, this list of conditions and the following disclaimer.
27 * Redistributions in binary form must reproduce the above copyright
28 notice, this list of conditions and the following disclaimer in
29 the documentation and/or other materials provided with the
30 distribution.
31 * Neither the name of Intel Corporation nor the names of its
32 contributors may be used to endorse or promote products derived
33 from this software without specific prior written permission.
34
35 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46*/
47#ifndef ADF_CFG_USER_H_
48#define ADF_CFG_USER_H_
49
50#include "adf_cfg_common.h"
51#include "adf_cfg_strings.h"
52
53struct adf_user_cfg_key_val {
54 char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
55 char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
56 union {
57 char *user_val_ptr;
58 uint64_t padding1;
59 };
60 union {
61 struct adf_user_cfg_key_val *prev;
62 uint64_t padding2;
63 };
64 union {
65 struct adf_user_cfg_key_val *next;
66 uint64_t padding3;
67 };
68 enum adf_cfg_val_type type;
69};
70
71struct adf_user_cfg_section {
72 char name[ADF_CFG_MAX_SECTION_LEN_IN_BYTES];
73 union {
74 struct adf_user_cfg_key_val *params;
75 uint64_t padding1;
76 };
77 union {
78 struct adf_user_cfg_section *prev;
79 uint64_t padding2;
80 };
81 union {
82 struct adf_user_cfg_section *next;
83 uint64_t padding3;
84 };
85};
86
87struct adf_user_cfg_ctl_data {
88 union {
89 struct adf_user_cfg_section *config_section;
90 uint64_t padding;
91 };
92 uint8_t device_id;
93};
94#endif
diff --git a/drivers/crypto/qat/qat_common/adf_common_drv.h b/drivers/crypto/qat/qat_common/adf_common_drv.h
new file mode 100644
index 000000000000..3cea9fa26158
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_common_drv.h
@@ -0,0 +1,192 @@
1/*
2 This file is provided under a dual BSD/GPLv2 license. When using or
3 redistributing this file, you may do so under either license.
4
5 GPL LICENSE SUMMARY
6 Copyright(c) 2014 Intel Corporation.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as
9 published by the Free Software Foundation.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 Contact Information:
17 qat-linux@intel.com
18
19 BSD LICENSE
20 Copyright(c) 2014 Intel Corporation.
21 Redistribution and use in source and binary forms, with or without
22 modification, are permitted provided that the following conditions
23 are met:
24
25 * Redistributions of source code must retain the above copyright
26 notice, this list of conditions and the following disclaimer.
27 * Redistributions in binary form must reproduce the above copyright
28 notice, this list of conditions and the following disclaimer in
29 the documentation and/or other materials provided with the
30 distribution.
31 * Neither the name of Intel Corporation nor the names of its
32 contributors may be used to endorse or promote products derived
33 from this software without specific prior written permission.
34
35 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46*/
47#ifndef ADF_DRV_H
48#define ADF_DRV_H
49
50#include <linux/list.h>
51#include <linux/pci.h>
52#include "adf_accel_devices.h"
53#include "icp_qat_fw_loader_handle.h"
54#include "icp_qat_hal.h"
55
56#define ADF_STATUS_RESTARTING 0
57#define ADF_STATUS_STARTING 1
58#define ADF_STATUS_CONFIGURED 2
59#define ADF_STATUS_STARTED 3
60#define ADF_STATUS_AE_INITIALISED 4
61#define ADF_STATUS_AE_UCODE_LOADED 5
62#define ADF_STATUS_AE_STARTED 6
63#define ADF_STATUS_ORPHAN_TH_RUNNING 7
64#define ADF_STATUS_IRQ_ALLOCATED 8
65
66enum adf_dev_reset_mode {
67 ADF_DEV_RESET_ASYNC = 0,
68 ADF_DEV_RESET_SYNC
69};
70
71enum adf_event {
72 ADF_EVENT_INIT = 0,
73 ADF_EVENT_START,
74 ADF_EVENT_STOP,
75 ADF_EVENT_SHUTDOWN,
76 ADF_EVENT_RESTARTING,
77 ADF_EVENT_RESTARTED,
78};
79
80struct service_hndl {
81 int (*event_hld)(struct adf_accel_dev *accel_dev,
82 enum adf_event event);
83 unsigned long init_status;
84 unsigned long start_status;
85 char *name;
86 struct list_head list;
87 int admin;
88};
89
90int adf_service_register(struct service_hndl *service);
91int adf_service_unregister(struct service_hndl *service);
92
93int adf_dev_init(struct adf_accel_dev *accel_dev);
94int adf_dev_start(struct adf_accel_dev *accel_dev);
95int adf_dev_stop(struct adf_accel_dev *accel_dev);
96int adf_dev_shutdown(struct adf_accel_dev *accel_dev);
97
98int adf_ctl_dev_register(void);
99void adf_ctl_dev_unregister(void);
100int adf_processes_dev_register(void);
101void adf_processes_dev_unregister(void);
102
103int adf_devmgr_add_dev(struct adf_accel_dev *accel_dev);
104void adf_devmgr_rm_dev(struct adf_accel_dev *accel_dev);
105struct list_head *adf_devmgr_get_head(void);
106struct adf_accel_dev *adf_devmgr_get_dev_by_id(uint32_t id);
107struct adf_accel_dev *adf_devmgr_get_first(void);
108struct adf_accel_dev *adf_devmgr_pci_to_accel_dev(struct pci_dev *pci_dev);
109int adf_devmgr_verify_id(uint32_t id);
110void adf_devmgr_get_num_dev(uint32_t *num);
111int adf_devmgr_in_reset(struct adf_accel_dev *accel_dev);
112int adf_dev_started(struct adf_accel_dev *accel_dev);
113int adf_dev_restarting_notify(struct adf_accel_dev *accel_dev);
114int adf_dev_restarted_notify(struct adf_accel_dev *accel_dev);
115int adf_ae_init(struct adf_accel_dev *accel_dev);
116int adf_ae_shutdown(struct adf_accel_dev *accel_dev);
117int adf_ae_fw_load(struct adf_accel_dev *accel_dev);
118int adf_ae_fw_release(struct adf_accel_dev *accel_dev);
119int adf_ae_start(struct adf_accel_dev *accel_dev);
120int adf_ae_stop(struct adf_accel_dev *accel_dev);
121
122int adf_enable_aer(struct adf_accel_dev *accel_dev, struct pci_driver *adf);
123void adf_disable_aer(struct adf_accel_dev *accel_dev);
124int adf_init_aer(void);
125void adf_exit_aer(void);
126
127int adf_dev_get(struct adf_accel_dev *accel_dev);
128void adf_dev_put(struct adf_accel_dev *accel_dev);
129int adf_dev_in_use(struct adf_accel_dev *accel_dev);
130int adf_init_etr_data(struct adf_accel_dev *accel_dev);
131void adf_cleanup_etr_data(struct adf_accel_dev *accel_dev);
132int qat_crypto_register(void);
133int qat_crypto_unregister(void);
134struct qat_crypto_instance *qat_crypto_get_instance_node(int node);
135void qat_crypto_put_instance(struct qat_crypto_instance *inst);
136void qat_alg_callback(void *resp);
137int qat_algs_init(void);
138void qat_algs_exit(void);
139int qat_algs_register(void);
140int qat_algs_unregister(void);
141
142int qat_hal_init(struct adf_accel_dev *accel_dev);
143void qat_hal_deinit(struct icp_qat_fw_loader_handle *handle);
144void qat_hal_start(struct icp_qat_fw_loader_handle *handle, unsigned char ae,
145 unsigned int ctx_mask);
146void qat_hal_stop(struct icp_qat_fw_loader_handle *handle, unsigned char ae,
147 unsigned int ctx_mask);
148void qat_hal_reset(struct icp_qat_fw_loader_handle *handle);
149int qat_hal_clr_reset(struct icp_qat_fw_loader_handle *handle);
150void qat_hal_set_live_ctx(struct icp_qat_fw_loader_handle *handle,
151 unsigned char ae, unsigned int ctx_mask);
152int qat_hal_set_ae_lm_mode(struct icp_qat_fw_loader_handle *handle,
153 unsigned char ae, enum icp_qat_uof_regtype lm_type,
154 unsigned char mode);
155int qat_hal_set_ae_ctx_mode(struct icp_qat_fw_loader_handle *handle,
156 unsigned char ae, unsigned char mode);
157int qat_hal_set_ae_nn_mode(struct icp_qat_fw_loader_handle *handle,
158 unsigned char ae, unsigned char mode);
159void qat_hal_set_pc(struct icp_qat_fw_loader_handle *handle,
160 unsigned char ae, unsigned int ctx_mask, unsigned int upc);
161void qat_hal_wr_uwords(struct icp_qat_fw_loader_handle *handle,
162 unsigned char ae, unsigned int uaddr,
163 unsigned int words_num, uint64_t *uword);
164void qat_hal_wr_umem(struct icp_qat_fw_loader_handle *handle, unsigned char ae,
165 unsigned int uword_addr, unsigned int words_num,
166 unsigned int *data);
167int qat_hal_get_ins_num(void);
168int qat_hal_batch_wr_lm(struct icp_qat_fw_loader_handle *handle,
169 unsigned char ae,
170 struct icp_qat_uof_batch_init *lm_init_header);
171int qat_hal_init_gpr(struct icp_qat_fw_loader_handle *handle,
172 unsigned char ae, unsigned char ctx_mask,
173 enum icp_qat_uof_regtype reg_type,
174 unsigned short reg_num, unsigned int regdata);
175int qat_hal_init_wr_xfer(struct icp_qat_fw_loader_handle *handle,
176 unsigned char ae, unsigned char ctx_mask,
177 enum icp_qat_uof_regtype reg_type,
178 unsigned short reg_num, unsigned int regdata);
179int qat_hal_init_rd_xfer(struct icp_qat_fw_loader_handle *handle,
180 unsigned char ae, unsigned char ctx_mask,
181 enum icp_qat_uof_regtype reg_type,
182 unsigned short reg_num, unsigned int regdata);
183int qat_hal_init_nn(struct icp_qat_fw_loader_handle *handle,
184 unsigned char ae, unsigned char ctx_mask,
185 unsigned short reg_num, unsigned int regdata);
186int qat_hal_wr_lm(struct icp_qat_fw_loader_handle *handle,
187 unsigned char ae, unsigned short lm_addr, unsigned int value);
188int qat_uclo_wr_all_uimage(struct icp_qat_fw_loader_handle *handle);
189int qat_uclo_del_uof_obj(struct icp_qat_fw_loader_handle *handle);
190int qat_uclo_map_uof_obj(struct icp_qat_fw_loader_handle *handle,
191 void *addr_ptr, int mem_size);
192#endif
diff --git a/drivers/crypto/qat/qat_common/adf_ctl_drv.c b/drivers/crypto/qat/qat_common/adf_ctl_drv.c
new file mode 100644
index 000000000000..d97069b8a8e4
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_ctl_drv.c
@@ -0,0 +1,490 @@
1/*
2 This file is provided under a dual BSD/GPLv2 license. When using or
3 redistributing this file, you may do so under either license.
4
5 GPL LICENSE SUMMARY
6 Copyright(c) 2014 Intel Corporation.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as
9 published by the Free Software Foundation.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 Contact Information:
17 qat-linux@intel.com
18
19 BSD LICENSE
20 Copyright(c) 2014 Intel Corporation.
21 Redistribution and use in source and binary forms, with or without
22 modification, are permitted provided that the following conditions
23 are met:
24
25 * Redistributions of source code must retain the above copyright
26 notice, this list of conditions and the following disclaimer.
27 * Redistributions in binary form must reproduce the above copyright
28 notice, this list of conditions and the following disclaimer in
29 the documentation and/or other materials provided with the
30 distribution.
31 * Neither the name of Intel Corporation nor the names of its
32 contributors may be used to endorse or promote products derived
33 from this software without specific prior written permission.
34
35 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46*/
47#include <linux/module.h>
48#include <linux/mutex.h>
49#include <linux/slab.h>
50#include <linux/fs.h>
51#include <linux/bitops.h>
52#include <linux/pci.h>
53#include <linux/cdev.h>
54#include <linux/uaccess.h>
55
56#include "adf_accel_devices.h"
57#include "adf_common_drv.h"
58#include "adf_cfg.h"
59#include "adf_cfg_common.h"
60#include "adf_cfg_user.h"
61
62#define DEVICE_NAME "qat_adf_ctl"
63
64static DEFINE_MUTEX(adf_ctl_lock);
65static long adf_ctl_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
66
67static const struct file_operations adf_ctl_ops = {
68 .owner = THIS_MODULE,
69 .unlocked_ioctl = adf_ctl_ioctl,
70 .compat_ioctl = adf_ctl_ioctl,
71};
72
73struct adf_ctl_drv_info {
74 unsigned int major;
75 struct cdev drv_cdev;
76 struct class *drv_class;
77};
78
79static struct adf_ctl_drv_info adt_ctl_drv;
80
81static void adf_chr_drv_destroy(void)
82{
83 device_destroy(adt_ctl_drv.drv_class, MKDEV(adt_ctl_drv.major, 0));
84 cdev_del(&adt_ctl_drv.drv_cdev);
85 class_destroy(adt_ctl_drv.drv_class);
86 unregister_chrdev_region(MKDEV(adt_ctl_drv.major, 0), 1);
87}
88
89static int adf_chr_drv_create(void)
90{
91 dev_t dev_id;
92 struct device *drv_device;
93
94 if (alloc_chrdev_region(&dev_id, 0, 1, DEVICE_NAME)) {
95 pr_err("QAT: unable to allocate chrdev region\n");
96 return -EFAULT;
97 }
98
99 adt_ctl_drv.drv_class = class_create(THIS_MODULE, DEVICE_NAME);
100 if (IS_ERR(adt_ctl_drv.drv_class)) {
101 pr_err("QAT: class_create failed for adf_ctl\n");
102 goto err_chrdev_unreg;
103 }
104 adt_ctl_drv.major = MAJOR(dev_id);
105 cdev_init(&adt_ctl_drv.drv_cdev, &adf_ctl_ops);
106 if (cdev_add(&adt_ctl_drv.drv_cdev, dev_id, 1)) {
107 pr_err("QAT: cdev add failed\n");
108 goto err_class_destr;
109 }
110
111 drv_device = device_create(adt_ctl_drv.drv_class, NULL,
112 MKDEV(adt_ctl_drv.major, 0),
113 NULL, DEVICE_NAME);
114 if (!drv_device) {
115 pr_err("QAT: failed to create device\n");
116 goto err_cdev_del;
117 }
118 return 0;
119err_cdev_del:
120 cdev_del(&adt_ctl_drv.drv_cdev);
121err_class_destr:
122 class_destroy(adt_ctl_drv.drv_class);
123err_chrdev_unreg:
124 unregister_chrdev_region(dev_id, 1);
125 return -EFAULT;
126}
127
128static int adf_ctl_alloc_resources(struct adf_user_cfg_ctl_data **ctl_data,
129 unsigned long arg)
130{
131 struct adf_user_cfg_ctl_data *cfg_data;
132
133 cfg_data = kzalloc(sizeof(*cfg_data), GFP_KERNEL);
134 if (!cfg_data)
135 return -ENOMEM;
136
137 /* Initialize device id to NO DEVICE as 0 is a valid device id */
138 cfg_data->device_id = ADF_CFG_NO_DEVICE;
139
140 if (copy_from_user(cfg_data, (void __user *)arg, sizeof(*cfg_data))) {
141 pr_err("QAT: failed to copy from user cfg_data.\n");
142 kfree(cfg_data);
143 return -EIO;
144 }
145
146 *ctl_data = cfg_data;
147 return 0;
148}
149
150static int adf_add_key_value_data(struct adf_accel_dev *accel_dev,
151 const char *section,
152 const struct adf_user_cfg_key_val *key_val)
153{
154 if (key_val->type == ADF_HEX) {
155 long *ptr = (long *)key_val->val;
156 long val = *ptr;
157
158 if (adf_cfg_add_key_value_param(accel_dev, section,
159 key_val->key, (void *)val,
160 key_val->type)) {
161 pr_err("QAT: failed to add keyvalue.\n");
162 return -EFAULT;
163 }
164 } else {
165 if (adf_cfg_add_key_value_param(accel_dev, section,
166 key_val->key, key_val->val,
167 key_val->type)) {
168 pr_err("QAT: failed to add keyvalue.\n");
169 return -EFAULT;
170 }
171 }
172 return 0;
173}
174
175static int adf_copy_key_value_data(struct adf_accel_dev *accel_dev,
176 struct adf_user_cfg_ctl_data *ctl_data)
177{
178 struct adf_user_cfg_key_val key_val;
179 struct adf_user_cfg_key_val *params_head;
180 struct adf_user_cfg_section section, *section_head;
181
182 section_head = ctl_data->config_section;
183
184 while (section_head) {
185 if (copy_from_user(&section, (void __user *)section_head,
186 sizeof(*section_head))) {
187 pr_err("QAT: failed to copy section info\n");
188 goto out_err;
189 }
190
191 if (adf_cfg_section_add(accel_dev, section.name)) {
192 pr_err("QAT: failed to add section.\n");
193 goto out_err;
194 }
195
196 params_head = section_head->params;
197
198 while (params_head) {
199 if (copy_from_user(&key_val, (void __user *)params_head,
200 sizeof(key_val))) {
201 pr_err("QAT: Failed to copy keyvalue.\n");
202 goto out_err;
203 }
204 if (adf_add_key_value_data(accel_dev, section.name,
205 &key_val)) {
206 goto out_err;
207 }
208 params_head = key_val.next;
209 }
210 section_head = section.next;
211 }
212 return 0;
213out_err:
214 adf_cfg_del_all(accel_dev);
215 return -EFAULT;
216}
217
218static int adf_ctl_ioctl_dev_config(struct file *fp, unsigned int cmd,
219 unsigned long arg)
220{
221 int ret;
222 struct adf_user_cfg_ctl_data *ctl_data;
223 struct adf_accel_dev *accel_dev;
224
225 ret = adf_ctl_alloc_resources(&ctl_data, arg);
226 if (ret)
227 return ret;
228
229 accel_dev = adf_devmgr_get_dev_by_id(ctl_data->device_id);
230 if (!accel_dev) {
231 ret = -EFAULT;
232 goto out;
233 }
234
235 if (adf_dev_started(accel_dev)) {
236 ret = -EFAULT;
237 goto out;
238 }
239
240 if (adf_copy_key_value_data(accel_dev, ctl_data)) {
241 ret = -EFAULT;
242 goto out;
243 }
244 set_bit(ADF_STATUS_CONFIGURED, &accel_dev->status);
245out:
246 kfree(ctl_data);
247 return ret;
248}
249
250static int adf_ctl_is_device_in_use(int id)
251{
252 struct list_head *itr, *head = adf_devmgr_get_head();
253
254 list_for_each(itr, head) {
255 struct adf_accel_dev *dev =
256 list_entry(itr, struct adf_accel_dev, list);
257
258 if (id == dev->accel_id || id == ADF_CFG_ALL_DEVICES) {
259 if (adf_devmgr_in_reset(dev) || adf_dev_in_use(dev)) {
260 pr_info("QAT: device qat_dev%d is busy\n",
261 dev->accel_id);
262 return -EBUSY;
263 }
264 }
265 }
266 return 0;
267}
268
269static int adf_ctl_stop_devices(uint32_t id)
270{
271 struct list_head *itr, *head = adf_devmgr_get_head();
272 int ret = 0;
273
274 list_for_each(itr, head) {
275 struct adf_accel_dev *accel_dev =
276 list_entry(itr, struct adf_accel_dev, list);
277 if (id == accel_dev->accel_id || id == ADF_CFG_ALL_DEVICES) {
278 if (!adf_dev_started(accel_dev))
279 continue;
280
281 if (adf_dev_stop(accel_dev)) {
282 pr_err("QAT: Failed to stop qat_dev%d\n", id);
283 ret = -EFAULT;
284 }
285 }
286 }
287 return ret;
288}
289
290static int adf_ctl_ioctl_dev_stop(struct file *fp, unsigned int cmd,
291 unsigned long arg)
292{
293 int ret;
294 struct adf_user_cfg_ctl_data *ctl_data;
295
296 ret = adf_ctl_alloc_resources(&ctl_data, arg);
297 if (ret)
298 return ret;
299
300 if (adf_devmgr_verify_id(ctl_data->device_id)) {
301 pr_err("QAT: Device %d not found\n", ctl_data->device_id);
302 ret = -ENODEV;
303 goto out;
304 }
305
306 ret = adf_ctl_is_device_in_use(ctl_data->device_id);
307 if (ret)
308 goto out;
309
310 if (ctl_data->device_id == ADF_CFG_ALL_DEVICES)
311 pr_info("QAT: Stopping all acceleration devices.\n");
312 else
313 pr_info("QAT: Stopping acceleration device qat_dev%d.\n",
314 ctl_data->device_id);
315
316 ret = adf_ctl_stop_devices(ctl_data->device_id);
317 if (ret)
318 pr_err("QAT: failed to stop device.\n");
319out:
320 kfree(ctl_data);
321 return ret;
322}
323
324static int adf_ctl_ioctl_dev_start(struct file *fp, unsigned int cmd,
325 unsigned long arg)
326{
327 int ret;
328 struct adf_user_cfg_ctl_data *ctl_data;
329 struct adf_accel_dev *accel_dev;
330
331 ret = adf_ctl_alloc_resources(&ctl_data, arg);
332 if (ret)
333 return ret;
334
335 accel_dev = adf_devmgr_get_dev_by_id(ctl_data->device_id);
336 if (!accel_dev) {
337 pr_err("QAT: Device %d not found\n", ctl_data->device_id);
338 ret = -ENODEV;
339 goto out;
340 }
341
342 if (!adf_dev_started(accel_dev)) {
343 pr_info("QAT: Starting acceleration device qat_dev%d.\n",
344 ctl_data->device_id);
345 ret = adf_dev_start(accel_dev);
346 } else {
347 pr_info("QAT: Acceleration device qat_dev%d already started.\n",
348 ctl_data->device_id);
349 }
350 if (ret) {
351 pr_err("QAT: Failed to start qat_dev%d\n", ctl_data->device_id);
352 adf_dev_stop(accel_dev);
353 }
354out:
355 kfree(ctl_data);
356 return ret;
357}
358
359static int adf_ctl_ioctl_get_num_devices(struct file *fp, unsigned int cmd,
360 unsigned long arg)
361{
362 uint32_t num_devices = 0;
363
364 adf_devmgr_get_num_dev(&num_devices);
365 if (copy_to_user((void __user *)arg, &num_devices, sizeof(num_devices)))
366 return -EFAULT;
367
368 return 0;
369}
370
371static int adf_ctl_ioctl_get_status(struct file *fp, unsigned int cmd,
372 unsigned long arg)
373{
374 struct adf_hw_device_data *hw_data;
375 struct adf_dev_status_info dev_info;
376 struct adf_accel_dev *accel_dev;
377
378 if (copy_from_user(&dev_info, (void __user *)arg,
379 sizeof(struct adf_dev_status_info))) {
380 pr_err("QAT: failed to copy from user.\n");
381 return -EFAULT;
382 }
383
384 accel_dev = adf_devmgr_get_dev_by_id(dev_info.accel_id);
385 if (!accel_dev) {
386 pr_err("QAT: Device %d not found\n", dev_info.accel_id);
387 return -ENODEV;
388 }
389 hw_data = accel_dev->hw_device;
390 dev_info.state = adf_dev_started(accel_dev) ? DEV_UP : DEV_DOWN;
391 dev_info.num_ae = hw_data->get_num_aes(hw_data);
392 dev_info.num_accel = hw_data->get_num_accels(hw_data);
393 dev_info.num_logical_accel = hw_data->num_logical_accel;
394 dev_info.banks_per_accel = hw_data->num_banks
395 / hw_data->num_logical_accel;
396 strlcpy(dev_info.name, hw_data->dev_class->name, sizeof(dev_info.name));
397 dev_info.instance_id = hw_data->instance_id;
398 dev_info.type = hw_data->dev_class->type;
399 dev_info.bus = accel_to_pci_dev(accel_dev)->bus->number;
400 dev_info.dev = PCI_SLOT(accel_to_pci_dev(accel_dev)->devfn);
401 dev_info.fun = PCI_FUNC(accel_to_pci_dev(accel_dev)->devfn);
402
403 if (copy_to_user((void __user *)arg, &dev_info,
404 sizeof(struct adf_dev_status_info))) {
405 pr_err("QAT: failed to copy status.\n");
406 return -EFAULT;
407 }
408 return 0;
409}
410
411static long adf_ctl_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
412{
413 int ret;
414
415 if (mutex_lock_interruptible(&adf_ctl_lock))
416 return -EFAULT;
417
418 switch (cmd) {
419 case IOCTL_CONFIG_SYS_RESOURCE_PARAMETERS:
420 ret = adf_ctl_ioctl_dev_config(fp, cmd, arg);
421 break;
422
423 case IOCTL_STOP_ACCEL_DEV:
424 ret = adf_ctl_ioctl_dev_stop(fp, cmd, arg);
425 break;
426
427 case IOCTL_START_ACCEL_DEV:
428 ret = adf_ctl_ioctl_dev_start(fp, cmd, arg);
429 break;
430
431 case IOCTL_GET_NUM_DEVICES:
432 ret = adf_ctl_ioctl_get_num_devices(fp, cmd, arg);
433 break;
434
435 case IOCTL_STATUS_ACCEL_DEV:
436 ret = adf_ctl_ioctl_get_status(fp, cmd, arg);
437 break;
438 default:
439 pr_err("QAT: Invalid ioclt\n");
440 ret = -EFAULT;
441 break;
442 }
443 mutex_unlock(&adf_ctl_lock);
444 return ret;
445}
446
447static int __init adf_register_ctl_device_driver(void)
448{
449 mutex_init(&adf_ctl_lock);
450
451 if (qat_algs_init())
452 goto err_algs_init;
453
454 if (adf_chr_drv_create())
455 goto err_chr_dev;
456
457 if (adf_init_aer())
458 goto err_aer;
459
460 if (qat_crypto_register())
461 goto err_crypto_register;
462
463 return 0;
464
465err_crypto_register:
466 adf_exit_aer();
467err_aer:
468 adf_chr_drv_destroy();
469err_chr_dev:
470 qat_algs_exit();
471err_algs_init:
472 mutex_destroy(&adf_ctl_lock);
473 return -EFAULT;
474}
475
476static void __exit adf_unregister_ctl_device_driver(void)
477{
478 adf_chr_drv_destroy();
479 adf_exit_aer();
480 qat_crypto_unregister();
481 qat_algs_exit();
482 mutex_destroy(&adf_ctl_lock);
483}
484
485module_init(adf_register_ctl_device_driver);
486module_exit(adf_unregister_ctl_device_driver);
487MODULE_LICENSE("Dual BSD/GPL");
488MODULE_AUTHOR("Intel");
489MODULE_DESCRIPTION("Intel(R) QuickAssist Technology");
490MODULE_ALIAS("intel_qat");
diff --git a/drivers/crypto/qat/qat_common/adf_dev_mgr.c b/drivers/crypto/qat/qat_common/adf_dev_mgr.c
new file mode 100644
index 000000000000..ae71555c0868
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_dev_mgr.c
@@ -0,0 +1,215 @@
1/*
2 This file is provided under a dual BSD/GPLv2 license. When using or
3 redistributing this file, you may do so under either license.
4
5 GPL LICENSE SUMMARY
6 Copyright(c) 2014 Intel Corporation.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as
9 published by the Free Software Foundation.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 Contact Information:
17 qat-linux@intel.com
18
19 BSD LICENSE
20 Copyright(c) 2014 Intel Corporation.
21 Redistribution and use in source and binary forms, with or without
22 modification, are permitted provided that the following conditions
23 are met:
24
25 * Redistributions of source code must retain the above copyright
26 notice, this list of conditions and the following disclaimer.
27 * Redistributions in binary form must reproduce the above copyright
28 notice, this list of conditions and the following disclaimer in
29 the documentation and/or other materials provided with the
30 distribution.
31 * Neither the name of Intel Corporation nor the names of its
32 contributors may be used to endorse or promote products derived
33 from this software without specific prior written permission.
34
35 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46*/
47#include <linux/mutex.h>
48#include <linux/list.h>
49#include "adf_cfg.h"
50#include "adf_common_drv.h"
51
52static LIST_HEAD(accel_table);
53static DEFINE_MUTEX(table_lock);
54static uint32_t num_devices;
55
56/**
57 * adf_devmgr_add_dev() - Add accel_dev to the acceleration framework
58 * @accel_dev: Pointer to acceleration device.
59 *
60 * Function adds acceleration device to the acceleration framework.
61 * To be used by QAT device specific drivers.
62 *
63 * Return: 0 on success, error code othewise.
64 */
65int adf_devmgr_add_dev(struct adf_accel_dev *accel_dev)
66{
67 struct list_head *itr;
68
69 if (num_devices == ADF_MAX_DEVICES) {
70 pr_err("QAT: Only support up to %d devices\n", ADF_MAX_DEVICES);
71 return -EFAULT;
72 }
73
74 mutex_lock(&table_lock);
75 list_for_each(itr, &accel_table) {
76 struct adf_accel_dev *ptr =
77 list_entry(itr, struct adf_accel_dev, list);
78
79 if (ptr == accel_dev) {
80 mutex_unlock(&table_lock);
81 return -EEXIST;
82 }
83 }
84 atomic_set(&accel_dev->ref_count, 0);
85 list_add_tail(&accel_dev->list, &accel_table);
86 accel_dev->accel_id = num_devices++;
87 mutex_unlock(&table_lock);
88 return 0;
89}
90EXPORT_SYMBOL_GPL(adf_devmgr_add_dev);
91
92struct list_head *adf_devmgr_get_head(void)
93{
94 return &accel_table;
95}
96
97/**
98 * adf_devmgr_rm_dev() - Remove accel_dev from the acceleration framework.
99 * @accel_dev: Pointer to acceleration device.
100 *
101 * Function removes acceleration device from the acceleration framework.
102 * To be used by QAT device specific drivers.
103 *
104 * Return: void
105 */
106void adf_devmgr_rm_dev(struct adf_accel_dev *accel_dev)
107{
108 mutex_lock(&table_lock);
109 list_del(&accel_dev->list);
110 num_devices--;
111 mutex_unlock(&table_lock);
112}
113EXPORT_SYMBOL_GPL(adf_devmgr_rm_dev);
114
115struct adf_accel_dev *adf_devmgr_get_first(void)
116{
117 struct adf_accel_dev *dev = NULL;
118
119 if (!list_empty(&accel_table))
120 dev = list_first_entry(&accel_table, struct adf_accel_dev,
121 list);
122 return dev;
123}
124
125/**
126 * adf_devmgr_pci_to_accel_dev() - Get accel_dev associated with the pci_dev.
127 * @accel_dev: Pointer to pci device.
128 *
129 * Function returns acceleration device associated with the given pci device.
130 * To be used by QAT device specific drivers.
131 *
132 * Return: pinter to accel_dev or NULL if not found.
133 */
134struct adf_accel_dev *adf_devmgr_pci_to_accel_dev(struct pci_dev *pci_dev)
135{
136 struct list_head *itr;
137
138 list_for_each(itr, &accel_table) {
139 struct adf_accel_dev *ptr =
140 list_entry(itr, struct adf_accel_dev, list);
141
142 if (ptr->accel_pci_dev.pci_dev == pci_dev) {
143 mutex_unlock(&table_lock);
144 return ptr;
145 }
146 }
147 return NULL;
148}
149EXPORT_SYMBOL_GPL(adf_devmgr_pci_to_accel_dev);
150
151struct adf_accel_dev *adf_devmgr_get_dev_by_id(uint32_t id)
152{
153 struct list_head *itr;
154
155 list_for_each(itr, &accel_table) {
156 struct adf_accel_dev *ptr =
157 list_entry(itr, struct adf_accel_dev, list);
158
159 if (ptr->accel_id == id) {
160 mutex_unlock(&table_lock);
161 return ptr;
162 }
163 }
164 return NULL;
165}
166
167int adf_devmgr_verify_id(uint32_t id)
168{
169 if (id == ADF_CFG_ALL_DEVICES)
170 return 0;
171
172 if (adf_devmgr_get_dev_by_id(id))
173 return 0;
174
175 return -ENODEV;
176}
177
178void adf_devmgr_get_num_dev(uint32_t *num)
179{
180 struct list_head *itr;
181
182 *num = 0;
183 list_for_each(itr, &accel_table) {
184 (*num)++;
185 }
186}
187
188int adf_dev_in_use(struct adf_accel_dev *accel_dev)
189{
190 return atomic_read(&accel_dev->ref_count) != 0;
191}
192
193int adf_dev_get(struct adf_accel_dev *accel_dev)
194{
195 if (atomic_add_return(1, &accel_dev->ref_count) == 1)
196 if (!try_module_get(accel_dev->owner))
197 return -EFAULT;
198 return 0;
199}
200
201void adf_dev_put(struct adf_accel_dev *accel_dev)
202{
203 if (atomic_sub_return(1, &accel_dev->ref_count) == 0)
204 module_put(accel_dev->owner);
205}
206
207int adf_devmgr_in_reset(struct adf_accel_dev *accel_dev)
208{
209 return test_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
210}
211
212int adf_dev_started(struct adf_accel_dev *accel_dev)
213{
214 return test_bit(ADF_STATUS_STARTED, &accel_dev->status);
215}
diff --git a/drivers/crypto/qat/qat_common/adf_init.c b/drivers/crypto/qat/qat_common/adf_init.c
new file mode 100644
index 000000000000..5c3d6f12951a
--- /dev/null
+++ b/drivers/crypto/qat/qat_common/adf_init.c
@@ -0,0 +1,388 @@
1/*
2 This file is provided under a dual BSD/GPLv2 license. When using or
3 redistributing this file, you may do so under either license.
4
5 GPL LICENSE SUMMARY
6 Copyright(c) 2014 Intel Corporation.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of version 2 of the GNU General Public License as
9 published by the Free Software Foundation.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 Contact Information:
17 qat-linux@intel.com
18
19 BSD LICENSE
20 Copyright(c) 2014 Intel Corporation.
21 Redistribution and use in source and binary forms, with or without
22 modification, are permitted provided that the following conditions
23 are met:
24
25 * Redistributions of source code must retain the above copyright
26 notice, this list of conditions and the following disclaimer.
27 * Redistributions in binary form must reproduce the above copyright
28 notice, this list of conditions and the following disclaimer in
29 the documentation and/or other materials provided with the
30 distribution.
31 * Neither the name of Intel Corporation nor the names of its
32 contributors may be used to endorse or promote products derived
33 from this software without specific prior written permission.
34
35 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46*/
47#include <linux/mutex.h>
48#include <linux/list.h>
49#include <linux/bitops.h>
50#include <linux/delay.h>
51#include "adf_accel_devices.h"
52#include "adf_cfg.h"
53#include "adf_common_drv.h"
54
55static LIST_HEAD(service_table);
56static DEFINE_MUTEX(service_lock);
57
58static void adf_service_add(struct service_hndl *service)
59{
60 mutex_lock(&service_lock);
61 list_add(&service->list, &service_table);
62 mutex_unlock(&service_lock);
63}
64
65/**
66 * adf_service_register() - Register acceleration service in the accel framework
67 * @service: Pointer to the service
68 *
69 * Function adds the acceleration service to the acceleration framework.
70 * To be used by QAT device specific drivers.
71 *
72 * Return: 0 on success, error code othewise.
73 */
74int adf_service_register(struct service_hndl *service)
75{
76 service->init_status = 0;
77 service->start_status = 0;
78 adf_service_add(service);
79 return 0;
80}
81EXPORT_SYMBOL_GPL(adf_service_register);
82
83static void adf_service_remove(struct service_hndl *service)
84{
85 mutex_lock(&service_lock);
86 list_del(&service->list);
87 mutex_unlock(&service_lock);
88}
89
90/**
91 * adf_service_unregister() - Unregister acceleration service from the framework
92 * @service: Pointer to the service
93 *
94 * Function remove the acceleration service from the acceleration framework.
95 * To be used by QAT device specific drivers.
96 *
97 * Return: 0 on success, error code othewise.
98 */
99int adf_service_unregister(struct service_hndl *service)
100{
101 if (service->init_status || service->start_status) {
102 pr_err("QAT: Could not remove active service\n");
103 return -EFAULT;
104 }
105 adf_service_remove(service);
106 return 0;
107}
108EXPORT_SYMBOL_GPL(adf_service_unregister);
109
110/**
111 * adf_dev_start() - Start acceleration service for the given accel device
112 * @accel_dev: Pointer to acceleration device.
113 *
114 * Function notifies all the registered services that the acceleration device
115 * is ready to be used.
116 * To be used by QAT device specific drivers.
117 *
118 * Return: 0 on success, error code othewise.
119 */
120int adf_dev_start(struct adf_accel_dev *accel_dev)
121{
122 struct service_hndl *service;
123 struct list_head *list_itr;
124 struct adf_hw_device_data *hw_data = accel_dev->hw_device;
125
126 if (!test_bit(ADF_STATUS_CONFIGURED, &accel_dev->status)) {
127 pr_info("QAT: Device not configured\n");
128 return -EFAULT;
129 }
130 set_bit(ADF_STATUS_STARTING, &accel_dev->status);
131
132 if (adf_ae_init(accel_dev)) {
133 pr_err("QAT: Failed to initialise Acceleration Engine\n");
134 return -EFAULT;
135 }
136 set_bit(ADF_STATUS_AE_INITIALISED, &accel_dev->status);
137
138 if (adf_ae_fw_load(accel_dev)) {
139 pr_err("Failed to load acceleration FW\n");
140 adf_ae_fw_release(accel_dev);
141 return -EFAULT;
142 }
143 set_bit(ADF_STATUS_AE_UCODE_LOADED, &accel_dev->status);
144
145 if (hw_data->alloc_irq(accel_dev)) {
146 pr_err("QAT: Failed to allocate interrupts\n");
147 return -EFAULT;
148 }
149 set_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status);
150
151 /*
152 * Subservice initialisation is divided into two stages: init and start.
153 * This is to facilitate any ordering dependencies between services
154 * prior to starting any of the accelerators.
155 */
156 list_for_each(list_itr, &service_table) {
157 service = list_entry(list_itr, struct service_hndl, list);
158 if (!service->admin)
159 continue;
160 if (service->event_hld(accel_dev, ADF_EVENT_INIT)) {
161 pr_err("QAT: Failed to initialise service %s\n",
162 service->name);
163 return -EFAULT;
164 }
165 set_bit(accel_dev->accel_id, &service->init_status);
166 }
167 list_for_each(list_itr, &service_table) {
168 service = list_entry(list_itr, struct service_hndl, list);
169 if (service->admin)
170 continue;
171 if (service->event_hld(accel_dev, ADF_EVENT_INIT)) {
172 pr_err("QAT: Failed to initialise service %s\n",
173 service->name);
174 return -EFAULT;
175 }
176 set_bit(accel_dev->accel_id, &service->init_status);
177 }
178
179 hw_data->enable_error_correction(accel_dev);
180
181 if (adf_ae_start(accel_dev)) {
182 pr_err("QAT: AE Start Failed\n");
183 return -EFAULT;
184 }
185 set_bit(ADF_STATUS_AE_STARTED, &accel_dev->status);
186
187 list_for_each(list_itr, &service_table) {
188 service = list_entry(list_itr, struct service_hndl, list);
189 if (!service->admin)
190 continue;
191 if (service->event_hld(accel_dev, ADF_EVENT_START)) {
192 pr_err("QAT: Failed to start service %s\n",
193 service->name);
194 return -EFAULT;
195 }
196 set_bit(accel_dev->accel_id, &service->start_status);
197 }
198 list_for_each(list_itr, &service_table) {
199 service = list_entry(list_itr, struct service_hndl, list);
200 if (service->admin)
201 continue;
202 if (service->event_hld(accel_dev, ADF_EVENT_START)) {
203 pr_err("QAT: Failed to start service %s\n",
204 service->name);
205 return -EFAULT;
206 }
207 set_bit(accel_dev->accel_id, &service->start_status);
208 }
209
210 clear_bit(ADF_STATUS_STARTING, &accel_dev->status);
211 set_bit(ADF_STATUS_STARTED, &accel_dev->status);
212
213 if (qat_algs_register()) {
214 pr_err("QAT: Failed to register crypto algs\n");
215 set_bit(ADF_STATUS_STARTING, &accel_dev->status);
216 clear_bit(ADF_STATUS_STARTED, &accel_dev->status);
217 return -EFAULT;
218 }
219 return 0;
220}
221EXPORT_SYMBOL_GPL(adf_dev_start);
222
223/**
224 * adf_dev_stop() - Stop acceleration service for the given accel device
225 * @accel_dev: Pointer to acceleration device.
226 *
227 * Function notifies all the registered services that the acceleration device
228 * is shuting down.
229 * To be used by QAT device specific drivers.
230 *
231 * Return: 0 on success, error code othewise.
232 */
233int adf_dev_stop(struct adf_accel_dev *accel_dev)
234{
235 struct adf_hw_device_data *hw_data = accel_dev->hw_device;
236 struct service_hndl *service;
237 struct list_head *list_itr;
238 int ret, wait = 0;
239
240 if (!adf_dev_started(accel_dev) &&
241 !test_bit(ADF_STATUS_STARTING, &accel_dev->status)) {
242 return 0;
243 }
244 clear_bit(ADF_STATUS_CONFIGURED, &accel_dev->status);
245 clear_bit(ADF_STATUS_STARTING, &accel_dev->status);
246 clear_bit(ADF_STATUS_STARTED, &accel_dev->status);
247
248 if (qat_algs_unregister())
249 pr_err("QAT: Failed to unregister crypto algs\n");
250
251 list_for_each(list_itr, &service_table) {
252 service = list_entry(list_itr, struct service_hndl, list);
253 if (service->admin)
254 continue;
255 if (!test_bit(accel_dev->accel_id, &service->start_status))
256 continue;
257 ret = service->event_hld(accel_dev, ADF_EVENT_STOP);
258 if (!ret) {
259 clear_bit(accel_dev->accel_id, &service->start_status);
260 } else if (ret == -EAGAIN) {
261 wait = 1;
262 clear_bit(accel_dev->accel_id, &service->start_status);
263 }
264 }
265 list_for_each(list_itr, &service_table) {
266 service = list_entry(list_itr, struct service_hndl, list);
267 if (!service->admin)
268 continue;
269 if (!test_bit(accel_dev->accel_id, &service->start_status))
270 continue;
271 if (service->event_hld(accel_dev, ADF_EVENT_STOP))
272 pr_err("QAT: Failed to shutdown service %s\n",
273 service->name);
274 else
275 clear_bit(accel_dev->accel_id, &service->start_status);
276 }
277
278 if (wait)
279 msleep(100);
280
281 if (adf_dev_started(accel_dev)) {
282 if (adf_ae_stop(accel_dev))
283 pr_err("QAT: failed to stop AE\n");
284 else
285 clear_bit(ADF_STATUS_AE_STARTED, &accel_dev->status);
286 }
287
288 if (test_bit(ADF_STATUS_AE_UCODE_LOADED, &accel_dev->status)) {
289 if (adf_ae_fw_release(accel_dev))
290 pr_err("QAT: Failed to release the ucode\n");
291 else
292 clear_bit(ADF_STATUS_AE_UCODE_LOADED,
293 &accel_dev->status);
294 }
295
296 if (test_bit(ADF_STATUS_AE_INITIALISED, &accel_dev->status)) {
297 if (adf_ae_shutdown(accel_dev))
298 pr_err("QAT: Failed to shutdown Accel Engine\n");
299 else
300 clear_bit(ADF_STATUS_AE_INITIALISED,
301 &accel_dev->status);
302 }
303
304 list_for_each(list_itr, &service_table) {
305 service = list_entry(list_itr, struct service_hndl, list);
306 if (service->admin)
307 continue;
308 if (!test_bit(accel_dev->accel_id, &service->init_status))
309 continue;
310 if (service->event_hld(accel_dev, ADF_EVENT_SHUTDOWN))
311 pr_err("QAT: Failed to shutdown service %s\n",
312 service->name);
313 else
314 clear_bit(accel_dev->accel_id, &service->init_status);
315 }
316 list_for_each(list_itr, &service_table) {
317 service = list_entry(list_itr, struct service_hndl, list);
318 if (!service->admin)
319 continue;
320 if (!test_bit(accel_dev->accel_id, &service->init_status))
321 continue;
322 if (service->event_hld(accel_dev, ADF_EVENT_SHUTDOWN))
323 pr_err("QAT: Failed to shutdown service %s\n",
324 service->name);
325 else
326 clear_bit(accel_dev->accel_id, &service->init_status);
327 }
328
329 if (test_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status)) {
330 hw_data->free_irq(accel_dev);
331 clear_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status);
332 }
333
334 /* Delete configuration only if not restarting */
335 if (!test_bit(ADF_STATUS_RESTARTING, &accel_dev->status))
336 adf_cfg_del_all(accel_dev);
337
338 return 0;
339}
340EXPORT_SYMBOL_GPL(adf_dev_stop);
341
342int adf_dev_restarting_notify(struct adf_accel_dev *accel_dev)
343{
344 struct service_hndl *service;
345 struct list_head *list_itr;
346
347 list_for_each(list_itr, &service_table) {
348 service = list_entry(list_itr, struct service_hndl, list);
349 if (service->admin)
350 continue;
351 if (service->event_hld(accel_dev, ADF_EVENT_RESTARTING))
352 pr_err("QAT: Failed to restart service %s.\n",
353 service->name);
354 }
355 list_for_each(list_itr, &service_table) {
356 service = list_entry(list_itr, struct service_hndl, list);
357 if (!service->admin)
358 continue;
359 if (service->event_hld(accel_dev, ADF_EVENT_RESTARTING))
360 pr_err("QAT: Failed to restart service %s.\n",
361 service->name);
362 }
363 return 0;
364}
365
366int adf_dev_restarted_notify(struct adf_accel_dev *accel_dev)
367{
368 struct service_hndl *service;
369 struct list_head *list_itr;
370
371 list_for_each(list_itr, &service_table) {
372 service = list_entry(list_itr, struct service_hndl, list);
373 if (service->admin)
374 continue;
375 if (service->event_hld(accel_dev, ADF_EVENT_RESTARTED))
376 pr_err("QAT: Failed to restart service %s.\n",
377 service->name);
378 }
379 list_for_each(list_itr, &service_table) {
380 service = list_entry(list_itr, struct service_hndl, list);
381 if (!service->admin)
382 continue;
383 if (service->event_hld(accel_dev, ADF_EVENT_RESTARTED))
384 pr_err("QAT: Failed to restart service %s.\n",
385 service->name);
386 }
387 return 0;
388}