// SPDX-License-Identifier: GPL-2.0
/*
 * Wireless Host Controller (WHC) debug.
 *
 * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
 */
#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);
	}
}
