/*
 * Copyright(c) 2018 Intel Corporation.
 *
 * This file is provided under a dual BSD/GPLv2 license.  When using or
 * redistributing this file, you may do so under either license.
 *
 * GPL LICENSE SUMMARY
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License 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.
 *
 * BSD LICENSE
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  - Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  - Neither the name of Intel Corporation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/bitmap.h>

#include "debugfs.h"
#include "fault.h"
#include "trace.h"

#define HFI1_FAULT_DIR_TX   BIT(0)
#define HFI1_FAULT_DIR_RX   BIT(1)
#define HFI1_FAULT_DIR_TXRX (HFI1_FAULT_DIR_TX | HFI1_FAULT_DIR_RX)

static void *_fault_stats_seq_start(struct seq_file *s, loff_t *pos)
{
	struct hfi1_opcode_stats_perctx *opstats;

	if (*pos >= ARRAY_SIZE(opstats->stats))
		return NULL;
	return pos;
}

static void *_fault_stats_seq_next(struct seq_file *s, void *v, loff_t *pos)
{
	struct hfi1_opcode_stats_perctx *opstats;

	++*pos;
	if (*pos >= ARRAY_SIZE(opstats->stats))
		return NULL;
	return pos;
}

static void _fault_stats_seq_stop(struct seq_file *s, void *v)
{
}

static int _fault_stats_seq_show(struct seq_file *s, void *v)
{
	loff_t *spos = v;
	loff_t i = *spos, j;
	u64 n_packets = 0, n_bytes = 0;
	struct hfi1_ibdev *ibd = (struct hfi1_ibdev *)s->private;
	struct hfi1_devdata *dd = dd_from_dev(ibd);
	struct hfi1_ctxtdata *rcd;

	for (j = 0; j < dd->first_dyn_alloc_ctxt; j++) {
		rcd = hfi1_rcd_get_by_index(dd, j);
		if (rcd) {
			n_packets += rcd->opstats->stats[i].n_packets;
			n_bytes += rcd->opstats->stats[i].n_bytes;
		}
		hfi1_rcd_put(rcd);
	}
	for_each_possible_cpu(j) {
		struct hfi1_opcode_stats_perctx *sp =
			per_cpu_ptr(dd->tx_opstats, j);

		n_packets += sp->stats[i].n_packets;
		n_bytes += sp->stats[i].n_bytes;
	}
	if (!n_packets && !n_bytes)
		return SEQ_SKIP;
	if (!ibd->fault->n_rxfaults[i] && !ibd->fault->n_txfaults[i])
		return SEQ_SKIP;
	seq_printf(s, "%02llx %llu/%llu (faults rx:%llu faults: tx:%llu)\n", i,
		   (unsigned long long)n_packets,
		   (unsigned long long)n_bytes,
		   (unsigned long long)ibd->fault->n_rxfaults[i],
		   (unsigned long long)ibd->fault->n_txfaults[i]);
	return 0;
}

DEBUGFS_SEQ_FILE_OPS(fault_stats);
DEBUGFS_SEQ_FILE_OPEN(fault_stats);
DEBUGFS_FILE_OPS(fault_stats);

static int fault_opcodes_open(struct inode *inode, struct file *file)
{
	file->private_data = inode->i_private;
	return nonseekable_open(inode, file);
}

static ssize_t fault_opcodes_write(struct file *file, const char __user *buf,
				   size_t len, loff_t *pos)
{
	ssize_t ret = 0;
	/* 1280 = 256 opcodes * 4 chars/opcode + 255 commas + NULL */
	size_t copy, datalen = 1280;
	char *data, *token, *ptr, *end;
	struct fault *fault = file->private_data;

	data = kcalloc(datalen, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;
	copy = min(len, datalen - 1);
	if (copy_from_user(data, buf, copy))
		return -EFAULT;

	ret = debugfs_file_get(file->f_path.dentry);
	if (unlikely(ret))
		return ret;
	ptr = data;
	token = ptr;
	for (ptr = data; *ptr; ptr = end + 1, token = ptr) {
		char *dash;
		unsigned long range_start, range_end, i;
		bool remove = false;

		end = strchr(ptr, ',');
		if (end)
			*end = '\0';
		if (token[0] == '-') {
			remove = true;
			token++;
		}
		dash = strchr(token, '-');
		if (dash)
			*dash = '\0';
		if (kstrtoul(token, 0, &range_start))
			break;
		if (dash) {
			token = dash + 1;
			if (kstrtoul(token, 0, &range_end))
				break;
		} else {
			range_end = range_start;
		}
		if (range_start == range_end && range_start == -1UL) {
			bitmap_zero(fault->opcodes, sizeof(fault->opcodes) *
				    BITS_PER_BYTE);
			break;
		}
		for (i = range_start; i <= range_end; i++) {
			if (remove)
				clear_bit(i, fault->opcodes);
			else
				set_bit(i, fault->opcodes);
		}
		if (!end)
			break;
	}
	ret = len;

	debugfs_file_put(file->f_path.dentry);
	kfree(data);
	return ret;
}

