// SPDX-License-Identifier: GPL-2.0
/*
 * Intel Vendor Specific Extended Capabilities auxiliary bus driver
 *
 * Copyright (c) 2021, Intel Corporation.
 * All Rights Reserved.
 *
 * Author: David E. Box <david.e.box@linux.intel.com>
 *
 * This driver discovers and creates auxiliary devices for Intel defined PCIe
 * "Vendor Specific" and "Designated Vendor Specific" Extended Capabilities,
 * VSEC and DVSEC respectively. The driver supports features on specific PCIe
 * endpoints that exist primarily to expose them.
 */

#include <linux/auxiliary_bus.h>
#include <linux/bits.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/idr.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/types.h>

#include "vsec.h"

/* Intel DVSEC offsets */
#define INTEL_DVSEC_ENTRIES		0xA
#define INTEL_DVSEC_SIZE		0xB
#define INTEL_DVSEC_TABLE		0xC
#define INTEL_DVSEC_TABLE_BAR(x)	((x) & GENMASK(2, 0))
#define INTEL_DVSEC_TABLE_OFFSET(x)	((x) & GENMASK(31, 3))
#define TABLE_OFFSET_SHIFT		3
#define PMT_XA_START			0
#define PMT_XA_MAX			INT_MAX
#define PMT_XA_LIMIT			XA_LIMIT(PMT_XA_START, PMT_XA_MAX)

static DEFINE_IDA(intel_vsec_ida);
static DEFINE_IDA(intel_vsec_sdsi_ida);
static DEFINE_XARRAY_ALLOC(auxdev_array);

/**
 * struct intel_vsec_header - Common fields of Intel VSEC and DVSEC registers.
 * @rev:         Revision ID of the VSEC/DVSEC register space
 * @length:      Length of the VSEC/DVSEC register space
 * @id:          ID of the feature
 * @num_entries: Number of instances of the feature
 * @entry_size:  Size of the discovery table for each feature
 * @tbir:        BAR containing the discovery tables
 * @offset:      BAR offset of start of the first discovery table
 */
struct intel_vsec_header {
	u8	rev;
	u16	length;
	u16	id;
	u8	num_entries;
	u8	entry_size;
	u8	tbir;
	u32	offset;
};

enum intel_vsec_id {
	VSEC_ID_TELEMETRY	= 2,
	VSEC_ID_WATCHER		= 3,
	VSEC_ID_CRASHLOG	= 4,
	VSEC_ID_SDSI		= 65,
};

static enum intel_vsec_id intel_vsec_allow_list[] = {
	VSEC_ID_TELEMETRY,
	VSEC_ID_WATCHER,
	VSEC_ID_CRASHLOG,
	VSEC_ID_SDSI,
};

static const char *intel_vsec_name(enum intel_vsec_id id)
{
	switch (id) {
	case VSEC_ID_TELEMETRY:
		return "telemetry";

	case VSEC_ID_WATCHER:
		return "watcher";

	case VSEC_ID_CRASHLOG:
		return "crashlog";

	case VSEC_ID_SDSI:
		return "sdsi";

	default:
		return NULL;
	}
}

static bool intel_vsec_allowed(u16 id)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(intel_vsec_allow_list); i++)
		if (intel_vsec_allow_list[i] == id)
			return true;

	return false;
}

static bool intel_vsec_disabled(u16 id, unsigned long quirks)
{
	switch (id) {
	case VSEC_ID_WATCHER:
		return !!(quirks & VSEC_QUIRK_NO_WATCHER);

	case VSEC_ID_CRASHLOG:
		return !!(quirks & VSEC_QUIRK_NO_CRASHLOG);

	default:
		return false;
	}
}

static void intel_vsec_remove_aux(void *data)
{
	auxiliary_device_delete(data);
	auxiliary_device_uninit(data);
}

static void intel_vsec_dev_release(struct device *dev)
{
	struct intel_vsec_device *intel_vsec_dev = dev_to_ivdev(dev);

	ida_free(intel_vsec_dev->ida, intel_vsec_dev->auxdev.id);
	kfree(intel_vsec_dev->resource);
	kfree(intel_vsec_dev);
}

