/*
 * Linux network driver for QLogic BR-series Converged Network Adapter.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License (GPL) Version 2 as
 * published by the Free Software Foundation
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */
/*
 * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
 * Copyright (c) 2014-2015 QLogic Corporation
 * All rights reserved
 * www.qlogic.com
 */

#include <linux/debugfs.h>
#include <linux/module.h>
#include "bnad.h"

/*
 * BNA debufs interface
 *
 * To access the interface, debugfs file system should be mounted
 * if not already mounted using:
 *	mount -t debugfs none /sys/kernel/debug
 *
 * BNA Hierarchy:
 *	- bna/pci_dev:<pci_name>
 * where the pci_name corresponds to the one under /sys/bus/pci/drivers/bna
 *
 * Debugging service available per pci_dev:
 *	fwtrc:  To collect current firmware trace.
 *	fwsave: To collect last saved fw trace as a result of firmware crash.
 *	regwr:  To write one word to chip register
 *	regrd:  To read one or more words from chip register.
 */

struct bnad_debug_info {
	char *debug_buffer;
	void *i_private;
	int buffer_len;
};

static int
bnad_debugfs_open_fwtrc(struct inode *inode, struct file *file)
{
	struct bnad *bnad = inode->i_private;
	struct bnad_debug_info *fw_debug;
	unsigned long flags;
	int rc;

	fw_debug = kzalloc(sizeof(struct bnad_debug_info), GFP_KERNEL);
	if (!fw_debug)
		return -ENOMEM;

	fw_debug->buffer_len = BNA_DBG_FWTRC_LEN;

	fw_debug->debug_buffer = kzalloc(fw_debug->buffer_len, GFP_KERNEL);
	if (!fw_debug->debug_buffer) {
		kfree(fw_debug);
		fw_debug = NULL;
		return -ENOMEM;
	}

	spin_lock_irqsave(&bnad->bna_lock, flags);
	rc = bfa_nw_ioc_debug_fwtrc(&bnad->bna.ioceth.ioc,
			fw_debug->debug_buffer,
			&fw_debug->buffer_len);
	spin_unlock_irqrestore(&bnad->bna_lock, flags);
	if (rc != BFA_STATUS_OK) {
		kfree(fw_debug->debug_buffer);
		fw_debug->debug_buffer = NULL;
		kfree(fw_debug);
		fw_debug = NULL;
		netdev_warn(bnad->netdev, "failed to collect fwtrc\n");
		return -ENOMEM;
	}

	file->private_data = fw_debug;

	return 0;
}

static int
bnad_debugfs_open_fwsave(struct inode *inode, struct file *file)
{
	struct bnad *bnad = inode->i_private;
	struct bnad_debug_info *fw_debug;
	unsigned long flags;
	int rc;

	fw_debug = kzalloc(sizeof(struct bnad_debug_info), GFP_KERNEL);
	if (!fw_debug)
		return -ENOMEM;

	fw_debug->buffer_len = BNA_DBG_FWTRC_LEN;

	fw_debug->debug_buffer = kzalloc(fw_debug->buffer_len, GFP_KERNEL);
	if (!fw_debug->debug_buffer) {
		kfree(fw_debug);
		fw_debug = NULL;
		return -ENOMEM;
	}

	spin_lock_irqsave(&bnad->bna_lock, flags);
	rc = bfa_nw_ioc_debug_fwsave(&bnad->bna.ioceth.ioc,
			fw_debug->debug_buffer,
			&fw_debug->buffer_len);
	spin_unlock_irqrestore(&bnad->bna_lock, flags);
	if (rc != BFA_STATUS_OK && rc != BFA_STATUS_ENOFSAVE) {
		kfree(fw_debug->debug_buffer);
		fw_debug->debug_buffer = NULL;
		kfree(fw_debug);
		fw_debug = NULL;
		netdev_warn(bnad->netdev, "failed to collect fwsave\n");
		return -ENOMEM;
	}

	file->private_data = fw_debug;

	return 0;
}

