1 // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
2 /* Copyright(c) 2014 - 2020 Intel Corporation */
3 
4 #include <crypto/algapi.h>
5 #include <linux/module.h>
6 #include <linux/mutex.h>
7 #include <linux/slab.h>
8 #include <linux/fs.h>
9 #include <linux/bitops.h>
10 #include <linux/pci.h>
11 #include <linux/cdev.h>
12 #include <linux/uaccess.h>
13 
14 #include "adf_accel_devices.h"
15 #include "adf_common_drv.h"
16 #include "adf_cfg.h"
17 #include "adf_cfg_common.h"
18 #include "adf_cfg_user.h"
19 
20 #define ADF_CFG_MAX_SECTION 512
21 #define ADF_CFG_MAX_KEY_VAL 256
22 
23 #define DEVICE_NAME "qat_adf_ctl"
24 
25 static DEFINE_MUTEX(adf_ctl_lock);
26 static long adf_ctl_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
27 
28 static const struct file_operations adf_ctl_ops = {
29 	.owner = THIS_MODULE,
30 	.unlocked_ioctl = adf_ctl_ioctl,
31 	.compat_ioctl = compat_ptr_ioctl,
32 };
33 
34 struct adf_ctl_drv_info {
35 	unsigned int major;
36 	struct cdev drv_cdev;
37 	struct class *drv_class;
38 };
39 
40 static struct adf_ctl_drv_info adf_ctl_drv;
41 
adf_chr_drv_destroy(void)42 static void adf_chr_drv_destroy(void)
43 {
44 	device_destroy(adf_ctl_drv.drv_class, MKDEV(adf_ctl_drv.major, 0));
45 	cdev_del(&adf_ctl_drv.drv_cdev);
46 	class_destroy(adf_ctl_drv.drv_class);
47 	unregister_chrdev_region(MKDEV(adf_ctl_drv.major, 0), 1);
48 }
49 
adf_chr_drv_create(void)50 static int adf_chr_drv_create(void)
51 {
52 	dev_t dev_id;
53 	struct device *drv_device;
54 
55 	if (alloc_chrdev_region(&dev_id, 0, 1, DEVICE_NAME)) {
56 		pr_err("QAT: unable to allocate chrdev region\n");
57 		return -EFAULT;
58 	}
59 
60 	adf_ctl_drv.drv_class = class_create(DEVICE_NAME);
61 	if (IS_ERR(adf_ctl_drv.drv_class)) {
62 		pr_err("QAT: class_create failed for adf_ctl\n");
63 		goto err_chrdev_unreg;
64 	}
65 	adf_ctl_drv.major = MAJOR(dev_id);
66 	cdev_init(&adf_ctl_drv.drv_cdev, &adf_ctl_ops);
67 	if (cdev_add(&adf_ctl_drv.drv_cdev, dev_id, 1)) {
68 		pr_err("QAT: cdev add failed\n");
69 		goto err_class_destr;
70 	}
71 
72 	drv_device = device_create(adf_ctl_drv.drv_class, NULL,
73 				   MKDEV(adf_ctl_drv.major, 0),
74 				   NULL, DEVICE_NAME);
75 	if (IS_ERR(drv_device)) {
76 		pr_err("QAT: failed to create device\n");
77 		goto err_cdev_del;
78 	}
79 	return 0;
80 err_cdev_del:
81 	cdev_del(&adf_ctl_drv.drv_cdev);
82 err_class_destr:
83 	class_destroy(adf_ctl_drv.drv_class);
84 err_chrdev_unreg:
85 	unregister_chrdev_region(dev_id, 1);
86 	return -EFAULT;
87 }
88 
adf_ctl_alloc_resources(struct adf_user_cfg_ctl_data ** ctl_data,unsigned long arg)89 static int adf_ctl_alloc_resources(struct adf_user_cfg_ctl_data **ctl_data,
90 				   unsigned long arg)
91 {
92 	struct adf_user_cfg_ctl_data *cfg_data;
93 
94 	cfg_data = kzalloc(sizeof(*cfg_data), GFP_KERNEL);
95 	if (!cfg_data)
96 		return -ENOMEM;
97 
98 	/* Initialize device id to NO DEVICE as 0 is a valid device id */
99 	cfg_data->device_id = ADF_CFG_NO_DEVICE;
100 
101 	if (copy_from_user(cfg_data, (void __user *)arg, sizeof(*cfg_data))) {
102 		pr_err("QAT: failed to copy from user cfg_data.\n");
103 		kfree(cfg_data);
104 		return -EIO;
105 	}
106 
107 	*ctl_data = cfg_data;
108 	return 0;
109 }
110 
adf_add_key_value_data(struct adf_accel_dev * accel_dev,const char * section,const struct adf_user_cfg_key_val * key_val)111 static int adf_add_key_value_data(struct adf_accel_dev *accel_dev,
112 				  const char *section,
113 				  const struct adf_user_cfg_key_val *key_val)
114 {
115 	if (key_val->type == ADF_HEX) {
116 		long *ptr = (long *)key_val->val;
117 		long val = *ptr;
118 
119 		if (adf_cfg_add_key_value_param(accel_dev, section,
120 						key_val->key, (void *)val,
121 						key_val->type)) {
122 			dev_err(&GET_DEV(accel_dev),
123 				"failed to add hex keyvalue.\n");
124 			return -EFAULT;
125 		}
126 	} else {
127 		if (adf_cfg_add_key_value_param(accel_dev, section,
128 						key_val->key, key_val->val,
129 						key_val->type)) {
130 			dev_err(&GET_DEV(accel_dev),
131 				"failed to add keyvalue.\n");
132 			return -EFAULT;
133 		}
134 	}
135 	return 0;
136 }
137 
adf_copy_key_value_data(struct adf_accel_dev * accel_dev,struct adf_user_cfg_ctl_data * ctl_data)138 static int adf_copy_key_value_data(struct adf_accel_dev *accel_dev,
139 				   struct adf_user_cfg_ctl_data *ctl_data)
140 {
141 	struct adf_user_cfg_key_val key_val;
142 	struct adf_user_cfg_key_val *params_head;
143 	struct adf_user_cfg_section section, *section_head;
144 	int i, j;
145 
146 	section_head = ctl_data->config_section;
147 
148 	for (i = 0; section_head && i < ADF_CFG_MAX_SECTION; i++) {
149 		if (copy_from_user(&section, (void __user *)section_head,
150 				   sizeof(*section_head))) {
151 			dev_err(&GET_DEV(accel_dev),
152 				"failed to copy section info\n");
153 			goto out_err;
154 		}
155 
156 		if (adf_cfg_section_add(accel_dev, section.name)) {
157 			dev_err(&GET_DEV(accel_dev),
158 				"failed to add section.\n");
159 			goto out_err;
160 		}
161 
162 		params_head = section.params;
163 
164 		for (j = 0; params_head && j < ADF_CFG_MAX_KEY_VAL; j++) {
165 			if (copy_from_user(&key_val, (void __user *)params_head,
166 					   sizeof(key_val))) {
167 				dev_err(&GET_DEV(accel_dev),
168 					"Failed to copy keyvalue.\n");
169 				goto out_err;
170 			}
171 			if (adf_add_key_value_data(accel_dev, section.name,
172 						   &key_val)) {
173 				goto out_err;
174 			}
175 			params_head = key_val.next;
176 		}
177 		section_head = section.next;
178 	}
179 	return 0;
180 out_err:
181 	adf_cfg_del_all(accel_dev);
182 	return -EFAULT;
183 }
184 
adf_ctl_ioctl_dev_config(struct file * fp,unsigned int cmd,unsigned long arg)185 static int adf_ctl_ioctl_dev_config(struct file *fp, unsigned int cmd,
186 				    unsigned long arg)
187 {
188 	int ret;
189 	struct adf_user_cfg_ctl_data *ctl_data;
190 	struct adf_accel_dev *accel_dev;
191 
192 	ret = adf_ctl_alloc_resources(&ctl_data, arg);
193 	if (ret)
194 		return ret;
195 
196 	accel_dev = adf_devmgr_get_dev_by_id(ctl_data->device_id);
197 	if (!accel_dev) {
198 		ret = -EFAULT;
199 		goto out;
200 	}
201 
202 	if (adf_dev_started(accel_dev)) {
203 		ret = -EFAULT;
204 		goto out;
205 	}
206 
207 	if (adf_copy_key_value_data(accel_dev, ctl_data)) {
208 		ret = -EFAULT;
209 		goto out;
210 	}
211 	set_bit(ADF_STATUS_CONFIGURED, &accel_dev->status);
212 out:
213 	kfree(ctl_data);
214 	return ret;
215 }
216 
adf_ctl_is_device_in_use(int id)217 static int adf_ctl_is_device_in_use(int id)
218 {
219 	struct adf_accel_dev *dev;
220 
221 	list_for_each_entry(dev, adf_devmgr_get_head(), list) {
222 		if (id == dev->accel_id || id == ADF_CFG_ALL_DEVICES) {
223 			if (adf_devmgr_in_reset(dev) || adf_dev_in_use(dev)) {
224 				dev_info(&GET_DEV(dev),
225 					 "device qat_dev%d is busy\n",
226 					 dev->accel_id);
227 				return -EBUSY;
228 			}
229 		}
230 	}
231 	return 0;
232 }
233 
adf_ctl_stop_devices(u32 id)234 static void adf_ctl_stop_devices(u32 id)
235 {
236 	struct adf_accel_dev *accel_dev;
237 
238 	list_for_each_entry(accel_dev, adf_devmgr_get_head(), list) {
239 		if (id == accel_dev->accel_id || id == ADF_CFG_ALL_DEVICES) {
240 			if (!adf_dev_started(accel_dev))
241 				continue;
242 
243 			/* First stop all VFs */
244 			if (!accel_dev->is_vf)
245 				continue;
246 
247 			adf_dev_down(accel_dev, false);
248 		}
249 	}
250 
251 	list_for_each_entry(accel_dev, adf_devmgr_get_head(), list) {
252 		if (id == accel_dev->accel_id || id == ADF_CFG_ALL_DEVICES) {
253 			if (!adf_dev_started(accel_dev))
254 				continue;
255 
256 			adf_dev_down(accel_dev, false);
257 		}
258 	}
259 }
260 
adf_ctl_ioctl_dev_stop(struct file * fp,unsigned int cmd,unsigned long arg)261 static int adf_ctl_ioctl_dev_stop(struct file *fp, unsigned int cmd,
262 				  unsigned long arg)
263 {
264 	int ret;
265 	struct adf_user_cfg_ctl_data *ctl_data;
266 
267 	ret = adf_ctl_alloc_resources(&ctl_data, arg);
268 	if (ret)
269 		return ret;
270 
271 	if (adf_devmgr_verify_id(ctl_data->device_id)) {
272 		pr_err("QAT: Device %d not found\n", ctl_data->device_id);
273 		ret = -ENODEV;
274 		goto out;
275 	}
276 
277 	ret = adf_ctl_is_device_in_use(ctl_data->device_id);
278 	if (ret)
279 		goto out;
280 
281 	if (ctl_data->device_id == ADF_CFG_ALL_DEVICES)
282 		pr_info("QAT: Stopping all acceleration devices.\n");
283 	else
284 		pr_info("QAT: Stopping acceleration device qat_dev%d.\n",
285 			ctl_data->device_id);
286 
287 	adf_ctl_stop_devices(ctl_data->device_id);
288 
289 out:
290 	kfree(ctl_data);
291 	return ret;
292 }
293 
adf_ctl_ioctl_dev_start(struct file * fp,unsigned int cmd,unsigned long arg)294 static int adf_ctl_ioctl_dev_start(struct file *fp, unsigned int cmd,
295 				   unsigned long arg)
296 {
297 	int ret;
298 	struct adf_user_cfg_ctl_data *ctl_data;
299 	struct adf_accel_dev *accel_dev;
300 
301 	ret = adf_ctl_alloc_resources(&ctl_data, arg);
302 	if (ret)
303 		return ret;
304 
305 	ret = -ENODEV;
306 	accel_dev = adf_devmgr_get_dev_by_id(ctl_data->device_id);
307 	if (!accel_dev)
308 		goto out;
309 
310 	dev_info(&GET_DEV(accel_dev),
311 		 "Starting acceleration device qat_dev%d.\n",
312 		 ctl_data->device_id);
313 
314 	ret = adf_dev_up(accel_dev, false);
315 
316 	if (ret) {
317 		dev_err(&GET_DEV(accel_dev), "Failed to start qat_dev%d\n",
318 			ctl_data->device_id);
319 		adf_dev_down(accel_dev, false);
320 	}
321 out:
322 	kfree(ctl_data);
323 	return ret;
324 }
325 
adf_ctl_ioctl_get_num_devices(struct file * fp,unsigned int cmd,unsigned long arg)326 static int adf_ctl_ioctl_get_num_devices(struct file *fp, unsigned int cmd,
327 					 unsigned long arg)
328 {
329 	u32 num_devices = 0;
330 
331 	adf_devmgr_get_num_dev(&num_devices);
332 	if (copy_to_user((void __user *)arg, &num_devices, sizeof(num_devices)))
333 		return -EFAULT;
334 
335 	return 0;
336 }
337 
adf_ctl_ioctl_get_status(struct file * fp,unsigned int cmd,unsigned long arg)338 static int adf_ctl_ioctl_get_status(struct file *fp, unsigned int cmd,
339 				    unsigned long arg)
340 {
341 	struct adf_hw_device_data *hw_data;
342 	struct adf_dev_status_info dev_info;
343 	struct adf_accel_dev *accel_dev;
344 
345 	if (copy_from_user(&dev_info, (void __user *)arg,
346 			   sizeof(struct adf_dev_status_info))) {
347 		pr_err("QAT: failed to copy from user.\n");
348 		return -EFAULT;
349 	}
350 
351 	accel_dev = adf_devmgr_get_dev_by_id(dev_info.accel_id);
352 	if (!accel_dev)
353 		return -ENODEV;
354 
355 	hw_data = accel_dev->hw_device;
356 	dev_info.state = adf_dev_started(accel_dev) ? DEV_UP : DEV_DOWN;
357 	dev_info.num_ae = hw_data->get_num_aes(hw_data);
358 	dev_info.num_accel = hw_data->get_num_accels(hw_data);
359 	dev_info.num_logical_accel = hw_data->num_logical_accel;
360 	dev_info.banks_per_accel = hw_data->num_banks
361 					/ hw_data->num_logical_accel;
362 	strscpy(dev_info.name, hw_data->dev_class->name, sizeof(dev_info.name));
363 	dev_info.instance_id = hw_data->instance_id;
364 	dev_info.type = hw_data->dev_class->type;
365 	dev_info.bus = accel_to_pci_dev(accel_dev)->bus->number;
366 	dev_info.dev = PCI_SLOT(accel_to_pci_dev(accel_dev)->devfn);
367 	dev_info.fun = PCI_FUNC(accel_to_pci_dev(accel_dev)->devfn);
368 
369 	if (copy_to_user((void __user *)arg, &dev_info,
370 			 sizeof(struct adf_dev_status_info))) {
371 		dev_err(&GET_DEV(accel_dev), "failed to copy status.\n");
372 		return -EFAULT;
373 	}
374 	return 0;
375 }
376 
adf_ctl_ioctl(struct file * fp,unsigned int cmd,unsigned long arg)377 static long adf_ctl_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
378 {
379 	int ret;
380 
381 	if (mutex_lock_interruptible(&adf_ctl_lock))
382 		return -EFAULT;
383 
384 	switch (cmd) {
385 	case IOCTL_CONFIG_SYS_RESOURCE_PARAMETERS:
386 		ret = adf_ctl_ioctl_dev_config(fp, cmd, arg);
387 		break;
388 
389 	case IOCTL_STOP_ACCEL_DEV:
390 		ret = adf_ctl_ioctl_dev_stop(fp, cmd, arg);
391 		break;
392 
393 	case IOCTL_START_ACCEL_DEV:
394 		ret = adf_ctl_ioctl_dev_start(fp, cmd, arg);
395 		break;
396 
397 	case IOCTL_GET_NUM_DEVICES:
398 		ret = adf_ctl_ioctl_get_num_devices(fp, cmd, arg);
399 		break;
400 
401 	case IOCTL_STATUS_ACCEL_DEV:
402 		ret = adf_ctl_ioctl_get_status(fp, cmd, arg);
403 		break;
404 	default:
405 		pr_err_ratelimited("QAT: Invalid ioctl %d\n", cmd);
406 		ret = -EFAULT;
407 		break;
408 	}
409 	mutex_unlock(&adf_ctl_lock);
410 	return ret;
411 }
412 
adf_register_ctl_device_driver(void)413 static int __init adf_register_ctl_device_driver(void)
414 {
415 	if (adf_chr_drv_create())
416 		goto err_chr_dev;
417 
418 	if (adf_init_misc_wq())
419 		goto err_misc_wq;
420 
421 	if (adf_init_aer())
422 		goto err_aer;
423 
424 	if (adf_init_pf_wq())
425 		goto err_pf_wq;
426 
427 	if (adf_init_vf_wq())
428 		goto err_vf_wq;
429 
430 	if (qat_crypto_register())
431 		goto err_crypto_register;
432 
433 	if (qat_compression_register())
434 		goto err_compression_register;
435 
436 	return 0;
437 
438 err_compression_register:
439 	qat_crypto_unregister();
440 err_crypto_register:
441 	adf_exit_vf_wq();
442 err_vf_wq:
443 	adf_exit_pf_wq();
444 err_pf_wq:
445 	adf_exit_aer();
446 err_aer:
447 	adf_exit_misc_wq();
448 err_misc_wq:
449 	adf_chr_drv_destroy();
450 err_chr_dev:
451 	mutex_destroy(&adf_ctl_lock);
452 	return -EFAULT;
453 }
454 
adf_unregister_ctl_device_driver(void)455 static void __exit adf_unregister_ctl_device_driver(void)
456 {
457 	adf_chr_drv_destroy();
458 	adf_exit_misc_wq();
459 	adf_exit_aer();
460 	adf_exit_vf_wq();
461 	adf_exit_pf_wq();
462 	qat_crypto_unregister();
463 	qat_compression_unregister();
464 	adf_clean_vf_map(false);
465 	mutex_destroy(&adf_ctl_lock);
466 }
467 
468 module_init(adf_register_ctl_device_driver);
469 module_exit(adf_unregister_ctl_device_driver);
470 MODULE_LICENSE("Dual BSD/GPL");
471 MODULE_AUTHOR("Intel");
472 MODULE_DESCRIPTION("Intel(R) QuickAssist Technology");
473 MODULE_ALIAS_CRYPTO("intel_qat");
474 MODULE_VERSION(ADF_DRV_VERSION);
475 MODULE_IMPORT_NS(CRYPTO_INTERNAL);
476