1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Intel Vendor Specific Extended Capabilities auxiliary bus driver 4 * 5 * Copyright (c) 2021, Intel Corporation. 6 * All Rights Reserved. 7 * 8 * Author: David E. Box <david.e.box@linux.intel.com> 9 * 10 * This driver discovers and creates auxiliary devices for Intel defined PCIe 11 * "Vendor Specific" and "Designated Vendor Specific" Extended Capabilities, 12 * VSEC and DVSEC respectively. The driver supports features on specific PCIe 13 * endpoints that exist primarily to expose them. 14 */ 15 16 #include <linux/auxiliary_bus.h> 17 #include <linux/bits.h> 18 #include <linux/bitops.h> 19 #include <linux/bug.h> 20 #include <linux/cleanup.h> 21 #include <linux/delay.h> 22 #include <linux/idr.h> 23 #include <linux/log2.h> 24 #include <linux/intel_vsec.h> 25 #include <linux/kernel.h> 26 #include <linux/module.h> 27 #include <linux/overflow.h> 28 #include <linux/pci.h> 29 #include <linux/string.h> 30 #include <linux/types.h> 31 32 #define PMT_XA_START 0 33 #define PMT_XA_MAX INT_MAX 34 #define PMT_XA_LIMIT XA_LIMIT(PMT_XA_START, PMT_XA_MAX) 35 36 static DEFINE_IDA(intel_vsec_ida); 37 static DEFINE_IDA(intel_vsec_sdsi_ida); 38 static DEFINE_XARRAY_ALLOC(auxdev_array); 39 40 enum vsec_device_state { 41 STATE_NOT_FOUND, 42 STATE_REGISTERED, 43 STATE_SKIP, 44 }; 45 46 struct vsec_priv { 47 const struct intel_vsec_platform_info *info; 48 struct device *suppliers[VSEC_FEATURE_COUNT]; 49 struct oobmsm_plat_info plat_info; 50 enum vsec_device_state state[VSEC_FEATURE_COUNT]; 51 unsigned long found_caps; 52 }; 53 54 static const char *intel_vsec_name(enum intel_vsec_id id) 55 { 56 switch (id) { 57 case VSEC_ID_TELEMETRY: 58 return "telemetry"; 59 60 case VSEC_ID_WATCHER: 61 return "watcher"; 62 63 case VSEC_ID_CRASHLOG: 64 return "crashlog"; 65 66 case VSEC_ID_SDSI: 67 return "sdsi"; 68 69 case VSEC_ID_TPMI: 70 return "tpmi"; 71 72 case VSEC_ID_DISCOVERY: 73 return "discovery"; 74 75 default: 76 return NULL; 77 } 78 } 79 80 static bool intel_vsec_supported(u16 id, unsigned long caps) 81 { 82 switch (id) { 83 case VSEC_ID_TELEMETRY: 84 return !!(caps & VSEC_CAP_TELEMETRY); 85 case VSEC_ID_WATCHER: 86 return !!(caps & VSEC_CAP_WATCHER); 87 case VSEC_ID_CRASHLOG: 88 return !!(caps & VSEC_CAP_CRASHLOG); 89 case VSEC_ID_SDSI: 90 return !!(caps & VSEC_CAP_SDSI); 91 case VSEC_ID_TPMI: 92 return !!(caps & VSEC_CAP_TPMI); 93 case VSEC_ID_DISCOVERY: 94 return !!(caps & VSEC_CAP_DISCOVERY); 95 default: 96 return false; 97 } 98 } 99 100 static void intel_vsec_remove_aux(void *data) 101 { 102 auxiliary_device_delete(data); 103 auxiliary_device_uninit(data); 104 } 105 106 static void intel_vsec_dev_release(struct device *dev) 107 { 108 struct intel_vsec_device *intel_vsec_dev = dev_to_ivdev(dev); 109 110 xa_erase(&auxdev_array, intel_vsec_dev->id); 111 112 ida_free(intel_vsec_dev->ida, intel_vsec_dev->auxdev.id); 113 114 kfree(intel_vsec_dev->acpi_disc); 115 kfree(intel_vsec_dev); 116 } 117 118 static const struct vsec_feature_dependency * 119 get_consumer_dependencies(struct vsec_priv *priv, int cap_id) 120 { 121 const struct vsec_feature_dependency *deps = priv->info->deps; 122 int consumer_id = priv->info->num_deps; 123 124 if (!deps) 125 return NULL; 126 127 while (consumer_id--) 128 if (deps[consumer_id].feature == BIT(cap_id)) 129 return &deps[consumer_id]; 130 131 return NULL; 132 } 133 134 static bool vsec_driver_present(int cap_id) 135 { 136 unsigned long bit = BIT(cap_id); 137 138 switch (bit) { 139 case VSEC_CAP_TELEMETRY: 140 return IS_ENABLED(CONFIG_INTEL_PMT_TELEMETRY); 141 case VSEC_CAP_WATCHER: 142 return IS_ENABLED(CONFIG_INTEL_PMT_WATCHER); 143 case VSEC_CAP_CRASHLOG: 144 return IS_ENABLED(CONFIG_INTEL_PMT_CRASHLOG); 145 case VSEC_CAP_SDSI: 146 return IS_ENABLED(CONFIG_INTEL_SDSI); 147 case VSEC_CAP_TPMI: 148 return IS_ENABLED(CONFIG_INTEL_TPMI); 149 case VSEC_CAP_DISCOVERY: 150 return IS_ENABLED(CONFIG_INTEL_PMT_DISCOVERY); 151 default: 152 return false; 153 } 154 } 155 156 /* 157 * Although pci_device_id table is available in the pdev, this prototype is 158 * necessary because the code using it can be called by an exported API that 159 * might pass a different pdev. 160 */ 161 static const struct pci_device_id intel_vsec_pci_ids[]; 162 163 static int intel_vsec_link_devices(struct device *parent, struct device *dev, 164 int consumer_id) 165 { 166 const struct vsec_feature_dependency *deps; 167 enum vsec_device_state *state; 168 struct device **suppliers; 169 struct vsec_priv *priv; 170 struct pci_dev *pdev; 171 int supplier_id; 172 173 if (!consumer_id) 174 return 0; 175 176 if (!dev_is_pci(parent)) 177 return 0; 178 179 pdev = to_pci_dev(parent); 180 if (!pci_match_id(intel_vsec_pci_ids, pdev)) 181 return 0; 182 183 priv = pci_get_drvdata(pdev); 184 state = priv->state; 185 suppliers = priv->suppliers; 186 187 priv->suppliers[consumer_id] = dev; 188 189 deps = get_consumer_dependencies(priv, consumer_id); 190 if (!deps) 191 return 0; 192 193 for_each_set_bit(supplier_id, &deps->supplier_bitmap, VSEC_FEATURE_COUNT) { 194 struct device_link *link; 195 196 if (state[supplier_id] != STATE_REGISTERED || 197 !vsec_driver_present(supplier_id)) 198 continue; 199 200 if (!suppliers[supplier_id]) { 201 dev_err(dev, "Bad supplier list\n"); 202 return -EINVAL; 203 } 204 205 link = device_link_add(dev, suppliers[supplier_id], 206 DL_FLAG_AUTOPROBE_CONSUMER); 207 if (!link) 208 return -EINVAL; 209 } 210 211 return 0; 212 } 213 214 int intel_vsec_add_aux(struct device *parent, 215 struct intel_vsec_device *intel_vsec_dev, 216 const char *name) 217 { 218 struct auxiliary_device *auxdev = &intel_vsec_dev->auxdev; 219 int ret, id; 220 221 if (!parent) 222 return -EINVAL; 223 224 ret = xa_alloc(&auxdev_array, &intel_vsec_dev->id, intel_vsec_dev, 225 PMT_XA_LIMIT, GFP_KERNEL); 226 if (ret < 0) { 227 kfree(intel_vsec_dev); 228 return ret; 229 } 230 231 id = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL); 232 if (id < 0) { 233 xa_erase(&auxdev_array, intel_vsec_dev->id); 234 kfree(intel_vsec_dev); 235 return id; 236 } 237 238 auxdev->id = id; 239 auxdev->name = name; 240 auxdev->dev.parent = parent; 241 auxdev->dev.release = intel_vsec_dev_release; 242 243 ret = auxiliary_device_init(auxdev); 244 if (ret < 0) { 245 intel_vsec_dev_release(&auxdev->dev); 246 return ret; 247 } 248 249 /* 250 * Assign a name now to ensure that the device link doesn't contain 251 * a null string for the consumer name. This is a problem when a supplier 252 * supplies more than one consumer and can lead to a duplicate name error 253 * when the link is created in sysfs. 254 */ 255 ret = dev_set_name(&auxdev->dev, "%s.%s.%d", KBUILD_MODNAME, auxdev->name, 256 auxdev->id); 257 if (ret) 258 goto cleanup_aux; 259 260 ret = intel_vsec_link_devices(parent, &auxdev->dev, intel_vsec_dev->cap_id); 261 if (ret) 262 goto cleanup_aux; 263 264 ret = auxiliary_device_add(auxdev); 265 if (ret) 266 goto cleanup_aux; 267 268 return devm_add_action_or_reset(parent, intel_vsec_remove_aux, 269 auxdev); 270 271 cleanup_aux: 272 auxiliary_device_uninit(auxdev); 273 return ret; 274 } 275 EXPORT_SYMBOL_NS_GPL(intel_vsec_add_aux, "INTEL_VSEC"); 276 277 static int intel_vsec_add_dev(struct device *dev, struct intel_vsec_header *header, 278 const struct intel_vsec_platform_info *info, 279 unsigned long cap_id, u64 base_addr) 280 { 281 struct intel_vsec_device __free(kfree) *intel_vsec_dev = NULL; 282 struct resource *res; 283 struct resource *tmp; 284 struct device *parent; 285 unsigned long quirks = info->quirks; 286 int i; 287 288 if (info->parent) 289 parent = info->parent; 290 else 291 parent = dev; 292 293 if (!intel_vsec_supported(header->id, info->caps)) 294 return -EINVAL; 295 296 if (!header->num_entries) { 297 dev_dbg(dev, "Invalid 0 entry count for header id %d\n", header->id); 298 return -EINVAL; 299 } 300 301 if (!header->entry_size) { 302 dev_dbg(dev, "Invalid 0 entry size for header id %d\n", header->id); 303 return -EINVAL; 304 } 305 306 intel_vsec_dev = kzalloc_flex(*intel_vsec_dev, resource, header->num_entries); 307 if (!intel_vsec_dev) 308 return -ENOMEM; 309 310 intel_vsec_dev->num_resources = header->num_entries; 311 res = intel_vsec_dev->resource; 312 313 if (quirks & VSEC_QUIRK_TABLE_SHIFT) 314 header->offset >>= TABLE_OFFSET_SHIFT; 315 316 /* 317 * The DVSEC/VSEC contains the starting offset and count for a block of 318 * discovery tables. Create a resource array of these tables to the 319 * auxiliary device driver. 320 */ 321 for (i = 0, tmp = res; i < header->num_entries; i++, tmp++) { 322 /* 323 * Skip resource mapping check for ACPI-based discovery 324 * since those tables are read from _DSD, not MMIO. 325 */ 326 if (info->src == INTEL_VSEC_DISC_ACPI) 327 break; 328 329 tmp->start = base_addr + header->offset + i * (header->entry_size * sizeof(u32)); 330 tmp->end = tmp->start + (header->entry_size * sizeof(u32)) - 1; 331 tmp->flags = IORESOURCE_MEM; 332 333 /* Check resource is not in use */ 334 if (!request_mem_region(tmp->start, resource_size(tmp), "")) 335 return -EBUSY; 336 337 release_mem_region(tmp->start, resource_size(tmp)); 338 } 339 340 intel_vsec_dev->dev = dev; 341 intel_vsec_dev->quirks = info->quirks; 342 intel_vsec_dev->base_addr = info->base_addr; 343 intel_vsec_dev->priv_data = info->priv_data; 344 intel_vsec_dev->cap_id = cap_id; 345 intel_vsec_dev->src = info->src; 346 347 if (info->src == INTEL_VSEC_DISC_ACPI) { 348 size_t bytes; 349 350 if (check_mul_overflow(intel_vsec_dev->num_resources, 351 sizeof(*info->acpi_disc), &bytes)) 352 return -EOVERFLOW; 353 354 intel_vsec_dev->acpi_disc = kmemdup(info->acpi_disc, bytes, GFP_KERNEL); 355 if (!intel_vsec_dev->acpi_disc) 356 return -ENOMEM; 357 } 358 359 if (header->id == VSEC_ID_SDSI) 360 intel_vsec_dev->ida = &intel_vsec_sdsi_ida; 361 else 362 intel_vsec_dev->ida = &intel_vsec_ida; 363 364 /* 365 * Pass the ownership of intel_vsec_dev and resource within it to 366 * intel_vsec_add_aux() 367 */ 368 return intel_vsec_add_aux(parent, no_free_ptr(intel_vsec_dev), 369 intel_vsec_name(header->id)); 370 } 371 372 static bool suppliers_ready(struct vsec_priv *priv, 373 const struct vsec_feature_dependency *consumer_deps, 374 int cap_id) 375 { 376 enum vsec_device_state *state = priv->state; 377 int supplier_id; 378 379 if (WARN_ON_ONCE(consumer_deps->feature != BIT(cap_id))) 380 return false; 381 382 /* 383 * Verify that all required suppliers have been found. Return false 384 * immediately if any are still missing. 385 */ 386 for_each_set_bit(supplier_id, &consumer_deps->supplier_bitmap, VSEC_FEATURE_COUNT) { 387 if (state[supplier_id] == STATE_SKIP) 388 continue; 389 390 if (state[supplier_id] == STATE_NOT_FOUND) 391 return false; 392 } 393 394 /* 395 * All suppliers have been found and the consumer is ready to be 396 * registered. 397 */ 398 return true; 399 } 400 401 static int get_cap_id(u32 header_id, unsigned long *cap_id) 402 { 403 switch (header_id) { 404 case VSEC_ID_TELEMETRY: 405 *cap_id = ilog2(VSEC_CAP_TELEMETRY); 406 break; 407 case VSEC_ID_WATCHER: 408 *cap_id = ilog2(VSEC_CAP_WATCHER); 409 break; 410 case VSEC_ID_CRASHLOG: 411 *cap_id = ilog2(VSEC_CAP_CRASHLOG); 412 break; 413 case VSEC_ID_SDSI: 414 *cap_id = ilog2(VSEC_CAP_SDSI); 415 break; 416 case VSEC_ID_TPMI: 417 *cap_id = ilog2(VSEC_CAP_TPMI); 418 break; 419 case VSEC_ID_DISCOVERY: 420 *cap_id = ilog2(VSEC_CAP_DISCOVERY); 421 break; 422 default: 423 return -EINVAL; 424 } 425 426 return 0; 427 } 428 429 static int intel_vsec_register_device(struct device *dev, 430 struct intel_vsec_header *header, 431 const struct intel_vsec_platform_info *info, 432 u64 base_addr) 433 { 434 const struct vsec_feature_dependency *consumer_deps; 435 struct vsec_priv *priv; 436 struct pci_dev *pdev; 437 unsigned long cap_id; 438 int ret; 439 440 ret = get_cap_id(header->id, &cap_id); 441 if (ret) 442 return ret; 443 444 /* 445 * Only track dependencies for devices probed by the VSEC driver. 446 * For others using the exported APIs, add the device directly. 447 */ 448 if (!dev_is_pci(dev)) 449 return intel_vsec_add_dev(dev, header, info, cap_id, base_addr); 450 451 pdev = to_pci_dev(dev); 452 if (!pci_match_id(intel_vsec_pci_ids, pdev)) 453 return intel_vsec_add_dev(dev, header, info, cap_id, base_addr); 454 455 priv = pci_get_drvdata(pdev); 456 if (priv->state[cap_id] == STATE_REGISTERED || 457 priv->state[cap_id] == STATE_SKIP) 458 return -EEXIST; 459 460 priv->found_caps |= BIT(cap_id); 461 462 if (!vsec_driver_present(cap_id)) { 463 priv->state[cap_id] = STATE_SKIP; 464 return -ENODEV; 465 } 466 467 consumer_deps = get_consumer_dependencies(priv, cap_id); 468 if (!consumer_deps || suppliers_ready(priv, consumer_deps, cap_id)) { 469 ret = intel_vsec_add_dev(dev, header, info, cap_id, base_addr); 470 if (ret) 471 priv->state[cap_id] = STATE_SKIP; 472 else 473 priv->state[cap_id] = STATE_REGISTERED; 474 475 return ret; 476 } 477 478 return -EAGAIN; 479 } 480 481 static int intel_vsec_walk_header(struct device *dev, 482 const struct intel_vsec_platform_info *info) 483 { 484 struct intel_vsec_header **header = info->headers; 485 u64 base_addr; 486 int ret; 487 488 for ( ; *header; header++) { 489 if (info->base_addr) { 490 base_addr = info->base_addr; 491 } else { 492 struct pci_dev *pdev; 493 494 if (!dev_is_pci(dev)) { 495 dev_err(dev, "non-PCI device without a base address\n"); 496 return -EINVAL; 497 } 498 499 pdev = to_pci_dev(dev); 500 base_addr = pci_resource_start(pdev, (*header)->tbir); 501 } 502 503 ret = intel_vsec_register_device(dev, *header, info, base_addr); 504 if (ret) 505 return ret; 506 } 507 508 return 0; 509 } 510 511 static bool intel_vsec_walk_dvsec(struct pci_dev *pdev, 512 const struct intel_vsec_platform_info *info) 513 { 514 bool have_devices = false; 515 int pos = 0; 516 517 do { 518 struct intel_vsec_header header; 519 u32 table, hdr; 520 u16 vid; 521 int ret; 522 523 pos = pci_find_next_ext_capability(pdev, pos, PCI_EXT_CAP_ID_DVSEC); 524 if (!pos) 525 break; 526 527 pci_read_config_dword(pdev, pos + PCI_DVSEC_HEADER1, &hdr); 528 vid = PCI_DVSEC_HEADER1_VID(hdr); 529 if (vid != PCI_VENDOR_ID_INTEL) 530 continue; 531 532 /* Support only revision 1 */ 533 header.rev = PCI_DVSEC_HEADER1_REV(hdr); 534 if (header.rev != 1) { 535 dev_info(&pdev->dev, "Unsupported DVSEC revision %d\n", header.rev); 536 continue; 537 } 538 539 header.length = PCI_DVSEC_HEADER1_LEN(hdr); 540 541 pci_read_config_byte(pdev, pos + INTEL_DVSEC_ENTRIES, &header.num_entries); 542 pci_read_config_byte(pdev, pos + INTEL_DVSEC_SIZE, &header.entry_size); 543 pci_read_config_dword(pdev, pos + INTEL_DVSEC_TABLE, &table); 544 545 header.tbir = INTEL_DVSEC_TABLE_BAR(table); 546 header.offset = INTEL_DVSEC_TABLE_OFFSET(table); 547 548 pci_read_config_dword(pdev, pos + PCI_DVSEC_HEADER2, &hdr); 549 header.id = PCI_DVSEC_HEADER2_ID(hdr); 550 551 ret = intel_vsec_register_device(&pdev->dev, &header, info, 552 pci_resource_start(pdev, header.tbir)); 553 if (ret) 554 continue; 555 556 have_devices = true; 557 } while (true); 558 559 return have_devices; 560 } 561 562 static bool intel_vsec_walk_vsec(struct pci_dev *pdev, 563 const struct intel_vsec_platform_info *info) 564 { 565 bool have_devices = false; 566 int pos = 0; 567 568 do { 569 struct intel_vsec_header header; 570 u32 table, hdr; 571 int ret; 572 573 pos = pci_find_next_ext_capability(pdev, pos, PCI_EXT_CAP_ID_VNDR); 574 if (!pos) 575 break; 576 577 pci_read_config_dword(pdev, pos + PCI_VNDR_HEADER, &hdr); 578 579 /* Support only revision 1 */ 580 header.rev = PCI_VNDR_HEADER_REV(hdr); 581 if (header.rev != 1) { 582 dev_info(&pdev->dev, "Unsupported VSEC revision %d\n", header.rev); 583 continue; 584 } 585 586 header.id = PCI_VNDR_HEADER_ID(hdr); 587 header.length = PCI_VNDR_HEADER_LEN(hdr); 588 589 /* entry, size, and table offset are the same as DVSEC */ 590 pci_read_config_byte(pdev, pos + INTEL_DVSEC_ENTRIES, &header.num_entries); 591 pci_read_config_byte(pdev, pos + INTEL_DVSEC_SIZE, &header.entry_size); 592 pci_read_config_dword(pdev, pos + INTEL_DVSEC_TABLE, &table); 593 594 header.tbir = INTEL_DVSEC_TABLE_BAR(table); 595 header.offset = INTEL_DVSEC_TABLE_OFFSET(table); 596 597 ret = intel_vsec_register_device(&pdev->dev, &header, info, 598 pci_resource_start(pdev, header.tbir)); 599 if (ret) 600 continue; 601 602 have_devices = true; 603 } while (true); 604 605 return have_devices; 606 } 607 608 int intel_vsec_register(struct device *dev, 609 const struct intel_vsec_platform_info *info) 610 { 611 if (!dev || !info || !info->headers) 612 return -EINVAL; 613 614 return intel_vsec_walk_header(dev, info); 615 } 616 EXPORT_SYMBOL_NS_GPL(intel_vsec_register, "INTEL_VSEC"); 617 618 static bool intel_vsec_get_features(struct pci_dev *pdev, 619 const struct intel_vsec_platform_info *info) 620 { 621 bool found = false; 622 623 /* 624 * Both DVSEC and VSEC capabilities can exist on the same device, 625 * so both intel_vsec_walk_dvsec() and intel_vsec_walk_vsec() must be 626 * called independently. Additionally, intel_vsec_walk_header() is 627 * needed for devices that do not have VSEC/DVSEC but provide the 628 * information via device_data. 629 */ 630 if (intel_vsec_walk_dvsec(pdev, info)) 631 found = true; 632 633 if (intel_vsec_walk_vsec(pdev, info)) 634 found = true; 635 636 if (info && (info->quirks & VSEC_QUIRK_NO_DVSEC) && 637 intel_vsec_walk_header(&pdev->dev, info)) 638 found = true; 639 640 return found; 641 } 642 643 static void intel_vsec_skip_missing_dependencies(struct pci_dev *pdev) 644 { 645 struct vsec_priv *priv = pci_get_drvdata(pdev); 646 const struct vsec_feature_dependency *deps = priv->info->deps; 647 int consumer_id = priv->info->num_deps; 648 649 while (consumer_id--) { 650 int supplier_id; 651 652 deps = &priv->info->deps[consumer_id]; 653 654 for_each_set_bit(supplier_id, &deps->supplier_bitmap, VSEC_FEATURE_COUNT) { 655 if (!(BIT(supplier_id) & priv->found_caps)) 656 priv->state[supplier_id] = STATE_SKIP; 657 } 658 } 659 } 660 661 static int intel_vsec_pci_init(struct pci_dev *pdev) 662 { 663 struct vsec_priv *priv = pci_get_drvdata(pdev); 664 const struct intel_vsec_platform_info *info = priv->info; 665 int run_once = 0; 666 bool found_any = false; 667 int num_caps; 668 669 num_caps = hweight_long(info->caps); 670 while (num_caps--) { 671 found_any |= intel_vsec_get_features(pdev, info); 672 673 if (priv->found_caps == info->caps) 674 break; 675 676 if (!run_once) { 677 intel_vsec_skip_missing_dependencies(pdev); 678 run_once = 1; 679 } 680 } 681 682 if (!found_any) 683 return -ENODEV; 684 685 return 0; 686 } 687 688 static int intel_vsec_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 689 { 690 const struct intel_vsec_platform_info *info; 691 struct vsec_priv *priv; 692 int ret; 693 694 ret = pcim_enable_device(pdev); 695 if (ret) 696 return ret; 697 698 pci_save_state(pdev); 699 info = (const struct intel_vsec_platform_info *)id->driver_data; 700 if (!info) 701 return -EINVAL; 702 703 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 704 if (!priv) 705 return -ENOMEM; 706 707 priv->info = info; 708 pci_set_drvdata(pdev, priv); 709 710 return intel_vsec_pci_init(pdev); 711 } 712 713 int intel_vsec_set_mapping(struct oobmsm_plat_info *plat_info, 714 struct intel_vsec_device *vsec_dev) 715 { 716 struct vsec_priv *priv; 717 718 if (!dev_is_pci(vsec_dev->dev)) 719 return -ENODEV; 720 721 priv = pci_get_drvdata(to_pci_dev(vsec_dev->dev)); 722 if (!priv) 723 return -EINVAL; 724 725 priv->plat_info = *plat_info; 726 727 return 0; 728 } 729 EXPORT_SYMBOL_NS_GPL(intel_vsec_set_mapping, "INTEL_VSEC"); 730 731 struct oobmsm_plat_info *intel_vsec_get_mapping(struct pci_dev *pdev) 732 { 733 struct vsec_priv *priv; 734 735 if (!pci_match_id(intel_vsec_pci_ids, pdev)) 736 return ERR_PTR(-EINVAL); 737 738 priv = pci_get_drvdata(pdev); 739 if (!priv) 740 return ERR_PTR(-EINVAL); 741 742 return &priv->plat_info; 743 } 744 EXPORT_SYMBOL_NS_GPL(intel_vsec_get_mapping, "INTEL_VSEC"); 745 746 /* DG1 info */ 747 static struct intel_vsec_header dg1_header = { 748 .length = 0x10, 749 .id = 2, 750 .num_entries = 1, 751 .entry_size = 3, 752 .tbir = 0, 753 .offset = 0x466000, 754 }; 755 756 static struct intel_vsec_header *dg1_headers[] = { 757 &dg1_header, 758 NULL 759 }; 760 761 static const struct intel_vsec_platform_info dg1_info = { 762 .caps = VSEC_CAP_TELEMETRY, 763 .headers = dg1_headers, 764 .quirks = VSEC_QUIRK_NO_DVSEC | VSEC_QUIRK_EARLY_HW, 765 }; 766 767 /* MTL info */ 768 static const struct intel_vsec_platform_info mtl_info = { 769 .caps = VSEC_CAP_TELEMETRY, 770 }; 771 772 static const struct vsec_feature_dependency oobmsm_deps[] = { 773 { 774 .feature = VSEC_CAP_TELEMETRY, 775 .supplier_bitmap = VSEC_CAP_DISCOVERY | VSEC_CAP_TPMI, 776 }, 777 }; 778 779 /* OOBMSM info */ 780 static const struct intel_vsec_platform_info oobmsm_info = { 781 .caps = VSEC_CAP_TELEMETRY | VSEC_CAP_SDSI | VSEC_CAP_TPMI | 782 VSEC_CAP_DISCOVERY, 783 .deps = oobmsm_deps, 784 .num_deps = ARRAY_SIZE(oobmsm_deps), 785 }; 786 787 /* DMR OOBMSM info */ 788 static const struct intel_vsec_platform_info dmr_oobmsm_info = { 789 .caps = VSEC_CAP_TELEMETRY | VSEC_CAP_TPMI | VSEC_CAP_DISCOVERY, 790 .deps = oobmsm_deps, 791 .num_deps = ARRAY_SIZE(oobmsm_deps), 792 }; 793 794 /* TGL info */ 795 static const struct intel_vsec_platform_info tgl_info = { 796 .caps = VSEC_CAP_TELEMETRY, 797 .quirks = VSEC_QUIRK_TABLE_SHIFT | VSEC_QUIRK_EARLY_HW, 798 }; 799 800 /* LNL info */ 801 static const struct intel_vsec_platform_info lnl_info = { 802 .caps = VSEC_CAP_TELEMETRY | VSEC_CAP_WATCHER, 803 }; 804 805 #define PCI_DEVICE_ID_INTEL_VSEC_ADL 0x467d 806 #define PCI_DEVICE_ID_INTEL_VSEC_DG1 0x490e 807 #define PCI_DEVICE_ID_INTEL_VSEC_MTL_M 0x7d0d 808 #define PCI_DEVICE_ID_INTEL_VSEC_MTL_S 0xad0d 809 #define PCI_DEVICE_ID_INTEL_VSEC_OOBMSM 0x09a7 810 #define PCI_DEVICE_ID_INTEL_VSEC_OOBMSM_DMR 0x09a1 811 #define PCI_DEVICE_ID_INTEL_VSEC_RPL 0xa77d 812 #define PCI_DEVICE_ID_INTEL_VSEC_TGL 0x9a0d 813 #define PCI_DEVICE_ID_INTEL_VSEC_LNL_M 0x647d 814 #define PCI_DEVICE_ID_INTEL_VSEC_PTL 0xb07d 815 #define PCI_DEVICE_ID_INTEL_VSEC_WCL 0xfd7d 816 #define PCI_DEVICE_ID_INTEL_VSEC_NVL 0xd70d 817 static const struct pci_device_id intel_vsec_pci_ids[] = { 818 { PCI_DEVICE_DATA(INTEL, VSEC_ADL, &tgl_info) }, 819 { PCI_DEVICE_DATA(INTEL, VSEC_DG1, &dg1_info) }, 820 { PCI_DEVICE_DATA(INTEL, VSEC_MTL_M, &mtl_info) }, 821 { PCI_DEVICE_DATA(INTEL, VSEC_MTL_S, &mtl_info) }, 822 { PCI_DEVICE_DATA(INTEL, VSEC_OOBMSM, &oobmsm_info) }, 823 { PCI_DEVICE_DATA(INTEL, VSEC_OOBMSM_DMR, &dmr_oobmsm_info) }, 824 { PCI_DEVICE_DATA(INTEL, VSEC_RPL, &tgl_info) }, 825 { PCI_DEVICE_DATA(INTEL, VSEC_TGL, &tgl_info) }, 826 { PCI_DEVICE_DATA(INTEL, VSEC_LNL_M, &lnl_info) }, 827 { PCI_DEVICE_DATA(INTEL, VSEC_PTL, &mtl_info) }, 828 { PCI_DEVICE_DATA(INTEL, VSEC_WCL, &mtl_info) }, 829 { PCI_DEVICE_DATA(INTEL, VSEC_NVL, &mtl_info) }, 830 { } 831 }; 832 MODULE_DEVICE_TABLE(pci, intel_vsec_pci_ids); 833 834 static pci_ers_result_t intel_vsec_pci_error_detected(struct pci_dev *pdev, 835 pci_channel_state_t state) 836 { 837 pci_ers_result_t status = PCI_ERS_RESULT_NEED_RESET; 838 839 dev_info(&pdev->dev, "PCI error detected, state %d", state); 840 841 if (state == pci_channel_io_perm_failure) 842 status = PCI_ERS_RESULT_DISCONNECT; 843 else 844 pci_disable_device(pdev); 845 846 return status; 847 } 848 849 static pci_ers_result_t intel_vsec_pci_slot_reset(struct pci_dev *pdev) 850 { 851 struct intel_vsec_device *intel_vsec_dev; 852 pci_ers_result_t status = PCI_ERS_RESULT_DISCONNECT; 853 unsigned long index; 854 855 dev_info(&pdev->dev, "Resetting PCI slot\n"); 856 857 msleep(2000); 858 if (pci_enable_device(pdev)) { 859 dev_info(&pdev->dev, 860 "Failed to re-enable PCI device after reset.\n"); 861 goto out; 862 } 863 864 status = PCI_ERS_RESULT_RECOVERED; 865 866 xa_for_each(&auxdev_array, index, intel_vsec_dev) { 867 /* check if pdev doesn't match */ 868 if (&pdev->dev != intel_vsec_dev->dev) 869 continue; 870 devm_release_action(&pdev->dev, intel_vsec_remove_aux, 871 &intel_vsec_dev->auxdev); 872 } 873 pci_restore_state(pdev); 874 intel_vsec_pci_init(pdev); 875 876 out: 877 return status; 878 } 879 880 static void intel_vsec_pci_resume(struct pci_dev *pdev) 881 { 882 dev_info(&pdev->dev, "Done resuming PCI device\n"); 883 } 884 885 static const struct pci_error_handlers intel_vsec_pci_err_handlers = { 886 .error_detected = intel_vsec_pci_error_detected, 887 .slot_reset = intel_vsec_pci_slot_reset, 888 .resume = intel_vsec_pci_resume, 889 }; 890 891 static struct pci_driver intel_vsec_pci_driver = { 892 .name = "intel_vsec", 893 .id_table = intel_vsec_pci_ids, 894 .probe = intel_vsec_pci_probe, 895 .err_handler = &intel_vsec_pci_err_handlers, 896 }; 897 module_pci_driver(intel_vsec_pci_driver); 898 899 MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>"); 900 MODULE_DESCRIPTION("Intel Extended Capabilities auxiliary bus driver"); 901 MODULE_LICENSE("GPL v2"); 902