// SPDX-License-Identifier: GPL-2.0
/*
 * Common methods for use with dell-wmi-sysman
 *
 *  Copyright (c) 2020 Dell Inc.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/fs.h>
#include <linux/dmi.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/wmi.h>
#include "dell-wmi-sysman.h"

#define MAX_TYPES  4
#include <linux/nls.h>

static struct class firmware_attributes_class = {
	.name = "firmware-attributes",
};

struct wmi_sysman_priv wmi_priv = {
	.mutex = __MUTEX_INITIALIZER(wmi_priv.mutex),
};

/* reset bios to defaults */
static const char * const reset_types[] = {"builtinsafe", "lastknowngood", "factory", "custom"};
static int reset_option = -1;


/**
 * populate_string_buffer() - populates a string buffer
 * @buffer: the start of the destination buffer
 * @buffer_len: length of the destination buffer
 * @str: the string to insert into buffer
 */
ssize_t populate_string_buffer(char *buffer, size_t buffer_len, const char *str)
{
	u16 *length = (u16 *)buffer;
	u16 *target = length + 1;
	int ret;

	ret = utf8s_to_utf16s(str, strlen(str), UTF16_HOST_ENDIAN,
			      target, buffer_len - sizeof(u16));
	if (ret < 0) {
		dev_err(wmi_priv.class_dev, "UTF16 conversion failed\n");
		return ret;
	}

	if ((ret * sizeof(u16)) > U16_MAX) {
		dev_err(wmi_priv.class_dev, "Error string too long\n");
		return -ERANGE;
	}

	*length = ret * sizeof(u16);
	return sizeof(u16) + *length;
}

/**
 * calculate_string_buffer() - determines size of string buffer for use with BIOS communication
 * @str: the string to calculate based upon
 *
 */
size_t calculate_string_buffer(const char *str)
{
	/* u16 length field + one UTF16 char for each input char */
	return sizeof(u16) + strlen(str) * sizeof(u16);
}

/**
 * calculate_security_buffer() - determines size of security buffer for authentication scheme
 * @authentication: the authentication content
 *
 * Currently only supported type is Admin password
 */
size_t calculate_security_buffer(char *authentication)
{
	if (strlen(authentication) > 0) {
		return (sizeof(u32) * 2) + strlen(authentication) +
			strlen(authentication) % 2;
	}
	return sizeof(u32) * 2;
}

/**
 * populate_security_buffer() - builds a security buffer for authentication scheme
 * @buffer: the buffer to populate
 * @authentication: the authentication content
 *
 * Currently only supported type is PLAIN TEXT
 */
void populate_security_buffer(char *buffer, char *authentication)
{
	char *auth = buffer + sizeof(u32) * 2;
	u32 *sectype = (u32 *) buffer;
	u32 *seclen = sectype + 1;

	*sectype = strlen(authentication) > 0 ? 1 : 0;
	*seclen = strlen(authentication);

	/* plain text */
	if (strlen(authentication) > 0)
		memcpy(auth, authentication, *seclen);
}

/**
 * map_wmi_error() - map errors from WMI methods to kernel error codes
 * @error_code: integer error code returned from Dell's firmware
 */
int map_wmi_error(int error_code)
{
	switch (error_code) {
	case 0:
		/* success */
		return 0;
	case 1:
		/* failed */
		return -EIO;
	case 2:
		/* invalid parameter */
		return -EINVAL;
	case 3:
		/* access denied */
		return -EACCES;
	case 4:
		/* not supported */
		return -EOPNOTSUPP;
	case 5:
		/* memory error */
		return -ENOMEM;
	case 6:
		/* protocol error */
		return -EPROTO;
	}
	/* unspecified error */
	return -EIO;
}

/**
 * reset_bios_show() - sysfs implementaton for read reset_bios
 * @kobj: Kernel object for this attribute
 * @attr: Kernel object attribute
 * @buf: The buffer to display to userspace
 */
static ssize_t reset_bios_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
	char *start = buf;
	int i;

	for (i = 0; i < MAX_TYPES; i++) {
		if (i == reset_option)
			buf += sprintf(buf, "[%s] ", reset_types[i]);
		else
			buf += sprintf(buf, "%s ", reset_types[i]);
	}
	buf += sprintf(buf, "\n");
	return buf-start;
}

/**
 * reset_bios_store() - sysfs implementaton for write reset_bios
 * @kobj: Kernel object for this attribute
 * @attr: Kernel object attribute
 * @buf: The buffer from userspace
 * @count: the size of the buffer from userspace
 */
