// SPDX-License-Identifier: GPL-2.0
/*
 * Thunderbolt XDomain property support
 *
 * Copyright (C) 2017, Intel Corporation
 * Authors: Michael Jamet <michael.jamet@intel.com>
 *          Mika Westerberg <mika.westerberg@linux.intel.com>
 */

#include <linux/err.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/uuid.h>
#include <linux/thunderbolt.h>

struct tb_property_entry {
	u32 key_hi;
	u32 key_lo;
	u16 length;
	u8 reserved;
	u8 type;
	u32 value;
};

struct tb_property_rootdir_entry {
	u32 magic;
	u32 length;
	struct tb_property_entry entries[];
};

struct tb_property_dir_entry {
	u32 uuid[4];
	struct tb_property_entry entries[];
};

#define TB_PROPERTY_ROOTDIR_MAGIC	0x55584401

static struct tb_property_dir *__tb_property_parse_dir(const u32 *block,
	size_t block_len, unsigned int dir_offset, size_t dir_len,
	bool is_root);

static inline void parse_dwdata(void *dst, const void *src, size_t dwords)
{
	be32_to_cpu_array(dst, src, dwords);
}

static inline void format_dwdata(void *dst, const void *src, size_t dwords)
{
	cpu_to_be32_array(dst, src, dwords);
}

static bool tb_property_entry_valid(const struct tb_property_entry *entry,
				  size_t block_len)
{
	switch (entry->type) {
	case TB_PROPERTY_TYPE_DIRECTORY:
	case TB_PROPERTY_TYPE_DATA:
	case TB_PROPERTY_TYPE_TEXT:
		if (entry->length > block_len)
			return false;
		if (entry->value + entry->length > block_len)
			return false;
		break;

	case TB_PROPERTY_TYPE_VALUE:
		if (entry->length != 1)
			return false;
		break;
	}

	return true;
}

static bool tb_property_key_valid(const char *key)
{
	return key && strlen(key) <= TB_PROPERTY_KEY_SIZE;
}

static struct tb_property *
tb_property_alloc(const char *key, enum tb_property_type type)
{
	struct tb_property *property;

	property = kzalloc(sizeof(*property), GFP_KERNEL);
	if (!property)
		return NULL;

	strcpy(property->key, key);
	property->type = type;
	INIT_LIST_HEAD(&property->list);

	return property;
}

static struct tb_property *tb_property_parse(const u32 *block, size_t block_len,
					const struct tb_property_entry *entry)
{
	char key[TB_PROPERTY_KEY_SIZE + 1];
	struct tb_property *property;
	struct tb_property_dir *dir;

	if (!tb_property_entry_valid(entry, block_len))
		return NULL;

	parse_dwdata(key, entry, 2);
	key[TB_PROPERTY_KEY_SIZE] = '\0';

	property = tb_property_alloc(key, entry->type);
	if (!property)
		return NULL;

	property->length = entry->length;

	switch (property->type) {
	case TB_PROPERTY_TYPE_DIRECTORY:
		dir = __tb_property_parse_dir(block, block_len, entry->value,
					      entry->length, false);
		if (!dir) {
			kfree(property);
			return NULL;
		}
		property->value.dir = dir;
		break;

	case TB_PROPERTY_TYPE_DATA:
		property->value.data = kcalloc(property->length, sizeof(u32),
					       GFP_KERNEL);
		if (!property->value.data) {
			kfree(property);
			return NULL;
		}
		parse_dwdata(property->value.data, block + entry->value,
			     entry->length);
		break;

	case TB_PROPERTY_TYPE_TEXT:
		property->value.text = kcalloc(property->length, sizeof(u32),
					       GFP_KERNEL);
		if (!property->value.text) {
			kfree(property);
			return NULL;
		}
		parse_dwdata(property->value.text, block + entry->value,
			     entry->length);
		/* Force null termination */
		property->value.text[property->length * 4 - 1] = '\0';
		break;

	case TB_PROPERTY_TYPE_VALUE:
		property->value.immediate = entry->value;
		break;

	default:
		property->type = TB_PROPERTY_TYPE_UNKNOWN;
		break;
	}

	return property;
}

