// SPDX-License-Identifier: GPL-2.0
/*
 * Greybus Firmware Management Protocol Driver.
 *
 * Copyright 2016 Google Inc.
 * Copyright 2016 Linaro Ltd.
 */

#include <linux/cdev.h>
#include <linux/completion.h>
#include <linux/firmware.h>
#include <linux/fs.h>
#include <linux/idr.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/greybus.h>

#include "firmware.h"
#include "greybus_firmware.h"

#define FW_MGMT_TIMEOUT_MS		1000

struct fw_mgmt {
	struct device		*parent;
	struct gb_connection	*connection;
	struct kref		kref;
	struct list_head	node;

	/* Common id-map for interface and backend firmware requests */
	struct ida		id_map;
	struct mutex		mutex;
	struct completion	completion;
	struct cdev		cdev;
	struct device		*class_device;
	dev_t			dev_num;
	unsigned int		timeout_jiffies;
	bool			disabled; /* connection getting disabled */

	/* Interface Firmware specific fields */
	bool			mode_switch_started;
	bool			intf_fw_loaded;
	u8			intf_fw_request_id;
	u8			intf_fw_status;
	u16			intf_fw_major;
	u16			intf_fw_minor;

	/* Backend Firmware specific fields */
	u8			backend_fw_request_id;
	u8			backend_fw_status;
};

/*
 * Number of minor devices this driver supports.
 * There will be exactly one required per Interface.
 */
#define NUM_MINORS		U8_MAX

static const struct class fw_mgmt_class = {
	.name = "gb_fw_mgmt",
};

static dev_t fw_mgmt_dev_num;
static DEFINE_IDA(fw_mgmt_minors_map);
static LIST_HEAD(fw_mgmt_list);
static DEFINE_MUTEX(list_mutex);

static void fw_mgmt_kref_release(struct kref *kref)
{
	struct fw_mgmt *fw_mgmt = container_of(kref, struct fw_mgmt, kref);

	ida_destroy(&fw_mgmt->id_map);
	kfree(fw_mgmt);
}

/*
 * All users of fw_mgmt take a reference (from within list_mutex lock), before
 * they get a pointer to play with. And the structure will be freed only after
 * the last user has put the reference to it.
 */
static void put_fw_mgmt(struct fw_mgmt *fw_mgmt)
{
	kref_put(&fw_mgmt->kref, fw_mgmt_kref_release);
}

/* Caller must call put_fw_mgmt() after using struct fw_mgmt */
static struct fw_mgmt *get_fw_mgmt(struct cdev *cdev)
{
	struct fw_mgmt *fw_mgmt;

	mutex_lock(&list_mutex);

	list_for_each_entry(fw_mgmt, &fw_mgmt_list, node) {
		if (&fw_mgmt->cdev == cdev) {
			kref_get(&fw_mgmt->kref);
			goto unlock;
		}
	}

	fw_mgmt = NULL;

unlock:
	mutex_unlock(&list_mutex);

	return fw_mgmt;
}

static int fw_mgmt_interface_fw_version_operation(struct fw_mgmt *fw_mgmt,
						  struct fw_mgmt_ioc_get_intf_version *fw_info)
{
	struct gb_connection *connection = fw_mgmt->connection;
	struct gb_fw_mgmt_interface_fw_version_response response;
	int ret;

	ret = gb_operation_sync(connection,
				GB_FW_MGMT_TYPE_INTERFACE_FW_VERSION, NULL, 0,
				&response, sizeof(response));
	if (ret) {
		dev_err(fw_mgmt->parent,
			"failed to get interface firmware version (%d)\n", ret);
		return ret;
	}

	fw_info->major = le16_to_cpu(response.major);
	fw_info->minor = le16_to_cpu(response.minor);

	strncpy(fw_info->firmware_tag, response.firmware_tag,
		GB_FIRMWARE_TAG_MAX_SIZE);

	/*
	 * The firmware-tag should be NULL terminated, otherwise throw error but
	 * don't fail.
	 */
	if (fw_info->firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
		dev_err(fw_mgmt->parent,
			"fw-version: firmware-tag is not NULL terminated\n");
		fw_info->firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] = '\0';
	}

	return 0;
}