static ssize_t reset_bios_store(struct kobject *kobj,
				struct kobj_attribute *attr, const char *buf, size_t count)
{
	int type = sysfs_match_string(reset_types, buf);
	int ret;

	if (type < 0)
		return type;

	ret = set_bios_defaults(type);
	pr_debug("reset all attributes request type %d: %d\n", type, ret);
	if (!ret) {
		reset_option = type;
		ret = count;
	}

	return ret;
}

/**
 * pending_reboot_show() - sysfs implementaton for read pending_reboot
 * @kobj: Kernel object for this attribute
 * @attr: Kernel object attribute
 * @buf: The buffer to display to userspace
 *
 * Stores default value as 0
 * When current_value is changed this attribute is set to 1 to notify reboot may be required
 */
static ssize_t pending_reboot_show(struct kobject *kobj, struct kobj_attribute *attr,
				   char *buf)
{
	return sprintf(buf, "%d\n", wmi_priv.pending_changes);
}

static struct kobj_attribute reset_bios = __ATTR_RW(reset_bios);
static struct kobj_attribute pending_reboot = __ATTR_RO(pending_reboot);


/**
 * create_attributes_level_sysfs_files() - Creates reset_bios and
 * pending_reboot attributes
 */
static int create_attributes_level_sysfs_files(void)
{
	int ret = sysfs_create_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr);

	if (ret) {
		pr_debug("could not create reset_bios file\n");
		return ret;
	}

	ret = sysfs_create_file(&wmi_priv.main_dir_kset->kobj, &pending_reboot.attr);
	if (ret) {
		pr_debug("could not create changing_pending_reboot file\n");
		sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr);
	}
	return ret;
}

static void release_reset_bios_data(void)
{
	sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &reset_bios.attr);
	sysfs_remove_file(&wmi_priv.main_dir_kset->kobj, &pending_reboot.attr);
}

static ssize_t wmi_sysman_attr_show(struct kobject *kobj, struct attribute *attr,
				    char *buf)
{
	struct kobj_attribute *kattr;
	ssize_t ret = -EIO;

	kattr = container_of(attr, struct kobj_attribute, attr);
	if (kattr->show)
		ret = kattr->show(kobj, kattr, buf);
	return ret;
}

static ssize_t wmi_sysman_attr_store(struct kobject *kobj, struct attribute *attr,
				     const char *buf, size_t count)
{
	struct kobj_attribute *kattr;
	ssize_t ret = -EIO;

	kattr = container_of(attr, struct kobj_attribute, attr);
	if (kattr->store)
		ret = kattr->store(kobj, kattr, buf, count);
	return ret;
}

static const struct sysfs_ops wmi_sysman_kobj_sysfs_ops = {
	.show	= wmi_sysman_attr_show,
	.store	= wmi_sysman_attr_store,
};

static void attr_name_release(struct kobject *kobj)
{
	kfree(kobj);
}

static struct kobj_type attr_name_ktype = {
	.release	= attr_name_release,
	.sysfs_ops	= &wmi_sysman_kobj_sysfs_ops,
};

/**
 * strlcpy_attr - Copy a length-limited, NULL-terminated string with bound checks
 * @dest: Where to copy the string to
 * @src: Where to copy the string from
 */
void strlcpy_attr(char *dest, char *src)
{
	size_t len = strlen(src) + 1;

	if (len > 1 && len <= MAX_BUFF)
		strlcpy(dest, src, len);

	/*len can be zero because any property not-applicable to attribute can
	 * be empty so check only for too long buffers and log error
	 */
	if (len > MAX_BUFF)
		pr_err("Source string returned from BIOS is out of bound!\n");
}

/**
 * get_wmiobj_pointer() - Get Content of WMI block for particular instance
 * @instance_id: WMI instance ID
 * @guid_string: WMI GUID (in str form)
 *
 * Fetches the content for WMI block (instance_id) under GUID (guid_string)
 * Caller must kfree the return
 */
union acpi_object *get_wmiobj_pointer(int instance_id, const char *guid_string)
{
	struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
	acpi_status status;

	status = wmi_query_block(guid_string, instance_id, &out);

	return ACPI_SUCCESS(status) ? (union acpi_object *)out.pointer : NULL;
}

/**
 * get_instance_count() - Compute total number of instances under guid_string
 * @guid_string: WMI GUID (in string form)
 */
int get_instance_count(const char *guid_string)
{
	union acpi_object *wmi_obj = NULL;
	int i = 0;

	do {
		kfree(wmi_obj);
		wmi_obj = get_wmiobj_pointer(i, guid_string);
		i++;
	} while (wmi_obj);

	return (i-1);
}