static struct tb_property_dir *__tb_property_parse_dir(const u32 *block,
	size_t block_len, unsigned int dir_offset, size_t dir_len, bool is_root)
{
	const struct tb_property_entry *entries;
	size_t i, content_len, nentries;
	unsigned int content_offset;
	struct tb_property_dir *dir;

	dir = kzalloc(sizeof(*dir), GFP_KERNEL);
	if (!dir)
		return NULL;

	if (is_root) {
		content_offset = dir_offset + 2;
		content_len = dir_len;
	} else {
		dir->uuid = kmemdup(&block[dir_offset], sizeof(*dir->uuid),
				    GFP_KERNEL);
		if (!dir->uuid) {
			tb_property_free_dir(dir);
			return NULL;
		}
		content_offset = dir_offset + 4;
		content_len = dir_len - 4; /* Length includes UUID */
	}

	entries = (const struct tb_property_entry *)&block[content_offset];
	nentries = content_len / (sizeof(*entries) / 4);

	INIT_LIST_HEAD(&dir->properties);

	for (i = 0; i < nentries; i++) {
		struct tb_property *property;

		property = tb_property_parse(block, block_len, &entries[i]);
		if (!property) {
			tb_property_free_dir(dir);
			return NULL;
		}

		list_add_tail(&property->list, &dir->properties);
	}

	return dir;
}

/**
 * tb_property_parse_dir() - Parses properties from given property block
 * @block: Property block to parse
 * @block_len: Number of dword elements in the property block
 *
 * This function parses the XDomain properties data block into format that
 * can be traversed using the helper functions provided by this module.
 *
 * The resulting &struct tb_property_dir needs to be released by
 * calling tb_property_free_dir() when not needed anymore.
 *
 * The @block is expected to be root directory.
 *
 * Return: Pointer to &struct tb_property_dir, %NULL in case of failure.
 */
struct tb_property_dir *tb_property_parse_dir(const u32 *block,
					      size_t block_len)
{
	const struct tb_property_rootdir_entry *rootdir =
		(const struct tb_property_rootdir_entry *)block;

	if (rootdir->magic != TB_PROPERTY_ROOTDIR_MAGIC)
		return NULL;
	if (rootdir->length > block_len)
		return NULL;

	return __tb_property_parse_dir(block, block_len, 0, rootdir->length,
				       true);
}

/**
 * tb_property_create_dir() - Creates new property directory
 * @uuid: UUID used to identify the particular directory
 *
 * Creates new, empty property directory. If @uuid is %NULL then the
 * directory is assumed to be root directory.
 *
 * Return: Pointer to &struct tb_property_dir, %NULL in case of failure.
 */
struct tb_property_dir *tb_property_create_dir(const uuid_t *uuid)
{
	struct tb_property_dir *dir;

	dir = kzalloc(sizeof(*dir), GFP_KERNEL);
	if (!dir)
		return NULL;

	INIT_LIST_HEAD(&dir->properties);
	if (uuid) {
		dir->uuid = kmemdup(uuid, sizeof(*dir->uuid), GFP_KERNEL);
		if (!dir->uuid) {
			kfree(dir);
			return NULL;
		}
	}

	return dir;
}
EXPORT_SYMBOL_GPL(tb_property_create_dir);

static void tb_property_free(struct tb_property *property)
{
	switch (property->type) {
	case TB_PROPERTY_TYPE_DIRECTORY:
		tb_property_free_dir(property->value.dir);
		break;

	case TB_PROPERTY_TYPE_DATA:
		kfree(property->value.data);
		break;

	case TB_PROPERTY_TYPE_TEXT:
		kfree(property->value.text);
		break;

	default:
		break;
	}

	kfree(property);
}

/**
 * tb_property_free_dir() - Release memory allocated for property directory
 * @dir: Directory to release
 *
 * This will release all the memory the directory occupies including all
 * descendants. It is OK to pass %NULL @dir, then the function does
 * nothing.
 */
void tb_property_free_dir(struct tb_property_dir *dir)
{
	struct tb_property *property, *tmp;

	if (!dir)
		return;

	list_for_each_entry_safe(property, tmp, &dir->properties, list) {
		list_del(&property->list);
		tb_property_free(property);
	}
	kfree(dir->uuid);
	kfree(dir);
}
EXPORT_SYMBOL_GPL(tb_property_free_dir);