static int intel_vsec_add_aux(struct pci_dev *pdev, struct intel_vsec_device *intel_vsec_dev,
			      const char *name)
{
	struct auxiliary_device *auxdev = &intel_vsec_dev->auxdev;
	int ret, id;

	ret = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL);
	if (ret < 0) {
		kfree(intel_vsec_dev);
		return ret;
	}

	auxdev->id = ret;
	auxdev->name = name;
	auxdev->dev.parent = &pdev->dev;
	auxdev->dev.release = intel_vsec_dev_release;

	ret = auxiliary_device_init(auxdev);
	if (ret < 0) {
		ida_free(intel_vsec_dev->ida, auxdev->id);
		kfree(intel_vsec_dev->resource);
		kfree(intel_vsec_dev);
		return ret;
	}

	ret = auxiliary_device_add(auxdev);
	if (ret < 0) {
		auxiliary_device_uninit(auxdev);
		return ret;
	}

	ret = devm_add_action_or_reset(&pdev->dev, intel_vsec_remove_aux,
				       auxdev);
	if (ret < 0)
		return ret;

	/* Add auxdev to list */
	ret = xa_alloc(&auxdev_array, &id, intel_vsec_dev, PMT_XA_LIMIT,
		       GFP_KERNEL);
	if (ret)
		return ret;

	return 0;
}

static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *header,
			      struct intel_vsec_platform_info *info)
{
	struct intel_vsec_device *intel_vsec_dev;
	struct resource *res, *tmp;
	unsigned long quirks = info->quirks;
	int i;

	if (!intel_vsec_allowed(header->id) || intel_vsec_disabled(header->id, quirks))
		return -EINVAL;

	if (!header->num_entries) {
		dev_dbg(&pdev->dev, "Invalid 0 entry count for header id %d\n", header->id);
		return -EINVAL;
	}

	if (!header->entry_size) {
		dev_dbg(&pdev->dev, "Invalid 0 entry size for header id %d\n", header->id);
		return -EINVAL;
	}

	intel_vsec_dev = kzalloc(sizeof(*intel_vsec_dev), GFP_KERNEL);
	if (!intel_vsec_dev)
		return -ENOMEM;

	res = kcalloc(header->num_entries, sizeof(*res), GFP_KERNEL);
	if (!res) {
		kfree(intel_vsec_dev);
		return -ENOMEM;
	}

	if (quirks & VSEC_QUIRK_TABLE_SHIFT)
		header->offset >>= TABLE_OFFSET_SHIFT;

	/*
	 * The DVSEC/VSEC contains the starting offset and count for a block of
	 * discovery tables. Create a resource array of these tables to the
	 * auxiliary device driver.
	 */
	for (i = 0, tmp = res; i < header->num_entries; i++, tmp++) {
		tmp->start = pdev->resource[header->tbir].start +
			     header->offset + i * (header->entry_size * sizeof(u32));
		tmp->end = tmp->start + (header->entry_size * sizeof(u32)) - 1;
		tmp->flags = IORESOURCE_MEM;
	}

	intel_vsec_dev->pcidev = pdev;
	intel_vsec_dev->resource = res;
	intel_vsec_dev->num_resources = header->num_entries;
	intel_vsec_dev->info = info;

	if (header->id == VSEC_ID_SDSI)
		intel_vsec_dev->ida = &intel_vsec_sdsi_ida;
	else
		intel_vsec_dev->ida = &intel_vsec_ida;

	return intel_vsec_add_aux(pdev, intel_vsec_dev, intel_vsec_name(header->id));
}

static bool intel_vsec_walk_header(struct pci_dev *pdev,
				   struct intel_vsec_platform_info *info)
{
	struct intel_vsec_header **header = info->capabilities;
	bool have_devices = false;
	int ret;

	for ( ; *header; header++) {
		ret = intel_vsec_add_dev(pdev, *header, info);
		if (ret)
			dev_info(&pdev->dev, "Could not add device for DVSEC id %d\n",
				 (*header)->id);
		else
			have_devices = true;
	}

	return have_devices;
}

static bool intel_vsec_walk_dvsec(struct pci_dev *pdev,
				  struct intel_vsec_platform_info *info)
{
	bool have_devices = false;
	int pos = 0;

