// SPDX-License-Identifier: GPL-2.0
/*
 * Intel Speed Select Interface: Common functions
 * Copyright (c) 2019, Intel Corporation.
 * All rights reserved.
 *
 * Author: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
 */

#include <linux/cpufeature.h>
#include <linux/cpuhotplug.h>
#include <linux/fs.h>
#include <linux/hashtable.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/sched/signal.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <uapi/linux/isst_if.h>

#include "isst_if_common.h"

#define MSR_THREAD_ID_INFO	0x53
#define MSR_CPU_BUS_NUMBER	0x128

static struct isst_if_cmd_cb punit_callbacks[ISST_IF_DEV_MAX];

static int punit_msr_white_list[] = {
	MSR_TURBO_RATIO_LIMIT,
	MSR_CONFIG_TDP_CONTROL,
	MSR_TURBO_RATIO_LIMIT1,
	MSR_TURBO_RATIO_LIMIT2,
};

struct isst_valid_cmd_ranges {
	u16 cmd;
	u16 sub_cmd_beg;
	u16 sub_cmd_end;
};

struct isst_cmd_set_req_type {
	u16 cmd;
	u16 sub_cmd;
	u16 param;
};

static const struct isst_valid_cmd_ranges isst_valid_cmds[] = {
	{0xD0, 0x00, 0x03},
	{0x7F, 0x00, 0x0B},
	{0x7F, 0x10, 0x12},
	{0x7F, 0x20, 0x23},
	{0x94, 0x03, 0x03},
	{0x95, 0x03, 0x03},
};

static const struct isst_cmd_set_req_type isst_cmd_set_reqs[] = {
	{0xD0, 0x00, 0x08},
	{0xD0, 0x01, 0x08},
	{0xD0, 0x02, 0x08},
	{0xD0, 0x03, 0x08},
	{0x7F, 0x02, 0x00},
	{0x7F, 0x08, 0x00},
	{0x95, 0x03, 0x03},
};

struct isst_cmd {
	struct hlist_node hnode;
	u64 data;
	u32 cmd;
	int cpu;
	int mbox_cmd_type;
	u32 param;
};

static DECLARE_HASHTABLE(isst_hash, 8);
static DEFINE_MUTEX(isst_hash_lock);

static int isst_store_new_cmd(int cmd, u32 cpu, int mbox_cmd_type, u32 param,
			      u32 data)
{
	struct isst_cmd *sst_cmd;

	sst_cmd = kmalloc(sizeof(*sst_cmd), GFP_KERNEL);
	if (!sst_cmd)
		return -ENOMEM;

	sst_cmd->cpu = cpu;
	sst_cmd->cmd = cmd;
	sst_cmd->mbox_cmd_type = mbox_cmd_type;
	sst_cmd->param = param;
	sst_cmd->data = data;

	hash_add(isst_hash, &sst_cmd->hnode, sst_cmd->cmd);

	return 0;
}

static void isst_delete_hash(void)
{
	struct isst_cmd *sst_cmd;
	struct hlist_node *tmp;
	int i;

	hash_for_each_safe(isst_hash, i, tmp, sst_cmd, hnode) {
		hash_del(&sst_cmd->hnode);
		kfree(sst_cmd);
	}
}

/**
 * isst_store_cmd() - Store command to a hash table
 * @cmd: Mailbox command.
 * @sub_cmd: Mailbox sub-command or MSR id.
 * @mbox_cmd_type: Mailbox or MSR command.
 * @param: Mailbox parameter.
 * @data: Mailbox request data or MSR data.
 *
 * Stores the command to a hash table if there is no such command already
 * stored. If already stored update the latest parameter and data for the
 * command.
 *
 * Return: Return result of store to hash table, 0 for success, others for
 * failure.
 */
