// SPDX-License-Identifier: GPL-2.0
/*
 * BOOTROM Greybus driver.
 *
 * Copyright 2016 Google Inc.
 * Copyright 2016 Linaro Ltd.
 */

#include <linux/firmware.h>
#include <linux/jiffies.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>
#include <linux/greybus.h>

#include "firmware.h"

/* Timeout, in jiffies, within which the next request must be received */
#define NEXT_REQ_TIMEOUT_MS	1000

/*
 * FIXME: Reduce this timeout once svc core handles parallel processing of
 * events from the SVC, which are handled sequentially today.
 */
#define MODE_SWITCH_TIMEOUT_MS	10000

enum next_request_type {
	NEXT_REQ_FIRMWARE_SIZE,
	NEXT_REQ_GET_FIRMWARE,
	NEXT_REQ_READY_TO_BOOT,
	NEXT_REQ_MODE_SWITCH,
};

struct gb_bootrom {
	struct gb_connection	*connection;
	const struct firmware	*fw;
	u8			protocol_major;
	u8			protocol_minor;
	enum next_request_type	next_request;
	struct delayed_work	dwork;
	struct mutex		mutex; /* Protects bootrom->fw */
};

static void free_firmware(struct gb_bootrom *bootrom)
{
	if (!bootrom->fw)
		return;

	release_firmware(bootrom->fw);
	bootrom->fw = NULL;
}

static void gb_bootrom_timedout(struct work_struct *work)
{
	struct delayed_work *dwork = to_delayed_work(work);
	struct gb_bootrom *bootrom = container_of(dwork,
						  struct gb_bootrom, dwork);
	struct device *dev = &bootrom->connection->bundle->dev;
	const char *reason;

	switch (bootrom->next_request) {
	case NEXT_REQ_FIRMWARE_SIZE:
		reason = "Firmware Size Request";
		break;
	case NEXT_REQ_GET_FIRMWARE:
		reason = "Get Firmware Request";
		break;
	case NEXT_REQ_READY_TO_BOOT:
		reason = "Ready to Boot Request";
		break;
	case NEXT_REQ_MODE_SWITCH:
		reason = "Interface Mode Switch";
		break;
	default:
		reason = NULL;
		dev_err(dev, "Invalid next-request: %u", bootrom->next_request);
		break;
	}

	dev_err(dev, "Timed out waiting for %s from the Module\n", reason);

	mutex_lock(&bootrom->mutex);
	free_firmware(bootrom);
	mutex_unlock(&bootrom->mutex);

	/* TODO: Power-off Module ? */
}

static void gb_bootrom_set_timeout(struct gb_bootrom *bootrom,
				   enum next_request_type next,
				   unsigned long timeout)
{
	bootrom->next_request = next;
	schedule_delayed_work(&bootrom->dwork, msecs_to_jiffies(timeout));
}

static void gb_bootrom_cancel_timeout(struct gb_bootrom *bootrom)
{
	cancel_delayed_work_sync(&bootrom->dwork);
}

/*
 * The es2 chip doesn't have VID/PID programmed into the hardware and we need to
 * hack that up to distinguish different modules and their firmware blobs.
 *
 * This fetches VID/PID (over bootrom protocol) for es2 chip only, when VID/PID
 * already sent during hotplug are 0.
 *
 * Otherwise, we keep intf->vendor_id/product_id same as what's passed
 * during hotplug.
 */
static void bootrom_es2_fixup_vid_pid(struct gb_bootrom *bootrom)
{
	struct gb_bootrom_get_vid_pid_response response;
	struct gb_connection *connection = bootrom->connection;
	struct gb_interface *intf = connection->bundle->intf;
	int ret;

	if (!(intf->quirks & GB_INTERFACE_QUIRK_NO_GMP_IDS))
		return;

	ret = gb_operation_sync(connection, GB_BOOTROM_TYPE_GET_VID_PID,
				NULL, 0, &response, sizeof(response));
	if (ret) {
		dev_err(&connection->bundle->dev,
			"Bootrom get vid/pid operation failed (%d)\n", ret);
		return;
	}

	/*
	 * NOTE: This is hacked, so that the same values of VID/PID can be used
	 * by next firmware level as well. The uevent for bootrom will still
	 * have VID/PID as 0, though after this point the sysfs files will start
	 * showing the updated values. But yeah, that's a bit racy as the same
	 * sysfs files would be showing 0 before this point.
	 */
	intf->vendor_id = le32_to_cpu(response.vendor_id);
	intf->product_id = le32_to_cpu(response.product_id);

	dev_dbg(&connection->bundle->dev, "Bootrom got vid (0x%x)/pid (0x%x)\n",
		intf->vendor_id, intf->product_id);
}