/**
 * alloc_attributes_data() - Allocate attributes data for a particular type
 * @attr_type: Attribute type to allocate
 */
static int alloc_attributes_data(int attr_type)
{
	int retval = 0;

	switch (attr_type) {
	case ENUM:
		retval = alloc_enum_data();
		break;
	case INT:
		retval = alloc_int_data();
		break;
	case STR:
		retval = alloc_str_data();
		break;
	case PO:
		retval = alloc_po_data();
		break;
	default:
		break;
	}

	return retval;
}

/**
 * destroy_attribute_objs() - Free a kset of kobjects
 * @kset: The kset to destroy
 *
 * Fress kobjects created for each attribute_name under attribute type kset
 */
static void destroy_attribute_objs(struct kset *kset)
{
	struct kobject *pos, *next;

	list_for_each_entry_safe(pos, next, &kset->list, entry) {
		kobject_put(pos);
	}
}

/**
 * release_attributes_data() - Clean-up all sysfs directories and files created
 */
static void release_attributes_data(void)
{
	release_reset_bios_data();

	mutex_lock(&wmi_priv.mutex);
	exit_enum_attributes();
	exit_int_attributes();
	exit_str_attributes();
	exit_po_attributes();
	if (wmi_priv.authentication_dir_kset) {
		destroy_attribute_objs(wmi_priv.authentication_dir_kset);
		kset_unregister(wmi_priv.authentication_dir_kset);
		wmi_priv.authentication_dir_kset = NULL;
	}
	if (wmi_priv.main_dir_kset) {
		destroy_attribute_objs(wmi_priv.main_dir_kset);
		kset_unregister(wmi_priv.main_dir_kset);
	}
	mutex_unlock(&wmi_priv.mutex);

}

/**
 * init_bios_attributes() - Initialize all attributes for a type
 * @attr_type: The attribute type to initialize
 * @guid: The WMI GUID associated with this type to initialize
 *
 * Initialiaze all 4 types of attributes enumeration, integer, string and password object.
 * Populates each attrbute typ's respective properties under sysfs files
 */
static int init_bios_attributes(int attr_type, const char *guid)
{
	struct kobject *attr_name_kobj; //individual attribute names
	union acpi_object *obj = NULL;
	union acpi_object *elements;
	struct kset *tmp_set;

	/* instance_id needs to be reset for each type GUID
	 * also, instance IDs are unique within GUID but not across
	 */
	int instance_id = 0;
	int retval = 0;

	retval = alloc_attributes_data(attr_type);
	if (retval)
		return retval;
	/* need to use specific instance_id and guid combination to get right data */
	obj = get_wmiobj_pointer(instance_id, guid);
	if (!obj)
		return -ENODEV;
	elements = obj->package.elements;

	mutex_lock(&wmi_priv.mutex);
	while (elements) {
		/* sanity checking */
		if (strlen(elements[ATTR_NAME].string.pointer) == 0) {
			pr_debug("empty attribute found\n");
			goto nextobj;
		}
		if (attr_type == PO)
			tmp_set = wmi_priv.authentication_dir_kset;
		else
			tmp_set = wmi_priv.main_dir_kset;

		if (kset_find_obj(tmp_set, elements[ATTR_NAME].string.pointer)) {
			pr_debug("duplicate attribute name found - %s\n",
				elements[ATTR_NAME].string.pointer);
			goto nextobj;
		}

		/* build attribute */
		attr_name_kobj = kzalloc(sizeof(*attr_name_kobj), GFP_KERNEL);
		if (!attr_name_kobj) {
			retval = -ENOMEM;
			goto err_attr_init;
		}

		attr_name_kobj->kset = tmp_set;

		retval = kobject_init_and_add(attr_name_kobj, &attr_name_ktype, NULL, "%s",
						elements[ATTR_NAME].string.pointer);
		if (retval) {
			kobject_put(attr_name_kobj);
			goto err_attr_init;
		}

		/* enumerate all of this attribute */
		switch (attr_type) {
		case ENUM:
			retval = populate_enum_data(elements, instance_id, attr_name_kobj);
			break;
		case INT:
			retval = populate_int_data(elements, instance_id, attr_name_kobj);
			break;
		case STR:
			retval = populate_str_data(elements, instance_id, attr_name_kobj);
			break;
		case PO:
			retval = populate_po_data(elements, instance_id, attr_name_kobj);
			break;
		default:
			break;
		}

		if (retval) {
			pr_debug("failed to populate %s\n",
				elements[ATTR_NAME].string.pointer);
			goto err_attr_init;
		}

nextobj:
		kfree(obj);
		instance_id++;
		obj = get_wmiobj_pointer(instance_id, guid);
		elements = obj ? obj->package.elements : NULL;
	}

	mutex_unlock(&wmi_priv.mutex);
	return 0;

err_attr_init:
	mutex_unlock(&wmi_priv.mutex);
	release_attributes_data();
	kfree(obj);
	return retval;
}

