/*
 * Copyright 2014 IBM Corp.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */

#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/sysfs.h>
#include <linux/pci_regs.h>

#include "cxl.h"

#define to_afu_chardev_m(d) dev_get_drvdata(d)

/*********  Adapter attributes  **********************************************/

static ssize_t caia_version_show(struct device *device,
				 struct device_attribute *attr,
				 char *buf)
{
	struct cxl *adapter = to_cxl_adapter(device);

	return scnprintf(buf, PAGE_SIZE, "%i.%i\n", adapter->caia_major,
			 adapter->caia_minor);
}

static ssize_t psl_revision_show(struct device *device,
				 struct device_attribute *attr,
				 char *buf)
{
	struct cxl *adapter = to_cxl_adapter(device);

	return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->psl_rev);
}

static ssize_t base_image_show(struct device *device,
			       struct device_attribute *attr,
			       char *buf)
{
	struct cxl *adapter = to_cxl_adapter(device);

	return scnprintf(buf, PAGE_SIZE, "%i\n", adapter->base_image);
}

static ssize_t image_loaded_show(struct device *device,
				 struct device_attribute *attr,
				 char *buf)
{
	struct cxl *adapter = to_cxl_adapter(device);

	if (adapter->user_image_loaded)
		return scnprintf(buf, PAGE_SIZE, "user\n");
	return scnprintf(buf, PAGE_SIZE, "factory\n");
}

static ssize_t reset_adapter_store(struct device *device,
				   struct device_attribute *attr,
				   const char *buf, size_t count)
{
	struct cxl *adapter = to_cxl_adapter(device);
	int rc;
	int val;

	rc = sscanf(buf, "%i", &val);
	if ((rc != 1) || (val != 1))
		return -EINVAL;

	if ((rc = cxl_reset(adapter)))
		return rc;
	return count;
}

static ssize_t load_image_on_perst_show(struct device *device,
				 struct device_attribute *attr,
				 char *buf)
{
	struct cxl *adapter = to_cxl_adapter(device);

	if (!adapter->perst_loads_image)
		return scnprintf(buf, PAGE_SIZE, "none\n");

	if (adapter->perst_select_user)
		return scnprintf(buf, PAGE_SIZE, "user\n");
	return scnprintf(buf, PAGE_SIZE, "factory\n");
}

static ssize_t load_image_on_perst_store(struct device *device,
				 struct device_attribute *attr,
				 const char *buf, size_t count)
{
	struct cxl *adapter = to_cxl_adapter(device);
	int rc;

	if (!strncmp(buf, "none", 4))
		adapter->perst_loads_image = false;
	else if (!strncmp(buf, "user", 4)) {
		adapter->perst_select_user = true;
		adapter->perst_loads_image = true;
	} else if (!strncmp(buf, "factory", 7)) {
		adapter->perst_select_user = false;
		adapter->perst_loads_image = true;
	} else
		return -EINVAL;

	if ((rc = cxl_update_image_control(adapter)))
		return rc;

	return count;
}

static struct device_attribute adapter_attrs[] = {
	__ATTR_RO(caia_version),
	__ATTR_RO(psl_revision),
	__ATTR_RO(base_image),
	__ATTR_RO(image_loaded),
	__ATTR_RW(load_image_on_perst),
	__ATTR(reset, S_IWUSR, NULL, reset_adapter_store),
};


/*********  AFU master specific attributes  **********************************/

static ssize_t mmio_size_show_master(struct device *device,
				     struct device_attribute *attr,
				     char *buf)
{
	struct cxl_afu *afu = to_afu_chardev_m(device);

	return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->adapter->ps_size);
}

static ssize_t pp_mmio_off_show(struct device *device,
				struct device_attribute *attr,
				char *buf)
{
	struct cxl_afu *afu = to_afu_chardev_m(device);

	return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->pp_offset);
}

static ssize_t pp_mmio_len_show(struct device *device,
				struct device_attribute *attr,
				char *buf)
{
	struct cxl_afu *afu = to_afu_chardev_m(device);

	return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->pp_size);
}

static struct device_attribute afu_master_attrs[] = {
	__ATTR(mmio_size, S_IRUGO, mmio_size_show_master, NULL),
	__ATTR_RO(pp_mmio_off),
	__ATTR_RO(pp_mmio_len),
};


/*********  AFU attributes  **************************************************/

static ssize_t mmio_size_show(struct device *device,
			      struct device_attribute *attr,
			      char *buf)
{
	struct cxl_afu *afu = to_cxl_afu(device);

	if (afu->pp_size)
		return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->pp_size);
	return scnprintf(buf, PAGE_SIZE, "%llu\n", afu->adapter->ps_size);
}