static size_t tb_property_dir_length(const struct tb_property_dir *dir,
				     bool recurse, size_t *data_len)
{
	const struct tb_property *property;
	size_t len = 0;

	if (dir->uuid)
		len += sizeof(*dir->uuid) / 4;
	else
		len += sizeof(struct tb_property_rootdir_entry) / 4;

	list_for_each_entry(property, &dir->properties, list) {
		len += sizeof(struct tb_property_entry) / 4;

		switch (property->type) {
		case TB_PROPERTY_TYPE_DIRECTORY:
			if (recurse) {
				len += tb_property_dir_length(
					property->value.dir, recurse, data_len);
			}
			/* Reserve dword padding after each directory */
			if (data_len)
				*data_len += 1;
			break;

		case TB_PROPERTY_TYPE_DATA:
		case TB_PROPERTY_TYPE_TEXT:
			if (data_len)
				*data_len += property->length;
			break;

		default:
			break;
		}
	}

	return len;
}

static ssize_t __tb_property_format_dir(const struct tb_property_dir *dir,
	u32 *block, unsigned int start_offset, size_t block_len)
{
	unsigned int data_offset, dir_end;
	const struct tb_property *property;
	struct tb_property_entry *entry;
	size_t dir_len, data_len = 0;
	int ret;

	/*
	 * The structure of property block looks like following. Leaf
	 * data/text is included right after the directory and each
	 * directory follows each other (even nested ones).
	 *
	 * +----------+ <-- start_offset
	 * |  header  | <-- root directory header
	 * +----------+ ---
	 * |  entry 0 | -^--------------------.
	 * +----------+  |                    |
	 * |  entry 1 | -|--------------------|--.
	 * +----------+  |                    |  |
	 * |  entry 2 | -|-----------------.  |  |
	 * +----------+  |                 |  |  |
	 * :          :  |  dir_len        |  |  |
	 * .          .  |                 |  |  |
	 * :          :  |                 |  |  |
	 * +----------+  |                 |  |  |
	 * |  entry n |  v                 |  |  |
	 * +----------+ <-- data_offset    |  |  |
	 * |  data 0  | <------------------|--'  |
	 * +----------+                    |     |
	 * |  data 1  | <------------------|-----'
	 * +----------+                    |
	 * | 00000000 | padding            |
	 * +----------+ <-- dir_end <------'
	 * |   UUID   | <-- directory UUID (child directory)
	 * +----------+
	 * |  entry 0 |
	 * +----------+
	 * |  entry 1 |
	 * +----------+
	 * :          :
	 * .          .
	 * :          :
	 * +----------+
	 * |  entry n |
	 * +----------+
	 * |  data 0  |
	 * +----------+
	 *
	 * We use dir_end to hold pointer to the end of the directory. It
	 * will increase as we add directories and each directory should be
	 * added starting from previous dir_end.
	 */
	dir_len = tb_property_dir_length(dir, false, &data_len);
	data_offset = start_offset + dir_len;
	dir_end = start_offset + data_len + dir_len;

	if (data_offset > dir_end)
		return -EINVAL;
	if (dir_end > block_len)
		return -EINVAL;

	/* Write headers first */
	if (dir->uuid) {
		struct tb_property_dir_entry *pe;

		pe = (struct tb_property_dir_entry *)&block[start_offset];
		memcpy(pe->uuid, dir->uuid, sizeof(pe->uuid));
		entry = pe->entries;
	} else {
		struct tb_property_rootdir_entry *re;

		re = (struct tb_property_rootdir_entry *)&block[start_offset];
		re->magic = TB_PROPERTY_ROOTDIR_MAGIC;
		re->length = dir_len - sizeof(*re) / 4;
		entry = re->entries;
	}

	list_for_each_entry(property, &dir->properties, list) {
		const struct tb_property_dir *child;

		format_dwdata(entry, property->key, 2);
		entry->type = property->type;

		switch (property->type) {
		case TB_PROPERTY_TYPE_DIRECTORY:
			child = property->value.dir;
			ret = __tb_property_format_dir(child, block, dir_end,
						       block_len);
			if (ret < 0)
				return ret;
			entry->length = tb_property_dir_length(child, false,
							       NULL);
			entry->value = dir_end;
			dir_end = ret;
			break;

		case TB_PROPERTY_TYPE_DATA:
			format_dwdata(&block[data_offset], property->value.data,
				      property->length);
			entry->length = property->length;
			entry->value = data_offset;
			data_offset += entry->length;
			break;

		case TB_PROPERTY_TYPE_TEXT:
			format_dwdata(&block[data_offset], property->value.text,
				      property->length);
			entry->length = property->length;
			entry->value = data_offset;
			data_offset += entry->length;
			break;

		case TB_PROPERTY_TYPE_VALUE:
			entry->length = property->length;
			entry->value = property->value.immediate;
			break;

		default:
			break;
		}

		entry++;
	}

	return dir_end;
}

