]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blob - drivers/crypto/qat/qat_common/adf_ctl_drv.c
power_supply: Correct kerneldoc copy paste errors
[mirror_ubuntu-focal-kernel.git] / drivers / crypto / qat / qat_common / adf_ctl_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/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 #include <linux/crypto.h>
56
57 #include "adf_accel_devices.h"
58 #include "adf_common_drv.h"
59 #include "adf_cfg.h"
60 #include "adf_cfg_common.h"
61 #include "adf_cfg_user.h"
62
63 #define DEVICE_NAME "qat_adf_ctl"
64
65 static DEFINE_MUTEX(adf_ctl_lock);
66 static long adf_ctl_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
67
68 static const struct file_operations adf_ctl_ops = {
69 .owner = THIS_MODULE,
70 .unlocked_ioctl = adf_ctl_ioctl,
71 .compat_ioctl = adf_ctl_ioctl,
72 };
73
74 struct adf_ctl_drv_info {
75 unsigned int major;
76 struct cdev drv_cdev;
77 struct class *drv_class;
78 };
79
80 static struct adf_ctl_drv_info adf_ctl_drv;
81
82 static void adf_chr_drv_destroy(void)
83 {
84 device_destroy(adf_ctl_drv.drv_class, MKDEV(adf_ctl_drv.major, 0));
85 cdev_del(&adf_ctl_drv.drv_cdev);
86 class_destroy(adf_ctl_drv.drv_class);
87 unregister_chrdev_region(MKDEV(adf_ctl_drv.major, 0), 1);
88 }
89
90 static int adf_chr_drv_create(void)
91 {
92 dev_t dev_id;
93 struct device *drv_device;
94
95 if (alloc_chrdev_region(&dev_id, 0, 1, DEVICE_NAME)) {
96 pr_err("QAT: unable to allocate chrdev region\n");
97 return -EFAULT;
98 }
99
100 adf_ctl_drv.drv_class = class_create(THIS_MODULE, DEVICE_NAME);
101 if (IS_ERR(adf_ctl_drv.drv_class)) {
102 pr_err("QAT: class_create failed for adf_ctl\n");
103 goto err_chrdev_unreg;
104 }
105 adf_ctl_drv.major = MAJOR(dev_id);
106 cdev_init(&adf_ctl_drv.drv_cdev, &adf_ctl_ops);
107 if (cdev_add(&adf_ctl_drv.drv_cdev, dev_id, 1)) {
108 pr_err("QAT: cdev add failed\n");
109 goto err_class_destr;
110 }
111
112 drv_device = device_create(adf_ctl_drv.drv_class, NULL,
113 MKDEV(adf_ctl_drv.major, 0),
114 NULL, DEVICE_NAME);
115 if (IS_ERR(drv_device)) {
116 pr_err("QAT: failed to create device\n");
117 goto err_cdev_del;
118 }
119 return 0;
120 err_cdev_del:
121 cdev_del(&adf_ctl_drv.drv_cdev);
122 err_class_destr:
123 class_destroy(adf_ctl_drv.drv_class);
124 err_chrdev_unreg:
125 unregister_chrdev_region(dev_id, 1);
126 return -EFAULT;
127 }
128
129 static int adf_ctl_alloc_resources(struct adf_user_cfg_ctl_data **ctl_data,
130 unsigned long arg)
131 {
132 struct adf_user_cfg_ctl_data *cfg_data;
133
134 cfg_data = kzalloc(sizeof(*cfg_data), GFP_KERNEL);
135 if (!cfg_data)
136 return -ENOMEM;
137
138 /* Initialize device id to NO DEVICE as 0 is a valid device id */
139 cfg_data->device_id = ADF_CFG_NO_DEVICE;
140
141 if (copy_from_user(cfg_data, (void __user *)arg, sizeof(*cfg_data))) {
142 pr_err("QAT: failed to copy from user cfg_data.\n");
143 kfree(cfg_data);
144 return -EIO;
145 }
146
147 *ctl_data = cfg_data;
148 return 0;
149 }
150
151 static int adf_add_key_value_data(struct adf_accel_dev *accel_dev,
152 const char *section,
153 const struct adf_user_cfg_key_val *key_val)
154 {
155 if (key_val->type == ADF_HEX) {
156 long *ptr = (long *)key_val->val;
157 long val = *ptr;
158
159 if (adf_cfg_add_key_value_param(accel_dev, section,
160 key_val->key, (void *)val,
161 key_val->type)) {
162 dev_err(&GET_DEV(accel_dev),
163 "failed to add hex keyvalue.\n");
164 return -EFAULT;
165 }
166 } else {
167 if (adf_cfg_add_key_value_param(accel_dev, section,
168 key_val->key, key_val->val,
169 key_val->type)) {
170 dev_err(&GET_DEV(accel_dev),
171 "failed to add keyvalue.\n");
172 return -EFAULT;
173 }
174 }
175 return 0;
176 }
177
178 static int adf_copy_key_value_data(struct adf_accel_dev *accel_dev,
179 struct adf_user_cfg_ctl_data *ctl_data)
180 {
181 struct adf_user_cfg_key_val key_val;
182 struct adf_user_cfg_key_val *params_head;
183 struct adf_user_cfg_section section, *section_head;
184
185 section_head = ctl_data->config_section;
186
187 while (section_head) {
188 if (copy_from_user(&section, (void __user *)section_head,
189 sizeof(*section_head))) {
190 dev_err(&GET_DEV(accel_dev),
191 "failed to copy section info\n");
192 goto out_err;
193 }
194
195 if (adf_cfg_section_add(accel_dev, section.name)) {
196 dev_err(&GET_DEV(accel_dev),
197 "failed to add section.\n");
198 goto out_err;
199 }
200
201 params_head = section_head->params;
202
203 while (params_head) {
204 if (copy_from_user(&key_val, (void __user *)params_head,
205 sizeof(key_val))) {
206 dev_err(&GET_DEV(accel_dev),
207 "Failed to copy keyvalue.\n");
208 goto out_err;
209 }
210 if (adf_add_key_value_data(accel_dev, section.name,
211 &key_val)) {
212 goto out_err;
213 }
214 params_head = key_val.next;
215 }
216 section_head = section.next;
217 }
218 return 0;
219 out_err:
220 adf_cfg_del_all(accel_dev);
221 return -EFAULT;
222 }
223
224 static int adf_ctl_ioctl_dev_config(struct file *fp, unsigned int cmd,
225 unsigned long arg)
226 {
227 int ret;
228 struct adf_user_cfg_ctl_data *ctl_data;
229 struct adf_accel_dev *accel_dev;
230
231 ret = adf_ctl_alloc_resources(&ctl_data, arg);
232 if (ret)
233 return ret;
234
235 accel_dev = adf_devmgr_get_dev_by_id(ctl_data->device_id);
236 if (!accel_dev) {
237 ret = -EFAULT;
238 goto out;
239 }
240
241 if (adf_dev_started(accel_dev)) {
242 ret = -EFAULT;
243 goto out;
244 }
245
246 if (adf_copy_key_value_data(accel_dev, ctl_data)) {
247 ret = -EFAULT;
248 goto out;
249 }
250 set_bit(ADF_STATUS_CONFIGURED, &accel_dev->status);
251 out:
252 kfree(ctl_data);
253 return ret;
254 }
255
256 static int adf_ctl_is_device_in_use(int id)
257 {
258 struct list_head *itr, *head = adf_devmgr_get_head();
259
260 list_for_each(itr, head) {
261 struct adf_accel_dev *dev =
262 list_entry(itr, struct adf_accel_dev, list);
263
264 if (id == dev->accel_id || id == ADF_CFG_ALL_DEVICES) {
265 if (adf_devmgr_in_reset(dev) || adf_dev_in_use(dev)) {
266 dev_info(&GET_DEV(dev),
267 "device qat_dev%d is busy\n",
268 dev->accel_id);
269 return -EBUSY;
270 }
271 }
272 }
273 return 0;
274 }
275
276 static int adf_ctl_stop_devices(uint32_t id)
277 {
278 struct list_head *itr, *head = adf_devmgr_get_head();
279 int ret = 0;
280
281 list_for_each(itr, head) {
282 struct adf_accel_dev *accel_dev =
283 list_entry(itr, struct adf_accel_dev, list);
284 if (id == accel_dev->accel_id || id == ADF_CFG_ALL_DEVICES) {
285 if (!adf_dev_started(accel_dev))
286 continue;
287
288 if (adf_dev_stop(accel_dev)) {
289 dev_err(&GET_DEV(accel_dev),
290 "Failed to stop qat_dev%d\n", id);
291 ret = -EFAULT;
292 } else {
293 adf_dev_shutdown(accel_dev);
294 }
295 }
296 }
297 return ret;
298 }
299
300 static int adf_ctl_ioctl_dev_stop(struct file *fp, unsigned int cmd,
301 unsigned long arg)
302 {
303 int ret;
304 struct adf_user_cfg_ctl_data *ctl_data;
305
306 ret = adf_ctl_alloc_resources(&ctl_data, arg);
307 if (ret)
308 return ret;
309
310 if (adf_devmgr_verify_id(ctl_data->device_id)) {
311 pr_err("QAT: Device %d not found\n", ctl_data->device_id);
312 ret = -ENODEV;
313 goto out;
314 }
315
316 ret = adf_ctl_is_device_in_use(ctl_data->device_id);
317 if (ret)
318 goto out;
319
320 if (ctl_data->device_id == ADF_CFG_ALL_DEVICES)
321 pr_info("QAT: Stopping all acceleration devices.\n");
322 else
323 pr_info("QAT: Stopping acceleration device qat_dev%d.\n",
324 ctl_data->device_id);
325
326 ret = adf_ctl_stop_devices(ctl_data->device_id);
327 if (ret)
328 pr_err("QAT: failed to stop device.\n");
329 out:
330 kfree(ctl_data);
331 return ret;
332 }
333
334 static int adf_ctl_ioctl_dev_start(struct file *fp, unsigned int cmd,
335 unsigned long arg)
336 {
337 int ret;
338 struct adf_user_cfg_ctl_data *ctl_data;
339 struct adf_accel_dev *accel_dev;
340
341 ret = adf_ctl_alloc_resources(&ctl_data, arg);
342 if (ret)
343 return ret;
344
345 accel_dev = adf_devmgr_get_dev_by_id(ctl_data->device_id);
346 if (!accel_dev) {
347 pr_err("QAT: Device %d not found\n", ctl_data->device_id);
348 ret = -ENODEV;
349 goto out;
350 }
351
352 if (!adf_dev_started(accel_dev)) {
353 dev_info(&GET_DEV(accel_dev),
354 "Starting acceleration device qat_dev%d.\n",
355 ctl_data->device_id);
356 ret = adf_dev_init(accel_dev);
357 if (!ret)
358 ret = adf_dev_start(accel_dev);
359 } else {
360 dev_info(&GET_DEV(accel_dev),
361 "Acceleration device qat_dev%d already started.\n",
362 ctl_data->device_id);
363 }
364 if (ret) {
365 dev_err(&GET_DEV(accel_dev), "Failed to start qat_dev%d\n",
366 ctl_data->device_id);
367 adf_dev_stop(accel_dev);
368 adf_dev_shutdown(accel_dev);
369 }
370 out:
371 kfree(ctl_data);
372 return ret;
373 }
374
375 static int adf_ctl_ioctl_get_num_devices(struct file *fp, unsigned int cmd,
376 unsigned long arg)
377 {
378 uint32_t num_devices = 0;
379
380 adf_devmgr_get_num_dev(&num_devices);
381 if (copy_to_user((void __user *)arg, &num_devices, sizeof(num_devices)))
382 return -EFAULT;
383
384 return 0;
385 }
386
387 static int adf_ctl_ioctl_get_status(struct file *fp, unsigned int cmd,
388 unsigned long arg)
389 {
390 struct adf_hw_device_data *hw_data;
391 struct adf_dev_status_info dev_info;
392 struct adf_accel_dev *accel_dev;
393
394 if (copy_from_user(&dev_info, (void __user *)arg,
395 sizeof(struct adf_dev_status_info))) {
396 pr_err("QAT: failed to copy from user.\n");
397 return -EFAULT;
398 }
399
400 accel_dev = adf_devmgr_get_dev_by_id(dev_info.accel_id);
401 if (!accel_dev) {
402 pr_err("QAT: Device %d not found\n", dev_info.accel_id);
403 return -ENODEV;
404 }
405 hw_data = accel_dev->hw_device;
406 dev_info.state = adf_dev_started(accel_dev) ? DEV_UP : DEV_DOWN;
407 dev_info.num_ae = hw_data->get_num_aes(hw_data);
408 dev_info.num_accel = hw_data->get_num_accels(hw_data);
409 dev_info.num_logical_accel = hw_data->num_logical_accel;
410 dev_info.banks_per_accel = hw_data->num_banks
411 / hw_data->num_logical_accel;
412 strlcpy(dev_info.name, hw_data->dev_class->name, sizeof(dev_info.name));
413 dev_info.instance_id = hw_data->instance_id;
414 dev_info.type = hw_data->dev_class->type;
415 dev_info.bus = accel_to_pci_dev(accel_dev)->bus->number;
416 dev_info.dev = PCI_SLOT(accel_to_pci_dev(accel_dev)->devfn);
417 dev_info.fun = PCI_FUNC(accel_to_pci_dev(accel_dev)->devfn);
418
419 if (copy_to_user((void __user *)arg, &dev_info,
420 sizeof(struct adf_dev_status_info))) {
421 dev_err(&GET_DEV(accel_dev), "failed to copy status.\n");
422 return -EFAULT;
423 }
424 return 0;
425 }
426
427 static long adf_ctl_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
428 {
429 int ret;
430
431 if (mutex_lock_interruptible(&adf_ctl_lock))
432 return -EFAULT;
433
434 switch (cmd) {
435 case IOCTL_CONFIG_SYS_RESOURCE_PARAMETERS:
436 ret = adf_ctl_ioctl_dev_config(fp, cmd, arg);
437 break;
438
439 case IOCTL_STOP_ACCEL_DEV:
440 ret = adf_ctl_ioctl_dev_stop(fp, cmd, arg);
441 break;
442
443 case IOCTL_START_ACCEL_DEV:
444 ret = adf_ctl_ioctl_dev_start(fp, cmd, arg);
445 break;
446
447 case IOCTL_GET_NUM_DEVICES:
448 ret = adf_ctl_ioctl_get_num_devices(fp, cmd, arg);
449 break;
450
451 case IOCTL_STATUS_ACCEL_DEV:
452 ret = adf_ctl_ioctl_get_status(fp, cmd, arg);
453 break;
454 default:
455 pr_err("QAT: Invalid ioctl\n");
456 ret = -EFAULT;
457 break;
458 }
459 mutex_unlock(&adf_ctl_lock);
460 return ret;
461 }
462
463 static int __init adf_register_ctl_device_driver(void)
464 {
465 mutex_init(&adf_ctl_lock);
466
467 if (qat_algs_init())
468 goto err_algs_init;
469
470 if (adf_chr_drv_create())
471 goto err_chr_dev;
472
473 if (adf_init_aer())
474 goto err_aer;
475
476 if (qat_crypto_register())
477 goto err_crypto_register;
478
479 return 0;
480
481 err_crypto_register:
482 adf_exit_aer();
483 err_aer:
484 adf_chr_drv_destroy();
485 err_chr_dev:
486 qat_algs_exit();
487 err_algs_init:
488 mutex_destroy(&adf_ctl_lock);
489 return -EFAULT;
490 }
491
492 static void __exit adf_unregister_ctl_device_driver(void)
493 {
494 adf_chr_drv_destroy();
495 adf_exit_aer();
496 qat_crypto_unregister();
497 qat_algs_exit();
498 mutex_destroy(&adf_ctl_lock);
499 }
500
501 module_init(adf_register_ctl_device_driver);
502 module_exit(adf_unregister_ctl_device_driver);
503 MODULE_LICENSE("Dual BSD/GPL");
504 MODULE_AUTHOR("Intel");
505 MODULE_DESCRIPTION("Intel(R) QuickAssist Technology");
506 MODULE_ALIAS_CRYPTO("intel_qat");