// 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
qedf_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
qedf_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(fcoe_mac, S_IRUGO, qedf_fcoe_mac_show, NULL);
static DEVICE_ATTR(fka_period, S_IRUGO, qedf_fka_period_show, NULL);

struct device_attribute *qedf_host_attrs[] = {
	&dev_attr_fcoe_mac,
	&dev_attr_fka_period,
	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);
}
