1 /* 2 * Copyright 2014 IBM Corp. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 */ 9 10 #include <linux/kernel.h> 11 #include <linux/device.h> 12 #include <linux/sysfs.h> 13 #include <linux/pci_regs.h> 14 15 #include "cxl.h" 16 17 #define to_afu_chardev_m(d) dev_get_drvdata(d) 18 19 /********* Adapter attributes **********************************************/ 20 21 static ssize_t caia_version_show(struct device *device, 22 struct device_attribute *attr, 23 char *buf) 24 { 25 struct cxl *adapter = to_cxl_adapter(device); 26 27 return scnprintf(buf, PAGE_SIZE, "%i.%i\n", adapter->caia_major, 28 adapter->caia_minor); 29 } 30 31 static ssize_t psl_revision_show(struct device *device, 32 struct device_attribute *attr, 33 char *buf) 34 { 35 struct cxl *adapter = to_cxl_adapter(device); 36 37 return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->psl_rev); 38 } 39 40 static ssize_t base_image_show(struct device *device, 41 struct device_attribute *attr, 42 char *buf) 43 { 44 struct cxl *adapter = to_cxl_adapter(device); 45 46 return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->base_image); 47 } 48 49 static ssize_t image_loaded_show(struct device *device, 50 struct device_attribute *attr, 51 char *buf) 52 { 53 struct cxl *adapter = to_cxl_adapter(device); 54 55 if (adapter->user_image_loaded) 56 return scnprintf(buf, PAGE_SIZE, "user\n"); 57 return scnprintf(buf, PAGE_SIZE, "factory\n"); 58 } 59 60 static ssize_t reset_adapter_store(struct device *device, 61 struct device_attribute *attr, 62 const char *buf, size_t count) 63 { 64 struct cxl *adapter = to_cxl_adapter(device); 65 int rc; 66 int val; 67 68 rc = sscanf(buf, "%i", &val); 69 if ((rc != 1) || (val != 1)) 70 return -EINVAL; 71 72 if ((rc = cxl_reset(adapter))) 73 return rc; 74 return count; 75 } 76 77 static ssize_t load_image_on_perst_show(struct device *device, 78 struct device_attribute *attr, 79 char *buf) 80 { 81 struct cxl *adapter = to_cxl_adapter(device); 82 83 if (!adapter->perst_loads_image) 84 return scnprintf(buf, PAGE_SIZE, "none\n"); 85 86 if (adapter->perst_select_user) 87 return scnprintf(buf, PAGE_SIZE, "user\n"); 88 return scnprintf(buf, PAGE_SIZE, "factory\n"); 89 } 90 91 static ssize_t load_image_on_perst_store(struct device *device, 92 struct device_attribute *attr, 93 const char *buf, size_t count) 94 { 95 struct cxl *adapter = to_cxl_adapter(device); 96 int rc; 97 98 if (!strncmp(buf, "none", 4)) 99 adapter->perst_loads_image = false; 100 else if (!strncmp(buf, "user", 4)) { 101 adapter->perst_select_user = true; 102 adapter->perst_loads_image = true; 103 } else if (!strncmp(buf, "factory", 7)) { 104 adapter->perst_select_user = false; 105 adapter->perst_loads_image = true; 106 } else 107 return -EINVAL; 108 109 if ((rc = cxl_update_image_control(adapter))) 110 return rc; 111 112 return count; 113 } 114 115 static ssize_t perst_reloads_same_image_show(struct device *device, 116 struct device_attribute *attr, 117 char *buf) 118 { 119 struct cxl *adapter = to_cxl_adapter(device); 120 121 return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->perst_same_image); 122 } 123 124 static ssize_t perst_reloads_same_image_store(struct device *device, 125 struct device_attribute *attr, 126 const char *buf, size_t count) 127 { 128 struct cxl *adapter = to_cxl_adapter(device); 129 int rc; 130 int val; 131 132 rc = sscanf(buf, "%i", &val); 133 if ((rc != 1) || !(val == 1 || val == 0)) 134 return -EINVAL; 135 136 adapter->perst_same_image = (val == 1 ? true : false); 137 return count; 138 } 139 140 static struct device_attribute adapter_attrs[] = { 141 __ATTR_RO(caia_version), 142 __ATTR_RO(psl_revision), 143 __ATTR_RO(base_image), 144 __ATTR_RO(image_loaded), 145 __ATTR_RW(load_image_on_perst), 146 __ATTR_RW(perst_reloads_same_image), 147 __ATTR(reset, S_IWUSR, NULL, reset_adapter_store), 148 }; 149 150 151 /********* AFU master specific attributes **********************************/ 152 153 static ssize_t mmio_size_show_master(struct device *device, 154 struct device_attribute *attr, 155 char *buf) 156 { 157 struct cxl_afu *afu = to_afu_chardev_m(device); 158 159 return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->adapter->ps_size); 160 } 161 162 static ssize_t pp_mmio_off_show(struct device *device, 163 struct device_attribute *attr, 164 char *buf) 165 { 166 struct cxl_afu *afu = to_afu_chardev_m(device); 167 168 return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->pp_offset); 169 } 170 171 static ssize_t pp_mmio_len_show(struct device *device, 172 struct device_attribute *attr, 173 char *buf) 174 { 175 struct cxl_afu *afu = to_afu_chardev_m(device); 176 177 return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->pp_size); 178 } 179 180 static struct device_attribute afu_master_attrs[] = { 181 __ATTR(mmio_size, S_IRUGO, mmio_size_show_master, NULL), 182 __ATTR_RO(pp_mmio_off), 183 __ATTR_RO(pp_mmio_len), 184 }; 185 186 187 /********* AFU attributes **************************************************/ 188 189 static ssize_t mmio_size_show(struct device *device, 190 struct device_attribute *attr, 191 char *buf) 192 { 193 struct cxl_afu *afu = to_cxl_afu(device); 194 195 if (afu->pp_size) 196 return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->pp_size); 197 return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->adapter->ps_size); 198 } 199 200 static ssize_t reset_store_afu(struct device *device, 201 struct device_attribute *attr, 202 const char *buf, size_t count) 203 { 204 struct cxl_afu *afu = to_cxl_afu(device); 205 int rc; 206 207 /* Not safe to reset if it is currently in use */ 208 mutex_lock(&afu->contexts_lock); 209 if (!idr_is_empty(&afu->contexts_idr)) { 210 rc = -EBUSY; 211 goto err; 212 } 213 214 if ((rc = __cxl_afu_reset(afu))) 215 goto err; 216 217 rc = count; 218 err: 219 mutex_unlock(&afu->contexts_lock); 220 return rc; 221 } 222 223 static ssize_t irqs_min_show(struct device *device, 224 struct device_attribute *attr, 225 char *buf) 226 { 227 struct cxl_afu *afu = to_cxl_afu(device); 228 229 return scnprintf(buf, PAGE_SIZE, "%i\n", afu->pp_irqs); 230 } 231 232 static ssize_t irqs_max_show(struct device *device, 233 struct device_attribute *attr, 234 char *buf) 235 { 236 struct cxl_afu *afu = to_cxl_afu(device); 237 238 return scnprintf(buf, PAGE_SIZE, "%i\n", afu->irqs_max); 239 } 240 241 static ssize_t irqs_max_store(struct device *device, 242 struct device_attribute *attr, 243 const char *buf, size_t count) 244 { 245 struct cxl_afu *afu = to_cxl_afu(device); 246 ssize_t ret; 247 int irqs_max; 248 249 ret = sscanf(buf, "%i", &irqs_max); 250 if (ret != 1) 251 return -EINVAL; 252 253 if (irqs_max < afu->pp_irqs) 254 return -EINVAL; 255 256 if (irqs_max > afu->adapter->user_irqs) 257 return -EINVAL; 258 259 afu->irqs_max = irqs_max; 260 return count; 261 } 262 263 static ssize_t modes_supported_show(struct device *device, 264 struct device_attribute *attr, char *buf) 265 { 266 struct cxl_afu *afu = to_cxl_afu(device); 267 char *p = buf, *end = buf + PAGE_SIZE; 268 269 if (afu->modes_supported & CXL_MODE_DEDICATED) 270 p += scnprintf(p, end - p, "dedicated_process\n"); 271 if (afu->modes_supported & CXL_MODE_DIRECTED) 272 p += scnprintf(p, end - p, "afu_directed\n"); 273 return (p - buf); 274 } 275 276 static ssize_t prefault_mode_show(struct device *device, 277 struct device_attribute *attr, 278 char *buf) 279 { 280 struct cxl_afu *afu = to_cxl_afu(device); 281 282 switch (afu->prefault_mode) { 283 case CXL_PREFAULT_WED: 284 return scnprintf(buf, PAGE_SIZE, "work_element_descriptor\n"); 285 case CXL_PREFAULT_ALL: 286 return scnprintf(buf, PAGE_SIZE, "all\n"); 287 default: 288 return scnprintf(buf, PAGE_SIZE, "none\n"); 289 } 290 } 291 292 static ssize_t prefault_mode_store(struct device *device, 293 struct device_attribute *attr, 294 const char *buf, size_t count) 295 { 296 struct cxl_afu *afu = to_cxl_afu(device); 297 enum prefault_modes mode = -1; 298 299 if (!strncmp(buf, "work_element_descriptor", 23)) 300 mode = CXL_PREFAULT_WED; 301 if (!strncmp(buf, "all", 3)) 302 mode = CXL_PREFAULT_ALL; 303 if (!strncmp(buf, "none", 4)) 304 mode = CXL_PREFAULT_NONE; 305 306 if (mode == -1) 307 return -EINVAL; 308 309 afu->prefault_mode = mode; 310 return count; 311 } 312 313 static ssize_t mode_show(struct device *device, 314 struct device_attribute *attr, 315 char *buf) 316 { 317 struct cxl_afu *afu = to_cxl_afu(device); 318 319 if (afu->current_mode == CXL_MODE_DEDICATED) 320 return scnprintf(buf, PAGE_SIZE, "dedicated_process\n"); 321 if (afu->current_mode == CXL_MODE_DIRECTED) 322 return scnprintf(buf, PAGE_SIZE, "afu_directed\n"); 323 return scnprintf(buf, PAGE_SIZE, "none\n"); 324 } 325 326 static ssize_t mode_store(struct device *device, struct device_attribute *attr, 327 const char *buf, size_t count) 328 { 329 struct cxl_afu *afu = to_cxl_afu(device); 330 int old_mode, mode = -1; 331 int rc = -EBUSY; 332 333 /* can't change this if we have a user */ 334 mutex_lock(&afu->contexts_lock); 335 if (!idr_is_empty(&afu->contexts_idr)) 336 goto err; 337 338 if (!strncmp(buf, "dedicated_process", 17)) 339 mode = CXL_MODE_DEDICATED; 340 if (!strncmp(buf, "afu_directed", 12)) 341 mode = CXL_MODE_DIRECTED; 342 if (!strncmp(buf, "none", 4)) 343 mode = 0; 344 345 if (mode == -1) { 346 rc = -EINVAL; 347 goto err; 348 } 349 350 /* 351 * cxl_afu_deactivate_mode needs to be done outside the lock, prevent 352 * other contexts coming in before we are ready: 353 */ 354 old_mode = afu->current_mode; 355 afu->current_mode = 0; 356 afu->num_procs = 0; 357 358 mutex_unlock(&afu->contexts_lock); 359 360 if ((rc = _cxl_afu_deactivate_mode(afu, old_mode))) 361 return rc; 362 if ((rc = cxl_afu_activate_mode(afu, mode))) 363 return rc; 364 365 return count; 366 err: 367 mutex_unlock(&afu->contexts_lock); 368 return rc; 369 } 370 371 static ssize_t api_version_show(struct device *device, 372 struct device_attribute *attr, 373 char *buf) 374 { 375 return scnprintf(buf, PAGE_SIZE, "%i\n", CXL_API_VERSION); 376 } 377 378 static ssize_t api_version_compatible_show(struct device *device, 379 struct device_attribute *attr, 380 char *buf) 381 { 382 return scnprintf(buf, PAGE_SIZE, "%i\n", CXL_API_VERSION_COMPATIBLE); 383 } 384 385 static ssize_t afu_eb_read(struct file *filp, struct kobject *kobj, 386 struct bin_attribute *bin_attr, char *buf, 387 loff_t off, size_t count) 388 { 389 struct cxl_afu *afu = to_cxl_afu(container_of(kobj, 390 struct device, kobj)); 391 392 return cxl_afu_read_err_buffer(afu, buf, off, count); 393 } 394 395 static struct device_attribute afu_attrs[] = { 396 __ATTR_RO(mmio_size), 397 __ATTR_RO(irqs_min), 398 __ATTR_RW(irqs_max), 399 __ATTR_RO(modes_supported), 400 __ATTR_RW(mode), 401 __ATTR_RW(prefault_mode), 402 __ATTR_RO(api_version), 403 __ATTR_RO(api_version_compatible), 404 __ATTR(reset, S_IWUSR, NULL, reset_store_afu), 405 }; 406 407 int cxl_sysfs_adapter_add(struct cxl *adapter) 408 { 409 int i, rc; 410 411 for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++) { 412 if ((rc = device_create_file(&adapter->dev, &adapter_attrs[i]))) 413 goto err; 414 } 415 return 0; 416 err: 417 for (i--; i >= 0; i--) 418 device_remove_file(&adapter->dev, &adapter_attrs[i]); 419 return rc; 420 } 421 void cxl_sysfs_adapter_remove(struct cxl *adapter) 422 { 423 int i; 424 425 for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++) 426 device_remove_file(&adapter->dev, &adapter_attrs[i]); 427 } 428 429 struct afu_config_record { 430 struct kobject kobj; 431 struct bin_attribute config_attr; 432 struct list_head list; 433 int cr; 434 u16 device; 435 u16 vendor; 436 u32 class; 437 }; 438 439 #define to_cr(obj) container_of(obj, struct afu_config_record, kobj) 440 441 static ssize_t vendor_show(struct kobject *kobj, 442 struct kobj_attribute *attr, char *buf) 443 { 444 struct afu_config_record *cr = to_cr(kobj); 445 446 return scnprintf(buf, PAGE_SIZE, "0x%.4x\n", cr->vendor); 447 } 448 449 static ssize_t device_show(struct kobject *kobj, 450 struct kobj_attribute *attr, char *buf) 451 { 452 struct afu_config_record *cr = to_cr(kobj); 453 454 return scnprintf(buf, PAGE_SIZE, "0x%.4x\n", cr->device); 455 } 456 457 static ssize_t class_show(struct kobject *kobj, 458 struct kobj_attribute *attr, char *buf) 459 { 460 struct afu_config_record *cr = to_cr(kobj); 461 462 return scnprintf(buf, PAGE_SIZE, "0x%.6x\n", cr->class); 463 } 464 465 static ssize_t afu_read_config(struct file *filp, struct kobject *kobj, 466 struct bin_attribute *bin_attr, char *buf, 467 loff_t off, size_t count) 468 { 469 struct afu_config_record *cr = to_cr(kobj); 470 struct cxl_afu *afu = to_cxl_afu(container_of(kobj->parent, struct device, kobj)); 471 472 u64 i, j, val; 473 474 for (i = 0; i < count;) { 475 val = cxl_afu_cr_read64(afu, cr->cr, off & ~0x7); 476 for (j = off & 0x7; j < 8 && i < count; i++, j++, off++) 477 buf[i] = (val >> (j * 8)) & 0xff; 478 } 479 480 return count; 481 } 482 483 static struct kobj_attribute vendor_attribute = 484 __ATTR_RO(vendor); 485 static struct kobj_attribute device_attribute = 486 __ATTR_RO(device); 487 static struct kobj_attribute class_attribute = 488 __ATTR_RO(class); 489 490 static struct attribute *afu_cr_attrs[] = { 491 &vendor_attribute.attr, 492 &device_attribute.attr, 493 &class_attribute.attr, 494 NULL, 495 }; 496 497 static void release_afu_config_record(struct kobject *kobj) 498 { 499 struct afu_config_record *cr = to_cr(kobj); 500 501 kfree(cr); 502 } 503 504 static struct kobj_type afu_config_record_type = { 505 .sysfs_ops = &kobj_sysfs_ops, 506 .release = release_afu_config_record, 507 .default_attrs = afu_cr_attrs, 508 }; 509 510 static struct afu_config_record *cxl_sysfs_afu_new_cr(struct cxl_afu *afu, int cr_idx) 511 { 512 struct afu_config_record *cr; 513 int rc; 514 515 cr = kzalloc(sizeof(struct afu_config_record), GFP_KERNEL); 516 if (!cr) 517 return ERR_PTR(-ENOMEM); 518 519 cr->cr = cr_idx; 520 cr->device = cxl_afu_cr_read16(afu, cr_idx, PCI_DEVICE_ID); 521 cr->vendor = cxl_afu_cr_read16(afu, cr_idx, PCI_VENDOR_ID); 522 cr->class = cxl_afu_cr_read32(afu, cr_idx, PCI_CLASS_REVISION) >> 8; 523 524 /* 525 * Export raw AFU PCIe like config record. For now this is read only by 526 * root - we can expand that later to be readable by non-root and maybe 527 * even writable provided we have a good use-case. Once we suport 528 * exposing AFUs through a virtual PHB they will get that for free from 529 * Linux' PCI infrastructure, but until then it's not clear that we 530 * need it for anything since the main use case is just identifying 531 * AFUs, which can be done via the vendor, device and class attributes. 532 */ 533 sysfs_bin_attr_init(&cr->config_attr); 534 cr->config_attr.attr.name = "config"; 535 cr->config_attr.attr.mode = S_IRUSR; 536 cr->config_attr.size = afu->crs_len; 537 cr->config_attr.read = afu_read_config; 538 539 rc = kobject_init_and_add(&cr->kobj, &afu_config_record_type, 540 &afu->dev.kobj, "cr%i", cr->cr); 541 if (rc) 542 goto err; 543 544 rc = sysfs_create_bin_file(&cr->kobj, &cr->config_attr); 545 if (rc) 546 goto err1; 547 548 rc = kobject_uevent(&cr->kobj, KOBJ_ADD); 549 if (rc) 550 goto err2; 551 552 return cr; 553 err2: 554 sysfs_remove_bin_file(&cr->kobj, &cr->config_attr); 555 err1: 556 kobject_put(&cr->kobj); 557 return ERR_PTR(rc); 558 err: 559 kfree(cr); 560 return ERR_PTR(rc); 561 } 562 563 void cxl_sysfs_afu_remove(struct cxl_afu *afu) 564 { 565 struct afu_config_record *cr, *tmp; 566 int i; 567 568 /* remove the err buffer bin attribute */ 569 if (afu->eb_len) 570 device_remove_bin_file(&afu->dev, &afu->attr_eb); 571 572 for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) 573 device_remove_file(&afu->dev, &afu_attrs[i]); 574 575 list_for_each_entry_safe(cr, tmp, &afu->crs, list) { 576 sysfs_remove_bin_file(&cr->kobj, &cr->config_attr); 577 kobject_put(&cr->kobj); 578 } 579 } 580 581 int cxl_sysfs_afu_add(struct cxl_afu *afu) 582 { 583 struct afu_config_record *cr; 584 int i, rc; 585 586 INIT_LIST_HEAD(&afu->crs); 587 588 for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) { 589 if ((rc = device_create_file(&afu->dev, &afu_attrs[i]))) 590 goto err; 591 } 592 593 /* conditionally create the add the binary file for error info buffer */ 594 if (afu->eb_len) { 595 sysfs_attr_init(&afu->attr_eb.attr); 596 597 afu->attr_eb.attr.name = "afu_err_buff"; 598 afu->attr_eb.attr.mode = S_IRUGO; 599 afu->attr_eb.size = afu->eb_len; 600 afu->attr_eb.read = afu_eb_read; 601 602 rc = device_create_bin_file(&afu->dev, &afu->attr_eb); 603 if (rc) { 604 dev_err(&afu->dev, 605 "Unable to create eb attr for the afu. Err(%d)\n", 606 rc); 607 goto err; 608 } 609 } 610 611 for (i = 0; i < afu->crs_num; i++) { 612 cr = cxl_sysfs_afu_new_cr(afu, i); 613 if (IS_ERR(cr)) { 614 rc = PTR_ERR(cr); 615 goto err1; 616 } 617 list_add(&cr->list, &afu->crs); 618 } 619 620 return 0; 621 622 err1: 623 cxl_sysfs_afu_remove(afu); 624 return rc; 625 err: 626 /* reset the eb_len as we havent created the bin attr */ 627 afu->eb_len = 0; 628 629 for (i--; i >= 0; i--) 630 device_remove_file(&afu->dev, &afu_attrs[i]); 631 return rc; 632 } 633 634 int cxl_sysfs_afu_m_add(struct cxl_afu *afu) 635 { 636 int i, rc; 637 638 for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++) { 639 if ((rc = device_create_file(afu->chardev_m, &afu_master_attrs[i]))) 640 goto err; 641 } 642 643 return 0; 644 645 err: 646 for (i--; i >= 0; i--) 647 device_remove_file(afu->chardev_m, &afu_master_attrs[i]); 648 return rc; 649 } 650 651 void cxl_sysfs_afu_m_remove(struct cxl_afu *afu) 652 { 653 int i; 654 655 for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++) 656 device_remove_file(afu->chardev_m, &afu_master_attrs[i]); 657 } 658