// SPDX-License-Identifier: GPL-2.0
/*
 * Greybus manifest parsing
 *
 * Copyright 2014-2015 Google Inc.
 * Copyright 2014-2015 Linaro Ltd.
 */

#include "greybus.h"

static const char *get_descriptor_type_string(u8 type)
{
	switch (type) {
	case GREYBUS_TYPE_INVALID:
		return "invalid";
	case GREYBUS_TYPE_STRING:
		return "string";
	case GREYBUS_TYPE_INTERFACE:
		return "interface";
	case GREYBUS_TYPE_CPORT:
		return "cport";
	case GREYBUS_TYPE_BUNDLE:
		return "bundle";
	default:
		WARN_ON(1);
		return "unknown";
	}
}

/*
 * We scan the manifest once to identify where all the descriptors
 * are.  The result is a list of these manifest_desc structures.  We
 * then pick through them for what we're looking for (starting with
 * the interface descriptor).  As each is processed we remove it from
 * the list.  When we're done the list should (probably) be empty.
 */
struct manifest_desc {
	struct list_head		links;

	size_t				size;
	void				*data;
	enum greybus_descriptor_type	type;
};

static void release_manifest_descriptor(struct manifest_desc *descriptor)
{
	list_del(&descriptor->links);
	kfree(descriptor);
}

static void release_manifest_descriptors(struct gb_interface *intf)
{
	struct manifest_desc *descriptor;
	struct manifest_desc *next;

	list_for_each_entry_safe(descriptor, next, &intf->manifest_descs, links)
		release_manifest_descriptor(descriptor);
}

static void release_cport_descriptors(struct list_head *head, u8 bundle_id)
{
	struct manifest_desc *desc, *tmp;
	struct greybus_descriptor_cport *desc_cport;

	list_for_each_entry_safe(desc, tmp, head, links) {
		desc_cport = desc->data;

		if (desc->type != GREYBUS_TYPE_CPORT)
			continue;

		if (desc_cport->bundle == bundle_id)
			release_manifest_descriptor(desc);
	}
}

static struct manifest_desc *get_next_bundle_desc(struct gb_interface *intf)
{
	struct manifest_desc *descriptor;
	struct manifest_desc *next;

	list_for_each_entry_safe(descriptor, next, &intf->manifest_descs, links)
		if (descriptor->type == GREYBUS_TYPE_BUNDLE)
			return descriptor;

	return NULL;
}

/*
 * Validate the given descriptor.  Its reported size must fit within
 * the number of bytes remaining, and it must have a recognized
 * type.  Check that the reported size is at least as big as what
 * we expect to see.  (It could be bigger, perhaps for a new version
 * of the format.)
 *
 * Returns the (non-zero) number of bytes consumed by the descriptor,
 * or a negative errno.
 */
static int identify_descriptor(struct gb_interface *intf,
			       struct greybus_descriptor *desc, size_t size)
{
	struct greybus_descriptor_header *desc_header = &desc->header;
	struct manifest_desc *descriptor;
	size_t desc_size;
	size_t expected_size;

	if (size < sizeof(*desc_header)) {
		dev_err(&intf->dev, "manifest too small (%zu < %zu)\n",
				size, sizeof(*desc_header));
		return -EINVAL;		/* Must at least have header */
	}

	desc_size = le16_to_cpu(desc_header->size);
	if (desc_size > size) {
		dev_err(&intf->dev, "descriptor too big (%zu > %zu)\n",
				desc_size, size);
		return -EINVAL;
	}

	/* Descriptor needs to at least have a header */
	expected_size = sizeof(*desc_header);

	switch (desc_header->type) {
	case GREYBUS_TYPE_STRING:
		expected_size += sizeof(struct greybus_descriptor_string);
		expected_size += desc->string.length;

		/* String descriptors are padded to 4 byte boundaries */
		expected_size = ALIGN(expected_size, 4);
		break;
	case GREYBUS_TYPE_INTERFACE:
		expected_size += sizeof(struct greybus_descriptor_interface);
		break;
	case GREYBUS_TYPE_BUNDLE:
		expected_size += sizeof(struct greybus_descriptor_bundle);
		break;
	case GREYBUS_TYPE_CPORT:
		expected_size += sizeof(struct greybus_descriptor_cport);
		break;
	case GREYBUS_TYPE_INVALID:
	default:
		dev_err(&intf->dev, "invalid descriptor type (%u)\n",
				desc_header->type);
		return -EINVAL;
	}