static int fw_mgmt_load_and_validate_operation(struct fw_mgmt *fw_mgmt,
					       u8 load_method, const char *tag)
{
	struct gb_fw_mgmt_load_and_validate_fw_request request;
	int ret;

	if (load_method != GB_FW_LOAD_METHOD_UNIPRO &&
	    load_method != GB_FW_LOAD_METHOD_INTERNAL) {
		dev_err(fw_mgmt->parent,
			"invalid load-method (%d)\n", load_method);
		return -EINVAL;
	}

	request.load_method = load_method;
	strncpy(request.firmware_tag, tag, GB_FIRMWARE_TAG_MAX_SIZE);

	/*
	 * The firmware-tag should be NULL terminated, otherwise throw error and
	 * fail.
	 */
	if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
		dev_err(fw_mgmt->parent, "load-and-validate: firmware-tag is not NULL terminated\n");
		return -EINVAL;
	}

	/* Allocate ids from 1 to 255 (u8-max), 0 is an invalid id */
	ret = ida_alloc_range(&fw_mgmt->id_map, 1, 255, GFP_KERNEL);
	if (ret < 0) {
		dev_err(fw_mgmt->parent, "failed to allocate request id (%d)\n",
			ret);
		return ret;
	}

	fw_mgmt->intf_fw_request_id = ret;
	fw_mgmt->intf_fw_loaded = false;
	request.request_id = ret;

	ret = gb_operation_sync(fw_mgmt->connection,
				GB_FW_MGMT_TYPE_LOAD_AND_VALIDATE_FW, &request,
				sizeof(request), NULL, 0);
	if (ret) {
		ida_free(&fw_mgmt->id_map, fw_mgmt->intf_fw_request_id);
		fw_mgmt->intf_fw_request_id = 0;
		dev_err(fw_mgmt->parent,
			"load and validate firmware request failed (%d)\n",
			ret);
		return ret;
	}

	return 0;
}

static int fw_mgmt_interface_fw_loaded_operation(struct gb_operation *op)
{
	struct gb_connection *connection = op->connection;
	struct fw_mgmt *fw_mgmt = gb_connection_get_data(connection);
	struct gb_fw_mgmt_loaded_fw_request *request;

	/* No pending load and validate request ? */
	if (!fw_mgmt->intf_fw_request_id) {
		dev_err(fw_mgmt->parent,
			"unexpected firmware loaded request received\n");
		return -ENODEV;
	}

	if (op->request->payload_size != sizeof(*request)) {
		dev_err(fw_mgmt->parent, "illegal size of firmware loaded request (%zu != %zu)\n",
			op->request->payload_size, sizeof(*request));
		return -EINVAL;
	}

	request = op->request->payload;

	/* Invalid request-id ? */
	if (request->request_id != fw_mgmt->intf_fw_request_id) {
		dev_err(fw_mgmt->parent, "invalid request id for firmware loaded request (%02u != %02u)\n",
			fw_mgmt->intf_fw_request_id, request->request_id);
		return -ENODEV;
	}

	ida_free(&fw_mgmt->id_map, fw_mgmt->intf_fw_request_id);
	fw_mgmt->intf_fw_request_id = 0;
	fw_mgmt->intf_fw_status = request->status;
	fw_mgmt->intf_fw_major = le16_to_cpu(request->major);
	fw_mgmt->intf_fw_minor = le16_to_cpu(request->minor);

	if (fw_mgmt->intf_fw_status == GB_FW_LOAD_STATUS_FAILED)
		dev_err(fw_mgmt->parent,
			"failed to load interface firmware, status:%02x\n",
			fw_mgmt->intf_fw_status);
	else if (fw_mgmt->intf_fw_status == GB_FW_LOAD_STATUS_VALIDATION_FAILED)
		dev_err(fw_mgmt->parent,
			"failed to validate interface firmware, status:%02x\n",
			fw_mgmt->intf_fw_status);
	else
		fw_mgmt->intf_fw_loaded = true;

	complete(&fw_mgmt->completion);

	return 0;
}

