// SPDX-License-Identifier: GPL-2.0-only
/**
 * IBM Accelerator Family 'GenWQE'
 *
 * (C) Copyright IBM Corp. 2013
 *
 * Author: Frank Haverkamp <haver@linux.vnet.ibm.com>
 * Author: Joerg-Stephan Vogt <jsvogt@de.ibm.com>
 * Author: Michael Jung <mijung@gmx.net>
 * Author: Michael Ruettger <michael@ibmra.de>
 */

/*
 * Sysfs interfaces for the GenWQE card. There are attributes to query
 * the version of the bitstream as well as some for the driver. For
 * debugging, please also see the debugfs interfaces of this driver.
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <linux/sysfs.h>
#include <linux/ctype.h>
#include <linux/device.h>

#include "card_base.h"
#include "card_ddcb.h"

static const char * const genwqe_types[] = {
	[GENWQE_TYPE_ALTERA_230] = "GenWQE4-230",
	[GENWQE_TYPE_ALTERA_530] = "GenWQE4-530",
	[GENWQE_TYPE_ALTERA_A4]  = "GenWQE5-A4",
	[GENWQE_TYPE_ALTERA_A7]  = "GenWQE5-A7",
};

static ssize_t status_show(struct device *dev, struct device_attribute *attr,
			   char *buf)
{
	struct genwqe_dev *cd = dev_get_drvdata(dev);
	const char *cs[GENWQE_CARD_STATE_MAX] = { "unused", "used", "error" };

	return sprintf(buf, "%s\n", cs[cd->card_state]);
}
static DEVICE_ATTR_RO(status);

static ssize_t appid_show(struct device *dev, struct device_attribute *attr,
			  char *buf)
{
	char app_name[5];
	struct genwqe_dev *cd = dev_get_drvdata(dev);

	genwqe_read_app_id(cd, app_name, sizeof(app_name));
	return sprintf(buf, "%s\n", app_name);
}
static DEVICE_ATTR_RO(appid);

static ssize_t version_show(struct device *dev, struct device_attribute *attr,
			    char *buf)
{
	u64 slu_id, app_id;
	struct genwqe_dev *cd = dev_get_drvdata(dev);

	slu_id = __genwqe_readq(cd, IO_SLU_UNITCFG);
	app_id = __genwqe_readq(cd, IO_APP_UNITCFG);

	return sprintf(buf, "%016llx.%016llx\n", slu_id, app_id);
}
static DEVICE_ATTR_RO(version);

static ssize_t type_show(struct device *dev, struct device_attribute *attr,
			 char *buf)
{
	u8 card_type;
	struct genwqe_dev *cd = dev_get_drvdata(dev);

	card_type = genwqe_card_type(cd);
	return sprintf(buf, "%s\n", (card_type >= ARRAY_SIZE(genwqe_types)) ?
		       "invalid" : genwqe_types[card_type]);
}
static DEVICE_ATTR_RO(type);

static ssize_t tempsens_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	u64 tempsens;
	struct genwqe_dev *cd = dev_get_drvdata(dev);

	tempsens = __genwqe_readq(cd, IO_SLU_TEMPERATURE_SENSOR);
	return sprintf(buf, "%016llx\n", tempsens);
}
static DEVICE_ATTR_RO(tempsens);

static ssize_t freerunning_timer_show(struct device *dev,
				      struct device_attribute *attr,
				      char *buf)
{
	u64 t;
	struct genwqe_dev *cd = dev_get_drvdata(dev);

	t = __genwqe_readq(cd, IO_SLC_FREE_RUNNING_TIMER);
	return sprintf(buf, "%016llx\n", t);
}
static DEVICE_ATTR_RO(freerunning_timer);

static ssize_t queue_working_time_show(struct device *dev,
				       struct device_attribute *attr,
				       char *buf)
{
	u64 t;
	struct genwqe_dev *cd = dev_get_drvdata(dev);

	t = __genwqe_readq(cd, IO_SLC_QUEUE_WTIME);
	return sprintf(buf, "%016llx\n", t);
}
static DEVICE_ATTR_RO(queue_working_time);

static ssize_t base_clock_show(struct device *dev,
			       struct device_attribute *attr,
			       char *buf)
{
	u64 base_clock;
	struct genwqe_dev *cd = dev_get_drvdata(dev);

	base_clock = genwqe_base_clock_frequency(cd);
	return sprintf(buf, "%lld\n", base_clock);
}
static DEVICE_ATTR_RO(base_clock);

/**
 * curr_bitstream_show() - Show the current bitstream id
 *
 * There is a bug in some old versions of the CPLD which selects the
 * bitstream, which causes the IO_SLU_BITSTREAM register to report
 * unreliable data in very rare cases. This makes this sysfs
 * unreliable up to the point were a new CPLD version is being used.
 *
 * Unfortunately there is no automatic way yet to query the CPLD
 * version, such that you need to manually ensure via programming
 * tools that you have a recent version of the CPLD software.
 *
 * The proposed circumvention is to use a special recovery bitstream
 * on the backup partition (0) to identify problems while loading the
 * image.
 */
