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 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 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 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 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 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(§ion, (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 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 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 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 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 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 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 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 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 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 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