static int fw_mgmt_backend_fw_version_operation(struct fw_mgmt *fw_mgmt,
						struct fw_mgmt_ioc_get_backend_version *fw_info)
{
	struct gb_connection *connection = fw_mgmt->connection;
	struct gb_fw_mgmt_backend_fw_version_request request;
	struct gb_fw_mgmt_backend_fw_version_response response;
	int ret;

	strncpy(request.firmware_tag, fw_info->firmware_tag,
		GB_FIRMWARE_TAG_MAX_SIZE);

	/*
	 * The firmware-tag should be NULL terminated, otherwise throw error and
	 * fail.
	 */
	if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
		dev_err(fw_mgmt->parent, "backend-version: firmware-tag is not NULL terminated\n");
		return -EINVAL;
	}

	ret = gb_operation_sync(connection,
				GB_FW_MGMT_TYPE_BACKEND_FW_VERSION, &request,
				sizeof(request), &response, sizeof(response));
	if (ret) {
		dev_err(fw_mgmt->parent, "failed to get version of %s backend firmware (%d)\n",
			fw_info->firmware_tag, ret);
		return ret;
	}

	fw_info->status = response.status;

	/* Reset version as that should be non-zero only for success case */
	fw_info->major = 0;
	fw_info->minor = 0;

	switch (fw_info->status) {
	case GB_FW_BACKEND_VERSION_STATUS_SUCCESS:
		fw_info->major = le16_to_cpu(response.major);
		fw_info->minor = le16_to_cpu(response.minor);
		break;
	case GB_FW_BACKEND_VERSION_STATUS_NOT_AVAILABLE:
	case GB_FW_BACKEND_VERSION_STATUS_RETRY:
		break;
	case GB_FW_BACKEND_VERSION_STATUS_NOT_SUPPORTED:
		dev_err(fw_mgmt->parent,
			"Firmware with tag %s is not supported by Interface\n",
			fw_info->firmware_tag);
		break;
	default:
		dev_err(fw_mgmt->parent, "Invalid status received: %u\n",
			fw_info->status);
	}

	return 0;
}

static int fw_mgmt_backend_fw_update_operation(struct fw_mgmt *fw_mgmt,
					       char *tag)
{
	struct gb_fw_mgmt_backend_fw_update_request request;
	int ret;

	strncpy(request.firmware_tag, tag, GB_FIRMWARE_TAG_MAX_SIZE);

	/*
	 * The firmware-tag should be NULL terminated, otherwise throw error and
	 * fail.
	 */
	if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
		dev_err(fw_mgmt->parent, "backend-update: firmware-tag is not NULL terminated\n");
		return -EINVAL;
	}

	/* Allocate ids from 1 to 255 (u8-max), 0 is an invalid id */
	ret = ida_alloc_range(&fw_mgmt->id_map, 1, 255, GFP_KERNEL);
	if (ret < 0) {
		dev_err(fw_mgmt->parent, "failed to allocate request id (%d)\n",
			ret);
		return ret;
	}

	fw_mgmt->backend_fw_request_id = ret;
	request.request_id = ret;

	ret = gb_operation_sync(fw_mgmt->connection,
				GB_FW_MGMT_TYPE_BACKEND_FW_UPDATE, &request,
				sizeof(request), NULL, 0);
	if (ret) {
		ida_free(&fw_mgmt->id_map, fw_mgmt->backend_fw_request_id);
		fw_mgmt->backend_fw_request_id = 0;
		dev_err(fw_mgmt->parent,
			"backend %s firmware update request failed (%d)\n", tag,
			ret);
		return ret;
	}

	return 0;
}