static int
bnad_debugfs_open_reg(struct inode *inode, struct file *file)
{
	struct bnad_debug_info *reg_debug;

	reg_debug = kzalloc(sizeof(struct bnad_debug_info), GFP_KERNEL);
	if (!reg_debug)
		return -ENOMEM;

	reg_debug->i_private = inode->i_private;

	file->private_data = reg_debug;

	return 0;
}

static int
bnad_get_debug_drvinfo(struct bnad *bnad, void *buffer, u32 len)
{
	struct bnad_drvinfo *drvinfo = (struct bnad_drvinfo *) buffer;
	struct bnad_iocmd_comp fcomp;
	unsigned long flags = 0;
	int ret = BFA_STATUS_FAILED;

	/* Get IOC info */
	spin_lock_irqsave(&bnad->bna_lock, flags);
	bfa_nw_ioc_get_attr(&bnad->bna.ioceth.ioc, &drvinfo->ioc_attr);
	spin_unlock_irqrestore(&bnad->bna_lock, flags);

	/* Retrieve CEE related info */
	fcomp.bnad = bnad;
	fcomp.comp_status = 0;
	init_completion(&fcomp.comp);
	spin_lock_irqsave(&bnad->bna_lock, flags);
	ret = bfa_nw_cee_get_attr(&bnad->bna.cee, &drvinfo->cee_attr,
				bnad_cb_completion, &fcomp);
	if (ret != BFA_STATUS_OK) {
		spin_unlock_irqrestore(&bnad->bna_lock, flags);
		goto out;
	}
	spin_unlock_irqrestore(&bnad->bna_lock, flags);
	wait_for_completion(&fcomp.comp);
	drvinfo->cee_status = fcomp.comp_status;

	/* Retrieve flash partition info */
	fcomp.comp_status = 0;
	reinit_completion(&fcomp.comp);
	spin_lock_irqsave(&bnad->bna_lock, flags);
	ret = bfa_nw_flash_get_attr(&bnad->bna.flash, &drvinfo->flash_attr,
				bnad_cb_completion, &fcomp);
	if (ret != BFA_STATUS_OK) {
		spin_unlock_irqrestore(&bnad->bna_lock, flags);
		goto out;
	}
	spin_unlock_irqrestore(&bnad->bna_lock, flags);
	wait_for_completion(&fcomp.comp);
	drvinfo->flash_status = fcomp.comp_status;
out:
	return ret;
}

static int
bnad_debugfs_open_drvinfo(struct inode *inode, struct file *file)
{
	struct bnad *bnad = inode->i_private;
	struct bnad_debug_info *drv_info;
	int rc;

	drv_info = kzalloc(sizeof(struct bnad_debug_info), GFP_KERNEL);
	if (!drv_info)
		return -ENOMEM;

	drv_info->buffer_len = sizeof(struct bnad_drvinfo);

	drv_info->debug_buffer = kzalloc(drv_info->buffer_len, GFP_KERNEL);
	if (!drv_info->debug_buffer) {
		kfree(drv_info);
		drv_info = NULL;
		return -ENOMEM;
	}

	mutex_lock(&bnad->conf_mutex);
	rc = bnad_get_debug_drvinfo(bnad, drv_info->debug_buffer,
				drv_info->buffer_len);
	mutex_unlock(&bnad->conf_mutex);
	if (rc != BFA_STATUS_OK) {
		kfree(drv_info->debug_buffer);
		drv_info->debug_buffer = NULL;
		kfree(drv_info);
		drv_info = NULL;
		netdev_warn(bnad->netdev, "failed to collect drvinfo\n");
		return -ENOMEM;
	}

	file->private_data = drv_info;

	return 0;
}

/* Changes the current file position */
static loff_t
bnad_debugfs_lseek(struct file *file, loff_t offset, int orig)
{
	struct bnad_debug_info *debug = file->private_data;

	if (!debug)
		return -EINVAL;

	return fixed_size_llseek(file, offset, orig, debug->buffer_len);
}

