crypto: prefix module autoloading with "crypto-"
[linux-2.6/btrfs-unstable.git] / drivers / crypto / qat / qat_common / adf_ctl_drv.c
blob7ee93f881db698af823bbd5d94fe0a01abcd900f
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.
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.
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.
16 Contact Information:
17 qat-linux@intel.com
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:
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.
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.
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>
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"
63 #define DEVICE_NAME "qat_adf_ctl"
65 static DEFINE_MUTEX(adf_ctl_lock);
66 static long adf_ctl_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
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,
74 struct adf_ctl_drv_info {
75 unsigned int major;
76 struct cdev drv_cdev;
77 struct class *drv_class;
80 static struct adf_ctl_drv_info adt_ctl_drv;
82 static void adf_chr_drv_destroy(void)
84 device_destroy(adt_ctl_drv.drv_class, MKDEV(adt_ctl_drv.major, 0));
85 cdev_del(&adt_ctl_drv.drv_cdev);
86 class_destroy(adt_ctl_drv.drv_class);
87 unregister_chrdev_region(MKDEV(adt_ctl_drv.major, 0), 1);
90 static int adf_chr_drv_create(void)
92 dev_t dev_id;
93 struct device *drv_device;
95 if (alloc_chrdev_region(&dev_id, 0, 1, DEVICE_NAME)) {
96 pr_err("QAT: unable to allocate chrdev region\n");
97 return -EFAULT;
100 adt_ctl_drv.drv_class = class_create(THIS_MODULE, DEVICE_NAME);
101 if (IS_ERR(adt_ctl_drv.drv_class)) {
102 pr_err("QAT: class_create failed for adf_ctl\n");
103 goto err_chrdev_unreg;
105 adt_ctl_drv.major = MAJOR(dev_id);
106 cdev_init(&adt_ctl_drv.drv_cdev, &adf_ctl_ops);
107 if (cdev_add(&adt_ctl_drv.drv_cdev, dev_id, 1)) {
108 pr_err("QAT: cdev add failed\n");
109 goto err_class_destr;
112 drv_device = device_create(adt_ctl_drv.drv_class, NULL,
113 MKDEV(adt_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;
119 return 0;
120 err_cdev_del:
121 cdev_del(&adt_ctl_drv.drv_cdev);
122 err_class_destr:
123 class_destroy(adt_ctl_drv.drv_class);
124 err_chrdev_unreg:
125 unregister_chrdev_region(dev_id, 1);
126 return -EFAULT;
129 static int adf_ctl_alloc_resources(struct adf_user_cfg_ctl_data **ctl_data,
130 unsigned long arg)
132 struct adf_user_cfg_ctl_data *cfg_data;
134 cfg_data = kzalloc(sizeof(*cfg_data), GFP_KERNEL);
135 if (!cfg_data)
136 return -ENOMEM;
138 /* Initialize device id to NO DEVICE as 0 is a valid device id */
139 cfg_data->device_id = ADF_CFG_NO_DEVICE;
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;
147 *ctl_data = cfg_data;
148 return 0;
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)
155 if (key_val->type == ADF_HEX) {
156 long *ptr = (long *)key_val->val;
157 long val = *ptr;
159 if (adf_cfg_add_key_value_param(accel_dev, section,
160 key_val->key, (void *)val,
161 key_val->type)) {
162 pr_err("QAT: failed to add keyvalue.\n");
163 return -EFAULT;
165 } else {
166 if (adf_cfg_add_key_value_param(accel_dev, section,
167 key_val->key, key_val->val,
168 key_val->type)) {
169 pr_err("QAT: failed to add keyvalue.\n");
170 return -EFAULT;
173 return 0;
176 static int adf_copy_key_value_data(struct adf_accel_dev *accel_dev,
177 struct adf_user_cfg_ctl_data *ctl_data)
179 struct adf_user_cfg_key_val key_val;
180 struct adf_user_cfg_key_val *params_head;
181 struct adf_user_cfg_section section, *section_head;
183 section_head = ctl_data->config_section;
185 while (section_head) {
186 if (copy_from_user(&section, (void __user *)section_head,
187 sizeof(*section_head))) {
188 pr_err("QAT: failed to copy section info\n");
189 goto out_err;
192 if (adf_cfg_section_add(accel_dev, section.name)) {
193 pr_err("QAT: failed to add section.\n");
194 goto out_err;
197 params_head = section_head->params;
199 while (params_head) {
200 if (copy_from_user(&key_val, (void __user *)params_head,
201 sizeof(key_val))) {
202 pr_err("QAT: Failed to copy keyvalue.\n");
203 goto out_err;
205 if (adf_add_key_value_data(accel_dev, section.name,
206 &key_val)) {
207 goto out_err;
209 params_head = key_val.next;
211 section_head = section.next;
213 return 0;
214 out_err:
215 adf_cfg_del_all(accel_dev);
216 return -EFAULT;
219 static int adf_ctl_ioctl_dev_config(struct file *fp, unsigned int cmd,
220 unsigned long arg)
222 int ret;
223 struct adf_user_cfg_ctl_data *ctl_data;
224 struct adf_accel_dev *accel_dev;
226 ret = adf_ctl_alloc_resources(&ctl_data, arg);
227 if (ret)
228 return ret;
230 accel_dev = adf_devmgr_get_dev_by_id(ctl_data->device_id);
231 if (!accel_dev) {
232 ret = -EFAULT;
233 goto out;
236 if (adf_dev_started(accel_dev)) {
237 ret = -EFAULT;
238 goto out;
241 if (adf_copy_key_value_data(accel_dev, ctl_data)) {
242 ret = -EFAULT;
243 goto out;
245 set_bit(ADF_STATUS_CONFIGURED, &accel_dev->status);
246 out:
247 kfree(ctl_data);
248 return ret;
251 static int adf_ctl_is_device_in_use(int id)
253 struct list_head *itr, *head = adf_devmgr_get_head();
255 list_for_each(itr, head) {
256 struct adf_accel_dev *dev =
257 list_entry(itr, struct adf_accel_dev, list);
259 if (id == dev->accel_id || id == ADF_CFG_ALL_DEVICES) {
260 if (adf_devmgr_in_reset(dev) || adf_dev_in_use(dev)) {
261 pr_info("QAT: device qat_dev%d is busy\n",
262 dev->accel_id);
263 return -EBUSY;
267 return 0;
270 static int adf_ctl_stop_devices(uint32_t id)
272 struct list_head *itr, *head = adf_devmgr_get_head();
273 int ret = 0;
275 list_for_each(itr, head) {
276 struct adf_accel_dev *accel_dev =
277 list_entry(itr, struct adf_accel_dev, list);
278 if (id == accel_dev->accel_id || id == ADF_CFG_ALL_DEVICES) {
279 if (!adf_dev_started(accel_dev))
280 continue;
282 if (adf_dev_stop(accel_dev)) {
283 pr_err("QAT: Failed to stop qat_dev%d\n", id);
284 ret = -EFAULT;
288 return ret;
291 static int adf_ctl_ioctl_dev_stop(struct file *fp, unsigned int cmd,
292 unsigned long arg)
294 int ret;
295 struct adf_user_cfg_ctl_data *ctl_data;
297 ret = adf_ctl_alloc_resources(&ctl_data, arg);
298 if (ret)
299 return ret;
301 if (adf_devmgr_verify_id(ctl_data->device_id)) {
302 pr_err("QAT: Device %d not found\n", ctl_data->device_id);
303 ret = -ENODEV;
304 goto out;
307 ret = adf_ctl_is_device_in_use(ctl_data->device_id);
308 if (ret)
309 goto out;
311 if (ctl_data->device_id == ADF_CFG_ALL_DEVICES)
312 pr_info("QAT: Stopping all acceleration devices.\n");
313 else
314 pr_info("QAT: Stopping acceleration device qat_dev%d.\n",
315 ctl_data->device_id);
317 ret = adf_ctl_stop_devices(ctl_data->device_id);
318 if (ret)
319 pr_err("QAT: failed to stop device.\n");
320 out:
321 kfree(ctl_data);
322 return ret;
325 static int adf_ctl_ioctl_dev_start(struct file *fp, unsigned int cmd,
326 unsigned long arg)
328 int ret;
329 struct adf_user_cfg_ctl_data *ctl_data;
330 struct adf_accel_dev *accel_dev;
332 ret = adf_ctl_alloc_resources(&ctl_data, arg);
333 if (ret)
334 return ret;
336 accel_dev = adf_devmgr_get_dev_by_id(ctl_data->device_id);
337 if (!accel_dev) {
338 pr_err("QAT: Device %d not found\n", ctl_data->device_id);
339 ret = -ENODEV;
340 goto out;
343 if (!adf_dev_started(accel_dev)) {
344 pr_info("QAT: Starting acceleration device qat_dev%d.\n",
345 ctl_data->device_id);
346 ret = adf_dev_start(accel_dev);
347 } else {
348 pr_info("QAT: Acceleration device qat_dev%d already started.\n",
349 ctl_data->device_id);
351 if (ret) {
352 pr_err("QAT: Failed to start qat_dev%d\n", ctl_data->device_id);
353 adf_dev_stop(accel_dev);
355 out:
356 kfree(ctl_data);
357 return ret;
360 static int adf_ctl_ioctl_get_num_devices(struct file *fp, unsigned int cmd,
361 unsigned long arg)
363 uint32_t num_devices = 0;
365 adf_devmgr_get_num_dev(&num_devices);
366 if (copy_to_user((void __user *)arg, &num_devices, sizeof(num_devices)))
367 return -EFAULT;
369 return 0;
372 static int adf_ctl_ioctl_get_status(struct file *fp, unsigned int cmd,
373 unsigned long arg)
375 struct adf_hw_device_data *hw_data;
376 struct adf_dev_status_info dev_info;
377 struct adf_accel_dev *accel_dev;
379 if (copy_from_user(&dev_info, (void __user *)arg,
380 sizeof(struct adf_dev_status_info))) {
381 pr_err("QAT: failed to copy from user.\n");
382 return -EFAULT;
385 accel_dev = adf_devmgr_get_dev_by_id(dev_info.accel_id);
386 if (!accel_dev) {
387 pr_err("QAT: Device %d not found\n", dev_info.accel_id);
388 return -ENODEV;
390 hw_data = accel_dev->hw_device;
391 dev_info.state = adf_dev_started(accel_dev) ? DEV_UP : DEV_DOWN;
392 dev_info.num_ae = hw_data->get_num_aes(hw_data);
393 dev_info.num_accel = hw_data->get_num_accels(hw_data);
394 dev_info.num_logical_accel = hw_data->num_logical_accel;
395 dev_info.banks_per_accel = hw_data->num_banks
396 / hw_data->num_logical_accel;
397 strlcpy(dev_info.name, hw_data->dev_class->name, sizeof(dev_info.name));
398 dev_info.instance_id = hw_data->instance_id;
399 dev_info.type = hw_data->dev_class->type;
400 dev_info.bus = accel_to_pci_dev(accel_dev)->bus->number;
401 dev_info.dev = PCI_SLOT(accel_to_pci_dev(accel_dev)->devfn);
402 dev_info.fun = PCI_FUNC(accel_to_pci_dev(accel_dev)->devfn);
404 if (copy_to_user((void __user *)arg, &dev_info,
405 sizeof(struct adf_dev_status_info))) {
406 pr_err("QAT: failed to copy status.\n");
407 return -EFAULT;
409 return 0;
412 static long adf_ctl_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
414 int ret;
416 if (mutex_lock_interruptible(&adf_ctl_lock))
417 return -EFAULT;
419 switch (cmd) {
420 case IOCTL_CONFIG_SYS_RESOURCE_PARAMETERS:
421 ret = adf_ctl_ioctl_dev_config(fp, cmd, arg);
422 break;
424 case IOCTL_STOP_ACCEL_DEV:
425 ret = adf_ctl_ioctl_dev_stop(fp, cmd, arg);
426 break;
428 case IOCTL_START_ACCEL_DEV:
429 ret = adf_ctl_ioctl_dev_start(fp, cmd, arg);
430 break;
432 case IOCTL_GET_NUM_DEVICES:
433 ret = adf_ctl_ioctl_get_num_devices(fp, cmd, arg);
434 break;
436 case IOCTL_STATUS_ACCEL_DEV:
437 ret = adf_ctl_ioctl_get_status(fp, cmd, arg);
438 break;
439 default:
440 pr_err("QAT: Invalid ioctl\n");
441 ret = -EFAULT;
442 break;
444 mutex_unlock(&adf_ctl_lock);
445 return ret;
448 static int __init adf_register_ctl_device_driver(void)
450 mutex_init(&adf_ctl_lock);
452 if (qat_algs_init())
453 goto err_algs_init;
455 if (adf_chr_drv_create())
456 goto err_chr_dev;
458 if (adf_init_aer())
459 goto err_aer;
461 if (qat_crypto_register())
462 goto err_crypto_register;
464 return 0;
466 err_crypto_register:
467 adf_exit_aer();
468 err_aer:
469 adf_chr_drv_destroy();
470 err_chr_dev:
471 qat_algs_exit();
472 err_algs_init:
473 mutex_destroy(&adf_ctl_lock);
474 return -EFAULT;
477 static void __exit adf_unregister_ctl_device_driver(void)
479 adf_chr_drv_destroy();
480 adf_exit_aer();
481 qat_crypto_unregister();
482 qat_algs_exit();
483 mutex_destroy(&adf_ctl_lock);
486 module_init(adf_register_ctl_device_driver);
487 module_exit(adf_unregister_ctl_device_driver);
488 MODULE_LICENSE("Dual BSD/GPL");
489 MODULE_AUTHOR("Intel");
490 MODULE_DESCRIPTION("Intel(R) QuickAssist Technology");
491 MODULE_ALIAS_CRYPTO("intel_qat");