/*
 * Copyright (c) 2012 Broadcom Corporation
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
#include <linux/debugfs.h>
#include <linux/netdevice.h>
#include <linux/module.h>

#include <brcmu_wifi.h>
#include <brcmu_utils.h>
#include "dhd.h"
#include "dhd_bus.h"
#include "dhd_dbg.h"
#include "tracepoint.h"

static struct dentry *root_folder;

void brcmf_debugfs_init(void)
{
	root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL);
	if (IS_ERR(root_folder))
		root_folder = NULL;
}

void brcmf_debugfs_exit(void)
{
	if (!root_folder)
		return;

	debugfs_remove_recursive(root_folder);
	root_folder = NULL;
}

int brcmf_debugfs_attach(struct brcmf_pub *drvr)
{
	struct device *dev = drvr->bus_if->dev;

	if (!root_folder)
		return -ENODEV;

	drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder);
	return PTR_ERR_OR_ZERO(drvr->dbgfs_dir);
}

void brcmf_debugfs_detach(struct brcmf_pub *drvr)
{
	if (!IS_ERR_OR_NULL(drvr->dbgfs_dir))
		debugfs_remove_recursive(drvr->dbgfs_dir);
}

struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr)
{
	return drvr->dbgfs_dir;
}

static
ssize_t brcmf_debugfs_sdio_counter_read(struct file *f, char __user *data,
					size_t count, loff_t *ppos)
{
	struct brcmf_sdio_count *sdcnt = f->private_data;
	char buf[750];
	int res;

	/* only allow read from start */
	if (*ppos > 0)
		return 0;

	res = scnprintf(buf, sizeof(buf),
			"intrcount:    %u\nlastintrs:    %u\n"
			"pollcnt:      %u\nregfails:     %u\n"
			"tx_sderrs:    %u\nfcqueued:     %u\n"
			"rxrtx:        %u\nrx_toolong:   %u\n"
			"rxc_errors:   %u\nrx_hdrfail:   %u\n"
			"rx_badhdr:    %u\nrx_badseq:    %u\n"
			"fc_rcvd:      %u\nfc_xoff:      %u\n"
			"fc_xon:       %u\nrxglomfail:   %u\n"
			"rxglomframes: %u\nrxglompkts:   %u\n"
			"f2rxhdrs:     %u\nf2rxdata:     %u\n"
			"f2txdata:     %u\nf1regdata:    %u\n"
			"tickcnt:      %u\ntx_ctlerrs:   %lu\n"
			"tx_ctlpkts:   %lu\nrx_ctlerrs:   %lu\n"
			"rx_ctlpkts:   %lu\nrx_readahead: %lu\n",
			sdcnt->intrcount, sdcnt->lastintrs,
			sdcnt->pollcnt, sdcnt->regfails,
			sdcnt->tx_sderrs, sdcnt->fcqueued,
			sdcnt->rxrtx, sdcnt->rx_toolong,
			sdcnt->rxc_errors, sdcnt->rx_hdrfail,
			sdcnt->rx_badhdr, sdcnt->rx_badseq,
			sdcnt->fc_rcvd, sdcnt->fc_xoff,
			sdcnt->fc_xon, sdcnt->rxglomfail,
			sdcnt->rxglomframes, sdcnt->rxglompkts,
			sdcnt->f2rxhdrs, sdcnt->f2rxdata,
			sdcnt->f2txdata, sdcnt->f1regdata,
			sdcnt->tickcnt, sdcnt->tx_ctlerrs,
			sdcnt->tx_ctlpkts, sdcnt->rx_ctlerrs,
			sdcnt->rx_ctlpkts, sdcnt->rx_readahead_cnt);

	return simple_read_from_buffer(data, count, ppos, buf, res);
}

static const struct file_operations brcmf_debugfs_sdio_counter_ops = {
	.owner = THIS_MODULE,
	.open = simple_open,
	.read = brcmf_debugfs_sdio_counter_read
};

void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr,
				     struct brcmf_sdio_count *sdcnt)
{
	struct dentry *dentry = drvr->dbgfs_dir;

	if (!IS_ERR_OR_NULL(dentry))
		debugfs_create_file("counters", S_IRUGO, dentry,
				    sdcnt, &brcmf_debugfs_sdio_counter_ops);
}

static
ssize_t brcmf_debugfs_fws_stats_read(struct file *f, char __user *data,
				     size_t count, loff_t *ppos)
{
	struct brcmf_fws_stats *fwstats = f->private_data;
	char buf[650];
	int res;

	/* only allow read from start */
	if (*ppos > 0)
		return 0;

	res = scnprintf(buf, sizeof(buf),
			"header_pulls:      %u\n"
			"header_only_pkt:   %u\n"
			"tlv_parse_failed:  %u\n"
			"tlv_invalid_type:  %u\n"
			"mac_update_fails:  %u\n"
			"ps_update_fails:   %u\n"
			"if_update_fails:   %u\n"
			"pkt2bus:           %u\n"
			"generic_error:     %u\n"
			"rollback_success:  %u\n"
			"rollback_failed:   %u\n"
			"delayq_full:       %u\n"
			"supprq_full:       %u\n"
			"txs_indicate:      %u\n"
			"txs_discard:       %u\n"
			"txs_suppr_core:    %u\n"
			"txs_suppr_ps:      %u\n"
			"txs_tossed:        %u\n"
			"txs_host_tossed:   %u\n"
			"bus_flow_block:    %u\n"
			"fws_flow_block:    %u\n"
			"send_pkts:         BK:%u BE:%u VO:%u VI:%u BCMC:%u\n"
			"requested_sent:    BK:%u BE:%u VO:%u VI:%u BCMC:%u\n",
			fwstats->header_pulls,
			fwstats->header_only_pkt,
			fwstats->tlv_parse_failed,
			fwstats->tlv_invalid_type,
			fwstats->mac_update_failed,
			fwstats->mac_ps_update_failed,
			fwstats->if_update_failed,
			fwstats->pkt2bus,
			fwstats->generic_error,
			fwstats->rollback_success,
			fwstats->rollback_failed,
			fwstats->delayq_full_error,
			fwstats->supprq_full_error,
			fwstats->txs_indicate,
			fwstats->txs_discard,
			fwstats->txs_supp_core,
			fwstats->txs_supp_ps,
			fwstats->txs_tossed,
			fwstats->txs_host_tossed,
			fwstats->bus_flow_block,
			fwstats->fws_flow_block,
			fwstats->send_pkts[0], fwstats->send_pkts[1],
			fwstats->send_pkts[2], fwstats->send_pkts[3],
			fwstats->send_pkts[4],
			fwstats->requested_sent[0],
			fwstats->requested_sent[1],
			fwstats->requested_sent[2],
			fwstats->requested_sent[3],
			fwstats->requested_sent[4]);

	return simple_read_from_buffer(data, count, ppos, buf, res);
}

static const struct file_operations brcmf_debugfs_fws_stats_ops = {
	.owner = THIS_MODULE,
	.open = simple_open,
	.read = brcmf_debugfs_fws_stats_read
};

void brcmf_debugfs_create_fws_stats(struct brcmf_pub *drvr,
				    struct brcmf_fws_stats *stats)
{
	struct dentry *dentry =  drvr->dbgfs_dir;

	if (!IS_ERR_OR_NULL(dentry))
		debugfs_create_file("fws_stats", S_IRUGO, dentry,
				    stats, &brcmf_debugfs_fws_stats_ops);
}
