// SPDX-License-Identifier: GPL-2.0
/*
 * PCI Backend - Handles the virtual fields found on the capability lists
 *               in the configuration space.
 *
 * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
 */

#include <linux/kernel.h>
#include <linux/pci.h>
#include "pciback.h"
#include "conf_space.h"

static LIST_HEAD(capabilities);
struct xen_pcibk_config_capability {
	struct list_head cap_list;

	int capability;

	/* If the device has the capability found above, add these fields */
	const struct config_field *fields;
};

static const struct config_field caplist_header[] = {
	{
	 .offset    = PCI_CAP_LIST_ID,
	 .size      = 2, /* encompass PCI_CAP_LIST_ID & PCI_CAP_LIST_NEXT */
	 .u.w.read  = xen_pcibk_read_config_word,
	 .u.w.write = NULL,
	},
	{}
};

static inline void register_capability(struct xen_pcibk_config_capability *cap)
{
	list_add_tail(&cap->cap_list, &capabilities);
}

int xen_pcibk_config_capability_add_fields(struct pci_dev *dev)
{
	int err = 0;
	struct xen_pcibk_config_capability *cap;
	int cap_offset;

	list_for_each_entry(cap, &capabilities, cap_list) {
		cap_offset = pci_find_capability(dev, cap->capability);
		if (cap_offset) {
			dev_dbg(&dev->dev, "Found capability 0x%x at 0x%x\n",
				cap->capability, cap_offset);

			err = xen_pcibk_config_add_fields_offset(dev,
							       caplist_header,
							       cap_offset);
			if (err)
				goto out;
			err = xen_pcibk_config_add_fields_offset(dev,
							       cap->fields,
							       cap_offset);
			if (err)
				goto out;
		}
	}

out:
	return err;
}

static int vpd_address_write(struct pci_dev *dev, int offset, u16 value,
			     void *data)
{
	/* Disallow writes to the vital product data */
	if (value & PCI_VPD_ADDR_F)
		return PCIBIOS_SET_FAILED;
	else
		return pci_write_config_word(dev, offset, value);
}

static const struct config_field caplist_vpd[] = {
	{
	 .offset    = PCI_VPD_ADDR,
	 .size      = 2,
	 .u.w.read  = xen_pcibk_read_config_word,
	 .u.w.write = vpd_address_write,
	 },
	{
	 .offset     = PCI_VPD_DATA,
	 .size       = 4,
	 .u.dw.read  = xen_pcibk_read_config_dword,
	 .u.dw.write = NULL,
	 },
	{}
};

static int pm_caps_read(struct pci_dev *dev, int offset, u16 *value,
			void *data)
{
	int err;
	u16 real_value;

	err = pci_read_config_word(dev, offset, &real_value);
	if (err)
		goto out;

	*value = real_value & ~PCI_PM_CAP_PME_MASK;

out:
	return err;
}

/* PM_OK_BITS specifies the bits that the driver domain is allowed to change.
 * Can't allow driver domain to enable PMEs - they're shared */
#define PM_OK_BITS (PCI_PM_CTRL_PME_STATUS|PCI_PM_CTRL_DATA_SEL_MASK)

static int pm_ctrl_write(struct pci_dev *dev, int offset, u16 new_value,
			 void *data)
{
	int err;
	u16 old_value;
	pci_power_t new_state;

	err = pci_read_config_word(dev, offset, &old_value);
	if (err)
		goto out;

	new_state = (pci_power_t)(new_value & PCI_PM_CTRL_STATE_MASK);

	new_value &= PM_OK_BITS;
	if ((old_value & PM_OK_BITS) != new_value) {
		new_value = (old_value & ~PM_OK_BITS) | new_value;
		err = pci_write_config_word(dev, offset, new_value);
		if (err)
			goto out;
	}

	/* Let pci core handle the power management change */
	dev_dbg(&dev->dev, "set power state to %x\n", new_state);
	err = pci_set_power_state(dev, new_state);
	if (err) {
		err = PCIBIOS_SET_FAILED;
		goto out;
	}

 out:
	return err;
}

/* Ensure PMEs are disabled */
static void *pm_ctrl_init(struct pci_dev *dev, int offset)
{
	int err;
	u16 value;

	err = pci_read_config_word(dev, offset, &value);
	if (err)
		goto out;

	if (value & PCI_PM_CTRL_PME_ENABLE) {
		value &= ~PCI_PM_CTRL_PME_ENABLE;
		err = pci_write_config_word(dev, offset, value);
	}

out:
	return err ? ERR_PTR(err) : NULL;
}

