]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/crypto/qat/qat_dh895xccvf/adf_drv.c
7bec249afdb9bc0c1ef21863631001074d71af1c
[mirror_ubuntu-bionic-kernel.git] / drivers / crypto / qat / qat_dh895xccvf / adf_drv.c
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/module.h>
49 #include <linux/pci.h>
50 #include <linux/init.h>
51 #include <linux/types.h>
52 #include <linux/fs.h>
53 #include <linux/slab.h>
54 #include <linux/errno.h>
55 #include <linux/device.h>
56 #include <linux/dma-mapping.h>
57 #include <linux/platform_device.h>
58 #include <linux/workqueue.h>
59 #include <linux/io.h>
60 #include <adf_accel_devices.h>
61 #include <adf_common_drv.h>
62 #include <adf_cfg.h>
63 #include <adf_transport_access_macros.h>
64 #include "adf_dh895xccvf_hw_data.h"
65 #include "adf_drv.h"
66
67 static const char adf_driver_name[] = ADF_DH895XCCVF_DEVICE_NAME;
68
69 #define ADF_SYSTEM_DEVICE(device_id) \
70 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
71
72 static const struct pci_device_id adf_pci_tbl[] = {
73 ADF_SYSTEM_DEVICE(ADF_DH895XCCIOV_PCI_DEVICE_ID),
74 {0,}
75 };
76 MODULE_DEVICE_TABLE(pci, adf_pci_tbl);
77
78 static int adf_probe(struct pci_dev *dev, const struct pci_device_id *ent);
79 static void adf_remove(struct pci_dev *dev);
80
81 static struct pci_driver adf_driver = {
82 .id_table = adf_pci_tbl,
83 .name = adf_driver_name,
84 .probe = adf_probe,
85 .remove = adf_remove,
86 };
87
88 static void adf_cleanup_pci_dev(struct adf_accel_dev *accel_dev)
89 {
90 pci_release_regions(accel_dev->accel_pci_dev.pci_dev);
91 pci_disable_device(accel_dev->accel_pci_dev.pci_dev);
92 }
93
94 static void adf_cleanup_accel(struct adf_accel_dev *accel_dev)
95 {
96 struct adf_accel_pci *accel_pci_dev = &accel_dev->accel_pci_dev;
97 struct adf_accel_dev *pf;
98 int i;
99
100 for (i = 0; i < ADF_PCI_MAX_BARS; i++) {
101 struct adf_bar *bar = &accel_pci_dev->pci_bars[i];
102
103 if (bar->virt_addr)
104 pci_iounmap(accel_pci_dev->pci_dev, bar->virt_addr);
105 }
106
107 if (accel_dev->hw_device) {
108 switch (accel_pci_dev->pci_dev->device) {
109 case ADF_DH895XCCIOV_PCI_DEVICE_ID:
110 adf_clean_hw_data_dh895xcciov(accel_dev->hw_device);
111 break;
112 default:
113 break;
114 }
115 kfree(accel_dev->hw_device);
116 accel_dev->hw_device = NULL;
117 }
118 adf_cfg_dev_remove(accel_dev);
119 debugfs_remove(accel_dev->debugfs_dir);
120 pf = adf_devmgr_pci_to_accel_dev(accel_pci_dev->pci_dev->physfn);
121 adf_devmgr_rm_dev(accel_dev, pf);
122 }
123
124 static int adf_dev_configure(struct adf_accel_dev *accel_dev)
125 {
126 char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
127 unsigned long val, bank = 0;
128
129 if (adf_cfg_section_add(accel_dev, ADF_KERNEL_SEC))
130 goto err;
131 if (adf_cfg_section_add(accel_dev, "Accelerator0"))
132 goto err;
133
134 snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_BANK_NUM, 0);
135 if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC, key,
136 (void *)&bank, ADF_DEC))
137 goto err;
138
139 val = bank;
140 snprintf(key, sizeof(key), ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY, 0);
141 if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC, key,
142 (void *)&val, ADF_DEC))
143 goto err;
144
145 snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_SIZE, 0);
146
147 val = 128;
148 if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC, key,
149 (void *)&val, ADF_DEC))
150 goto err;
151
152 val = 512;
153 snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_SYM_SIZE, 0);
154 if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
155 key, (void *)&val, ADF_DEC))
156 goto err;
157
158 val = 0;
159 snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_TX, 0);
160 if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
161 key, (void *)&val, ADF_DEC))
162 goto err;
163
164 val = 2;
165 snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_SYM_TX, 0);
166 if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
167 key, (void *)&val, ADF_DEC))
168 goto err;
169
170 val = 8;
171 snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_RX, 0);
172 if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
173 key, (void *)&val, ADF_DEC))
174 goto err;
175
176 val = 10;
177 snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_SYM_RX, 0);
178 if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
179 key, (void *)&val, ADF_DEC))
180 goto err;
181
182 val = ADF_COALESCING_DEF_TIME;
183 snprintf(key, sizeof(key), ADF_ETRMGR_COALESCE_TIMER_FORMAT,
184 (int)bank);
185 if (adf_cfg_add_key_value_param(accel_dev, "Accelerator0",
186 key, (void *)&val, ADF_DEC))
187 goto err;
188
189 val = 1;
190 if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC,
191 ADF_NUM_CY, (void *)&val, ADF_DEC))
192 goto err;
193
194 set_bit(ADF_STATUS_CONFIGURED, &accel_dev->status);
195 return 0;
196 err:
197 dev_err(&GET_DEV(accel_dev), "Failed to configure QAT accel dev\n");
198 return -EINVAL;
199 }
200
201 static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
202 {
203 struct adf_accel_dev *accel_dev;
204 struct adf_accel_dev *pf;
205 struct adf_accel_pci *accel_pci_dev;
206 struct adf_hw_device_data *hw_data;
207 char name[ADF_DEVICE_NAME_LENGTH];
208 unsigned int i, bar_nr;
209 int ret, bar_mask;
210
211 switch (ent->device) {
212 case ADF_DH895XCCIOV_PCI_DEVICE_ID:
213 break;
214 default:
215 dev_err(&pdev->dev, "Invalid device 0x%x.\n", ent->device);
216 return -ENODEV;
217 }
218
219 accel_dev = kzalloc_node(sizeof(*accel_dev), GFP_KERNEL,
220 dev_to_node(&pdev->dev));
221 if (!accel_dev)
222 return -ENOMEM;
223
224 accel_dev->is_vf = true;
225 pf = adf_devmgr_pci_to_accel_dev(pdev->physfn);
226 accel_pci_dev = &accel_dev->accel_pci_dev;
227 accel_pci_dev->pci_dev = pdev;
228
229 /* Add accel device to accel table */
230 if (adf_devmgr_add_dev(accel_dev, pf)) {
231 dev_err(&pdev->dev, "Failed to add new accelerator device.\n");
232 kfree(accel_dev);
233 return -EFAULT;
234 }
235 INIT_LIST_HEAD(&accel_dev->crypto_list);
236
237 accel_dev->owner = THIS_MODULE;
238 /* Allocate and configure device configuration structure */
239 hw_data = kzalloc_node(sizeof(*hw_data), GFP_KERNEL,
240 dev_to_node(&pdev->dev));
241 if (!hw_data) {
242 ret = -ENOMEM;
243 goto out_err;
244 }
245 accel_dev->hw_device = hw_data;
246 adf_init_hw_data_dh895xcciov(accel_dev->hw_device);
247
248 /* Get Accelerators and Accelerators Engines masks */
249 hw_data->accel_mask = hw_data->get_accel_mask(hw_data->fuses);
250 hw_data->ae_mask = hw_data->get_ae_mask(hw_data->fuses);
251 accel_pci_dev->sku = hw_data->get_sku(hw_data);
252
253 /* Create dev top level debugfs entry */
254 snprintf(name, sizeof(name), "%s%s_%02x:%02d.%02d",
255 ADF_DEVICE_NAME_PREFIX, hw_data->dev_class->name,
256 pdev->bus->number, PCI_SLOT(pdev->devfn),
257 PCI_FUNC(pdev->devfn));
258
259 accel_dev->debugfs_dir = debugfs_create_dir(name, NULL);
260 if (!accel_dev->debugfs_dir) {
261 dev_err(&pdev->dev, "Could not create debugfs dir %s\n", name);
262 ret = -EINVAL;
263 goto out_err;
264 }
265
266 /* Create device configuration table */
267 ret = adf_cfg_dev_add(accel_dev);
268 if (ret)
269 goto out_err;
270
271 /* enable PCI device */
272 if (pci_enable_device(pdev)) {
273 ret = -EFAULT;
274 goto out_err;
275 }
276
277 /* set dma identifier */
278 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
279 if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) {
280 dev_err(&pdev->dev, "No usable DMA configuration\n");
281 ret = -EFAULT;
282 goto out_err_disable;
283 } else {
284 pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
285 }
286
287 } else {
288 pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
289 }
290
291 if (pci_request_regions(pdev, adf_driver_name)) {
292 ret = -EFAULT;
293 goto out_err_disable;
294 }
295
296 /* Find and map all the device's BARS */
297 i = 0;
298 bar_mask = pci_select_bars(pdev, IORESOURCE_MEM);
299 for_each_set_bit(bar_nr, (const unsigned long *)&bar_mask,
300 ADF_PCI_MAX_BARS * 2) {
301 struct adf_bar *bar = &accel_pci_dev->pci_bars[i++];
302
303 bar->base_addr = pci_resource_start(pdev, bar_nr);
304 if (!bar->base_addr)
305 break;
306 bar->size = pci_resource_len(pdev, bar_nr);
307 bar->virt_addr = pci_iomap(accel_pci_dev->pci_dev, bar_nr, 0);
308 if (!bar->virt_addr) {
309 dev_err(&pdev->dev, "Failed to map BAR %d\n", bar_nr);
310 ret = -EFAULT;
311 goto out_err_free_reg;
312 }
313 }
314 pci_set_master(pdev);
315 /* Completion for VF2PF request/response message exchange */
316 init_completion(&accel_dev->vf.iov_msg_completion);
317
318 ret = adf_dev_configure(accel_dev);
319 if (ret)
320 goto out_err_free_reg;
321
322 ret = adf_dev_init(accel_dev);
323 if (ret)
324 goto out_err_dev_shutdown;
325
326 ret = adf_dev_start(accel_dev);
327 if (ret)
328 goto out_err_dev_stop;
329
330 return ret;
331
332 out_err_dev_stop:
333 adf_dev_stop(accel_dev);
334 out_err_dev_shutdown:
335 adf_dev_shutdown(accel_dev);
336 out_err_free_reg:
337 pci_release_regions(accel_pci_dev->pci_dev);
338 out_err_disable:
339 pci_disable_device(accel_pci_dev->pci_dev);
340 out_err:
341 adf_cleanup_accel(accel_dev);
342 kfree(accel_dev);
343 return ret;
344 }
345
346 static void adf_remove(struct pci_dev *pdev)
347 {
348 struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev);
349
350 if (!accel_dev) {
351 pr_err("QAT: Driver removal failed\n");
352 return;
353 }
354 if (adf_dev_stop(accel_dev))
355 dev_err(&GET_DEV(accel_dev), "Failed to stop QAT accel dev\n");
356
357 adf_dev_shutdown(accel_dev);
358 adf_cleanup_accel(accel_dev);
359 adf_cleanup_pci_dev(accel_dev);
360 kfree(accel_dev);
361 }
362
363 static int __init adfdrv_init(void)
364 {
365 request_module("intel_qat");
366
367 if (pci_register_driver(&adf_driver)) {
368 pr_err("QAT: Driver initialization failed\n");
369 return -EFAULT;
370 }
371 return 0;
372 }
373
374 static void __exit adfdrv_release(void)
375 {
376 pci_unregister_driver(&adf_driver);
377 adf_clean_vf_map(true);
378 }
379
380 module_init(adfdrv_init);
381 module_exit(adfdrv_release);
382
383 MODULE_LICENSE("Dual BSD/GPL");
384 MODULE_AUTHOR("Intel");
385 MODULE_DESCRIPTION("Intel(R) QuickAssist Technology");
386 MODULE_VERSION(ADF_DRV_VERSION);