static ssize_t fault_opcodes_read(struct file *file, char __user *buf,
				  size_t len, loff_t *pos)
{
	ssize_t ret = 0;
	char *data;
	size_t datalen = 1280, size = 0; /* see fault_opcodes_write() */
	unsigned long bit = 0, zero = 0;
	struct fault *fault = file->private_data;
	size_t bitsize = sizeof(fault->opcodes) * BITS_PER_BYTE;

	data = kcalloc(datalen, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;
	ret = debugfs_file_get(file->f_path.dentry);
	if (unlikely(ret))
		return ret;
	bit = find_first_bit(fault->opcodes, bitsize);
	while (bit < bitsize) {
		zero = find_next_zero_bit(fault->opcodes, bitsize, bit);
		if (zero - 1 != bit)
			size += snprintf(data + size,
					 datalen - size - 1,
					 "0x%lx-0x%lx,", bit, zero - 1);
		else
			size += snprintf(data + size,
					 datalen - size - 1, "0x%lx,",
					 bit);
		bit = find_next_bit(fault->opcodes, bitsize, zero);
	}
	debugfs_file_put(file->f_path.dentry);
	data[size - 1] = '\n';
	data[size] = '\0';
	ret = simple_read_from_buffer(buf, len, pos, data, size);
	kfree(data);
	return ret;
}

static const struct file_operations __fault_opcodes_fops = {
	.owner = THIS_MODULE,
	.open = fault_opcodes_open,
	.read = fault_opcodes_read,
	.write = fault_opcodes_write,
	.llseek = no_llseek
};

void hfi1_fault_exit_debugfs(struct hfi1_ibdev *ibd)
{
	if (ibd->fault)
		debugfs_remove_recursive(ibd->fault->dir);
	kfree(ibd->fault);
	ibd->fault = NULL;
}

int hfi1_fault_init_debugfs(struct hfi1_ibdev *ibd)
{
	struct dentry *parent = ibd->hfi1_ibdev_dbg;

	ibd->fault = kzalloc(sizeof(*ibd->fault), GFP_KERNEL);
	if (!ibd->fault)
		return -ENOMEM;

	ibd->fault->attr.interval = 1;
	ibd->fault->attr.require_end = ULONG_MAX;
	ibd->fault->attr.stacktrace_depth = 32;
	ibd->fault->attr.dname = NULL;
	ibd->fault->attr.verbose = 0;
	ibd->fault->enable = false;
	ibd->fault->opcode = false;
	ibd->fault->fault_skip = 0;
	ibd->fault->skip = 0;
	ibd->fault->direction = HFI1_FAULT_DIR_TXRX;
	ibd->fault->suppress_err = false;
	bitmap_zero(ibd->fault->opcodes,
		    sizeof(ibd->fault->opcodes) * BITS_PER_BYTE);

	ibd->fault->dir =
		fault_create_debugfs_attr("fault", parent,
					  &ibd->fault->attr);
	if (IS_ERR(ibd->fault->dir)) {
		kfree(ibd->fault);
		ibd->fault = NULL;
		return -ENOENT;
	}

	DEBUGFS_SEQ_FILE_CREATE(fault_stats, ibd->fault->dir, ibd);
	if (!debugfs_create_bool("enable", 0600, ibd->fault->dir,
				 &ibd->fault->enable))
		goto fail;
	if (!debugfs_create_bool("suppress_err", 0600,
				 ibd->fault->dir,
				 &ibd->fault->suppress_err))
		goto fail;
	if (!debugfs_create_bool("opcode_mode", 0600, ibd->fault->dir,
				 &ibd->fault->opcode))
		goto fail;
	if (!debugfs_create_file("opcodes", 0600, ibd->fault->dir,
				 ibd->fault, &__fault_opcodes_fops))
		goto fail;
	if (!debugfs_create_u64("skip_pkts", 0600,
				ibd->fault->dir,
				&ibd->fault->fault_skip))
		goto fail;
	if (!debugfs_create_u64("skip_usec", 0600,
				ibd->fault->dir,
				&ibd->fault->fault_skip_usec))
		goto fail;
	if (!debugfs_create_u8("direction", 0600, ibd->fault->dir,
			       &ibd->fault->direction))
		goto fail;

	return 0;
fail:
	hfi1_fault_exit_debugfs(ibd);
	return -ENOMEM;
}

bool hfi1_dbg_fault_suppress_err(struct hfi1_ibdev *ibd)
{
	if (ibd->fault)
		return ibd->fault->suppress_err;
	return false;
}

static bool __hfi1_should_fault(struct hfi1_ibdev *ibd, u32 opcode,
				u8 direction)
{
	bool ret = false;

	if (!ibd->fault || !ibd->fault->enable)
		return false;
	if (!(ibd->fault->direction & direction))
		return false;
	if (ibd->fault->opcode) {
		if (bitmap_empty(ibd->fault->opcodes,
				 (sizeof(ibd->fault->opcodes) *
				  BITS_PER_BYTE)))
			return false;
		if (!(test_bit(opcode, ibd->fault->opcodes)))
			return false;
	}
	if (ibd->fault->fault_skip_usec &&
	    time_before(jiffies, ibd->fault->skip_usec))
		return false;
	if (ibd->fault->fault_skip && ibd->fault->skip) {
		ibd->fault->skip--;
		return false;
	}
	ret = should_fail(&ibd->fault->attr, 1);
	if (ret) {
		ibd->fault->skip = ibd->fault->fault_skip;
		ibd->fault->skip_usec = jiffies +
			usecs_to_jiffies(ibd->fault->fault_skip_usec);
	}
	return ret;
}

bool hfi1_dbg_should_fault_tx(struct rvt_qp *qp, u32 opcode)
{
	struct hfi1_ibdev *ibd = to_idev(qp->ibqp.device);

	if (__hfi1_should_fault(ibd, opcode, HFI1_FAULT_DIR_TX)) {
		trace_hfi1_fault_opcode(qp, opcode);
		ibd->fault->n_txfaults[opcode]++;
		return true;
	}
	return false;
}

bool hfi1_dbg_should_fault_rx(struct hfi1_packet *packet)
{
	struct hfi1_ibdev *ibd = &packet->rcd->dd->verbs_dev;

	if (__hfi1_should_fault(ibd, packet->opcode, HFI1_FAULT_DIR_RX)) {
		trace_hfi1_fault_packet(packet);
		ibd->fault->n_rxfaults[packet->opcode]++;
		return true;
	}
	return false;
}
