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