static const struct config_field caplist_pm[] = {
	{
		.offset     = PCI_PM_PMC,
		.size       = 2,
		.u.w.read   = pm_caps_read,
	},
	{
		.offset     = PCI_PM_CTRL,
		.size       = 2,
		.init       = pm_ctrl_init,
		.u.w.read   = xen_pcibk_read_config_word,
		.u.w.write  = pm_ctrl_write,
	},
	{
		.offset     = PCI_PM_PPB_EXTENSIONS,
		.size       = 1,
		.u.b.read   = xen_pcibk_read_config_byte,
	},
	{
		.offset     = PCI_PM_DATA_REGISTER,
		.size       = 1,
		.u.b.read   = xen_pcibk_read_config_byte,
	},
	{}
};

static struct msi_msix_field_config {
	u16          enable_bit;   /* bit for enabling MSI/MSI-X */
	u16          allowed_bits; /* bits allowed to be changed */
	unsigned int int_type;     /* interrupt type for exclusiveness check */
} msi_field_config = {
	.enable_bit	= PCI_MSI_FLAGS_ENABLE,
	.allowed_bits	= PCI_MSI_FLAGS_ENABLE,
	.int_type	= INTERRUPT_TYPE_MSI,
}, msix_field_config = {
	.enable_bit	= PCI_MSIX_FLAGS_ENABLE,
	.allowed_bits	= PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL,
	.int_type	= INTERRUPT_TYPE_MSIX,
};

static void *msi_field_init(struct pci_dev *dev, int offset)
{
	return &msi_field_config;
}

static void *msix_field_init(struct pci_dev *dev, int offset)
{
	return &msix_field_config;
}

static int msi_msix_flags_write(struct pci_dev *dev, int offset, u16 new_value,
				void *data)
{
	int err;
	u16 old_value;
	const struct msi_msix_field_config *field_config = data;
	const struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev);

	if (xen_pcibk_permissive || dev_data->permissive)
		goto write;

	err = pci_read_config_word(dev, offset, &old_value);
	if (err)
		return err;

	if (new_value == old_value)
		return 0;

	if (!dev_data->allow_interrupt_control ||
	    (new_value ^ old_value) & ~field_config->allowed_bits)
		return PCIBIOS_SET_FAILED;

	if (new_value & field_config->enable_bit) {
		/*
		 * Don't allow enabling together with other interrupt type, but do
		 * allow enabling MSI(-X) while INTx is still active to please Linuxes
		 * MSI(-X) startup sequence. It is safe to do, as according to PCI
		 * spec, device with enabled MSI(-X) shouldn't use INTx.
		 */
		int int_type = xen_pcibk_get_interrupt_type(dev);

		if (int_type == INTERRUPT_TYPE_NONE ||
		    int_type == INTERRUPT_TYPE_INTX ||
		    int_type == field_config->int_type)
			goto write;
		return PCIBIOS_SET_FAILED;
	}

write:
	return pci_write_config_word(dev, offset, new_value);
}

static const struct config_field caplist_msix[] = {
	{
		.offset    = PCI_MSIX_FLAGS,
		.size      = 2,
		.init      = msix_field_init,
		.u.w.read  = xen_pcibk_read_config_word,
		.u.w.write = msi_msix_flags_write,
	},
	{}
};

static const struct config_field caplist_msi[] = {
	{
		.offset    = PCI_MSI_FLAGS,
		.size      = 2,
		.init      = msi_field_init,
		.u.w.read  = xen_pcibk_read_config_word,
		.u.w.write = msi_msix_flags_write,
	},
	{}
};

static struct xen_pcibk_config_capability xen_pcibk_config_capability_pm = {
	.capability = PCI_CAP_ID_PM,
	.fields = caplist_pm,
};
static struct xen_pcibk_config_capability xen_pcibk_config_capability_vpd = {
	.capability = PCI_CAP_ID_VPD,
	.fields = caplist_vpd,
};
static struct xen_pcibk_config_capability xen_pcibk_config_capability_msi = {
	.capability = PCI_CAP_ID_MSI,
	.fields = caplist_msi,
};
static struct xen_pcibk_config_capability xen_pcibk_config_capability_msix = {
	.capability = PCI_CAP_ID_MSIX,
	.fields = caplist_msix,
};

int xen_pcibk_config_capability_init(void)
{
	register_capability(&xen_pcibk_config_capability_vpd);
	register_capability(&xen_pcibk_config_capability_pm);
	register_capability(&xen_pcibk_config_capability_msi);
	register_capability(&xen_pcibk_config_capability_msix);

	return 0;
}