int isst_store_cmd(int cmd, int sub_cmd, u32 cpu, int mbox_cmd_type,
		   u32 param, u64 data)
{
	struct isst_cmd *sst_cmd;
	int full_cmd, ret;

	full_cmd = (cmd & GENMASK_ULL(15, 0)) << 16;
	full_cmd |= (sub_cmd & GENMASK_ULL(15, 0));
	mutex_lock(&isst_hash_lock);
	hash_for_each_possible(isst_hash, sst_cmd, hnode, full_cmd) {
		if (sst_cmd->cmd == full_cmd && sst_cmd->cpu == cpu &&
		    sst_cmd->mbox_cmd_type == mbox_cmd_type) {
			sst_cmd->param = param;
			sst_cmd->data = data;
			mutex_unlock(&isst_hash_lock);
			return 0;
		}
	}

	ret = isst_store_new_cmd(full_cmd, cpu, mbox_cmd_type, param, data);
	mutex_unlock(&isst_hash_lock);

	return ret;
}
EXPORT_SYMBOL_GPL(isst_store_cmd);

static void isst_mbox_resume_command(struct isst_if_cmd_cb *cb,
				     struct isst_cmd *sst_cmd)
{
	struct isst_if_mbox_cmd mbox_cmd;
	int wr_only;

	mbox_cmd.command = (sst_cmd->cmd & GENMASK_ULL(31, 16)) >> 16;
	mbox_cmd.sub_command = sst_cmd->cmd & GENMASK_ULL(15, 0);
	mbox_cmd.parameter = sst_cmd->param;
	mbox_cmd.req_data = sst_cmd->data;
	mbox_cmd.logical_cpu = sst_cmd->cpu;
	(cb->cmd_callback)((u8 *)&mbox_cmd, &wr_only, 1);
}

/**
 * isst_resume_common() - Process Resume request
 *
 * On resume replay all mailbox commands and MSRs.
 *
 * Return: None.
 */
void isst_resume_common(void)
{
	struct isst_cmd *sst_cmd;
	int i;

	hash_for_each(isst_hash, i, sst_cmd, hnode) {
		struct isst_if_cmd_cb *cb;

		if (sst_cmd->mbox_cmd_type) {
			cb = &punit_callbacks[ISST_IF_DEV_MBOX];
			if (cb->registered)
				isst_mbox_resume_command(cb, sst_cmd);
		} else {
			wrmsrl_safe_on_cpu(sst_cmd->cpu, sst_cmd->cmd,
					   sst_cmd->data);
		}
	}
}
EXPORT_SYMBOL_GPL(isst_resume_common);

static void isst_restore_msr_local(int cpu)
{
	struct isst_cmd *sst_cmd;
	int i;

	mutex_lock(&isst_hash_lock);
	for (i = 0; i < ARRAY_SIZE(punit_msr_white_list); ++i) {
		if (!punit_msr_white_list[i])
			break;

		hash_for_each_possible(isst_hash, sst_cmd, hnode,
				       punit_msr_white_list[i]) {
			if (!sst_cmd->mbox_cmd_type && sst_cmd->cpu == cpu)
				wrmsrl_safe(sst_cmd->cmd, sst_cmd->data);
		}
	}
	mutex_unlock(&isst_hash_lock);
}

/**
 * isst_if_mbox_cmd_invalid() - Check invalid mailbox commands
 * @cmd: Pointer to the command structure to verify.
 *
 * Invalid command to PUNIT to may result in instability of the platform.
 * This function has a whitelist of commands, which are allowed.
 *
 * Return: Return true if the command is invalid, else false.
 */
bool isst_if_mbox_cmd_invalid(struct isst_if_mbox_cmd *cmd)
{
	int i;

	if (cmd->logical_cpu >= nr_cpu_ids)
		return true;

	for (i = 0; i < ARRAY_SIZE(isst_valid_cmds); ++i) {
		if (cmd->command == isst_valid_cmds[i].cmd &&
		    (cmd->sub_command >= isst_valid_cmds[i].sub_cmd_beg &&
		     cmd->sub_command <= isst_valid_cmds[i].sub_cmd_end)) {
			return false;
		}
	}

	return true;
}
EXPORT_SYMBOL_GPL(isst_if_mbox_cmd_invalid);

