crypto: s5p-sss - Fix missed interrupts when working with 8 kB blocks
[cascardo/linux.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.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 adf_accel_dev *dev;
259
260         list_for_each_entry(dev, adf_devmgr_get_head(), list) {
261                 if (id == dev->accel_id || id == ADF_CFG_ALL_DEVICES) {
262                         if (adf_devmgr_in_reset(dev) || adf_dev_in_use(dev)) {
263                                 dev_info(&GET_DEV(dev),
264                                          "device qat_dev%d is busy\n",
265                                          dev->accel_id);
266                                 return -EBUSY;
267                         }
268                 }
269         }
270         return 0;
271 }
272
273 static int adf_ctl_stop_devices(uint32_t id)
274 {
275         struct adf_accel_dev *accel_dev;
276         int ret = 0;
277
278         list_for_each_entry(accel_dev, adf_devmgr_get_head(), list) {
279                 if (id == accel_dev->accel_id || id == ADF_CFG_ALL_DEVICES) {
280                         if (!adf_dev_started(accel_dev))
281                                 continue;
282
283                         /* First stop all VFs */
284                         if (!accel_dev->is_vf)
285                                 continue;
286
287                         adf_dev_stop(accel_dev);
288                         adf_dev_shutdown(accel_dev);
289                 }
290         }
291
292         list_for_each_entry(accel_dev, adf_devmgr_get_head(), list) {
293                 if (id == accel_dev->accel_id || id == ADF_CFG_ALL_DEVICES) {
294                         if (!adf_dev_started(accel_dev))
295                                 continue;
296
297                         adf_dev_stop(accel_dev);
298                         adf_dev_shutdown(accel_dev);
299                 }
300         }
301         return ret;
302 }
303
304 static int adf_ctl_ioctl_dev_stop(struct file *fp, unsigned int cmd,
305                                   unsigned long arg)
306 {
307         int ret;
308         struct adf_user_cfg_ctl_data *ctl_data;
309
310         ret = adf_ctl_alloc_resources(&ctl_data, arg);
311         if (ret)
312                 return ret;
313
314         if (adf_devmgr_verify_id(ctl_data->device_id)) {
315                 pr_err("QAT: Device %d not found\n", ctl_data->device_id);
316                 ret = -ENODEV;
317                 goto out;
318         }
319
320         ret = adf_ctl_is_device_in_use(ctl_data->device_id);
321         if (ret)
322                 goto out;
323
324         if (ctl_data->device_id == ADF_CFG_ALL_DEVICES)
325                 pr_info("QAT: Stopping all acceleration devices.\n");
326         else
327                 pr_info("QAT: Stopping acceleration device qat_dev%d.\n",
328                         ctl_data->device_id);
329
330         ret = adf_ctl_stop_devices(ctl_data->device_id);
331         if (ret)
332                 pr_err("QAT: failed to stop device.\n");
333 out:
334         kfree(ctl_data);
335         return ret;
336 }
337
338 static int adf_ctl_ioctl_dev_start(struct file *fp, unsigned int cmd,
339                                    unsigned long arg)
340 {
341         int ret;
342         struct adf_user_cfg_ctl_data *ctl_data;
343         struct adf_accel_dev *accel_dev;
344
345         ret = adf_ctl_alloc_resources(&ctl_data, arg);
346         if (ret)
347                 return ret;
348
349         ret = -ENODEV;
350         accel_dev = adf_devmgr_get_dev_by_id(ctl_data->device_id);
351         if (!accel_dev)
352                 goto out;
353
354         if (!adf_dev_started(accel_dev)) {
355                 dev_info(&GET_DEV(accel_dev),
356                          "Starting acceleration device qat_dev%d.\n",
357                          ctl_data->device_id);
358                 ret = adf_dev_init(accel_dev);
359                 if (!ret)
360                         ret = adf_dev_start(accel_dev);
361         } else {
362                 dev_info(&GET_DEV(accel_dev),
363                          "Acceleration device qat_dev%d already started.\n",
364                          ctl_data->device_id);
365         }
366         if (ret) {
367                 dev_err(&GET_DEV(accel_dev), "Failed to start qat_dev%d\n",
368                         ctl_data->device_id);
369                 adf_dev_stop(accel_dev);
370                 adf_dev_shutdown(accel_dev);
371         }
372 out:
373         kfree(ctl_data);
374         return ret;
375 }
376
377 static int adf_ctl_ioctl_get_num_devices(struct file *fp, unsigned int cmd,
378                                          unsigned long arg)
379 {
380         uint32_t num_devices = 0;
381
382         adf_devmgr_get_num_dev(&num_devices);
383         if (copy_to_user((void __user *)arg, &num_devices, sizeof(num_devices)))
384                 return -EFAULT;
385
386         return 0;
387 }
388
389 static int adf_ctl_ioctl_get_status(struct file *fp, unsigned int cmd,
390                                     unsigned long arg)
391 {
392         struct adf_hw_device_data *hw_data;
393         struct adf_dev_status_info dev_info;
394         struct adf_accel_dev *accel_dev;
395
396         if (copy_from_user(&dev_info, (void __user *)arg,
397                            sizeof(struct adf_dev_status_info))) {
398                 pr_err("QAT: failed to copy from user.\n");
399                 return -EFAULT;
400         }
401
402         accel_dev = adf_devmgr_get_dev_by_id(dev_info.accel_id);
403         if (!accel_dev)
404                 return -ENODEV;
405
406         hw_data = accel_dev->hw_device;
407         dev_info.state = adf_dev_started(accel_dev) ? DEV_UP : DEV_DOWN;
408         dev_info.num_ae = hw_data->get_num_aes(hw_data);
409         dev_info.num_accel = hw_data->get_num_accels(hw_data);
410         dev_info.num_logical_accel = hw_data->num_logical_accel;
411         dev_info.banks_per_accel = hw_data->num_banks
412                                         / hw_data->num_logical_accel;
413         strlcpy(dev_info.name, hw_data->dev_class->name, sizeof(dev_info.name));
414         dev_info.instance_id = hw_data->instance_id;
415         dev_info.type = hw_data->dev_class->type;
416         dev_info.bus = accel_to_pci_dev(accel_dev)->bus->number;
417         dev_info.dev = PCI_SLOT(accel_to_pci_dev(accel_dev)->devfn);
418         dev_info.fun = PCI_FUNC(accel_to_pci_dev(accel_dev)->devfn);
419
420         if (copy_to_user((void __user *)arg, &dev_info,
421                          sizeof(struct adf_dev_status_info))) {
422                 dev_err(&GET_DEV(accel_dev), "failed to copy status.\n");
423                 return -EFAULT;
424         }
425         return 0;
426 }
427
428 static long adf_ctl_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
429 {
430         int ret;
431
432         if (mutex_lock_interruptible(&adf_ctl_lock))
433                 return -EFAULT;
434
435         switch (cmd) {
436         case IOCTL_CONFIG_SYS_RESOURCE_PARAMETERS:
437                 ret = adf_ctl_ioctl_dev_config(fp, cmd, arg);
438                 break;
439
440         case IOCTL_STOP_ACCEL_DEV:
441                 ret = adf_ctl_ioctl_dev_stop(fp, cmd, arg);
442                 break;
443
444         case IOCTL_START_ACCEL_DEV:
445                 ret = adf_ctl_ioctl_dev_start(fp, cmd, arg);
446                 break;
447
448         case IOCTL_GET_NUM_DEVICES:
449                 ret = adf_ctl_ioctl_get_num_devices(fp, cmd, arg);
450                 break;
451
452         case IOCTL_STATUS_ACCEL_DEV:
453                 ret = adf_ctl_ioctl_get_status(fp, cmd, arg);
454                 break;
455         default:
456                 pr_err("QAT: Invalid ioctl\n");
457                 ret = -EFAULT;
458                 break;
459         }
460         mutex_unlock(&adf_ctl_lock);
461         return ret;
462 }
463
464 static int __init adf_register_ctl_device_driver(void)
465 {
466         mutex_init(&adf_ctl_lock);
467
468         if (adf_chr_drv_create())
469                 goto err_chr_dev;
470
471         if (adf_init_aer())
472                 goto err_aer;
473
474         if (adf_init_vf_wq())
475                 goto err_vf_wq;
476
477         if (qat_crypto_register())
478                 goto err_crypto_register;
479
480         return 0;
481
482 err_crypto_register:
483         adf_exit_vf_wq();
484 err_vf_wq:
485         adf_exit_aer();
486 err_aer:
487         adf_chr_drv_destroy();
488 err_chr_dev:
489         mutex_destroy(&adf_ctl_lock);
490         return -EFAULT;
491 }
492
493 static void __exit adf_unregister_ctl_device_driver(void)
494 {
495         adf_chr_drv_destroy();
496         adf_exit_aer();
497         adf_exit_vf_wq();
498         qat_crypto_unregister();
499         adf_clean_vf_map(false);
500         mutex_destroy(&adf_ctl_lock);
501 }
502
503 module_init(adf_register_ctl_device_driver);
504 module_exit(adf_unregister_ctl_device_driver);
505 MODULE_LICENSE("Dual BSD/GPL");
506 MODULE_AUTHOR("Intel");
507 MODULE_DESCRIPTION("Intel(R) QuickAssist Technology");
508 MODULE_ALIAS_CRYPTO("intel_qat");
509 MODULE_VERSION(ADF_DRV_VERSION);