static int fw_mgmt_backend_fw_updated_operation(struct gb_operation *op)
{
	struct gb_connection *connection = op->connection;
	struct fw_mgmt *fw_mgmt = gb_connection_get_data(connection);
	struct gb_fw_mgmt_backend_fw_updated_request *request;

	/* No pending load and validate request ? */
	if (!fw_mgmt->backend_fw_request_id) {
		dev_err(fw_mgmt->parent, "unexpected backend firmware updated request received\n");
		return -ENODEV;
	}

	if (op->request->payload_size != sizeof(*request)) {
		dev_err(fw_mgmt->parent, "illegal size of backend firmware updated request (%zu != %zu)\n",
			op->request->payload_size, sizeof(*request));
		return -EINVAL;
	}

	request = op->request->payload;

	/* Invalid request-id ? */
	if (request->request_id != fw_mgmt->backend_fw_request_id) {
		dev_err(fw_mgmt->parent, "invalid request id for backend firmware updated request (%02u != %02u)\n",
			fw_mgmt->backend_fw_request_id, request->request_id);
		return -ENODEV;
	}

	ida_free(&fw_mgmt->id_map, fw_mgmt->backend_fw_request_id);
	fw_mgmt->backend_fw_request_id = 0;
	fw_mgmt->backend_fw_status = request->status;

	if ((fw_mgmt->backend_fw_status != GB_FW_BACKEND_FW_STATUS_SUCCESS) &&
	    (fw_mgmt->backend_fw_status != GB_FW_BACKEND_FW_STATUS_RETRY))
		dev_err(fw_mgmt->parent,
			"failed to load backend firmware: %02x\n",
			fw_mgmt->backend_fw_status);

	complete(&fw_mgmt->completion);

	return 0;
}

/* Char device fops */

static int fw_mgmt_open(struct inode *inode, struct file *file)
{
	struct fw_mgmt *fw_mgmt = get_fw_mgmt(inode->i_cdev);

	/* fw_mgmt structure can't get freed until file descriptor is closed */
	if (fw_mgmt) {
		file->private_data = fw_mgmt;
		return 0;
	}

	return -ENODEV;
}

static int fw_mgmt_release(struct inode *inode, struct file *file)
{
	struct fw_mgmt *fw_mgmt = file->private_data;

	put_fw_mgmt(fw_mgmt);
	return 0;
}

static int fw_mgmt_ioctl(struct fw_mgmt *fw_mgmt, unsigned int cmd,
			 void __user *buf)
{
	struct fw_mgmt_ioc_get_intf_version intf_fw_info;
	struct fw_mgmt_ioc_get_backend_version backend_fw_info;
	struct fw_mgmt_ioc_intf_load_and_validate intf_load;
	struct fw_mgmt_ioc_backend_fw_update backend_update;
	unsigned int timeout;
	int ret;

	/* Reject any operations after mode-switch has started */
	if (fw_mgmt->mode_switch_started)
		return -EBUSY;

	switch (cmd) {
	case FW_MGMT_IOC_GET_INTF_FW:
		ret = fw_mgmt_interface_fw_version_operation(fw_mgmt,
							     &intf_fw_info);
		if (ret)
			return ret;

		if (copy_to_user(buf, &intf_fw_info, sizeof(intf_fw_info)))
			return -EFAULT;

		return 0;
	case FW_MGMT_IOC_GET_BACKEND_FW:
		if (copy_from_user(&backend_fw_info, buf,
				   sizeof(backend_fw_info)))
			return -EFAULT;

		ret = fw_mgmt_backend_fw_version_operation(fw_mgmt,
							   &backend_fw_info);
		if (ret)
			return ret;

		if (copy_to_user(buf, &backend_fw_info,
				 sizeof(backend_fw_info)))
			return -EFAULT;

		return 0;
	case FW_MGMT_IOC_INTF_LOAD_AND_VALIDATE:
		if (copy_from_user(&intf_load, buf, sizeof(intf_load)))
			return -EFAULT;

		ret = fw_mgmt_load_and_validate_operation(fw_mgmt,
				intf_load.load_method, intf_load.firmware_tag);
		if (ret)
			return ret;

		if (!wait_for_completion_timeout(&fw_mgmt->completion,
						 fw_mgmt->timeout_jiffies)) {
			dev_err(fw_mgmt->parent, "timed out waiting for firmware load and validation to finish\n");
			return -ETIMEDOUT;
		}

		intf_load.status = fw_mgmt->intf_fw_status;
		intf_load.major = fw_mgmt->intf_fw_major;
		intf_load.minor = fw_mgmt->intf_fw_minor;

		if (copy_to_user(buf, &intf_load, sizeof(intf_load)))
			return -EFAULT;

		return 0;
	case FW_MGMT_IOC_INTF_BACKEND_FW_UPDATE:
		if (copy_from_user(&backend_update, buf,
				   sizeof(backend_update)))
			return -EFAULT;

		ret = fw_mgmt_backend_fw_update_operation(fw_mgmt,
							  backend_update.firmware_tag);
		if (ret)
			return ret;

		if (!wait_for_completion_timeout(&fw_mgmt->completion,
						 fw_mgmt->timeout_jiffies)) {
			dev_err(fw_mgmt->parent, "timed out waiting for backend firmware update to finish\n");
			return -ETIMEDOUT;
		}

		backend_update.status = fw_mgmt->backend_fw_status;

		if (copy_to_user(buf, &backend_update, sizeof(backend_update)))
			return -EFAULT;

		return 0;
	case FW_MGMT_IOC_SET_TIMEOUT_MS:
		if (get_user(timeout, (unsigned int __user *)buf))
			return -EFAULT;

		if (!timeout) {
			dev_err(fw_mgmt->parent, "timeout can't be zero\n");
			return -EINVAL;
		}

		fw_mgmt->timeout_jiffies = msecs_to_jiffies(timeout);

		return 0;
	case FW_MGMT_IOC_MODE_SWITCH:
		if (!fw_mgmt->intf_fw_loaded) {
			dev_err(fw_mgmt->parent,
				"Firmware not loaded for mode-switch\n");
			return -EPERM;
		}

		/*
		 * Disallow new ioctls as the fw-core bundle driver is going to
		 * get disconnected soon and the character device will get
		 * removed.
		 */
		fw_mgmt->mode_switch_started = true;

		ret = gb_interface_request_mode_switch(fw_mgmt->connection->intf);
		if (ret) {
			dev_err(fw_mgmt->parent, "Mode-switch failed: %d\n",
				ret);
			fw_mgmt->mode_switch_started = false;
			return ret;
		}

		return 0;
	default:
		return -ENOTTY;
	}
}