/* This returns path of the firmware blob on the disk */
static int find_firmware(struct gb_bootrom *bootrom, u8 stage)
{
	struct gb_connection *connection = bootrom->connection;
	struct gb_interface *intf = connection->bundle->intf;
	char firmware_name[49];
	int rc;

	/* Already have a firmware, free it */
	free_firmware(bootrom);

	/* Bootrom protocol is only supported for loading Stage 2 firmware */
	if (stage != 2) {
		dev_err(&connection->bundle->dev, "Invalid boot stage: %u\n",
			stage);
		return -EINVAL;
	}

	/*
	 * Create firmware name
	 *
	 * XXX Name it properly..
	 */
	snprintf(firmware_name, sizeof(firmware_name),
		 FW_NAME_PREFIX "%08x_%08x_%08x_%08x_s2l.tftf",
		 intf->ddbl1_manufacturer_id, intf->ddbl1_product_id,
		 intf->vendor_id, intf->product_id);

	// FIXME:
	// Turn to dev_dbg later after everyone has valid bootloaders with good
	// ids, but leave this as dev_info for now to make it easier to track
	// down "empty" vid/pid modules.
	dev_info(&connection->bundle->dev, "Firmware file '%s' requested\n",
		 firmware_name);

	rc = request_firmware(&bootrom->fw, firmware_name,
			      &connection->bundle->dev);
	if (rc) {
		dev_err(&connection->bundle->dev,
			"failed to find %s firmware (%d)\n", firmware_name, rc);
	}

	return rc;
}

static int gb_bootrom_firmware_size_request(struct gb_operation *op)
{
	struct gb_bootrom *bootrom = gb_connection_get_data(op->connection);
	struct gb_bootrom_firmware_size_request *size_request =
		op->request->payload;
	struct gb_bootrom_firmware_size_response *size_response;
	struct device *dev = &op->connection->bundle->dev;
	int ret;

	/* Disable timeouts */
	gb_bootrom_cancel_timeout(bootrom);

	if (op->request->payload_size != sizeof(*size_request)) {
		dev_err(dev, "%s: illegal size of firmware size request (%zu != %zu)\n",
			__func__, op->request->payload_size,
			sizeof(*size_request));
		ret = -EINVAL;
		goto queue_work;
	}

	mutex_lock(&bootrom->mutex);

	ret = find_firmware(bootrom, size_request->stage);
	if (ret)
		goto unlock;

	if (!gb_operation_response_alloc(op, sizeof(*size_response),
					 GFP_KERNEL)) {
		dev_err(dev, "%s: error allocating response\n", __func__);
		free_firmware(bootrom);
		ret = -ENOMEM;
		goto unlock;
	}

	size_response = op->response->payload;
	size_response->size = cpu_to_le32(bootrom->fw->size);

	dev_dbg(dev, "%s: firmware size %d bytes\n",
		__func__, size_response->size);

unlock:
	mutex_unlock(&bootrom->mutex);

queue_work:
	if (!ret) {
		/* Refresh timeout */
		gb_bootrom_set_timeout(bootrom, NEXT_REQ_GET_FIRMWARE,
				       NEXT_REQ_TIMEOUT_MS);
	}

	return ret;
}