/**
 * isst_if_mbox_cmd_set_req() - Check mailbox command is a set request
 * @cmd: Pointer to the command structure to verify.
 *
 * Check if the given mail box level is set request and not a get request.
 *
 * Return: Return true if the command is set_req, else false.
 */
bool isst_if_mbox_cmd_set_req(struct isst_if_mbox_cmd *cmd)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(isst_cmd_set_reqs); ++i) {
		if (cmd->command == isst_cmd_set_reqs[i].cmd &&
		    cmd->sub_command == isst_cmd_set_reqs[i].sub_cmd &&
		    cmd->parameter == isst_cmd_set_reqs[i].param) {
			return true;
		}
	}

	return false;
}
EXPORT_SYMBOL_GPL(isst_if_mbox_cmd_set_req);

static int isst_if_get_platform_info(void __user *argp)
{
	struct isst_if_platform_info info;

	info.api_version = ISST_IF_API_VERSION;
	info.driver_version = ISST_IF_DRIVER_VERSION;
	info.max_cmds_per_ioctl = ISST_IF_CMD_LIMIT;
	info.mbox_supported = punit_callbacks[ISST_IF_DEV_MBOX].registered;
	info.mmio_supported = punit_callbacks[ISST_IF_DEV_MMIO].registered;

	if (copy_to_user(argp, &info, sizeof(info)))
		return -EFAULT;

	return 0;
}


struct isst_if_cpu_info {
	/* For BUS 0 and BUS 1 only, which we need for PUNIT interface */
	int bus_info[2];
	struct pci_dev *pci_dev[2];
	int punit_cpu_id;
	int numa_node;
};

static struct isst_if_cpu_info *isst_cpu_info;
#define ISST_MAX_PCI_DOMAINS	8

static struct pci_dev *_isst_if_get_pci_dev(int cpu, int bus_no, int dev, int fn)
{
	struct pci_dev *matched_pci_dev = NULL;
	struct pci_dev *pci_dev = NULL;
	int no_matches = 0;
	int i, bus_number;

	if (bus_no < 0 || bus_no > 1 || cpu < 0 || cpu >= nr_cpu_ids ||
	    cpu >= num_possible_cpus())
		return NULL;

	bus_number = isst_cpu_info[cpu].bus_info[bus_no];
	if (bus_number < 0)
		return NULL;

	for (i = 0; i < ISST_MAX_PCI_DOMAINS; ++i) {
		struct pci_dev *_pci_dev;
		int node;

		_pci_dev = pci_get_domain_bus_and_slot(i, bus_number, PCI_DEVFN(dev, fn));
		if (!_pci_dev)
			continue;

		++no_matches;
		if (!matched_pci_dev)
			matched_pci_dev = _pci_dev;

		node = dev_to_node(&_pci_dev->dev);
		if (node == NUMA_NO_NODE) {
			pr_info("Fail to get numa node for CPU:%d bus:%d dev:%d fn:%d\n",
				cpu, bus_no, dev, fn);
			continue;
		}

		if (node == isst_cpu_info[cpu].numa_node) {
			pci_dev = _pci_dev;
			break;
		}
	}

	/*
	 * If there is no numa matched pci_dev, then there can be following cases:
	 * 1. CONFIG_NUMA is not defined: In this case if there is only single device
	 *    match, then we don't need numa information. Simply return last match.
	 *    Othewise return NULL.
	 * 2. NUMA information is not exposed via _SEG method. In this case it is similar
	 *    to case 1.
	 * 3. Numa information doesn't match with CPU numa node and more than one match
	 *    return NULL.
	 */
	if (!pci_dev && no_matches == 1)
		pci_dev = matched_pci_dev;

	return pci_dev;
}

/**
 * isst_if_get_pci_dev() - Get the PCI device instance for a CPU
 * @cpu: Logical CPU number.
 * @bus_number: The bus number assigned by the hardware.
 * @dev: The device number assigned by the hardware.
 * @fn: The function number assigned by the hardware.
 *
 * Using cached bus information, find out the PCI device for a bus number,
 * device and function.
 *
 * Return: Return pci_dev pointer or NULL.
 */