static long fw_mgmt_ioctl_unlocked(struct file *file, unsigned int cmd,
				   unsigned long arg)
{
	struct fw_mgmt *fw_mgmt = file->private_data;
	struct gb_bundle *bundle = fw_mgmt->connection->bundle;
	int ret = -ENODEV;

	/*
	 * Serialize ioctls.
	 *
	 * We don't want the user to do few operations in parallel. For example,
	 * updating Interface firmware in parallel for the same Interface. There
	 * is no need to do things in parallel for speed and we can avoid having
	 * complicated code for now.
	 *
	 * This is also used to protect ->disabled, which is used to check if
	 * the connection is getting disconnected, so that we don't start any
	 * new operations.
	 */
	mutex_lock(&fw_mgmt->mutex);
	if (!fw_mgmt->disabled) {
		ret = gb_pm_runtime_get_sync(bundle);
		if (!ret) {
			ret = fw_mgmt_ioctl(fw_mgmt, cmd, (void __user *)arg);
			gb_pm_runtime_put_autosuspend(bundle);
		}
	}
	mutex_unlock(&fw_mgmt->mutex);

	return ret;
}

static const struct file_operations fw_mgmt_fops = {
	.owner		= THIS_MODULE,
	.open		= fw_mgmt_open,
	.release	= fw_mgmt_release,
	.unlocked_ioctl	= fw_mgmt_ioctl_unlocked,
};

int gb_fw_mgmt_request_handler(struct gb_operation *op)
{
	u8 type = op->type;

	switch (type) {
	case GB_FW_MGMT_TYPE_LOADED_FW:
		return fw_mgmt_interface_fw_loaded_operation(op);
	case GB_FW_MGMT_TYPE_BACKEND_FW_UPDATED:
		return fw_mgmt_backend_fw_updated_operation(op);
	default:
		dev_err(&op->connection->bundle->dev,
			"unsupported request: %u\n", type);
		return -EINVAL;
	}
}

