/*
 * Wireless Host Controller (WHC) debug.
 *
 * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/export.h>

#include "../../wusbcore/wusbhc.h"

#include "whcd.h"

struct whc_dbg {
	struct dentry *di_f;
	struct dentry *asl_f;
	struct dentry *pzl_f;
};

static void qset_print(struct seq_file *s, struct whc_qset *qset)
{
	static const char *qh_type[] = {
		"ctrl", "isoc", "bulk", "intr", "rsvd", "rsvd", "rsvd", "lpintr", };
	struct whc_std *std;
	struct urb *urb = NULL;
	int i;

	seq_printf(s, "qset %08x", (u32)qset->qset_dma);
	if (&qset->list_node == qset->whc->async_list.prev) {
		seq_printf(s, " (dummy)\n");
	} else {
		seq_printf(s, " ep%d%s-%s maxpkt: %d\n",
			   qset->qh.info1 & 0x0f,
			   (qset->qh.info1 >> 4) & 0x1 ? "in" : "out",
			   qh_type[(qset->qh.info1 >> 5) & 0x7],
			   (qset->qh.info1 >> 16) & 0xffff);
	}
	seq_printf(s, "  -> %08x\n", (u32)qset->qh.link);
	seq_printf(s, "  info: %08x %08x %08x\n",
		   qset->qh.info1, qset->qh.info2,  qset->qh.info3);
	seq_printf(s, "  sts: %04x errs: %d curwin: %08x\n",
		   qset->qh.status, qset->qh.err_count, qset->qh.cur_window);
	seq_printf(s, "  TD: sts: %08x opts: %08x\n",
		   qset->qh.overlay.qtd.status, qset->qh.overlay.qtd.options);

	for (i = 0; i < WHCI_QSET_TD_MAX; i++) {
		seq_printf(s, "  %c%c TD[%d]: sts: %08x opts: %08x ptr: %08x\n",
			i == qset->td_start ? 'S' : ' ',
			i == qset->td_end ? 'E' : ' ',
			i, qset->qtd[i].status, qset->qtd[i].options,
			(u32)qset->qtd[i].page_list_ptr);
	}
	seq_printf(s, "  ntds: %d\n", qset->ntds);
	list_for_each_entry(std, &qset->stds, list_node) {
		if (urb != std->urb) {
			urb = std->urb;
			seq_printf(s, "  urb %p transferred: %d bytes\n", urb,
				urb->actual_length);
		}
		if (std->qtd)
			seq_printf(s, "    sTD[%td]: %zu bytes @ %08x\n",
				std->qtd - &qset->qtd[0],
				std->len, std->num_pointers ?
				(u32)(std->pl_virt[0].buf_ptr) : (u32)std->dma_addr);
		else
			seq_printf(s, "    sTD[-]: %zd bytes @ %08x\n",
				std->len, std->num_pointers ?
				(u32)(std->pl_virt[0].buf_ptr) : (u32)std->dma_addr);
	}
}

static int di_print(struct seq_file *s, void *p)
{
	struct whc *whc = s->private;
	int d;

	for (d = 0; d < whc->n_devices; d++) {
		struct di_buf_entry *di = &whc->di_buf[d];

		seq_printf(s, "DI[%d]\n", d);
		seq_printf(s, "  availability: %*pb\n",
			   UWB_NUM_MAS, (unsigned long *)di->availability_info);
		seq_printf(s, "  %c%c key idx: %d dev addr: %d\n",
			   (di->addr_sec_info & WHC_DI_SECURE) ? 'S' : ' ',
			   (di->addr_sec_info & WHC_DI_DISABLE) ? 'D' : ' ',
			   (di->addr_sec_info & WHC_DI_KEY_IDX_MASK) >> 8,
			   (di->addr_sec_info & WHC_DI_DEV_ADDR_MASK));
	}
	return 0;
}

static int asl_print(struct seq_file *s, void *p)
{
	struct whc *whc = s->private;
	struct whc_qset *qset;

	list_for_each_entry(qset, &whc->async_list, list_node) {
		qset_print(s, qset);
	}

	return 0;
}

static int pzl_print(struct seq_file *s, void *p)
{
	struct whc *whc = s->private;
	struct whc_qset *qset;
	int period;

	for (period = 0; period < 5; period++) {
		seq_printf(s, "Period %d\n", period);
		list_for_each_entry(qset, &whc->periodic_list[period], list_node) {
			qset_print(s, qset);
		}
	}
	return 0;
}

static int di_open(struct inode *inode, struct file *file)
{
	return single_open(file, di_print, inode->i_private);
}

static int asl_open(struct inode *inode, struct file *file)
{
	return single_open(file, asl_print, inode->i_private);
}

static int pzl_open(struct inode *inode, struct file *file)
{
	return single_open(file, pzl_print, inode->i_private);
}

static const struct file_operations di_fops = {
	.open    = di_open,
	.read    = seq_read,
	.llseek  = seq_lseek,
	.release = single_release,
	.owner   = THIS_MODULE,
};

static const struct file_operations asl_fops = {
	.open    = asl_open,
	.read    = seq_read,
	.llseek  = seq_lseek,
	.release = single_release,
	.owner   = THIS_MODULE,
};

static const struct file_operations pzl_fops = {
	.open    = pzl_open,
	.read    = seq_read,
	.llseek  = seq_lseek,
	.release = single_release,
	.owner   = THIS_MODULE,
};

void whc_dbg_init(struct whc *whc)
{
	if (whc->wusbhc.pal.debugfs_dir == NULL)
		return;

	whc->dbg = kzalloc(sizeof(struct whc_dbg), GFP_KERNEL);
	if (whc->dbg == NULL)
		return;

	whc->dbg->di_f = debugfs_create_file("di", 0444,
					      whc->wusbhc.pal.debugfs_dir, whc,
					      &di_fops);
	whc->dbg->asl_f = debugfs_create_file("asl", 0444,
					      whc->wusbhc.pal.debugfs_dir, whc,
					      &asl_fops);
	whc->dbg->pzl_f = debugfs_create_file("pzl", 0444,
					      whc->wusbhc.pal.debugfs_dir, whc,
					      &pzl_fops);
}

void whc_dbg_clean_up(struct whc *whc)
{
	if (whc->dbg) {
		debugfs_remove(whc->dbg->pzl_f);
		debugfs_remove(whc->dbg->asl_f);
		debugfs_remove(whc->dbg->di_f);
		kfree(whc->dbg);
	}
}