struct pci_dev *isst_if_get_pci_dev(int cpu, int bus_no, int dev, int fn)
{
	struct pci_dev *pci_dev;

	if (bus_no < 0 || bus_no > 1 || cpu < 0 || cpu >= nr_cpu_ids ||
	    cpu >= num_possible_cpus())
		return NULL;

	pci_dev = isst_cpu_info[cpu].pci_dev[bus_no];

	if (pci_dev && pci_dev->devfn == PCI_DEVFN(dev, fn))
		return pci_dev;

	return _isst_if_get_pci_dev(cpu, bus_no, dev, fn);
}
EXPORT_SYMBOL_GPL(isst_if_get_pci_dev);

static int isst_if_cpu_online(unsigned int cpu)
{
	u64 data;
	int ret;

	isst_cpu_info[cpu].numa_node = cpu_to_node(cpu);

	ret = rdmsrl_safe(MSR_CPU_BUS_NUMBER, &data);
	if (ret) {
		/* This is not a fatal error on MSR mailbox only I/F */
		isst_cpu_info[cpu].bus_info[0] = -1;
		isst_cpu_info[cpu].bus_info[1] = -1;
	} else {
		isst_cpu_info[cpu].bus_info[0] = data & 0xff;
		isst_cpu_info[cpu].bus_info[1] = (data >> 8) & 0xff;
		isst_cpu_info[cpu].pci_dev[0] = _isst_if_get_pci_dev(cpu, 0, 0, 1);
		isst_cpu_info[cpu].pci_dev[1] = _isst_if_get_pci_dev(cpu, 1, 30, 1);
	}

	ret = rdmsrl_safe(MSR_THREAD_ID_INFO, &data);
	if (ret) {
		isst_cpu_info[cpu].punit_cpu_id = -1;
		return ret;
	}
	isst_cpu_info[cpu].punit_cpu_id = data;

	isst_restore_msr_local(cpu);

	return 0;
}

static int isst_if_online_id;

static int isst_if_cpu_info_init(void)
{
	int ret;

	isst_cpu_info = kcalloc(num_possible_cpus(),
				sizeof(*isst_cpu_info),
				GFP_KERNEL);
	if (!isst_cpu_info)
		return -ENOMEM;

	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
				"platform/x86/isst-if:online",
				isst_if_cpu_online, NULL);
	if (ret < 0) {
		kfree(isst_cpu_info);
		return ret;
	}

	isst_if_online_id = ret;

	return 0;
}

static void isst_if_cpu_info_exit(void)
{
	cpuhp_remove_state(isst_if_online_id);
	kfree(isst_cpu_info);
};

static long isst_if_proc_phyid_req(u8 *cmd_ptr, int *write_only, int resume)
{
	struct isst_if_cpu_map *cpu_map;

	cpu_map = (struct isst_if_cpu_map *)cmd_ptr;
	if (cpu_map->logical_cpu >= nr_cpu_ids ||
	    cpu_map->logical_cpu >= num_possible_cpus())
		return -EINVAL;

	*write_only = 0;
	cpu_map->physical_cpu = isst_cpu_info[cpu_map->logical_cpu].punit_cpu_id;

	return 0;
}

static bool match_punit_msr_white_list(int msr)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(punit_msr_white_list); ++i) {
		if (punit_msr_white_list[i] == msr)
			return true;
	}

	return false;
}