static ssize_t
bnad_debugfs_read(struct file *file, char __user *buf,
		  size_t nbytes, loff_t *pos)
{
	struct bnad_debug_info *debug = file->private_data;

	if (!debug || !debug->debug_buffer)
		return 0;

	return simple_read_from_buffer(buf, nbytes, pos,
				debug->debug_buffer, debug->buffer_len);
}

#define BFA_REG_CT_ADDRSZ	(0x40000)
#define BFA_REG_CB_ADDRSZ	(0x20000)
#define BFA_REG_ADDRSZ(__ioc)	\
	((u32)(bfa_asic_id_ctc(bfa_ioc_devid(__ioc)) ?  \
	 BFA_REG_CT_ADDRSZ : BFA_REG_CB_ADDRSZ))
#define BFA_REG_ADDRMSK(__ioc)	(BFA_REG_ADDRSZ(__ioc) - 1)

/*
 * Function to check if the register offset passed is valid.
 */
static int
bna_reg_offset_check(struct bfa_ioc *ioc, u32 offset, u32 len)
{
	u8 area;

	/* check [16:15] */
	area = (offset >> 15) & 0x7;
	if (area == 0) {
		/* PCIe core register */
		if (offset + (len << 2) > 0x8000)	/* 8k dwords or 32KB */
			return BFA_STATUS_EINVAL;
	} else if (area == 0x1) {
		/* CB 32 KB memory page */
		if (offset + (len << 2) > 0x10000)	/* 8k dwords or 32KB */
			return BFA_STATUS_EINVAL;
	} else {
		/* CB register space 64KB */
		if (offset + (len << 2) > BFA_REG_ADDRMSK(ioc))
			return BFA_STATUS_EINVAL;
	}
	return BFA_STATUS_OK;
}

static ssize_t
bnad_debugfs_read_regrd(struct file *file, char __user *buf,
			size_t nbytes, loff_t *pos)
{
	struct bnad_debug_info *regrd_debug = file->private_data;
	struct bnad *bnad = (struct bnad *)regrd_debug->i_private;
	ssize_t rc;

	if (!bnad->regdata)
		return 0;

	rc = simple_read_from_buffer(buf, nbytes, pos,
			bnad->regdata, bnad->reglen);

	if ((*pos + nbytes) >= bnad->reglen) {
		kfree(bnad->regdata);
		bnad->regdata = NULL;
		bnad->reglen = 0;
	}

	return rc;
}

static ssize_t
bnad_debugfs_write_regrd(struct file *file, const char __user *buf,
		size_t nbytes, loff_t *ppos)
{
	struct bnad_debug_info *regrd_debug = file->private_data;
	struct bnad *bnad = (struct bnad *)regrd_debug->i_private;
	struct bfa_ioc *ioc = &bnad->bna.ioceth.ioc;
	int rc, i;
	u32 addr, len;
	u32 *regbuf;
	void __iomem *rb, *reg_addr;
	unsigned long flags;
	void *kern_buf;

	/* Copy the user space buf */
	kern_buf = memdup_user(buf, nbytes);
	if (IS_ERR(kern_buf))
		return PTR_ERR(kern_buf);

	rc = sscanf(kern_buf, "%x:%x", &addr, &len);
	if (rc < 2 || len > UINT_MAX >> 2) {
		netdev_warn(bnad->netdev, "failed to read user buffer\n");
		kfree(kern_buf);
		return -EINVAL;
	}

	kfree(kern_buf);
	kfree(bnad->regdata);
	bnad->reglen = 0;

	bnad->regdata = kzalloc(len << 2, GFP_KERNEL);
	if (!bnad->regdata)
		return -ENOMEM;

	bnad->reglen = len << 2;
	rb = bfa_ioc_bar0(ioc);
	addr &= BFA_REG_ADDRMSK(ioc);

	/* offset and len sanity check */
	rc = bna_reg_offset_check(ioc, addr, len);
	if (rc) {
		netdev_warn(bnad->netdev, "failed reg offset check\n");
		kfree(bnad->regdata);
		bnad->regdata = NULL;
		bnad->reglen = 0;
		return -EINVAL;
	}

	reg_addr = rb + addr;
	regbuf =  (u32 *)bnad->regdata;
	spin_lock_irqsave(&bnad->bna_lock, flags);
	for (i = 0; i < len; i++) {
		*regbuf = readl(reg_addr);
		regbuf++;
		reg_addr += sizeof(u32);
	}
	spin_unlock_irqrestore(&bnad->bna_lock, flags);

	return nbytes;
}