static int gb_bootrom_get_firmware(struct gb_operation *op)
{
	struct gb_bootrom *bootrom = gb_connection_get_data(op->connection);
	const struct firmware *fw;
	struct gb_bootrom_get_firmware_request *firmware_request;
	struct device *dev = &op->connection->bundle->dev;
	unsigned int offset, size;
	enum next_request_type next_request;
	u8 *firmware_response;
	int ret = 0;

	/* Disable timeouts */
	gb_bootrom_cancel_timeout(bootrom);

	if (op->request->payload_size != sizeof(*firmware_request)) {
		dev_err(dev, "%s: Illegal size of get firmware request (%zu %zu)\n",
			__func__, op->request->payload_size,
			sizeof(*firmware_request));
		ret = -EINVAL;
		goto queue_work;
	}

	mutex_lock(&bootrom->mutex);

	fw = bootrom->fw;
	if (!fw) {
		dev_err(dev, "%s: firmware not available\n", __func__);
		ret = -EINVAL;
		goto unlock;
	}

	firmware_request = op->request->payload;
	offset = le32_to_cpu(firmware_request->offset);
	size = le32_to_cpu(firmware_request->size);

	if (offset >= fw->size || size > fw->size - offset) {
		dev_warn(dev, "bad firmware request (offs = %u, size = %u)\n",
			 offset, size);
		ret = -EINVAL;
		goto unlock;
	}

	/* gb_bootrom_get_firmware_response contains only a byte array */
	if (!gb_operation_response_alloc(op, size, GFP_KERNEL)) {
		dev_err(dev, "%s: error allocating response\n", __func__);
		ret = -ENOMEM;
		goto unlock;
	}

	firmware_response = op->response->payload;
	memcpy(firmware_response, fw->data + offset, size);

	dev_dbg(dev, "responding with firmware (offs = %u, size = %u)\n",
		offset, size);

unlock:
	mutex_unlock(&bootrom->mutex);

queue_work:
	/* Refresh timeout */
	if (!ret && (offset + size == fw->size))
		next_request = NEXT_REQ_READY_TO_BOOT;
	else
		next_request = NEXT_REQ_GET_FIRMWARE;

	gb_bootrom_set_timeout(bootrom, next_request, NEXT_REQ_TIMEOUT_MS);

	return ret;
}

static int gb_bootrom_ready_to_boot(struct gb_operation *op)
{
	struct gb_connection *connection = op->connection;
	struct gb_bootrom *bootrom = gb_connection_get_data(connection);
	struct gb_bootrom_ready_to_boot_request *rtb_request;
	struct device *dev = &connection->bundle->dev;
	u8 status;
	int ret = 0;

	/* Disable timeouts */
	gb_bootrom_cancel_timeout(bootrom);

	if (op->request->payload_size != sizeof(*rtb_request)) {
		dev_err(dev, "%s: Illegal size of ready to boot request (%zu %zu)\n",
			__func__, op->request->payload_size,
			sizeof(*rtb_request));
		ret = -EINVAL;
		goto queue_work;
	}

	rtb_request = op->request->payload;
	status = rtb_request->status;

	/* Return error if the blob was invalid */
	if (status == GB_BOOTROM_BOOT_STATUS_INVALID) {
		ret = -EINVAL;
		goto queue_work;
	}

	/*
	 * XXX Should we return error for insecure firmware?
	 */
	dev_dbg(dev, "ready to boot: 0x%x, 0\n", status);

queue_work:
	/*
	 * Refresh timeout, the Interface shall load the new personality and
	 * send a new hotplug request, which shall get rid of the bootrom
	 * connection. As that can take some time, increase the timeout a bit.
	 */
	gb_bootrom_set_timeout(bootrom, NEXT_REQ_MODE_SWITCH,
			       MODE_SWITCH_TIMEOUT_MS);

	return ret;
}

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

	switch (type) {
	case GB_BOOTROM_TYPE_FIRMWARE_SIZE:
		return gb_bootrom_firmware_size_request(op);
	case GB_BOOTROM_TYPE_GET_FIRMWARE:
		return gb_bootrom_get_firmware(op);
	case GB_BOOTROM_TYPE_READY_TO_BOOT:
		return gb_bootrom_ready_to_boot(op);
	default:
		dev_err(&op->connection->bundle->dev,
			"unsupported request: %u\n", type);
		return -EINVAL;
	}
}