	do {
		struct intel_vsec_header header;
		u32 table, hdr;
		u16 vid;
		int ret;

		pos = pci_find_next_ext_capability(pdev, pos, PCI_EXT_CAP_ID_DVSEC);
		if (!pos)
			break;

		pci_read_config_dword(pdev, pos + PCI_DVSEC_HEADER1, &hdr);
		vid = PCI_DVSEC_HEADER1_VID(hdr);
		if (vid != PCI_VENDOR_ID_INTEL)
			continue;

		/* Support only revision 1 */
		header.rev = PCI_DVSEC_HEADER1_REV(hdr);
		if (header.rev != 1) {
			dev_info(&pdev->dev, "Unsupported DVSEC revision %d\n", header.rev);
			continue;
		}

		header.length = PCI_DVSEC_HEADER1_LEN(hdr);

		pci_read_config_byte(pdev, pos + INTEL_DVSEC_ENTRIES, &header.num_entries);
		pci_read_config_byte(pdev, pos + INTEL_DVSEC_SIZE, &header.entry_size);
		pci_read_config_dword(pdev, pos + INTEL_DVSEC_TABLE, &table);

		header.tbir = INTEL_DVSEC_TABLE_BAR(table);
		header.offset = INTEL_DVSEC_TABLE_OFFSET(table);

		pci_read_config_dword(pdev, pos + PCI_DVSEC_HEADER2, &hdr);
		header.id = PCI_DVSEC_HEADER2_ID(hdr);

		ret = intel_vsec_add_dev(pdev, &header, info);
		if (ret)
			continue;

		have_devices = true;
	} while (true);

	return have_devices;
}

static bool intel_vsec_walk_vsec(struct pci_dev *pdev,
				 struct intel_vsec_platform_info *info)
{
	bool have_devices = false;
	int pos = 0;

	do {
		struct intel_vsec_header header;
		u32 table, hdr;
		int ret;

		pos = pci_find_next_ext_capability(pdev, pos, PCI_EXT_CAP_ID_VNDR);
		if (!pos)
			break;

		pci_read_config_dword(pdev, pos + PCI_VNDR_HEADER, &hdr);

		/* Support only revision 1 */
		header.rev = PCI_VNDR_HEADER_REV(hdr);
		if (header.rev != 1) {
			dev_info(&pdev->dev, "Unsupported VSEC revision %d\n", header.rev);
			continue;
		}

		header.id = PCI_VNDR_HEADER_ID(hdr);
		header.length = PCI_VNDR_HEADER_LEN(hdr);

		/* entry, size, and table offset are the same as DVSEC */
		pci_read_config_byte(pdev, pos + INTEL_DVSEC_ENTRIES, &header.num_entries);
		pci_read_config_byte(pdev, pos + INTEL_DVSEC_SIZE, &header.entry_size);
		pci_read_config_dword(pdev, pos + INTEL_DVSEC_TABLE, &table);

		header.tbir = INTEL_DVSEC_TABLE_BAR(table);
		header.offset = INTEL_DVSEC_TABLE_OFFSET(table);

		ret = intel_vsec_add_dev(pdev, &header, info);
		if (ret)
			continue;

		have_devices = true;
	} while (true);

	return have_devices;
}

static int intel_vsec_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	struct intel_vsec_platform_info *info;
	bool have_devices = false;
	int ret;

	ret = pcim_enable_device(pdev);
	if (ret)
		return ret;

	pci_save_state(pdev);
	info = (struct intel_vsec_platform_info *)id->driver_data;
	if (!info)
		return -EINVAL;

	if (intel_vsec_walk_dvsec(pdev, info))
		have_devices = true;

	if (intel_vsec_walk_vsec(pdev, info))
		have_devices = true;

	if (info && (info->quirks & VSEC_QUIRK_NO_DVSEC) &&
	    intel_vsec_walk_header(pdev, info))
		have_devices = true;

	if (!have_devices)
		return -ENODEV;

	return 0;
}

/* TGL info */
static const struct intel_vsec_platform_info tgl_info = {
	.quirks = VSEC_QUIRK_NO_WATCHER | VSEC_QUIRK_NO_CRASHLOG |
		  VSEC_QUIRK_TABLE_SHIFT | VSEC_QUIRK_EARLY_HW,
};

