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.
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.
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
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
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>
51 #include <linux/bitops.h>
52 #include <linux/pci.h>
53 #include <linux/cdev.h>
54 #include <linux/uaccess.h>
56 #include "adf_accel_devices.h"
57 #include "adf_common_drv.h"
59 #include "adf_cfg_common.h"
60 #include "adf_cfg_user.h"
62 #define DEVICE_NAME "qat_adf_ctl"
64 static DEFINE_MUTEX(adf_ctl_lock);
65 static long adf_ctl_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
67 static const struct file_operations adf_ctl_ops = {
69 .unlocked_ioctl = adf_ctl_ioctl,
70 .compat_ioctl = adf_ctl_ioctl,
73 struct adf_ctl_drv_info {
76 struct class *drv_class;
79 static struct adf_ctl_drv_info adt_ctl_drv;
81 static void adf_chr_drv_destroy(void)
83 device_destroy(adt_ctl_drv.drv_class, MKDEV(adt_ctl_drv.major, 0));
84 cdev_del(&adt_ctl_drv.drv_cdev);
85 class_destroy(adt_ctl_drv.drv_class);
86 unregister_chrdev_region(MKDEV(adt_ctl_drv.major, 0), 1);
89 static int adf_chr_drv_create(void)
92 struct device *drv_device;
94 if (alloc_chrdev_region(&dev_id, 0, 1, DEVICE_NAME)) {
95 pr_err("QAT: unable to allocate chrdev region\n");
99 adt_ctl_drv.drv_class = class_create(THIS_MODULE, DEVICE_NAME);
100 if (IS_ERR(adt_ctl_drv.drv_class)) {
101 pr_err("QAT: class_create failed for adf_ctl\n");
102 goto err_chrdev_unreg;
104 adt_ctl_drv.major = MAJOR(dev_id);
105 cdev_init(&adt_ctl_drv.drv_cdev, &adf_ctl_ops);
106 if (cdev_add(&adt_ctl_drv.drv_cdev, dev_id, 1)) {
107 pr_err("QAT: cdev add failed\n");
108 goto err_class_destr;
111 drv_device = device_create(adt_ctl_drv.drv_class, NULL,
112 MKDEV(adt_ctl_drv.major, 0),
114 if (IS_ERR(drv_device)) {
115 pr_err("QAT: failed to create device\n");
120 cdev_del(&adt_ctl_drv.drv_cdev);
122 class_destroy(adt_ctl_drv.drv_class);
124 unregister_chrdev_region(dev_id, 1);
128 static int adf_ctl_alloc_resources(struct adf_user_cfg_ctl_data **ctl_data,
131 struct adf_user_cfg_ctl_data *cfg_data;
133 cfg_data = kzalloc(sizeof(*cfg_data), GFP_KERNEL);
137 /* Initialize device id to NO DEVICE as 0 is a valid device id */
138 cfg_data->device_id = ADF_CFG_NO_DEVICE;
140 if (copy_from_user(cfg_data, (void __user *)arg, sizeof(*cfg_data))) {
141 pr_err("QAT: failed to copy from user cfg_data.\n");
146 *ctl_data = cfg_data;
150 static int adf_add_key_value_data(struct adf_accel_dev *accel_dev,
152 const struct adf_user_cfg_key_val *key_val)
154 if (key_val->type == ADF_HEX) {
155 long *ptr = (long *)key_val->val;
158 if (adf_cfg_add_key_value_param(accel_dev, section,
159 key_val->key, (void *)val,
161 pr_err("QAT: failed to add keyvalue.\n");
165 if (adf_cfg_add_key_value_param(accel_dev, section,
166 key_val->key, key_val->val,
168 pr_err("QAT: failed to add keyvalue.\n");
175 static int adf_copy_key_value_data(struct adf_accel_dev *accel_dev,
176 struct adf_user_cfg_ctl_data *ctl_data)
178 struct adf_user_cfg_key_val key_val;
179 struct adf_user_cfg_key_val *params_head;
180 struct adf_user_cfg_section section, *section_head;
182 section_head = ctl_data->config_section;
184 while (section_head) {
185 if (copy_from_user(§ion, (void __user *)section_head,
186 sizeof(*section_head))) {
187 pr_err("QAT: failed to copy section info\n");
191 if (adf_cfg_section_add(accel_dev, section.name)) {
192 pr_err("QAT: failed to add section.\n");
196 params_head = section_head->params;
198 while (params_head) {
199 if (copy_from_user(&key_val, (void __user *)params_head,
201 pr_err("QAT: Failed to copy keyvalue.\n");
204 if (adf_add_key_value_data(accel_dev, section.name,
208 params_head = key_val.next;
210 section_head = section.next;
214 adf_cfg_del_all(accel_dev);
218 static int adf_ctl_ioctl_dev_config(struct file *fp, unsigned int cmd,
222 struct adf_user_cfg_ctl_data *ctl_data;
223 struct adf_accel_dev *accel_dev;
225 ret = adf_ctl_alloc_resources(&ctl_data, arg);
229 accel_dev = adf_devmgr_get_dev_by_id(ctl_data->device_id);
235 if (adf_dev_started(accel_dev)) {
240 if (adf_copy_key_value_data(accel_dev, ctl_data)) {
244 set_bit(ADF_STATUS_CONFIGURED, &accel_dev->status);
250 static int adf_ctl_is_device_in_use(int id)
252 struct list_head *itr, *head = adf_devmgr_get_head();
254 list_for_each(itr, head) {
255 struct adf_accel_dev *dev =
256 list_entry(itr, struct adf_accel_dev, list);
258 if (id == dev->accel_id || id == ADF_CFG_ALL_DEVICES) {
259 if (adf_devmgr_in_reset(dev) || adf_dev_in_use(dev)) {
260 pr_info("QAT: device qat_dev%d is busy\n",
269 static int adf_ctl_stop_devices(uint32_t id)
271 struct list_head *itr, *head = adf_devmgr_get_head();
274 list_for_each(itr, head) {
275 struct adf_accel_dev *accel_dev =
276 list_entry(itr, struct adf_accel_dev, list);
277 if (id == accel_dev->accel_id || id == ADF_CFG_ALL_DEVICES) {
278 if (!adf_dev_started(accel_dev))
281 if (adf_dev_stop(accel_dev)) {
282 pr_err("QAT: Failed to stop qat_dev%d\n", id);
290 static int adf_ctl_ioctl_dev_stop(struct file *fp, unsigned int cmd,
294 struct adf_user_cfg_ctl_data *ctl_data;
296 ret = adf_ctl_alloc_resources(&ctl_data, arg);
300 if (adf_devmgr_verify_id(ctl_data->device_id)) {
301 pr_err("QAT: Device %d not found\n", ctl_data->device_id);
306 ret = adf_ctl_is_device_in_use(ctl_data->device_id);
310 if (ctl_data->device_id == ADF_CFG_ALL_DEVICES)
311 pr_info("QAT: Stopping all acceleration devices.\n");
313 pr_info("QAT: Stopping acceleration device qat_dev%d.\n",
314 ctl_data->device_id);
316 ret = adf_ctl_stop_devices(ctl_data->device_id);
318 pr_err("QAT: failed to stop device.\n");
324 static int adf_ctl_ioctl_dev_start(struct file *fp, unsigned int cmd,
328 struct adf_user_cfg_ctl_data *ctl_data;
329 struct adf_accel_dev *accel_dev;
331 ret = adf_ctl_alloc_resources(&ctl_data, arg);
335 accel_dev = adf_devmgr_get_dev_by_id(ctl_data->device_id);
337 pr_err("QAT: Device %d not found\n", ctl_data->device_id);
342 if (!adf_dev_started(accel_dev)) {
343 pr_info("QAT: Starting acceleration device qat_dev%d.\n",
344 ctl_data->device_id);
345 ret = adf_dev_start(accel_dev);
347 pr_info("QAT: Acceleration device qat_dev%d already started.\n",
348 ctl_data->device_id);
351 pr_err("QAT: Failed to start qat_dev%d\n", ctl_data->device_id);
352 adf_dev_stop(accel_dev);
359 static int adf_ctl_ioctl_get_num_devices(struct file *fp, unsigned int cmd,
362 uint32_t num_devices = 0;
364 adf_devmgr_get_num_dev(&num_devices);
365 if (copy_to_user((void __user *)arg, &num_devices, sizeof(num_devices)))
371 static int adf_ctl_ioctl_get_status(struct file *fp, unsigned int cmd,
374 struct adf_hw_device_data *hw_data;
375 struct adf_dev_status_info dev_info;
376 struct adf_accel_dev *accel_dev;
378 if (copy_from_user(&dev_info, (void __user *)arg,
379 sizeof(struct adf_dev_status_info))) {
380 pr_err("QAT: failed to copy from user.\n");
384 accel_dev = adf_devmgr_get_dev_by_id(dev_info.accel_id);
386 pr_err("QAT: Device %d not found\n", dev_info.accel_id);
389 hw_data = accel_dev->hw_device;
390 dev_info.state = adf_dev_started(accel_dev) ? DEV_UP : DEV_DOWN;
391 dev_info.num_ae = hw_data->get_num_aes(hw_data);
392 dev_info.num_accel = hw_data->get_num_accels(hw_data);
393 dev_info.num_logical_accel = hw_data->num_logical_accel;
394 dev_info.banks_per_accel = hw_data->num_banks
395 / hw_data->num_logical_accel;
396 strlcpy(dev_info.name, hw_data->dev_class->name, sizeof(dev_info.name));
397 dev_info.instance_id = hw_data->instance_id;
398 dev_info.type = hw_data->dev_class->type;
399 dev_info.bus = accel_to_pci_dev(accel_dev)->bus->number;
400 dev_info.dev = PCI_SLOT(accel_to_pci_dev(accel_dev)->devfn);
401 dev_info.fun = PCI_FUNC(accel_to_pci_dev(accel_dev)->devfn);
403 if (copy_to_user((void __user *)arg, &dev_info,
404 sizeof(struct adf_dev_status_info))) {
405 pr_err("QAT: failed to copy status.\n");
411 static long adf_ctl_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
415 if (mutex_lock_interruptible(&adf_ctl_lock))
419 case IOCTL_CONFIG_SYS_RESOURCE_PARAMETERS:
420 ret = adf_ctl_ioctl_dev_config(fp, cmd, arg);
423 case IOCTL_STOP_ACCEL_DEV:
424 ret = adf_ctl_ioctl_dev_stop(fp, cmd, arg);
427 case IOCTL_START_ACCEL_DEV:
428 ret = adf_ctl_ioctl_dev_start(fp, cmd, arg);
431 case IOCTL_GET_NUM_DEVICES:
432 ret = adf_ctl_ioctl_get_num_devices(fp, cmd, arg);
435 case IOCTL_STATUS_ACCEL_DEV:
436 ret = adf_ctl_ioctl_get_status(fp, cmd, arg);
439 pr_err("QAT: Invalid ioctl\n");
443 mutex_unlock(&adf_ctl_lock);
447 static int __init adf_register_ctl_device_driver(void)
449 mutex_init(&adf_ctl_lock);
454 if (adf_chr_drv_create())
460 if (qat_crypto_register())
461 goto err_crypto_register;
468 adf_chr_drv_destroy();
472 mutex_destroy(&adf_ctl_lock);
476 static void __exit adf_unregister_ctl_device_driver(void)
478 adf_chr_drv_destroy();
480 qat_crypto_unregister();
482 mutex_destroy(&adf_ctl_lock);
485 module_init(adf_register_ctl_device_driver);
486 module_exit(adf_unregister_ctl_device_driver);
487 MODULE_LICENSE("Dual BSD/GPL");
488 MODULE_AUTHOR("Intel");
489 MODULE_DESCRIPTION("Intel(R) QuickAssist Technology");
490 MODULE_ALIAS("intel_qat");