static long isst_if_msr_cmd_req(u8 *cmd_ptr, int *write_only, int resume)
{
	struct isst_if_msr_cmd *msr_cmd;
	int ret;

	msr_cmd = (struct isst_if_msr_cmd *)cmd_ptr;

	if (!match_punit_msr_white_list(msr_cmd->msr))
		return -EINVAL;

	if (msr_cmd->logical_cpu >= nr_cpu_ids)
		return -EINVAL;

	if (msr_cmd->read_write) {
		if (!capable(CAP_SYS_ADMIN))
			return -EPERM;

		ret = wrmsrl_safe_on_cpu(msr_cmd->logical_cpu,
					 msr_cmd->msr,
					 msr_cmd->data);
		*write_only = 1;
		if (!ret && !resume)
			ret = isst_store_cmd(0, msr_cmd->msr,
					     msr_cmd->logical_cpu,
					     0, 0, msr_cmd->data);
	} else {
		u64 data;

		ret = rdmsrl_safe_on_cpu(msr_cmd->logical_cpu,
					 msr_cmd->msr, &data);
		if (!ret) {
			msr_cmd->data = data;
			*write_only = 0;
		}
	}


	return ret;
}

static long isst_if_exec_multi_cmd(void __user *argp, struct isst_if_cmd_cb *cb)
{
	unsigned char __user *ptr;
	u32 cmd_count;
	u8 *cmd_ptr;
	long ret;
	int i;

	/* Each multi command has u32 command count as the first field */
	if (copy_from_user(&cmd_count, argp, sizeof(cmd_count)))
		return -EFAULT;

	if (!cmd_count || cmd_count > ISST_IF_CMD_LIMIT)
		return -EINVAL;

	cmd_ptr = kmalloc(cb->cmd_size, GFP_KERNEL);
	if (!cmd_ptr)
		return -ENOMEM;

	/* cb->offset points to start of the command after the command count */
	ptr = argp + cb->offset;

	for (i = 0; i < cmd_count; ++i) {
		int wr_only;

		if (signal_pending(current)) {
			ret = -EINTR;
			break;
		}

		if (copy_from_user(cmd_ptr, ptr, cb->cmd_size)) {
			ret = -EFAULT;
			break;
		}

		ret = cb->cmd_callback(cmd_ptr, &wr_only, 0);
		if (ret)
			break;

		if (!wr_only && copy_to_user(ptr, cmd_ptr, cb->cmd_size)) {
			ret = -EFAULT;
			break;
		}

		ptr += cb->cmd_size;
	}

	kfree(cmd_ptr);

	return i ? i : ret;
}

static long isst_if_def_ioctl(struct file *file, unsigned int cmd,
			      unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	struct isst_if_cmd_cb cmd_cb;
	struct isst_if_cmd_cb *cb;
	long ret = -ENOTTY;

	switch (cmd) {
	case ISST_IF_GET_PLATFORM_INFO:
		ret = isst_if_get_platform_info(argp);
		break;
	case ISST_IF_GET_PHY_ID:
		cmd_cb.cmd_size = sizeof(struct isst_if_cpu_map);
		cmd_cb.offset = offsetof(struct isst_if_cpu_maps, cpu_map);
		cmd_cb.cmd_callback = isst_if_proc_phyid_req;
		ret = isst_if_exec_multi_cmd(argp, &cmd_cb);
		break;
	case ISST_IF_IO_CMD:
		cb = &punit_callbacks[ISST_IF_DEV_MMIO];
		if (cb->registered)
			ret = isst_if_exec_multi_cmd(argp, cb);
		break;
	case ISST_IF_MBOX_COMMAND:
		cb = &punit_callbacks[ISST_IF_DEV_MBOX];
		if (cb->registered)
			ret = isst_if_exec_multi_cmd(argp, cb);
		break;
	case ISST_IF_MSR_COMMAND:
		cmd_cb.cmd_size = sizeof(struct isst_if_msr_cmd);
		cmd_cb.offset = offsetof(struct isst_if_msr_cmds, msr_cmd);
		cmd_cb.cmd_callback = isst_if_msr_cmd_req;
		ret = isst_if_exec_multi_cmd(argp, &cmd_cb);
		break;
	default:
		break;
	}

	return ret;
}

static DEFINE_MUTEX(punit_misc_dev_lock);
static int misc_usage_count;
static int misc_device_ret;
static int misc_device_open;