/**
 * tb_property_format_dir() - Formats directory to the packed XDomain format
 * @dir: Directory to format
 * @block: Property block where the packed data is placed
 * @block_len: Length of the property block
 *
 * This function formats the directory to the packed format that can be
 * then sent over the thunderbolt fabric to receiving host.
 *
 * Passing %NULL in @block returns number of entries the block takes.
 *
 * Return: %0 on success, negative errno otherwise.
 */
ssize_t tb_property_format_dir(const struct tb_property_dir *dir, u32 *block,
			       size_t block_len)
{
	ssize_t ret;

	if (!block) {
		size_t dir_len, data_len = 0;

		dir_len = tb_property_dir_length(dir, true, &data_len);
		return dir_len + data_len;
	}

	ret = __tb_property_format_dir(dir, block, 0, block_len);
	return ret < 0 ? ret : 0;
}

/**
 * tb_property_copy_dir() - Take a deep copy of directory
 * @dir: Directory to copy
 *
 * The resulting directory needs to be released by calling tb_property_free_dir().
 *
 * Return: Pointer to &struct tb_property_dir, %NULL in case of failure.
 */
struct tb_property_dir *tb_property_copy_dir(const struct tb_property_dir *dir)
{
	struct tb_property *property, *p = NULL;
	struct tb_property_dir *d;

	if (!dir)
		return NULL;

	d = tb_property_create_dir(dir->uuid);
	if (!d)
		return NULL;

	list_for_each_entry(property, &dir->properties, list) {
		struct tb_property *p;

		p = tb_property_alloc(property->key, property->type);
		if (!p)
			goto err_free;

		p->length = property->length;

		switch (property->type) {
		case TB_PROPERTY_TYPE_DIRECTORY:
			p->value.dir = tb_property_copy_dir(property->value.dir);
			if (!p->value.dir)
				goto err_free;
			break;

		case TB_PROPERTY_TYPE_DATA:
			p->value.data = kmemdup(property->value.data,
						property->length * 4,
						GFP_KERNEL);
			if (!p->value.data)
				goto err_free;
			break;

		case TB_PROPERTY_TYPE_TEXT:
			p->value.text = kzalloc(p->length * 4, GFP_KERNEL);
			if (!p->value.text)
				goto err_free;
			strcpy(p->value.text, property->value.text);
			break;

		case TB_PROPERTY_TYPE_VALUE:
			p->value.immediate = property->value.immediate;
			break;

		default:
			break;
		}

		list_add_tail(&p->list, &d->properties);
	}

	return d;

err_free:
	kfree(p);
	tb_property_free_dir(d);

	return NULL;
}

/**
 * tb_property_add_immediate() - Add immediate property to directory
 * @parent: Directory to add the property
 * @key: Key for the property
 * @value: Immediate value to store with the property
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_property_add_immediate(struct tb_property_dir *parent, const char *key,
			      u32 value)
{
	struct tb_property *property;

	if (!tb_property_key_valid(key))
		return -EINVAL;

	property = tb_property_alloc(key, TB_PROPERTY_TYPE_VALUE);
	if (!property)
		return -ENOMEM;

	property->length = 1;
	property->value.immediate = value;

	list_add_tail(&property->list, &parent->properties);
	return 0;
}
EXPORT_SYMBOL_GPL(tb_property_add_immediate);

/**
 * tb_property_add_data() - Adds arbitrary data property to directory
 * @parent: Directory to add the property
 * @key: Key for the property
 * @buf: Data buffer to add
 * @buflen: Number of bytes in the data buffer
 *
 * Function takes a copy of @buf and adds it to the directory.
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_property_add_data(struct tb_property_dir *parent, const char *key,
			 const void *buf, size_t buflen)
{
	/* Need to pad to dword boundary */
	size_t size = round_up(buflen, 4);
	struct tb_property *property;

	if (!tb_property_key_valid(key))
		return -EINVAL;

	property = tb_property_alloc(key, TB_PROPERTY_TYPE_DATA);
	if (!property)
		return -ENOMEM;

	property->length = size / 4;
	property->value.data = kzalloc(size, GFP_KERNEL);
	if (!property->value.data) {
		kfree(property);
		return -ENOMEM;
	}

	memcpy(property->value.data, buf, buflen);

	list_add_tail(&property->list, &parent->properties);
	return 0;
}
EXPORT_SYMBOL_GPL(tb_property_add_data);