	if (desc_size < expected_size) {
		dev_err(&intf->dev, "%s descriptor too small (%zu < %zu)\n",
				get_descriptor_type_string(desc_header->type),
				desc_size, expected_size);
		return -EINVAL;
	}

	/* Descriptor bigger than what we expect */
	if (desc_size > expected_size) {
		dev_warn(&intf->dev, "%s descriptor size mismatch (want %zu got %zu)\n",
				get_descriptor_type_string(desc_header->type),
				expected_size, desc_size);
	}

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

	descriptor->size = desc_size;
	descriptor->data = (char *)desc + sizeof(*desc_header);
	descriptor->type = desc_header->type;
	list_add_tail(&descriptor->links, &intf->manifest_descs);

	/* desc_size is positive and is known to fit in a signed int */

	return desc_size;
}

/*
 * Find the string descriptor having the given id, validate it, and
 * allocate a duplicate copy of it.  The duplicate has an extra byte
 * which guarantees the returned string is NUL-terminated.
 *
 * String index 0 is valid (it represents "no string"), and for
 * that a null pointer is returned.
 *
 * Otherwise returns a pointer to a newly-allocated copy of the
 * descriptor string, or an error-coded pointer on failure.
 */
static char *gb_string_get(struct gb_interface *intf, u8 string_id)
{
	struct greybus_descriptor_string *desc_string;
	struct manifest_desc *descriptor;
	bool found = false;
	char *string;

	/* A zero string id means no string (but no error) */
	if (!string_id)
		return NULL;

	list_for_each_entry(descriptor, &intf->manifest_descs, links) {
		if (descriptor->type != GREYBUS_TYPE_STRING)
			continue;

		desc_string = descriptor->data;
		if (desc_string->id == string_id) {
			found = true;
			break;
		}
	}
	if (!found)
		return ERR_PTR(-ENOENT);

	/* Allocate an extra byte so we can guarantee it's NUL-terminated */
	string = kmemdup(&desc_string->string, desc_string->length + 1,
				GFP_KERNEL);
	if (!string)
		return ERR_PTR(-ENOMEM);
	string[desc_string->length] = '\0';

	/* Ok we've used this string, so we're done with it */
	release_manifest_descriptor(descriptor);

	return string;
}

/*
 * Find cport descriptors in the manifest associated with the given
 * bundle, and set up data structures for the functions that use
 * them.  Returns the number of cports set up for the bundle, or 0
 * if there is an error.
 */
static u32 gb_manifest_parse_cports(struct gb_bundle *bundle)
{
	struct gb_interface *intf = bundle->intf;
	struct greybus_descriptor_cport *desc_cport;
	struct manifest_desc *desc, *next, *tmp;
	LIST_HEAD(list);
	u8 bundle_id = bundle->id;
	u16 cport_id;
	u32 count = 0;
	int i;

	/* Set up all cport descriptors associated with this bundle */
	list_for_each_entry_safe(desc, next, &intf->manifest_descs, links) {
		if (desc->type != GREYBUS_TYPE_CPORT)
			continue;

		desc_cport = desc->data;
		if (desc_cport->bundle != bundle_id)
			continue;

		cport_id = le16_to_cpu(desc_cport->id);
		if (cport_id > CPORT_ID_MAX)
			goto exit;

		/* Nothing else should have its cport_id as control cport id */
		if (cport_id == GB_CONTROL_CPORT_ID) {
			dev_err(&bundle->dev, "invalid cport id found (%02u)\n",
				cport_id);
			goto exit;
		}

		/*
		 * Found one, move it to our temporary list after checking for
		 * duplicates.
		 */
		list_for_each_entry(tmp, &list, links) {
			desc_cport = tmp->data;
			if (cport_id == le16_to_cpu(desc_cport->id)) {
				dev_err(&bundle->dev,
						"duplicate CPort %u found\n",
						cport_id);
				goto exit;
			}
		}
		list_move_tail(&desc->links, &list);
		count++;
	}

	if (!count)
		return 0;

	bundle->cport_desc = kcalloc(count, sizeof(*bundle->cport_desc),
					GFP_KERNEL);
	if (!bundle->cport_desc)
		goto exit;

	bundle->num_cports = count;

	i = 0;
	list_for_each_entry_safe(desc, next, &list, links) {
		desc_cport = desc->data;
		memcpy(&bundle->cport_desc[i++], desc_cport,
				sizeof(*desc_cport));

		/* Release the cport descriptor */
		release_manifest_descriptor(desc);
	}

	return count;
exit:
	release_cport_descriptors(&list, bundle_id);
	/*
	 * Free all cports for this bundle to avoid 'excess descriptors'
	 * warnings.
	 */
	release_cport_descriptors(&intf->manifest_descs, bundle_id);

	return 0;	/* Error; count should also be 0 */
}

