// SPDX-License-Identifier: GPL-2.0

/* Copyright (C) 2021 Linaro Ltd. */

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

#include "ipa.h"
#include "ipa_version.h"
#include "ipa_sysfs.h"

static const char *ipa_version_string(struct ipa *ipa)
{
	switch (ipa->version) {
	case IPA_VERSION_3_0:
		return "3.0";
	case IPA_VERSION_3_1:
		return "3.1";
	case IPA_VERSION_3_5:
		return "3.5";
	case IPA_VERSION_3_5_1:
		return "3.5.1";
	case IPA_VERSION_4_0:
		return "4.0";
	case IPA_VERSION_4_1:
		return "4.1";
	case IPA_VERSION_4_2:
		return "4.2";
	case IPA_VERSION_4_5:
		return "4.5";
	case IPA_VERSION_4_7:
		return "4.7";
	case IPA_VERSION_4_9:
		return "4.9";
	case IPA_VERSION_4_11:
		return "4.11";
	default:
		return "0.0";	/* Won't happen (checked at probe time) */
	}
}

static ssize_t
version_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct ipa *ipa = dev_get_drvdata(dev);

	return scnprintf(buf, PAGE_SIZE, "%s\n", ipa_version_string(ipa));
}

static DEVICE_ATTR_RO(version);

static struct attribute *ipa_attrs[] = {
	&dev_attr_version.attr,
	NULL
};

const struct attribute_group ipa_attribute_group = {
	.attrs		= ipa_attrs,
};

static const char *ipa_offload_string(struct ipa *ipa)
{
	return ipa->version < IPA_VERSION_4_5 ? "MAPv4" : "MAPv5";
}

static ssize_t rx_offload_show(struct device *dev,
			       struct device_attribute *attr, char *buf)
{
	struct ipa *ipa = dev_get_drvdata(dev);

	return scnprintf(buf, PAGE_SIZE, "%s\n", ipa_offload_string(ipa));
}

static DEVICE_ATTR_RO(rx_offload);

static ssize_t tx_offload_show(struct device *dev,
			       struct device_attribute *attr, char *buf)
{
	struct ipa *ipa = dev_get_drvdata(dev);

	return scnprintf(buf, PAGE_SIZE, "%s\n", ipa_offload_string(ipa));
}

static DEVICE_ATTR_RO(tx_offload);

static struct attribute *ipa_feature_attrs[] = {
	&dev_attr_rx_offload.attr,
	&dev_attr_tx_offload.attr,
	NULL
};

const struct attribute_group ipa_feature_attribute_group = {
	.name		= "feature",
	.attrs		= ipa_feature_attrs,
};

static umode_t ipa_endpoint_id_is_visible(struct kobject *kobj,
					  struct attribute *attr, int n)
{
	struct ipa *ipa = dev_get_drvdata(kobj_to_dev(kobj));
	struct device_attribute *dev_attr;
	struct dev_ext_attribute *ea;
	bool visible;

	/* An endpoint id attribute is only visible if it's defined */
	dev_attr = container_of(attr, struct device_attribute, attr);
	ea = container_of(dev_attr, struct dev_ext_attribute, attr);

	visible = !!ipa->name_map[(enum ipa_endpoint_name)(uintptr_t)ea->var];

	return visible ? attr->mode : 0;
}

static ssize_t endpoint_id_attr_show(struct device *dev,
				     struct device_attribute *attr, char *buf)
{
	struct ipa *ipa = dev_get_drvdata(dev);
	struct ipa_endpoint *endpoint;
	struct dev_ext_attribute *ea;

	ea = container_of(attr, struct dev_ext_attribute, attr);
	endpoint = ipa->name_map[(enum ipa_endpoint_name)(uintptr_t)ea->var];

	return sysfs_emit(buf, "%u\n", endpoint->endpoint_id);
}

#define ENDPOINT_ID_ATTR(_n, _endpoint_name)				    \
	static struct dev_ext_attribute dev_attr_endpoint_id_ ## _n = {	    \
		.attr	= __ATTR(_n, 0444, endpoint_id_attr_show, NULL),    \
		.var	= (void *)(_endpoint_name),			    \
	}

ENDPOINT_ID_ATTR(modem_rx, IPA_ENDPOINT_AP_MODEM_RX);
ENDPOINT_ID_ATTR(modem_tx, IPA_ENDPOINT_AP_MODEM_TX);

static struct attribute *ipa_endpoint_id_attrs[] = {
	&dev_attr_endpoint_id_modem_rx.attr.attr,
	&dev_attr_endpoint_id_modem_tx.attr.attr,
	NULL
};

const struct attribute_group ipa_endpoint_id_attribute_group = {
	.name		= "endpoint_id",
	.is_visible	= ipa_endpoint_id_is_visible,
	.attrs		= ipa_endpoint_id_attrs,
};

/* Reuse endpoint ID attributes for the legacy modem endpoint IDs */
#define MODEM_ATTR(_n, _endpoint_name)					    \
	static struct dev_ext_attribute dev_attr_modem_ ## _n = {	    \
		.attr	= __ATTR(_n, 0444, endpoint_id_attr_show, NULL),    \
		.var	= (void *)(_endpoint_name),			    \
	}

MODEM_ATTR(rx_endpoint_id, IPA_ENDPOINT_AP_MODEM_RX);
MODEM_ATTR(tx_endpoint_id, IPA_ENDPOINT_AP_MODEM_TX);

static struct attribute *ipa_modem_attrs[] = {
	&dev_attr_modem_rx_endpoint_id.attr.attr,
	&dev_attr_modem_tx_endpoint_id.attr.attr,
	NULL,
};

const struct attribute_group ipa_modem_attribute_group = {
	.name		= "modem",
	.attrs		= ipa_modem_attrs,
};
