• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
adf_chr_drv_destroy(void)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 
adf_chr_drv_create(void)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 
adf_ctl_alloc_resources(struct adf_user_cfg_ctl_data ** ctl_data,unsigned long arg)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 
adf_add_key_value_data(struct adf_accel_dev * accel_dev,const char * section,const struct adf_user_cfg_key_val * key_val)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 
adf_copy_key_value_data(struct adf_accel_dev * accel_dev,struct adf_user_cfg_ctl_data * ctl_data)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 
adf_ctl_ioctl_dev_config(struct file * fp,unsigned int cmd,unsigned long arg)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 
adf_ctl_is_device_in_use(int id)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 
adf_ctl_stop_devices(uint32_t id)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 
adf_ctl_ioctl_dev_stop(struct file * fp,unsigned int cmd,unsigned long arg)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 
adf_ctl_ioctl_dev_start(struct file * fp,unsigned int cmd,unsigned long arg)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 
adf_ctl_ioctl_get_num_devices(struct file * fp,unsigned int cmd,unsigned long arg)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 
adf_ctl_ioctl_get_status(struct file * fp,unsigned int cmd,unsigned long arg)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 
adf_ctl_ioctl(struct file * fp,unsigned int cmd,unsigned long arg)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 
adf_register_ctl_device_driver(void)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 (adf_init_pf_wq())
473 		goto err_pf_wq;
474 
475 	if (qat_crypto_register())
476 		goto err_crypto_register;
477 
478 	return 0;
479 
480 err_crypto_register:
481 	adf_exit_pf_wq();
482 err_pf_wq:
483 	adf_exit_aer();
484 err_aer:
485 	adf_chr_drv_destroy();
486 err_chr_dev:
487 	mutex_destroy(&adf_ctl_lock);
488 	return -EFAULT;
489 }
490 
adf_unregister_ctl_device_driver(void)491 static void __exit adf_unregister_ctl_device_driver(void)
492 {
493 	adf_chr_drv_destroy();
494 	adf_exit_aer();
495 	adf_exit_pf_wq();
496 	qat_crypto_unregister();
497 	adf_clean_vf_map(false);
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");
507 MODULE_VERSION(ADF_DRV_VERSION);
508