/**
 * tb_property_add_text() - Adds string property to directory
 * @parent: Directory to add the property
 * @key: Key for the property
 * @text: String to add
 *
 * Function takes a copy of @text and adds it to the directory.
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_property_add_text(struct tb_property_dir *parent, const char *key,
			 const char *text)
{
	/* Need to pad to dword boundary */
	size_t size = round_up(strlen(text) + 1, 4);
	struct tb_property *property;

	if (!tb_property_key_valid(key))
		return -EINVAL;

	property = tb_property_alloc(key, TB_PROPERTY_TYPE_TEXT);
	if (!property)
		return -ENOMEM;

	property->length = size / 4;
	property->value.text = kzalloc(size, GFP_KERNEL);
	if (!property->value.text) {
		kfree(property);
		return -ENOMEM;
	}

	strcpy(property->value.text, text);

	list_add_tail(&property->list, &parent->properties);
	return 0;
}
EXPORT_SYMBOL_GPL(tb_property_add_text);

/**
 * tb_property_add_dir() - Adds a directory to the parent directory
 * @parent: Directory to add the property
 * @key: Key for the property
 * @dir: Directory to add
 *
 * Return: %0 on success, negative errno otherwise.
 */
int tb_property_add_dir(struct tb_property_dir *parent, const char *key,
			struct tb_property_dir *dir)
{
	struct tb_property *property;

	if (!tb_property_key_valid(key))
		return -EINVAL;

	property = tb_property_alloc(key, TB_PROPERTY_TYPE_DIRECTORY);
	if (!property)
		return -ENOMEM;

	property->value.dir = dir;

	list_add_tail(&property->list, &parent->properties);
	return 0;
}
EXPORT_SYMBOL_GPL(tb_property_add_dir);

/**
 * tb_property_remove() - Removes property from a parent directory
 * @property: Property to remove
 *
 * Note memory for @property is released as well so it is not allowed to
 * touch the object after call to this function.
 */
void tb_property_remove(struct tb_property *property)
{
	list_del(&property->list);
	kfree(property);
}
EXPORT_SYMBOL_GPL(tb_property_remove);

/**
 * tb_property_find() - Find a property from a directory
 * @dir: Directory where the property is searched
 * @key: Key to look for
 * @type: Type of the property
 *
 * Finds and returns property from the given directory. Does not
 * recurse into sub-directories.
 *
 * Return: Pointer to &struct tb_property, %NULL if the property was not found.
 */
struct tb_property *tb_property_find(struct tb_property_dir *dir,
	const char *key, enum tb_property_type type)
{
	struct tb_property *property;

	list_for_each_entry(property, &dir->properties, list) {
		if (property->type == type && !strcmp(property->key, key))
			return property;
	}

	return NULL;
}
EXPORT_SYMBOL_GPL(tb_property_find);

/**
 * tb_property_get_next() - Get next property from directory
 * @dir: Directory holding properties
 * @prev: Previous property in the directory (%NULL returns the first)
 *
 * Return: Pointer to &struct tb_property, %NULL if property was not found.
 */
struct tb_property *tb_property_get_next(struct tb_property_dir *dir,
					 struct tb_property *prev)
{
	if (prev) {
		if (list_is_last(&prev->list, &dir->properties))
			return NULL;
		return list_next_entry(prev, list);
	}
	return list_first_entry_or_null(&dir->properties, struct tb_property,
					list);
}
EXPORT_SYMBOL_GPL(tb_property_get_next);
