]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/crypto/qat/qat_common/adf_ctl_drv.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide
[karo-tx-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_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                 return -ENODEV;
403
404         hw_data = accel_dev->hw_device;
405         dev_info.state = adf_dev_started(accel_dev) ? DEV_UP : DEV_DOWN;
406         dev_info.num_ae = hw_data->get_num_aes(hw_data);
407         dev_info.num_accel = hw_data->get_num_accels(hw_data);
408         dev_info.num_logical_accel = hw_data->num_logical_accel;
409         dev_info.banks_per_accel = hw_data->num_banks
410                                         / hw_data->num_logical_accel;
411         strlcpy(dev_info.name, hw_data->dev_class->name, sizeof(dev_info.name));
412         dev_info.instance_id = hw_data->instance_id;
413         dev_info.type = hw_data->dev_class->type;
414         dev_info.bus = accel_to_pci_dev(accel_dev)->bus->number;
415         dev_info.dev = PCI_SLOT(accel_to_pci_dev(accel_dev)->devfn);
416         dev_info.fun = PCI_FUNC(accel_to_pci_dev(accel_dev)->devfn);
417
418         if (copy_to_user((void __user *)arg, &dev_info,
419                          sizeof(struct adf_dev_status_info))) {
420                 dev_err(&GET_DEV(accel_dev), "failed to copy status.\n");
421                 return -EFAULT;
422         }
423         return 0;
424 }
425
426 static long adf_ctl_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
427 {
428         int ret;
429
430         if (mutex_lock_interruptible(&adf_ctl_lock))
431                 return -EFAULT;
432
433         switch (cmd) {
434         case IOCTL_CONFIG_SYS_RESOURCE_PARAMETERS:
435                 ret = adf_ctl_ioctl_dev_config(fp, cmd, arg);
436                 break;
437
438         case IOCTL_STOP_ACCEL_DEV:
439                 ret = adf_ctl_ioctl_dev_stop(fp, cmd, arg);
440                 break;
441
442         case IOCTL_START_ACCEL_DEV:
443                 ret = adf_ctl_ioctl_dev_start(fp, cmd, arg);
444                 break;
445
446         case IOCTL_GET_NUM_DEVICES:
447                 ret = adf_ctl_ioctl_get_num_devices(fp, cmd, arg);
448                 break;
449
450         case IOCTL_STATUS_ACCEL_DEV:
451                 ret = adf_ctl_ioctl_get_status(fp, cmd, arg);
452                 break;
453         default:
454                 pr_err("QAT: Invalid ioctl\n");
455                 ret = -EFAULT;
456                 break;
457         }
458         mutex_unlock(&adf_ctl_lock);
459         return ret;
460 }
461
462 static int __init adf_register_ctl_device_driver(void)
463 {
464         mutex_init(&adf_ctl_lock);
465
466         if (adf_chr_drv_create())
467                 goto err_chr_dev;
468
469         if (adf_init_aer())
470                 goto err_aer;
471
472         if (qat_crypto_register())
473                 goto err_crypto_register;
474
475         return 0;
476
477 err_crypto_register:
478         adf_exit_aer();
479 err_aer:
480         adf_chr_drv_destroy();
481 err_chr_dev:
482         mutex_destroy(&adf_ctl_lock);
483         return -EFAULT;
484 }
485
486 static void __exit adf_unregister_ctl_device_driver(void)
487 {
488         adf_chr_drv_destroy();
489         adf_exit_aer();
490         qat_crypto_unregister();
491         adf_clean_vf_map(false);
492         mutex_destroy(&adf_ctl_lock);
493 }
494
495 module_init(adf_register_ctl_device_driver);
496 module_exit(adf_unregister_ctl_device_driver);
497 MODULE_LICENSE("Dual BSD/GPL");
498 MODULE_AUTHOR("Intel");
499 MODULE_DESCRIPTION("Intel(R) QuickAssist Technology");
500 MODULE_ALIAS_CRYPTO("intel_qat");
501 MODULE_VERSION(ADF_DRV_VERSION);