int gb_fw_mgmt_connection_init(struct gb_connection *connection)
{
	struct fw_mgmt *fw_mgmt;
	int ret, minor;

	if (!connection)
		return 0;

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

	fw_mgmt->parent = &connection->bundle->dev;
	fw_mgmt->timeout_jiffies = msecs_to_jiffies(FW_MGMT_TIMEOUT_MS);
	fw_mgmt->connection = connection;

	gb_connection_set_data(connection, fw_mgmt);
	init_completion(&fw_mgmt->completion);
	ida_init(&fw_mgmt->id_map);
	mutex_init(&fw_mgmt->mutex);
	kref_init(&fw_mgmt->kref);

	mutex_lock(&list_mutex);
	list_add(&fw_mgmt->node, &fw_mgmt_list);
	mutex_unlock(&list_mutex);

	ret = gb_connection_enable(connection);
	if (ret)
		goto err_list_del;

	minor = ida_alloc_max(&fw_mgmt_minors_map, NUM_MINORS - 1, GFP_KERNEL);
	if (minor < 0) {
		ret = minor;
		goto err_connection_disable;
	}

	/* Add a char device to allow userspace to interact with fw-mgmt */
	fw_mgmt->dev_num = MKDEV(MAJOR(fw_mgmt_dev_num), minor);
	cdev_init(&fw_mgmt->cdev, &fw_mgmt_fops);

	ret = cdev_add(&fw_mgmt->cdev, fw_mgmt->dev_num, 1);
	if (ret)
		goto err_remove_ida;

	/* Add a soft link to the previously added char-dev within the bundle */
	fw_mgmt->class_device = device_create(&fw_mgmt_class, fw_mgmt->parent,
					      fw_mgmt->dev_num, NULL,
					      "gb-fw-mgmt-%d", minor);
	if (IS_ERR(fw_mgmt->class_device)) {
		ret = PTR_ERR(fw_mgmt->class_device);
		goto err_del_cdev;
	}

	return 0;

err_del_cdev:
	cdev_del(&fw_mgmt->cdev);
err_remove_ida:
	ida_free(&fw_mgmt_minors_map, minor);
err_connection_disable:
	gb_connection_disable(connection);
err_list_del:
	mutex_lock(&list_mutex);
	list_del(&fw_mgmt->node);
	mutex_unlock(&list_mutex);

	put_fw_mgmt(fw_mgmt);

	return ret;
}

void gb_fw_mgmt_connection_exit(struct gb_connection *connection)
{
	struct fw_mgmt *fw_mgmt;

	if (!connection)
		return;

	fw_mgmt = gb_connection_get_data(connection);

	device_destroy(&fw_mgmt_class, fw_mgmt->dev_num);
	cdev_del(&fw_mgmt->cdev);
	ida_free(&fw_mgmt_minors_map, MINOR(fw_mgmt->dev_num));

	/*
	 * Disallow any new ioctl operations on the char device and wait for
	 * existing ones to finish.
	 */
	mutex_lock(&fw_mgmt->mutex);
	fw_mgmt->disabled = true;
	mutex_unlock(&fw_mgmt->mutex);

	/* All pending greybus operations should have finished by now */
	gb_connection_disable(fw_mgmt->connection);

	/* Disallow new users to get access to the fw_mgmt structure */
	mutex_lock(&list_mutex);
	list_del(&fw_mgmt->node);
	mutex_unlock(&list_mutex);

	/*
	 * All current users of fw_mgmt would have taken a reference to it by
	 * now, we can drop our reference and wait the last user will get
	 * fw_mgmt freed.
	 */
	put_fw_mgmt(fw_mgmt);
}

int fw_mgmt_init(void)
{
	int ret;

	ret = class_register(&fw_mgmt_class);
	if (ret)
		return ret;

	ret = alloc_chrdev_region(&fw_mgmt_dev_num, 0, NUM_MINORS,
				  "gb_fw_mgmt");
	if (ret)
		goto err_remove_class;

	return 0;

err_remove_class:
	class_unregister(&fw_mgmt_class);
	return ret;
}

void fw_mgmt_exit(void)
{
	unregister_chrdev_region(fw_mgmt_dev_num, NUM_MINORS);
	class_unregister(&fw_mgmt_class);
	ida_destroy(&fw_mgmt_minors_map);
}
