// SPDX-License-Identifier: GPL-2.0-only
/*
 *  QLogic FCoE Offload Driver
 *  Copyright (c) 2016-2018 Cavium Inc.
 */
#include "qedf.h"

inline bool qedf_is_vport(struct qedf_ctx *qedf)
{
	return qedf->lport->vport != NULL;
}

/* Get base qedf for physical port from vport */
static struct qedf_ctx *qedf_get_base_qedf(struct qedf_ctx *qedf)
{
	struct fc_lport *lport;
	struct fc_lport *base_lport;

	if (!(qedf_is_vport(qedf)))
		return NULL;

	lport = qedf->lport;
	base_lport = shost_priv(vport_to_shost(lport->vport));
	return lport_priv(base_lport);
}

static ssize_t fcoe_mac_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
{
	struct fc_lport *lport = shost_priv(class_to_shost(dev));
	u32 port_id;
	u8 lport_src_id[3];
	u8 fcoe_mac[6];

	port_id = fc_host_port_id(lport->host);
	lport_src_id[2] = (port_id & 0x000000FF);
	lport_src_id[1] = (port_id & 0x0000FF00) >> 8;
	lport_src_id[0] = (port_id & 0x00FF0000) >> 16;
	fc_fcoe_set_mac(fcoe_mac, lport_src_id);

	return scnprintf(buf, PAGE_SIZE, "%pM\n", fcoe_mac);
}

static ssize_t fka_period_show(struct device *dev,
			       struct device_attribute *attr, char *buf)
{
	struct fc_lport *lport = shost_priv(class_to_shost(dev));
	struct qedf_ctx *qedf = lport_priv(lport);
	int fka_period = -1;

	if (qedf_is_vport(qedf))
		qedf = qedf_get_base_qedf(qedf);

	if (qedf->ctlr.sel_fcf)
		fka_period = qedf->ctlr.sel_fcf->fka_period;

	return scnprintf(buf, PAGE_SIZE, "%d\n", fka_period);
}

static DEVICE_ATTR_RO(fcoe_mac);
static DEVICE_ATTR_RO(fka_period);

static struct attribute *qedf_host_attrs[] = {
	&dev_attr_fcoe_mac.attr,
	&dev_attr_fka_period.attr,
	NULL,
};

static const struct attribute_group qedf_host_attr_group = {
	.attrs = qedf_host_attrs
};

const struct attribute_group *qedf_host_groups[] = {
	&qedf_host_attr_group,
	NULL
};

extern const struct qed_fcoe_ops *qed_ops;

void qedf_capture_grc_dump(struct qedf_ctx *qedf)
{
	struct qedf_ctx *base_qedf;

	/* Make sure we use the base qedf to take the GRC dump */
	if (qedf_is_vport(qedf))
		base_qedf = qedf_get_base_qedf(qedf);
	else
		base_qedf = qedf;

	if (test_bit(QEDF_GRCDUMP_CAPTURE, &base_qedf->flags)) {
		QEDF_INFO(&(base_qedf->dbg_ctx), QEDF_LOG_INFO,
		    "GRC Dump already captured.\n");
		return;
	}


	qedf_get_grc_dump(base_qedf->cdev, qed_ops->common,
	    &base_qedf->grcdump, &base_qedf->grcdump_size);
	QEDF_ERR(&(base_qedf->dbg_ctx), "GRC Dump captured.\n");
	set_bit(QEDF_GRCDUMP_CAPTURE, &base_qedf->flags);
	qedf_uevent_emit(base_qedf->lport->host, QEDF_UEVENT_CODE_GRCDUMP,
	    NULL);
}

static ssize_t
qedf_sysfs_read_grcdump(struct file *filep, struct kobject *kobj,
			struct bin_attribute *ba, char *buf, loff_t off,
			size_t count)
{
	ssize_t ret = 0;
	struct fc_lport *lport = shost_priv(dev_to_shost(container_of(kobj,
							struct device, kobj)));
	struct qedf_ctx *qedf = lport_priv(lport);

	if (test_bit(QEDF_GRCDUMP_CAPTURE, &qedf->flags)) {
		ret = memory_read_from_buffer(buf, count, &off,
		    qedf->grcdump, qedf->grcdump_size);
	} else {
		QEDF_ERR(&(qedf->dbg_ctx), "GRC Dump not captured!\n");
	}

	return ret;
}

static ssize_t
qedf_sysfs_write_grcdump(struct file *filep, struct kobject *kobj,
			struct bin_attribute *ba, char *buf, loff_t off,
			size_t count)
{
	struct fc_lport *lport = NULL;
	struct qedf_ctx *qedf = NULL;
	long reading;
	int ret = 0;
	char msg[40];

	if (off != 0)
		return ret;


	lport = shost_priv(dev_to_shost(container_of(kobj,
	    struct device, kobj)));
	qedf = lport_priv(lport);

	buf[1] = 0;
	ret = kstrtol(buf, 10, &reading);
	if (ret) {
		QEDF_ERR(&(qedf->dbg_ctx), "Invalid input, err(%d)\n", ret);
		return ret;
	}

	memset(msg, 0, sizeof(msg));
	switch (reading) {
	case 0:
		memset(qedf->grcdump, 0, qedf->grcdump_size);
		clear_bit(QEDF_GRCDUMP_CAPTURE, &qedf->flags);
		break;
	case 1:
		qedf_capture_grc_dump(qedf);
		break;
	}

	return count;
}

static struct bin_attribute sysfs_grcdump_attr = {
	.attr = {
		.name = "grcdump",
		.mode = S_IRUSR | S_IWUSR,
	},
	.size = 0,
	.read = qedf_sysfs_read_grcdump,
	.write = qedf_sysfs_write_grcdump,
};

static struct sysfs_bin_attrs bin_file_entries[] = {
	{"grcdump", &sysfs_grcdump_attr},
	{NULL},
};

void qedf_create_sysfs_ctx_attr(struct qedf_ctx *qedf)
{
	qedf_create_sysfs_attr(qedf->lport->host, bin_file_entries);
}

void qedf_remove_sysfs_ctx_attr(struct qedf_ctx *qedf)
{
	qedf_remove_sysfs_attr(qedf->lport->host, bin_file_entries);
}