/*
 * Find bundle descriptors in the manifest and set up their data
 * structures.  Returns the number of bundles set up for the
 * given interface.
 */
static u32 gb_manifest_parse_bundles(struct gb_interface *intf)
{
	struct manifest_desc *desc;
	struct gb_bundle *bundle;
	struct gb_bundle *bundle_next;
	u32 count = 0;
	u8 bundle_id;
	u8 class;

	while ((desc = get_next_bundle_desc(intf))) {
		struct greybus_descriptor_bundle *desc_bundle;

		/* Found one.  Set up its bundle structure*/
		desc_bundle = desc->data;
		bundle_id = desc_bundle->id;
		class = desc_bundle->class;

		/* Done with this bundle descriptor */
		release_manifest_descriptor(desc);

		/* Ignore any legacy control bundles */
		if (bundle_id == GB_CONTROL_BUNDLE_ID) {
			dev_dbg(&intf->dev, "%s - ignoring control bundle\n",
					__func__);
			release_cport_descriptors(&intf->manifest_descs,
								bundle_id);
			continue;
		}

		/* Nothing else should have its class set to control class */
		if (class == GREYBUS_CLASS_CONTROL) {
			dev_err(&intf->dev,
				"bundle %u cannot use control class\n",
				bundle_id);
			goto cleanup;
		}

		bundle = gb_bundle_create(intf, bundle_id, class);
		if (!bundle)
			goto cleanup;

		/*
		 * Now go set up this bundle's functions and cports.
		 *
		 * A 'bundle' represents a device in greybus. It may require
		 * multiple cports for its functioning. If we fail to setup any
		 * cport of a bundle, we better reject the complete bundle as
		 * the device may not be able to function properly then.
		 *
		 * But, failing to setup a cport of bundle X doesn't mean that
		 * the device corresponding to bundle Y will not work properly.
		 * Bundles should be treated as separate independent devices.
		 *
		 * While parsing manifest for an interface, treat bundles as
		 * separate entities and don't reject entire interface and its
		 * bundles on failing to initialize a cport. But make sure the
		 * bundle which needs the cport, gets destroyed properly.
		 */
		if (!gb_manifest_parse_cports(bundle)) {
			gb_bundle_destroy(bundle);
			continue;
		}

		count++;
	}

	return count;
cleanup:
	/* An error occurred; undo any changes we've made */
	list_for_each_entry_safe(bundle, bundle_next, &intf->bundles, links) {
		gb_bundle_destroy(bundle);
		count--;
	}
	return 0;	/* Error; count should also be 0 */
}

static bool gb_manifest_parse_interface(struct gb_interface *intf,
					struct manifest_desc *interface_desc)
{
	struct greybus_descriptor_interface *desc_intf = interface_desc->data;
	struct gb_control *control = intf->control;
	char *str;

	/* Handle the strings first--they can fail */
	str = gb_string_get(intf, desc_intf->vendor_stringid);
	if (IS_ERR(str))
		return false;
	control->vendor_string = str;