static ssize_t
bnad_debugfs_write_regwr(struct file *file, const char __user *buf,
		size_t nbytes, loff_t *ppos)
{
	struct bnad_debug_info *debug = file->private_data;
	struct bnad *bnad = (struct bnad *)debug->i_private;
	struct bfa_ioc *ioc = &bnad->bna.ioceth.ioc;
	int rc;
	u32 addr, val;
	void __iomem *reg_addr;
	unsigned long flags;
	void *kern_buf;

	/* Copy the user space buf */
	kern_buf = memdup_user(buf, nbytes);
	if (IS_ERR(kern_buf))
		return PTR_ERR(kern_buf);

	rc = sscanf(kern_buf, "%x:%x", &addr, &val);
	if (rc < 2) {
		netdev_warn(bnad->netdev, "failed to read user buffer\n");
		kfree(kern_buf);
		return -EINVAL;
	}
	kfree(kern_buf);

	addr &= BFA_REG_ADDRMSK(ioc); /* offset only 17 bit and word align */

	/* offset and len sanity check */
	rc = bna_reg_offset_check(ioc, addr, 1);
	if (rc) {
		netdev_warn(bnad->netdev, "failed reg offset check\n");
		return -EINVAL;
	}

	reg_addr = (bfa_ioc_bar0(ioc)) + addr;
	spin_lock_irqsave(&bnad->bna_lock, flags);
	writel(val, reg_addr);
	spin_unlock_irqrestore(&bnad->bna_lock, flags);

	return nbytes;
}

static int
bnad_debugfs_release(struct inode *inode, struct file *file)
{
	struct bnad_debug_info *debug = file->private_data;

	if (!debug)
		return 0;

	file->private_data = NULL;
	kfree(debug);
	return 0;
}

static int
bnad_debugfs_buffer_release(struct inode *inode, struct file *file)
{
	struct bnad_debug_info *debug = file->private_data;

	if (!debug)
		return 0;

	kfree(debug->debug_buffer);

	file->private_data = NULL;
	kfree(debug);
	debug = NULL;
	return 0;
}

static const struct file_operations bnad_debugfs_op_fwtrc = {
	.owner		=	THIS_MODULE,
	.open		=	bnad_debugfs_open_fwtrc,
	.llseek		=	bnad_debugfs_lseek,
	.read		=	bnad_debugfs_read,
	.release	=	bnad_debugfs_buffer_release,
};

static const struct file_operations bnad_debugfs_op_fwsave = {
	.owner		=	THIS_MODULE,
	.open		=	bnad_debugfs_open_fwsave,
	.llseek		=	bnad_debugfs_lseek,
	.read		=	bnad_debugfs_read,
	.release	=	bnad_debugfs_buffer_release,
};

static const struct file_operations bnad_debugfs_op_regrd = {
	.owner		=       THIS_MODULE,
	.open		=	bnad_debugfs_open_reg,
	.llseek		=	bnad_debugfs_lseek,
	.read		=	bnad_debugfs_read_regrd,
	.write		=	bnad_debugfs_write_regrd,
	.release	=	bnad_debugfs_release,
};

