diff options
author | Tadeusz Struk <tadeusz.struk@intel.com> | 2014-06-05 16:42:39 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2014-06-20 09:26:15 -0400 |
commit | d8cba25d2c68992a6e7c1d329b690a9ebe01167d (patch) | |
tree | af71c6b9fc92678d4ab6cf60cfd46b1bda99b5aa | |
parent | c4f4b325e9c885b11901174158d5e1ff4b19a189 (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/Kconfig | 22 | ||||
-rw-r--r-- | drivers/crypto/qat/Makefile | 2 | ||||
-rw-r--r-- | drivers/crypto/qat/qat_common/Makefile | 14 | ||||
-rw-r--r-- | drivers/crypto/qat/qat_common/adf_accel_devices.h | 204 | ||||
-rw-r--r-- | drivers/crypto/qat/qat_common/adf_accel_engine.c | 168 | ||||
-rw-r--r-- | drivers/crypto/qat/qat_common/adf_aer.c | 258 | ||||
-rw-r--r-- | drivers/crypto/qat/qat_common/adf_cfg.c | 359 | ||||
-rw-r--r-- | drivers/crypto/qat/qat_common/adf_cfg.h | 87 | ||||
-rw-r--r-- | drivers/crypto/qat/qat_common/adf_cfg_common.h | 100 | ||||
-rw-r--r-- | drivers/crypto/qat/qat_common/adf_cfg_strings.h | 83 | ||||
-rw-r--r-- | drivers/crypto/qat/qat_common/adf_cfg_user.h | 94 | ||||
-rw-r--r-- | drivers/crypto/qat/qat_common/adf_common_drv.h | 192 | ||||
-rw-r--r-- | drivers/crypto/qat/qat_common/adf_ctl_drv.c | 490 | ||||
-rw-r--r-- | drivers/crypto/qat/qat_common/adf_dev_mgr.c | 215 | ||||
-rw-r--r-- | drivers/crypto/qat/qat_common/adf_init.c | 388 |
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 @@ | |||
1 | config 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 | |||
12 | config 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 @@ | |||
1 | obj-$(CONFIG_CRYPTO_DEV_QAT) += qat_common/ | ||
2 | obj-$(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 @@ | |||
1 | obj-$(CONFIG_CRYPTO_DEV_QAT) += intel_qat.o | ||
2 | intel_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 | |||
14 | intel_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 | |||
66 | enum 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 | |||
77 | struct adf_bar { | ||
78 | resource_size_t base_addr; | ||
79 | void __iomem *virt_addr; | ||
80 | resource_size_t size; | ||
81 | } __packed; | ||
82 | |||
83 | struct adf_accel_msix { | ||
84 | struct msix_entry *entries; | ||
85 | char **names; | ||
86 | } __packed; | ||
87 | |||
88 | struct 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 | |||
96 | enum dev_state { | ||
97 | DEV_DOWN = 0, | ||
98 | DEV_UP | ||
99 | }; | ||
100 | |||
101 | enum 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 | |||
109 | static 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 | |||
127 | struct adf_hw_device_class { | ||
128 | const char *name; | ||
129 | const enum adf_device_type type; | ||
130 | uint32_t instances; | ||
131 | } __packed; | ||
132 | |||
133 | struct adf_cfg_device_data; | ||
134 | struct adf_accel_dev; | ||
135 | struct adf_etr_data; | ||
136 | struct adf_etr_ring_data; | ||
137 | |||
138 | struct 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 | |||
181 | struct adf_admin_comms; | ||
182 | struct icp_qat_fw_loader_handle; | ||
183 | struct adf_fw_loader_data { | ||
184 | struct icp_qat_fw_loader_handle *fw_loader; | ||
185 | const struct firmware *uof_fw; | ||
186 | }; | ||
187 | |||
188 | struct 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 | |||
54 | int 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 | |||
79 | out_err: | ||
80 | release_firmware(loader_data->uof_fw); | ||
81 | return -EFAULT; | ||
82 | } | ||
83 | |||
84 | int 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 | |||
95 | int 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 | |||
112 | int 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 | |||
129 | static 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 | |||
140 | int 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 | |||
163 | int 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 | |||
56 | static struct workqueue_struct *device_reset_wq; | ||
57 | |||
58 | static 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 */ | ||
78 | struct 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 | ||
86 | static 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 | |||
119 | static 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 | |||
145 | static 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 | |||
181 | static 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 | |||
196 | static 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 | |||
202 | static 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 | */ | ||
219 | int 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 | } | ||
227 | EXPORT_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 | */ | ||
239 | void 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 | } | ||
245 | EXPORT_SYMBOL_GPL(adf_disable_aer); | ||
246 | |||
247 | int 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 | |||
253 | void 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 | |||
55 | static DEFINE_MUTEX(qat_cfg_read_lock); | ||
56 | |||
57 | static 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 | |||
64 | static 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 | |||
79 | static 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 | |||
85 | static void qat_dev_cfg_stop(struct seq_file *sfile, void *v) | ||
86 | { | ||
87 | mutex_unlock(&qat_cfg_read_lock); | ||
88 | } | ||
89 | |||
90 | static 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 | |||
97 | static 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 | |||
108 | static 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 | */ | ||
125 | int 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 | } | ||
149 | EXPORT_SYMBOL_GPL(adf_cfg_dev_add); | ||
150 | |||
151 | static void adf_cfg_section_del_all(struct list_head *head); | ||
152 | |||
153 | void 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 | */ | ||
172 | void 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 | } | ||
183 | EXPORT_SYMBOL_GPL(adf_cfg_dev_remove); | ||
184 | |||
185 | static 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 | |||
191 | static 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 | |||
203 | static 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 | |||
216 | static 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 | |||
230 | static 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 | |||
245 | static 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 | */ | ||
276 | int 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 | } | ||
314 | EXPORT_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 | */ | ||
327 | int 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 | } | ||
346 | EXPORT_SYMBOL_GPL(adf_cfg_section_add); | ||
347 | |||
348 | int 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 | |||
57 | struct 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 | |||
64 | struct 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 | |||
70 | struct adf_cfg_device_data { | ||
71 | struct list_head sec_list; | ||
72 | struct dentry *debug; | ||
73 | struct rw_semaphore lock; | ||
74 | }; | ||
75 | |||
76 | int adf_cfg_dev_add(struct adf_accel_dev *accel_dev); | ||
77 | void adf_cfg_dev_remove(struct adf_accel_dev *accel_dev); | ||
78 | int adf_cfg_section_add(struct adf_accel_dev *accel_dev, const char *name); | ||
79 | void adf_cfg_del_all(struct adf_accel_dev *accel_dev); | ||
80 | int 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); | ||
84 | int 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 | |||
65 | enum adf_cfg_val_type { | ||
66 | ADF_DEC, | ||
67 | ADF_HEX, | ||
68 | ADF_STR | ||
69 | }; | ||
70 | |||
71 | enum adf_device_type { | ||
72 | DEV_UNKNOWN = 0, | ||
73 | DEV_DH895XCC, | ||
74 | }; | ||
75 | |||
76 | struct 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 | |||
53 | struct 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 | |||
71 | struct 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 | |||
87 | struct 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 | |||
66 | enum adf_dev_reset_mode { | ||
67 | ADF_DEV_RESET_ASYNC = 0, | ||
68 | ADF_DEV_RESET_SYNC | ||
69 | }; | ||
70 | |||
71 | enum 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 | |||
80 | struct 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 | |||
90 | int adf_service_register(struct service_hndl *service); | ||
91 | int adf_service_unregister(struct service_hndl *service); | ||
92 | |||
93 | int adf_dev_init(struct adf_accel_dev *accel_dev); | ||
94 | int adf_dev_start(struct adf_accel_dev *accel_dev); | ||
95 | int adf_dev_stop(struct adf_accel_dev *accel_dev); | ||
96 | int adf_dev_shutdown(struct adf_accel_dev *accel_dev); | ||
97 | |||
98 | int adf_ctl_dev_register(void); | ||
99 | void adf_ctl_dev_unregister(void); | ||
100 | int adf_processes_dev_register(void); | ||
101 | void adf_processes_dev_unregister(void); | ||
102 | |||
103 | int adf_devmgr_add_dev(struct adf_accel_dev *accel_dev); | ||
104 | void adf_devmgr_rm_dev(struct adf_accel_dev *accel_dev); | ||
105 | struct list_head *adf_devmgr_get_head(void); | ||
106 | struct adf_accel_dev *adf_devmgr_get_dev_by_id(uint32_t id); | ||
107 | struct adf_accel_dev *adf_devmgr_get_first(void); | ||
108 | struct adf_accel_dev *adf_devmgr_pci_to_accel_dev(struct pci_dev *pci_dev); | ||
109 | int adf_devmgr_verify_id(uint32_t id); | ||
110 | void adf_devmgr_get_num_dev(uint32_t *num); | ||
111 | int adf_devmgr_in_reset(struct adf_accel_dev *accel_dev); | ||
112 | int adf_dev_started(struct adf_accel_dev *accel_dev); | ||
113 | int adf_dev_restarting_notify(struct adf_accel_dev *accel_dev); | ||
114 | int adf_dev_restarted_notify(struct adf_accel_dev *accel_dev); | ||
115 | int adf_ae_init(struct adf_accel_dev *accel_dev); | ||
116 | int adf_ae_shutdown(struct adf_accel_dev *accel_dev); | ||
117 | int adf_ae_fw_load(struct adf_accel_dev *accel_dev); | ||
118 | int adf_ae_fw_release(struct adf_accel_dev *accel_dev); | ||
119 | int adf_ae_start(struct adf_accel_dev *accel_dev); | ||
120 | int adf_ae_stop(struct adf_accel_dev *accel_dev); | ||
121 | |||
122 | int adf_enable_aer(struct adf_accel_dev *accel_dev, struct pci_driver *adf); | ||
123 | void adf_disable_aer(struct adf_accel_dev *accel_dev); | ||
124 | int adf_init_aer(void); | ||
125 | void adf_exit_aer(void); | ||
126 | |||
127 | int adf_dev_get(struct adf_accel_dev *accel_dev); | ||
128 | void adf_dev_put(struct adf_accel_dev *accel_dev); | ||
129 | int adf_dev_in_use(struct adf_accel_dev *accel_dev); | ||
130 | int adf_init_etr_data(struct adf_accel_dev *accel_dev); | ||
131 | void adf_cleanup_etr_data(struct adf_accel_dev *accel_dev); | ||
132 | int qat_crypto_register(void); | ||
133 | int qat_crypto_unregister(void); | ||
134 | struct qat_crypto_instance *qat_crypto_get_instance_node(int node); | ||
135 | void qat_crypto_put_instance(struct qat_crypto_instance *inst); | ||
136 | void qat_alg_callback(void *resp); | ||
137 | int qat_algs_init(void); | ||
138 | void qat_algs_exit(void); | ||
139 | int qat_algs_register(void); | ||
140 | int qat_algs_unregister(void); | ||
141 | |||
142 | int qat_hal_init(struct adf_accel_dev *accel_dev); | ||
143 | void qat_hal_deinit(struct icp_qat_fw_loader_handle *handle); | ||
144 | void qat_hal_start(struct icp_qat_fw_loader_handle *handle, unsigned char ae, | ||
145 | unsigned int ctx_mask); | ||
146 | void qat_hal_stop(struct icp_qat_fw_loader_handle *handle, unsigned char ae, | ||
147 | unsigned int ctx_mask); | ||
148 | void qat_hal_reset(struct icp_qat_fw_loader_handle *handle); | ||
149 | int qat_hal_clr_reset(struct icp_qat_fw_loader_handle *handle); | ||
150 | void qat_hal_set_live_ctx(struct icp_qat_fw_loader_handle *handle, | ||
151 | unsigned char ae, unsigned int ctx_mask); | ||
152 | int 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); | ||
155 | int qat_hal_set_ae_ctx_mode(struct icp_qat_fw_loader_handle *handle, | ||
156 | unsigned char ae, unsigned char mode); | ||
157 | int qat_hal_set_ae_nn_mode(struct icp_qat_fw_loader_handle *handle, | ||
158 | unsigned char ae, unsigned char mode); | ||
159 | void qat_hal_set_pc(struct icp_qat_fw_loader_handle *handle, | ||
160 | unsigned char ae, unsigned int ctx_mask, unsigned int upc); | ||
161 | void 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); | ||
164 | void 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); | ||
167 | int qat_hal_get_ins_num(void); | ||
168 | int 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); | ||
171 | int 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); | ||
175 | int 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); | ||
179 | int 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); | ||
183 | int 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); | ||
186 | int qat_hal_wr_lm(struct icp_qat_fw_loader_handle *handle, | ||
187 | unsigned char ae, unsigned short lm_addr, unsigned int value); | ||
188 | int qat_uclo_wr_all_uimage(struct icp_qat_fw_loader_handle *handle); | ||
189 | int qat_uclo_del_uof_obj(struct icp_qat_fw_loader_handle *handle); | ||
190 | int 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 | |||
64 | static DEFINE_MUTEX(adf_ctl_lock); | ||
65 | static long adf_ctl_ioctl(struct file *fp, unsigned int cmd, unsigned long arg); | ||
66 | |||
67 | static 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 | |||
73 | struct adf_ctl_drv_info { | ||
74 | unsigned int major; | ||
75 | struct cdev drv_cdev; | ||
76 | struct class *drv_class; | ||
77 | }; | ||
78 | |||
79 | static struct adf_ctl_drv_info adt_ctl_drv; | ||
80 | |||
81 | static 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 | |||
89 | static 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; | ||
119 | err_cdev_del: | ||
120 | cdev_del(&adt_ctl_drv.drv_cdev); | ||
121 | err_class_destr: | ||
122 | class_destroy(adt_ctl_drv.drv_class); | ||
123 | err_chrdev_unreg: | ||
124 | unregister_chrdev_region(dev_id, 1); | ||
125 | return -EFAULT; | ||
126 | } | ||
127 | |||
128 | static 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 | |||
150 | static 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 | |||
175 | static 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(§ion, (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; | ||
213 | out_err: | ||
214 | adf_cfg_del_all(accel_dev); | ||
215 | return -EFAULT; | ||
216 | } | ||
217 | |||
218 | static 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); | ||
245 | out: | ||
246 | kfree(ctl_data); | ||
247 | return ret; | ||
248 | } | ||
249 | |||
250 | static 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 | |||
269 | static 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 | |||
290 | static 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"); | ||
319 | out: | ||
320 | kfree(ctl_data); | ||
321 | return ret; | ||
322 | } | ||
323 | |||
324 | static 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 | } | ||
354 | out: | ||
355 | kfree(ctl_data); | ||
356 | return ret; | ||
357 | } | ||
358 | |||
359 | static 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 | |||
371 | static 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 | |||
411 | static 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 | |||
447 | static 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 | |||
465 | err_crypto_register: | ||
466 | adf_exit_aer(); | ||
467 | err_aer: | ||
468 | adf_chr_drv_destroy(); | ||
469 | err_chr_dev: | ||
470 | qat_algs_exit(); | ||
471 | err_algs_init: | ||
472 | mutex_destroy(&adf_ctl_lock); | ||
473 | return -EFAULT; | ||
474 | } | ||
475 | |||
476 | static 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 | |||
485 | module_init(adf_register_ctl_device_driver); | ||
486 | module_exit(adf_unregister_ctl_device_driver); | ||
487 | MODULE_LICENSE("Dual BSD/GPL"); | ||
488 | MODULE_AUTHOR("Intel"); | ||
489 | MODULE_DESCRIPTION("Intel(R) QuickAssist Technology"); | ||
490 | MODULE_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 | |||
52 | static LIST_HEAD(accel_table); | ||
53 | static DEFINE_MUTEX(table_lock); | ||
54 | static 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 | */ | ||
65 | int 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 | } | ||
90 | EXPORT_SYMBOL_GPL(adf_devmgr_add_dev); | ||
91 | |||
92 | struct 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 | */ | ||
106 | void 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 | } | ||
113 | EXPORT_SYMBOL_GPL(adf_devmgr_rm_dev); | ||
114 | |||
115 | struct 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 | */ | ||
134 | struct 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 | } | ||
149 | EXPORT_SYMBOL_GPL(adf_devmgr_pci_to_accel_dev); | ||
150 | |||
151 | struct 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 | |||
167 | int 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 | |||
178 | void 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 | |||
188 | int adf_dev_in_use(struct adf_accel_dev *accel_dev) | ||
189 | { | ||
190 | return atomic_read(&accel_dev->ref_count) != 0; | ||
191 | } | ||
192 | |||
193 | int 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 | |||
201 | void 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 | |||
207 | int adf_devmgr_in_reset(struct adf_accel_dev *accel_dev) | ||
208 | { | ||
209 | return test_bit(ADF_STATUS_RESTARTING, &accel_dev->status); | ||
210 | } | ||
211 | |||
212 | int 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 | |||
55 | static LIST_HEAD(service_table); | ||
56 | static DEFINE_MUTEX(service_lock); | ||
57 | |||
58 | static 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 | */ | ||
74 | int 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 | } | ||
81 | EXPORT_SYMBOL_GPL(adf_service_register); | ||
82 | |||
83 | static 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 | */ | ||
99 | int 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 | } | ||
108 | EXPORT_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 | */ | ||
120 | int 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 | } | ||
221 | EXPORT_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 | */ | ||
233 | int 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 | } | ||
340 | EXPORT_SYMBOL_GPL(adf_dev_stop); | ||
341 | |||
342 | int 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 | |||
366 | int 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 | } | ||