static int __init sysman_init(void)
{
	int ret = 0;

	if (!dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "Dell System", NULL) &&
	    !dmi_find_device(DMI_DEV_TYPE_OEM_STRING, "www.dell.com", NULL)) {
		pr_err("Unable to run on non-Dell system\n");
		return -ENODEV;
	}

	ret = init_bios_attr_set_interface();
	if (ret || !wmi_priv.bios_attr_wdev) {
		pr_debug("failed to initialize set interface\n");
		goto fail_set_interface;
	}

	ret = init_bios_attr_pass_interface();
	if (ret || !wmi_priv.password_attr_wdev) {
		pr_debug("failed to initialize pass interface\n");
		goto fail_pass_interface;
	}

	ret = class_register(&firmware_attributes_class);
	if (ret)
		goto fail_class;

	wmi_priv.class_dev = device_create(&firmware_attributes_class, NULL, MKDEV(0, 0),
				  NULL, "%s", DRIVER_NAME);
	if (IS_ERR(wmi_priv.class_dev)) {
		ret = PTR_ERR(wmi_priv.class_dev);
		goto fail_classdev;
	}

	wmi_priv.main_dir_kset = kset_create_and_add("attributes", NULL,
						     &wmi_priv.class_dev->kobj);
	if (!wmi_priv.main_dir_kset) {
		ret = -ENOMEM;
		goto fail_main_kset;
	}

	wmi_priv.authentication_dir_kset = kset_create_and_add("authentication", NULL,
								&wmi_priv.class_dev->kobj);
	if (!wmi_priv.authentication_dir_kset) {
		ret = -ENOMEM;
		goto fail_authentication_kset;
	}

	ret = create_attributes_level_sysfs_files();
	if (ret) {
		pr_debug("could not create reset BIOS attribute\n");
		goto fail_reset_bios;
	}

	ret = init_bios_attributes(ENUM, DELL_WMI_BIOS_ENUMERATION_ATTRIBUTE_GUID);
	if (ret) {
		pr_debug("failed to populate enumeration type attributes\n");
		goto fail_create_group;
	}

	ret = init_bios_attributes(INT, DELL_WMI_BIOS_INTEGER_ATTRIBUTE_GUID);
	if (ret) {
		pr_debug("failed to populate integer type attributes\n");
		goto fail_create_group;
	}

	ret = init_bios_attributes(STR, DELL_WMI_BIOS_STRING_ATTRIBUTE_GUID);
	if (ret) {
		pr_debug("failed to populate string type attributes\n");
		goto fail_create_group;
	}

	ret = init_bios_attributes(PO, DELL_WMI_BIOS_PASSOBJ_ATTRIBUTE_GUID);
	if (ret) {
		pr_debug("failed to populate pass object type attributes\n");
		goto fail_create_group;
	}

	return 0;

fail_create_group:
	release_attributes_data();

fail_reset_bios:
	if (wmi_priv.authentication_dir_kset) {
		kset_unregister(wmi_priv.authentication_dir_kset);
		wmi_priv.authentication_dir_kset = NULL;
	}

fail_authentication_kset:
	if (wmi_priv.main_dir_kset) {
		kset_unregister(wmi_priv.main_dir_kset);
		wmi_priv.main_dir_kset = NULL;
	}

fail_main_kset:
	device_destroy(&firmware_attributes_class, MKDEV(0, 0));

fail_classdev:
	class_unregister(&firmware_attributes_class);

fail_class:
	exit_bios_attr_pass_interface();

fail_pass_interface:
	exit_bios_attr_set_interface();

fail_set_interface:
	return ret;
}

static void __exit sysman_exit(void)
{
	release_attributes_data();
	device_destroy(&firmware_attributes_class, MKDEV(0, 0));
	class_unregister(&firmware_attributes_class);
	exit_bios_attr_set_interface();
	exit_bios_attr_pass_interface();
}

module_init(sysman_init);
module_exit(sysman_exit);

MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>");
MODULE_AUTHOR("Prasanth Ksr <prasanth.ksr@dell.com>");
MODULE_AUTHOR("Divya Bharathi <divya.bharathi@dell.com>");
MODULE_DESCRIPTION("Dell platform setting control interface");
MODULE_LICENSE("GPL");