/* DG1 info */
static struct intel_vsec_header dg1_telemetry = {
	.length = 0x10,
	.id = 2,
	.num_entries = 1,
	.entry_size = 3,
	.tbir = 0,
	.offset = 0x466000,
};

static struct intel_vsec_header *dg1_capabilities[] = {
	&dg1_telemetry,
	NULL
};

static const struct intel_vsec_platform_info dg1_info = {
	.capabilities = dg1_capabilities,
	.quirks = VSEC_QUIRK_NO_DVSEC | VSEC_QUIRK_EARLY_HW,
};

#define PCI_DEVICE_ID_INTEL_VSEC_ADL		0x467d
#define PCI_DEVICE_ID_INTEL_VSEC_DG1		0x490e
#define PCI_DEVICE_ID_INTEL_VSEC_OOBMSM		0x09a7
#define PCI_DEVICE_ID_INTEL_VSEC_RPL		0xa77d
#define PCI_DEVICE_ID_INTEL_VSEC_TGL		0x9a0d
static const struct pci_device_id intel_vsec_pci_ids[] = {
	{ PCI_DEVICE_DATA(INTEL, VSEC_ADL, &tgl_info) },
	{ PCI_DEVICE_DATA(INTEL, VSEC_DG1, &dg1_info) },
	{ PCI_DEVICE_DATA(INTEL, VSEC_OOBMSM, &(struct intel_vsec_platform_info) {}) },
	{ PCI_DEVICE_DATA(INTEL, VSEC_RPL, &tgl_info) },
	{ PCI_DEVICE_DATA(INTEL, VSEC_TGL, &tgl_info) },
	{ }
};
MODULE_DEVICE_TABLE(pci, intel_vsec_pci_ids);

static pci_ers_result_t intel_vsec_pci_error_detected(struct pci_dev *pdev,
						      pci_channel_state_t state)
{
	pci_ers_result_t status = PCI_ERS_RESULT_NEED_RESET;

	dev_info(&pdev->dev, "PCI error detected, state %d", state);

	if (state == pci_channel_io_perm_failure)
		status = PCI_ERS_RESULT_DISCONNECT;
	else
		pci_disable_device(pdev);

	return status;
}

static pci_ers_result_t intel_vsec_pci_slot_reset(struct pci_dev *pdev)
{
	struct intel_vsec_device *intel_vsec_dev;
	pci_ers_result_t status = PCI_ERS_RESULT_DISCONNECT;
	const struct pci_device_id *pci_dev_id;
	unsigned long index;

	dev_info(&pdev->dev, "Resetting PCI slot\n");

	msleep(2000);
	if (pci_enable_device(pdev)) {
		dev_info(&pdev->dev,
			 "Failed to re-enable PCI device after reset.\n");
		goto out;
	}

	status = PCI_ERS_RESULT_RECOVERED;

	xa_for_each(&auxdev_array, index, intel_vsec_dev) {
		/* check if pdev doesn't match */
		if (pdev != intel_vsec_dev->pcidev)
			continue;
		devm_release_action(&pdev->dev, intel_vsec_remove_aux,
				    &intel_vsec_dev->auxdev);
	}
	pci_disable_device(pdev);
	pci_restore_state(pdev);
	pci_dev_id = pci_match_id(intel_vsec_pci_ids, pdev);
	intel_vsec_pci_probe(pdev, pci_dev_id);

out:
	return status;
}

static void intel_vsec_pci_resume(struct pci_dev *pdev)
{
	dev_info(&pdev->dev, "Done resuming PCI device\n");
}

static const struct pci_error_handlers intel_vsec_pci_err_handlers = {
	.error_detected = intel_vsec_pci_error_detected,
	.slot_reset = intel_vsec_pci_slot_reset,
	.resume = intel_vsec_pci_resume,
};

static struct pci_driver intel_vsec_pci_driver = {
	.name = "intel_vsec",
	.id_table = intel_vsec_pci_ids,
	.probe = intel_vsec_pci_probe,
	.err_handler = &intel_vsec_pci_err_handlers,
};
module_pci_driver(intel_vsec_pci_driver);

MODULE_AUTHOR("David E. Box <david.e.box@linux.intel.com>");
MODULE_DESCRIPTION("Intel Extended Capabilities auxiliary bus driver");
MODULE_LICENSE("GPL v2");