static ssize_t reset_store_afu(struct device *device,
			       struct device_attribute *attr,
			       const char *buf, size_t count)
{
	struct cxl_afu *afu = to_cxl_afu(device);
	int rc;

	/* Not safe to reset if it is currently in use */
	mutex_lock(&afu->contexts_lock);
	if (!idr_is_empty(&afu->contexts_idr)) {
		rc = -EBUSY;
		goto err;
	}

	if ((rc = cxl_afu_reset(afu)))
		goto err;

	rc = count;
err:
	mutex_unlock(&afu->contexts_lock);
	return rc;
}

static ssize_t irqs_min_show(struct device *device,
			     struct device_attribute *attr,
			     char *buf)
{
	struct cxl_afu *afu = to_cxl_afu(device);

	return scnprintf(buf, PAGE_SIZE, "%i\n", afu->pp_irqs);
}

static ssize_t irqs_max_show(struct device *device,
				  struct device_attribute *attr,
				  char *buf)
{
	struct cxl_afu *afu = to_cxl_afu(device);

	return scnprintf(buf, PAGE_SIZE, "%i\n", afu->irqs_max);
}

static ssize_t irqs_max_store(struct device *device,
				  struct device_attribute *attr,
				  const char *buf, size_t count)
{
	struct cxl_afu *afu = to_cxl_afu(device);
	ssize_t ret;
	int irqs_max;

	ret = sscanf(buf, "%i", &irqs_max);
	if (ret != 1)
		return -EINVAL;

	if (irqs_max < afu->pp_irqs)
		return -EINVAL;

	if (irqs_max > afu->adapter->user_irqs)
		return -EINVAL;

	afu->irqs_max = irqs_max;
	return count;
}

static ssize_t modes_supported_show(struct device *device,
				    struct device_attribute *attr, char *buf)
{
	struct cxl_afu *afu = to_cxl_afu(device);
	char *p = buf, *end = buf + PAGE_SIZE;

	if (afu->modes_supported & CXL_MODE_DEDICATED)
		p += scnprintf(p, end - p, "dedicated_process\n");
	if (afu->modes_supported & CXL_MODE_DIRECTED)
		p += scnprintf(p, end - p, "afu_directed\n");
	return (p - buf);
}

static ssize_t prefault_mode_show(struct device *device,
				  struct device_attribute *attr,
				  char *buf)
{
	struct cxl_afu *afu = to_cxl_afu(device);

	switch (afu->prefault_mode) {
	case CXL_PREFAULT_WED:
		return scnprintf(buf, PAGE_SIZE, "work_element_descriptor\n");
	case CXL_PREFAULT_ALL:
		return scnprintf(buf, PAGE_SIZE, "all\n");
	default:
		return scnprintf(buf, PAGE_SIZE, "none\n");
	}
}

static ssize_t prefault_mode_store(struct device *device,
			  struct device_attribute *attr,
			  const char *buf, size_t count)
{
	struct cxl_afu *afu = to_cxl_afu(device);
	enum prefault_modes mode = -1;

	if (!strncmp(buf, "work_element_descriptor", 23))
		mode = CXL_PREFAULT_WED;
	if (!strncmp(buf, "all", 3))
		mode = CXL_PREFAULT_ALL;
	if (!strncmp(buf, "none", 4))
		mode = CXL_PREFAULT_NONE;

	if (mode == -1)
		return -EINVAL;

	afu->prefault_mode = mode;
	return count;
}

static ssize_t mode_show(struct device *device,
			 struct device_attribute *attr,
			 char *buf)
{
	struct cxl_afu *afu = to_cxl_afu(device);

	if (afu->current_mode == CXL_MODE_DEDICATED)
		return scnprintf(buf, PAGE_SIZE, "dedicated_process\n");
	if (afu->current_mode == CXL_MODE_DIRECTED)
		return scnprintf(buf, PAGE_SIZE, "afu_directed\n");
	return scnprintf(buf, PAGE_SIZE, "none\n");
}