static ssize_t curr_bitstream_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
	int curr_bitstream;
	struct genwqe_dev *cd = dev_get_drvdata(dev);

	curr_bitstream = __genwqe_readq(cd, IO_SLU_BITSTREAM) & 0x1;
	return sprintf(buf, "%d\n", curr_bitstream);
}
static DEVICE_ATTR_RO(curr_bitstream);

/**
 * next_bitstream_show() - Show the next activated bitstream
 *
 * IO_SLC_CFGREG_SOFTRESET: This register can only be accessed by the PF.
 */
static ssize_t next_bitstream_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
	int next_bitstream;
	struct genwqe_dev *cd = dev_get_drvdata(dev);

	switch ((cd->softreset & 0xc) >> 2) {
	case 0x2:
		next_bitstream =  0;
		break;
	case 0x3:
		next_bitstream =  1;
		break;
	default:
		next_bitstream = -1;
		break;		/* error */
	}
	return sprintf(buf, "%d\n", next_bitstream);
}

static ssize_t next_bitstream_store(struct device *dev,
				    struct device_attribute *attr,
				    const char *buf, size_t count)
{
	int partition;
	struct genwqe_dev *cd = dev_get_drvdata(dev);

	if (kstrtoint(buf, 0, &partition) < 0)
		return -EINVAL;

	switch (partition) {
	case 0x0:
		cd->softreset = 0x78;
		break;
	case 0x1:
		cd->softreset = 0x7c;
		break;
	default:
		return -EINVAL;
	}

	__genwqe_writeq(cd, IO_SLC_CFGREG_SOFTRESET, cd->softreset);
	return count;
}
static DEVICE_ATTR_RW(next_bitstream);

static ssize_t reload_bitstream_store(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	int reload;
	struct genwqe_dev *cd = dev_get_drvdata(dev);

	if (kstrtoint(buf, 0, &reload) < 0)
		return -EINVAL;

	if (reload == 0x1) {
		if (cd->card_state == GENWQE_CARD_UNUSED ||
		    cd->card_state == GENWQE_CARD_USED)
			cd->card_state = GENWQE_CARD_RELOAD_BITSTREAM;
		else
			return -EIO;
	} else {
		return -EINVAL;
	}

	return count;
}
static DEVICE_ATTR_WO(reload_bitstream);

/*
 * Create device_attribute structures / params: name, mode, show, store
 * additional flag if valid in VF
 */
static struct attribute *genwqe_attributes[] = {
	&dev_attr_tempsens.attr,
	&dev_attr_next_bitstream.attr,
	&dev_attr_curr_bitstream.attr,
	&dev_attr_base_clock.attr,
	&dev_attr_type.attr,
	&dev_attr_version.attr,
	&dev_attr_appid.attr,
	&dev_attr_status.attr,
	&dev_attr_freerunning_timer.attr,
	&dev_attr_queue_working_time.attr,
	&dev_attr_reload_bitstream.attr,
	NULL,
};

static struct attribute *genwqe_normal_attributes[] = {
	&dev_attr_type.attr,
	&dev_attr_version.attr,
	&dev_attr_appid.attr,
	&dev_attr_status.attr,
	&dev_attr_freerunning_timer.attr,
	&dev_attr_queue_working_time.attr,
	NULL,
};

/**
 * genwqe_is_visible() - Determine if sysfs attribute should be visible or not
 *
 * VFs have restricted mmio capabilities, so not all sysfs entries
 * are allowed in VFs.
 */
static umode_t genwqe_is_visible(struct kobject *kobj,
				 struct attribute *attr, int n)
{
	unsigned int j;
	struct device *dev = kobj_to_dev(kobj);
	struct genwqe_dev *cd = dev_get_drvdata(dev);
	umode_t mode = attr->mode;

	if (genwqe_is_privileged(cd))
		return mode;

	for (j = 0; genwqe_normal_attributes[j] != NULL;  j++)
		if (genwqe_normal_attributes[j] == attr)
			return mode;

	return 0;
}

static struct attribute_group genwqe_attribute_group = {
	.is_visible = genwqe_is_visible,
	.attrs      = genwqe_attributes,
};

const struct attribute_group *genwqe_attribute_groups[] = {
	&genwqe_attribute_group,
	NULL,
};