static const struct file_operations bnad_debugfs_op_regwr = {
	.owner		=	THIS_MODULE,
	.open		=	bnad_debugfs_open_reg,
	.llseek		=	bnad_debugfs_lseek,
	.write		=	bnad_debugfs_write_regwr,
	.release	=	bnad_debugfs_release,
};

static const struct file_operations bnad_debugfs_op_drvinfo = {
	.owner		=	THIS_MODULE,
	.open		=	bnad_debugfs_open_drvinfo,
	.llseek		=	bnad_debugfs_lseek,
	.read		=	bnad_debugfs_read,
	.release	=	bnad_debugfs_buffer_release,
};

struct bnad_debugfs_entry {
	const char *name;
	umode_t  mode;
	const struct file_operations *fops;
};

static const struct bnad_debugfs_entry bnad_debugfs_files[] = {
	{ "fwtrc",  S_IFREG|S_IRUGO, &bnad_debugfs_op_fwtrc, },
	{ "fwsave", S_IFREG|S_IRUGO, &bnad_debugfs_op_fwsave, },
	{ "regrd",  S_IFREG|S_IRUGO|S_IWUSR, &bnad_debugfs_op_regrd, },
	{ "regwr",  S_IFREG|S_IWUSR, &bnad_debugfs_op_regwr, },
	{ "drvinfo", S_IFREG|S_IRUGO, &bnad_debugfs_op_drvinfo, },
};

static struct dentry *bna_debugfs_root;
static atomic_t bna_debugfs_port_count;

/* Initialize debugfs interface for BNA */
void
bnad_debugfs_init(struct bnad *bnad)
{
	const struct bnad_debugfs_entry *file;
	char name[64];
	int i;

	/* Setup the BNA debugfs root directory*/
	if (!bna_debugfs_root) {
		bna_debugfs_root = debugfs_create_dir("bna", NULL);
		atomic_set(&bna_debugfs_port_count, 0);
		if (!bna_debugfs_root) {
			netdev_warn(bnad->netdev,
				    "debugfs root dir creation failed\n");
			return;
		}
	}

	/* Setup the pci_dev debugfs directory for the port */
	snprintf(name, sizeof(name), "pci_dev:%s", pci_name(bnad->pcidev));
	if (!bnad->port_debugfs_root) {
		bnad->port_debugfs_root =
			debugfs_create_dir(name, bna_debugfs_root);
		if (!bnad->port_debugfs_root) {
			netdev_warn(bnad->netdev,
				    "debugfs root dir creation failed\n");
			return;
		}

		atomic_inc(&bna_debugfs_port_count);

		for (i = 0; i < ARRAY_SIZE(bnad_debugfs_files); i++) {
			file = &bnad_debugfs_files[i];
			bnad->bnad_dentry_files[i] =
					debugfs_create_file(file->name,
							file->mode,
							bnad->port_debugfs_root,
							bnad,
							file->fops);
			if (!bnad->bnad_dentry_files[i]) {
				netdev_warn(bnad->netdev,
					    "create %s entry failed\n",
					    file->name);
				return;
			}
		}
	}
}

/* Uninitialize debugfs interface for BNA */
void
bnad_debugfs_uninit(struct bnad *bnad)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(bnad_debugfs_files); i++) {
		if (bnad->bnad_dentry_files[i]) {
			debugfs_remove(bnad->bnad_dentry_files[i]);
			bnad->bnad_dentry_files[i] = NULL;
		}
	}

	/* Remove the pci_dev debugfs directory for the port */
	if (bnad->port_debugfs_root) {
		debugfs_remove(bnad->port_debugfs_root);
		bnad->port_debugfs_root = NULL;
		atomic_dec(&bna_debugfs_port_count);
	}

	/* Remove the BNA debugfs root directory */
	if (atomic_read(&bna_debugfs_port_count) == 0) {
		debugfs_remove(bna_debugfs_root);
		bna_debugfs_root = NULL;
	}
}