static ssize_t mode_store(struct device *device, struct device_attribute *attr,
			  const char *buf, size_t count)
{
	struct cxl_afu *afu = to_cxl_afu(device);
	int old_mode, mode = -1;
	int rc = -EBUSY;

	/* can't change this if we have a user */
	mutex_lock(&afu->contexts_lock);
	if (!idr_is_empty(&afu->contexts_idr))
		goto err;

	if (!strncmp(buf, "dedicated_process", 17))
		mode = CXL_MODE_DEDICATED;
	if (!strncmp(buf, "afu_directed", 12))
		mode = CXL_MODE_DIRECTED;
	if (!strncmp(buf, "none", 4))
		mode = 0;

	if (mode == -1) {
		rc = -EINVAL;
		goto err;
	}

	/*
	 * cxl_afu_deactivate_mode needs to be done outside the lock, prevent
	 * other contexts coming in before we are ready:
	 */
	old_mode = afu->current_mode;
	afu->current_mode = 0;
	afu->num_procs = 0;

	mutex_unlock(&afu->contexts_lock);

	if ((rc = _cxl_afu_deactivate_mode(afu, old_mode)))
		return rc;
	if ((rc = cxl_afu_activate_mode(afu, mode)))
		return rc;

	return count;
err:
	mutex_unlock(&afu->contexts_lock);
	return rc;
}

static ssize_t api_version_show(struct device *device,
				struct device_attribute *attr,
				char *buf)
{
	return scnprintf(buf, PAGE_SIZE, "%i\n", CXL_API_VERSION);
}

static ssize_t api_version_compatible_show(struct device *device,
					   struct device_attribute *attr,
					   char *buf)
{
	return scnprintf(buf, PAGE_SIZE, "%i\n", CXL_API_VERSION_COMPATIBLE);
}

static struct device_attribute afu_attrs[] = {
	__ATTR_RO(mmio_size),
	__ATTR_RO(irqs_min),
	__ATTR_RW(irqs_max),
	__ATTR_RO(modes_supported),
	__ATTR_RW(mode),
	__ATTR_RW(prefault_mode),
	__ATTR_RO(api_version),
	__ATTR_RO(api_version_compatible),
	__ATTR(reset, S_IWUSR, NULL, reset_store_afu),
};

int cxl_sysfs_adapter_add(struct cxl *adapter)
{
	int i, rc;

	for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++) {
		if ((rc = device_create_file(&adapter->dev, &adapter_attrs[i])))
			goto err;
	}
	return 0;
err:
	for (i--; i >= 0; i--)
		device_remove_file(&adapter->dev, &adapter_attrs[i]);
	return rc;
}
void cxl_sysfs_adapter_remove(struct cxl *adapter)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(adapter_attrs); i++)
		device_remove_file(&adapter->dev, &adapter_attrs[i]);
}

struct afu_config_record {
	struct kobject kobj;
	struct bin_attribute config_attr;
	struct list_head list;
	int cr;
	u16 device;
	u16 vendor;
	u32 class;
};

#define to_cr(obj) container_of(obj, struct afu_config_record, kobj)

static ssize_t vendor_show(struct kobject *kobj,
			   struct kobj_attribute *attr, char *buf)
{
	struct afu_config_record *cr = to_cr(kobj);

	return scnprintf(buf, PAGE_SIZE, "0x%.4x\n", cr->vendor);
}

static ssize_t device_show(struct kobject *kobj,
			   struct kobj_attribute *attr, char *buf)
{
	struct afu_config_record *cr = to_cr(kobj);

	return scnprintf(buf, PAGE_SIZE, "0x%.4x\n", cr->device);
}

static ssize_t class_show(struct kobject *kobj,
			  struct kobj_attribute *attr, char *buf)
{
	struct afu_config_record *cr = to_cr(kobj);

	return scnprintf(buf, PAGE_SIZE, "0x%.6x\n", cr->class);
}

static ssize_t afu_read_config(struct file *filp, struct kobject *kobj,
			       struct bin_attribute *bin_attr, char *buf,
			       loff_t off, size_t count)
{
	struct afu_config_record *cr = to_cr(kobj);
	struct cxl_afu *afu = to_cxl_afu(container_of(kobj->parent, struct device, kobj));

	u64 i, j, val, size = afu->crs_len;

	if (off > size)
		return 0;
	if (off + count > size)
		count = size - off;

	for (i = 0; i < count;) {
		val = cxl_afu_cr_read64(afu, cr->cr, off & ~0x7);
		for (j = off & 0x7; j < 8 && i < count; i++, j++, off++)
			buf[i] = (val >> (j * 8)) & 0xff;
	}

	return count;
}

static struct kobj_attribute vendor_attribute =
	__ATTR_RO(vendor);
static struct kobj_attribute device_attribute =
	__ATTR_RO(device);
static struct kobj_attribute class_attribute =
	__ATTR_RO(class);

