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