static int gb_bootrom_get_version(struct gb_bootrom *bootrom)
{
	struct gb_bundle *bundle = bootrom->connection->bundle;
	struct gb_bootrom_version_request request;
	struct gb_bootrom_version_response response;
	int ret;

	request.major = GB_BOOTROM_VERSION_MAJOR;
	request.minor = GB_BOOTROM_VERSION_MINOR;

	ret = gb_operation_sync(bootrom->connection,
				GB_BOOTROM_TYPE_VERSION,
				&request, sizeof(request), &response,
				sizeof(response));
	if (ret) {
		dev_err(&bundle->dev,
			"failed to get protocol version: %d\n",
			ret);
		return ret;
	}

	if (response.major > request.major) {
		dev_err(&bundle->dev,
			"unsupported major protocol version (%u > %u)\n",
			response.major, request.major);
		return -ENOTSUPP;
	}

	bootrom->protocol_major = response.major;
	bootrom->protocol_minor = response.minor;

	dev_dbg(&bundle->dev, "%s - %u.%u\n", __func__, response.major,
		response.minor);

	return 0;
}

static int gb_bootrom_probe(struct gb_bundle *bundle,
			    const struct greybus_bundle_id *id)
{
	struct greybus_descriptor_cport *cport_desc;
	struct gb_connection *connection;
	struct gb_bootrom *bootrom;
	int ret;

	if (bundle->num_cports != 1)
		return -ENODEV;

	cport_desc = &bundle->cport_desc[0];
	if (cport_desc->protocol_id != GREYBUS_PROTOCOL_BOOTROM)
		return -ENODEV;

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

	connection = gb_connection_create(bundle,
					  le16_to_cpu(cport_desc->id),
					  gb_bootrom_request_handler);
	if (IS_ERR(connection)) {
		ret = PTR_ERR(connection);
		goto err_free_bootrom;
	}

	gb_connection_set_data(connection, bootrom);

	bootrom->connection = connection;

	mutex_init(&bootrom->mutex);
	INIT_DELAYED_WORK(&bootrom->dwork, gb_bootrom_timedout);
	greybus_set_drvdata(bundle, bootrom);

	ret = gb_connection_enable_tx(connection);
	if (ret)
		goto err_connection_destroy;

	ret = gb_bootrom_get_version(bootrom);
	if (ret)
		goto err_connection_disable;

	bootrom_es2_fixup_vid_pid(bootrom);

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

	/* Refresh timeout */
	gb_bootrom_set_timeout(bootrom, NEXT_REQ_FIRMWARE_SIZE,
			       NEXT_REQ_TIMEOUT_MS);

	/* Tell bootrom we're ready. */
	ret = gb_operation_sync(connection, GB_BOOTROM_TYPE_AP_READY, NULL, 0,
				NULL, 0);
	if (ret) {
		dev_err(&connection->bundle->dev,
			"failed to send AP READY: %d\n", ret);
		goto err_cancel_timeout;
	}

	dev_dbg(&bundle->dev, "AP_READY sent\n");

	return 0;

err_cancel_timeout:
	gb_bootrom_cancel_timeout(bootrom);
err_connection_disable:
	gb_connection_disable(connection);
err_connection_destroy:
	gb_connection_destroy(connection);
err_free_bootrom:
	kfree(bootrom);

	return ret;
}

static void gb_bootrom_disconnect(struct gb_bundle *bundle)
{
	struct gb_bootrom *bootrom = greybus_get_drvdata(bundle);

	gb_connection_disable(bootrom->connection);

	/* Disable timeouts */
	gb_bootrom_cancel_timeout(bootrom);

	/*
	 * Release firmware:
	 *
	 * As the connection and the delayed work are already disabled, we don't
	 * need to lock access to bootrom->fw here.
	 */
	free_firmware(bootrom);

	gb_connection_destroy(bootrom->connection);
	kfree(bootrom);
}

static const struct greybus_bundle_id gb_bootrom_id_table[] = {
	{ GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_BOOTROM) },
	{ }
};

static struct greybus_driver gb_bootrom_driver = {
	.name		= "bootrom",
	.probe		= gb_bootrom_probe,
	.disconnect	= gb_bootrom_disconnect,
	.id_table	= gb_bootrom_id_table,
};

module_greybus_driver(gb_bootrom_driver);

MODULE_LICENSE("GPL v2");