static int isst_if_open(struct inode *inode, struct file *file)
{
	int i, ret = 0;

	/* Fail open, if a module is going away */
	mutex_lock(&punit_misc_dev_lock);
	for (i = 0; i < ISST_IF_DEV_MAX; ++i) {
		struct isst_if_cmd_cb *cb = &punit_callbacks[i];

		if (cb->registered && !try_module_get(cb->owner)) {
			ret = -ENODEV;
			break;
		}
	}
	if (ret) {
		int j;

		for (j = 0; j < i; ++j) {
			struct isst_if_cmd_cb *cb;

			cb = &punit_callbacks[j];
			if (cb->registered)
				module_put(cb->owner);
		}
	} else {
		misc_device_open++;
	}
	mutex_unlock(&punit_misc_dev_lock);

	return ret;
}

static int isst_if_relase(struct inode *inode, struct file *f)
{
	int i;

	mutex_lock(&punit_misc_dev_lock);
	misc_device_open--;
	for (i = 0; i < ISST_IF_DEV_MAX; ++i) {
		struct isst_if_cmd_cb *cb = &punit_callbacks[i];

		if (cb->registered)
			module_put(cb->owner);
	}
	mutex_unlock(&punit_misc_dev_lock);

	return 0;
}

static const struct file_operations isst_if_char_driver_ops = {
	.open = isst_if_open,
	.unlocked_ioctl = isst_if_def_ioctl,
	.release = isst_if_relase,
};

static struct miscdevice isst_if_char_driver = {
	.minor		= MISC_DYNAMIC_MINOR,
	.name		= "isst_interface",
	.fops		= &isst_if_char_driver_ops,
};

/**
 * isst_if_cdev_register() - Register callback for IOCTL
 * @device_type: The device type this callback handling.
 * @cb:	Callback structure.
 *
 * This function registers a callback to device type. On very first call
 * it will register a misc device, which is used for user kernel interface.
 * Other calls simply increment ref count. Registry will fail, if the user
 * already opened misc device for operation. Also if the misc device
 * creation failed, then it will not try again and all callers will get
 * failure code.
 *
 * Return: Return the return value from the misc creation device or -EINVAL
 * for unsupported device type.
 */
int isst_if_cdev_register(int device_type, struct isst_if_cmd_cb *cb)
{
	if (misc_device_ret)
		return misc_device_ret;

	if (device_type >= ISST_IF_DEV_MAX)
		return -EINVAL;

	mutex_lock(&punit_misc_dev_lock);
	if (misc_device_open) {
		mutex_unlock(&punit_misc_dev_lock);
		return -EAGAIN;
	}
	if (!misc_usage_count) {
		int ret;

		misc_device_ret = misc_register(&isst_if_char_driver);
		if (misc_device_ret)
			goto unlock_exit;

		ret = isst_if_cpu_info_init();
		if (ret) {
			misc_deregister(&isst_if_char_driver);
			misc_device_ret = ret;
			goto unlock_exit;
		}
	}
	memcpy(&punit_callbacks[device_type], cb, sizeof(*cb));
	punit_callbacks[device_type].registered = 1;
	misc_usage_count++;
unlock_exit:
	mutex_unlock(&punit_misc_dev_lock);

	return misc_device_ret;
}
EXPORT_SYMBOL_GPL(isst_if_cdev_register);

/**
 * isst_if_cdev_unregister() - Unregister callback for IOCTL
 * @device_type: The device type to unregister.
 *
 * This function unregisters the previously registered callback. If this
 * is the last callback unregistering, then misc device is removed.
 *
 * Return: None.
 */
void isst_if_cdev_unregister(int device_type)
{
	mutex_lock(&punit_misc_dev_lock);
	misc_usage_count--;
	punit_callbacks[device_type].registered = 0;
	if (device_type == ISST_IF_DEV_MBOX)
		isst_delete_hash();
	if (!misc_usage_count && !misc_device_ret) {
		misc_deregister(&isst_if_char_driver);
		isst_if_cpu_info_exit();
	}
	mutex_unlock(&punit_misc_dev_lock);
}
EXPORT_SYMBOL_GPL(isst_if_cdev_unregister);

MODULE_LICENSE("GPL v2");