	str = gb_string_get(intf, desc_intf->product_stringid);
	if (IS_ERR(str))
		goto out_free_vendor_string;
	control->product_string = str;

	/* Assign feature flags communicated via manifest */
	intf->features = desc_intf->features;

	/* Release the interface descriptor, now that we're done with it */
	release_manifest_descriptor(interface_desc);

	/* An interface must have at least one bundle descriptor */
	if (!gb_manifest_parse_bundles(intf)) {
		dev_err(&intf->dev, "manifest bundle descriptors not valid\n");
		goto out_err;
	}

	return true;
out_err:
	kfree(control->product_string);
	control->product_string = NULL;
out_free_vendor_string:
	kfree(control->vendor_string);
	control->vendor_string = NULL;

	return false;
}

/*
 * Parse a buffer containing an interface manifest.
 *
 * If we find anything wrong with the content/format of the buffer
 * we reject it.
 *
 * The first requirement is that the manifest's version is
 * one we can parse.
 *
 * We make an initial pass through the buffer and identify all of
 * the descriptors it contains, keeping track for each its type
 * and the location size of its data in the buffer.
 *
 * Next we scan the descriptors, looking for an interface descriptor;
 * there must be exactly one of those.  When found, we record the
 * information it contains, and then remove that descriptor (and any
 * string descriptors it refers to) from further consideration.
 *
 * After that we look for the interface's bundles--there must be at
 * least one of those.
 *
 * Returns true if parsing was successful, false otherwise.
 */
bool gb_manifest_parse(struct gb_interface *intf, void *data, size_t size)
{
	struct greybus_manifest *manifest;
	struct greybus_manifest_header *header;
	struct greybus_descriptor *desc;
	struct manifest_desc *descriptor;
	struct manifest_desc *interface_desc = NULL;
	u16 manifest_size;
	u32 found = 0;
	bool result;

	/* Manifest descriptor list should be empty here */
	if (WARN_ON(!list_empty(&intf->manifest_descs)))
		return false;

	/* we have to have at _least_ the manifest header */
	if (size < sizeof(*header)) {
		dev_err(&intf->dev, "short manifest (%zu < %zu)\n",
				size, sizeof(*header));
		return false;
	}

	/* Make sure the size is right */
	manifest = data;
	header = &manifest->header;
	manifest_size = le16_to_cpu(header->size);
	if (manifest_size != size) {
		dev_err(&intf->dev, "manifest size mismatch (%zu != %u)\n",
				size, manifest_size);
		return false;
	}

	/* Validate major/minor number */
	if (header->version_major > GREYBUS_VERSION_MAJOR) {
		dev_err(&intf->dev, "manifest version too new (%u.%u > %u.%u)\n",
				header->version_major, header->version_minor,
				GREYBUS_VERSION_MAJOR, GREYBUS_VERSION_MINOR);
		return false;
	}

	/* OK, find all the descriptors */
	desc = manifest->descriptors;
	size -= sizeof(*header);
	while (size) {
		int desc_size;

		desc_size = identify_descriptor(intf, desc, size);
		if (desc_size < 0) {
			result = false;
			goto out;
		}
		desc = (struct greybus_descriptor *)((char *)desc + desc_size);
		size -= desc_size;
	}

	/* There must be a single interface descriptor */
	list_for_each_entry(descriptor, &intf->manifest_descs, links) {
		if (descriptor->type == GREYBUS_TYPE_INTERFACE)
			if (!found++)
				interface_desc = descriptor;
	}
	if (found != 1) {
		dev_err(&intf->dev, "manifest must have 1 interface descriptor (%u found)\n",
				found);
		result = false;
		goto out;
	}

	/* Parse the manifest, starting with the interface descriptor */
	result = gb_manifest_parse_interface(intf, interface_desc);

	/*
	 * We really should have no remaining descriptors, but we
	 * don't know what newer format manifests might leave.
	 */
	if (result && !list_empty(&intf->manifest_descs))
		dev_info(&intf->dev, "excess descriptors in interface manifest\n");
out:
	release_manifest_descriptors(intf);

	return result;
}