static struct attribute *afu_cr_attrs[] = {
	&vendor_attribute.attr,
	&device_attribute.attr,
	&class_attribute.attr,
	NULL,
};

static void release_afu_config_record(struct kobject *kobj)
{
	struct afu_config_record *cr = to_cr(kobj);

	kfree(cr);
}

static struct kobj_type afu_config_record_type = {
	.sysfs_ops = &kobj_sysfs_ops,
	.release = release_afu_config_record,
	.default_attrs = afu_cr_attrs,
};

static struct afu_config_record *cxl_sysfs_afu_new_cr(struct cxl_afu *afu, int cr_idx)
{
	struct afu_config_record *cr;
	int rc;

	cr = kzalloc(sizeof(struct afu_config_record), GFP_KERNEL);
	if (!cr)
		return ERR_PTR(-ENOMEM);

	cr->cr = cr_idx;
	cr->device = cxl_afu_cr_read16(afu, cr_idx, PCI_DEVICE_ID);
	cr->vendor = cxl_afu_cr_read16(afu, cr_idx, PCI_VENDOR_ID);
	cr->class = cxl_afu_cr_read32(afu, cr_idx, PCI_CLASS_REVISION) >> 8;

	/*
	 * Export raw AFU PCIe like config record. For now this is read only by
	 * root - we can expand that later to be readable by non-root and maybe
	 * even writable provided we have a good use-case. Once we suport
	 * exposing AFUs through a virtual PHB they will get that for free from
	 * Linux' PCI infrastructure, but until then it's not clear that we
	 * need it for anything since the main use case is just identifying
	 * AFUs, which can be done via the vendor, device and class attributes.
	 */
	sysfs_bin_attr_init(&cr->config_attr);
	cr->config_attr.attr.name = "config";
	cr->config_attr.attr.mode = S_IRUSR;
	cr->config_attr.size = afu->crs_len;
	cr->config_attr.read = afu_read_config;

	rc = kobject_init_and_add(&cr->kobj, &afu_config_record_type,
				  &afu->dev.kobj, "cr%i", cr->cr);
	if (rc)
		goto err;

	rc = sysfs_create_bin_file(&cr->kobj, &cr->config_attr);
	if (rc)
		goto err1;

	rc = kobject_uevent(&cr->kobj, KOBJ_ADD);
	if (rc)
		goto err2;

	return cr;
err2:
	sysfs_remove_bin_file(&cr->kobj, &cr->config_attr);
err1:
	kobject_put(&cr->kobj);
	return ERR_PTR(rc);
err:
	kfree(cr);
	return ERR_PTR(rc);
}

void cxl_sysfs_afu_remove(struct cxl_afu *afu)
{
	struct afu_config_record *cr, *tmp;
	int i;

	for (i = 0; i < ARRAY_SIZE(afu_attrs); i++)
		device_remove_file(&afu->dev, &afu_attrs[i]);

	list_for_each_entry_safe(cr, tmp, &afu->crs, list) {
		sysfs_remove_bin_file(&cr->kobj, &cr->config_attr);
		kobject_put(&cr->kobj);
	}
}

int cxl_sysfs_afu_add(struct cxl_afu *afu)
{
	struct afu_config_record *cr;
	int i, rc;

	INIT_LIST_HEAD(&afu->crs);

	for (i = 0; i < ARRAY_SIZE(afu_attrs); i++) {
		if ((rc = device_create_file(&afu->dev, &afu_attrs[i])))
			goto err;
	}

	for (i = 0; i < afu->crs_num; i++) {
		cr = cxl_sysfs_afu_new_cr(afu, i);
		if (IS_ERR(cr)) {
			rc = PTR_ERR(cr);
			goto err1;
		}
		list_add(&cr->list, &afu->crs);
	}

	return 0;

err1:
	cxl_sysfs_afu_remove(afu);
	return rc;
err:
	for (i--; i >= 0; i--)
		device_remove_file(&afu->dev, &afu_attrs[i]);
	return rc;
}

int cxl_sysfs_afu_m_add(struct cxl_afu *afu)
{
	int i, rc;

	for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++) {
		if ((rc = device_create_file(afu->chardev_m, &afu_master_attrs[i])))
			goto err;
	}

	return 0;

err:
	for (i--; i >= 0; i--)
		device_remove_file(afu->chardev_m, &afu_master_attrs[i]);
	return rc;
}

void cxl_sysfs_afu_m_remove(struct cxl_afu *afu)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(afu_master_attrs); i++)
		device_remove_file(afu->chardev_m, &afu_master_attrs[i]);
}
