/*
 * Marvell Wireless LAN device driver: debugfs
 *
 * Copyright (C) 2011-2014, Marvell International Ltd.
 *
 * This software file (the "File") is distributed by Marvell International
 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
 * (the "License").  You may use, redistribute and/or modify this File in
 * accordance with the terms and conditions of the License, a copy of which
 * is available by writing to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
 *
 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
 * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
 * this warranty disclaimer.
 */

#include <linux/debugfs.h>

#include "main.h"
#include "11n.h"


static struct dentry *mwifiex_dfs_dir;

static char *bss_modes[] = {
	"UNSPECIFIED",
	"ADHOC",
	"STATION",
	"AP",
	"AP_VLAN",
	"WDS",
	"MONITOR",
	"MESH_POINT",
	"P2P_CLIENT",
	"P2P_GO",
	"P2P_DEVICE",
};

/*
 * Proc info file read handler.
 *
 * This function is called when the 'info' file is opened for reading.
 * It prints the following driver related information -
 *      - Driver name
 *      - Driver version
 *      - Driver extended version
 *      - Interface name
 *      - BSS mode
 *      - Media state (connected or disconnected)
 *      - MAC address
 *      - Total number of Tx bytes
 *      - Total number of Rx bytes
 *      - Total number of Tx packets
 *      - Total number of Rx packets
 *      - Total number of dropped Tx packets
 *      - Total number of dropped Rx packets
 *      - Total number of corrupted Tx packets
 *      - Total number of corrupted Rx packets
 *      - Carrier status (on or off)
 *      - Tx queue status (started or stopped)
 *
 * For STA mode drivers, it also prints the following extra -
 *      - ESSID
 *      - BSSID
 *      - Channel
 *      - Region code
 *      - Multicast count
 *      - Multicast addresses
 */
static ssize_t
mwifiex_info_read(struct file *file, char __user *ubuf,
		  size_t count, loff_t *ppos)
{
	struct mwifiex_private *priv =
		(struct mwifiex_private *) file->private_data;
	struct net_device *netdev = priv->netdev;
	struct netdev_hw_addr *ha;
	struct netdev_queue *txq;
	unsigned long page = get_zeroed_page(GFP_KERNEL);
	char *p = (char *) page, fmt[64];
	struct mwifiex_bss_info info;
	ssize_t ret;
	int i = 0;

	if (!p)
		return -ENOMEM;

	memset(&info, 0, sizeof(info));
	ret = mwifiex_get_bss_info(priv, &info);
	if (ret)
		goto free_and_exit;

	mwifiex_drv_get_driver_version(priv->adapter, fmt, sizeof(fmt) - 1);

	if (!priv->version_str[0])
		mwifiex_get_ver_ext(priv);

	p += sprintf(p, "driver_name = " "\"mwifiex\"\n");
	p += sprintf(p, "driver_version = %s", fmt);
	p += sprintf(p, "\nverext = %s", priv->version_str);
	p += sprintf(p, "\ninterface_name=\"%s\"\n", netdev->name);

	if (info.bss_mode >= ARRAY_SIZE(bss_modes))
		p += sprintf(p, "bss_mode=\"%d\"\n", info.bss_mode);
	else
		p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]);

	p += sprintf(p, "media_state=\"%s\"\n",
		     (!priv->media_connected ? "Disconnected" : "Connected"));
	p += sprintf(p, "mac_address=\"%pM\"\n", netdev->dev_addr);

	if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) {
		p += sprintf(p, "multicast_count=\"%d\"\n",
			     netdev_mc_count(netdev));
		p += sprintf(p, "essid=\"%s\"\n", info.ssid.ssid);
		p += sprintf(p, "bssid=\"%pM\"\n", info.bssid);
		p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan);
		p += sprintf(p, "country_code = \"%s\"\n", info.country_code);

		netdev_for_each_mc_addr(ha, netdev)
			p += sprintf(p, "multicast_address[%d]=\"%pM\"\n",
					i++, ha->addr);
	}

	p += sprintf(p, "num_tx_bytes = %lu\n", priv->stats.tx_bytes);
	p += sprintf(p, "num_rx_bytes = %lu\n", priv->stats.rx_bytes);
	p += sprintf(p, "num_tx_pkts = %lu\n", priv->stats.tx_packets);
	p += sprintf(p, "num_rx_pkts = %lu\n", priv->stats.rx_packets);
	p += sprintf(p, "num_tx_pkts_dropped = %lu\n", priv->stats.tx_dropped);
	p += sprintf(p, "num_rx_pkts_dropped = %lu\n", priv->stats.rx_dropped);
	p += sprintf(p, "num_tx_pkts_err = %lu\n", priv->stats.tx_errors);
	p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors);
	p += sprintf(p, "carrier %s\n", ((netif_carrier_ok(priv->netdev))
					 ? "on" : "off"));
	p += sprintf(p, "tx queue");
	for (i = 0; i < netdev->num_tx_queues; i++) {
		txq = netdev_get_tx_queue(netdev, i);
		p += sprintf(p, " %d:%s", i, netif_tx_queue_stopped(txq) ?
			     "stopped" : "started");
	}
	p += sprintf(p, "\n");

	ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
				      (unsigned long) p - page);

free_and_exit:
	free_page(page);
	return ret;
}

/*
 * Proc firmware dump read handler.
 *
 * This function is called when the 'fw_dump' file is opened for
 * reading.
 * This function dumps firmware memory in different files
 * (ex. DTCM, ITCM, SQRAM etc.) based on the the segments for
 * debugging.
 */
static ssize_t
mwifiex_fw_dump_read(struct file *file, char __user *ubuf,
		     size_t count, loff_t *ppos)
{
	struct mwifiex_private *priv = file->private_data;

	if (!priv->adapter->if_ops.fw_dump)
		return -EIO;

	priv->adapter->if_ops.fw_dump(priv->adapter);

	return 0;
}

/*
 * Proc getlog file read handler.
 *
 * This function is called when the 'getlog' file is opened for reading
 * It prints the following log information -
 *      - Number of multicast Tx frames
 *      - Number of failed packets
 *      - Number of Tx retries
 *      - Number of multicast Tx retries
 *      - Number of duplicate frames
 *      - Number of RTS successes
 *      - Number of RTS failures
 *      - Number of ACK failures
 *      - Number of fragmented Rx frames
 *      - Number of multicast Rx frames
 *      - Number of FCS errors
 *      - Number of Tx frames
 *      - WEP ICV error counts
 *      - Number of received beacons
 *      - Number of missed beacons
 */
static ssize_t
mwifiex_getlog_read(struct file *file, char __user *ubuf,
		    size_t count, loff_t *ppos)
{
	struct mwifiex_private *priv =
		(struct mwifiex_private *) file->private_data;
	unsigned long page = get_zeroed_page(GFP_KERNEL);
	char *p = (char *) page;
	ssize_t ret;
	struct mwifiex_ds_get_stats stats;

	if (!p)
		return -ENOMEM;

	memset(&stats, 0, sizeof(stats));
	ret = mwifiex_get_stats_info(priv, &stats);
	if (ret)
		goto free_and_exit;

	p += sprintf(p, "\n"
		     "mcasttxframe     %u\n"
		     "failed           %u\n"
		     "retry            %u\n"
		     "multiretry       %u\n"
		     "framedup         %u\n"
		     "rtssuccess       %u\n"
		     "rtsfailure       %u\n"
		     "ackfailure       %u\n"
		     "rxfrag           %u\n"
		     "mcastrxframe     %u\n"
		     "fcserror         %u\n"
		     "txframe          %u\n"
		     "wepicverrcnt-1   %u\n"
		     "wepicverrcnt-2   %u\n"
		     "wepicverrcnt-3   %u\n"
		     "wepicverrcnt-4   %u\n"
		     "bcn_rcv_cnt   %u\n"
		     "bcn_miss_cnt   %u\n",
		     stats.mcast_tx_frame,
		     stats.failed,
		     stats.retry,
		     stats.multi_retry,
		     stats.frame_dup,
		     stats.rts_success,
		     stats.rts_failure,
		     stats.ack_failure,
		     stats.rx_frag,
		     stats.mcast_rx_frame,
		     stats.fcs_error,
		     stats.tx_frame,
		     stats.wep_icv_error[0],
		     stats.wep_icv_error[1],
		     stats.wep_icv_error[2],
		     stats.wep_icv_error[3],
		     stats.bcn_rcv_cnt,
		     stats.bcn_miss_cnt);


	ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
				      (unsigned long) p - page);

free_and_exit:
	free_page(page);
	return ret;
}

/* Sysfs histogram file read handler.
 *
 * This function is called when the 'histogram' file is opened for reading
 * It prints the following histogram information -
 *      - Number of histogram samples
 *      - Receive packet number of each rx_rate
 *      - Receive packet number of each snr
 *      - Receive packet number of each nosie_flr
 *      - Receive packet number of each signal streath
 */
static ssize_t
mwifiex_histogram_read(struct file *file, char __user *ubuf,
		       size_t count, loff_t *ppos)
{
	struct mwifiex_private *priv =
		(struct mwifiex_private *)file->private_data;
	ssize_t ret;
	struct mwifiex_histogram_data *phist_data;
	int i, value;
	unsigned long page = get_zeroed_page(GFP_KERNEL);
	char *p = (char *)page;

	if (!p)
		return -ENOMEM;

	if (!priv || !priv->hist_data)
		return -EFAULT;
	phist_data = priv->hist_data;

	p += sprintf(p, "\n"
		     "total samples = %d\n",
		     atomic_read(&phist_data->num_samples));

	p += sprintf(p, "rx rates (in Mbps): 0=1M   1=2M");
	p += sprintf(p, "2=5.5M  3=11M   4=6M   5=9M  6=12M\n");
	p += sprintf(p, "7=18M  8=24M  9=36M  10=48M  11=54M");
	p += sprintf(p, "12-27=MCS0-15(BW20) 28-43=MCS0-15(BW40)\n");

	if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info)) {
		p += sprintf(p, "44-53=MCS0-9(VHT:BW20)");
		p += sprintf(p, "54-63=MCS0-9(VHT:BW40)");
		p += sprintf(p, "64-73=MCS0-9(VHT:BW80)\n\n");
	} else {
		p += sprintf(p, "\n");
	}

	for (i = 0; i < MWIFIEX_MAX_RX_RATES; i++) {
		value = atomic_read(&phist_data->rx_rate[i]);
		if (value)
			p += sprintf(p, "rx_rate[%02d] = %d\n", i, value);
	}

	if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info)) {
		for (i = MWIFIEX_MAX_RX_RATES; i < MWIFIEX_MAX_AC_RX_RATES;
		     i++) {
			value = atomic_read(&phist_data->rx_rate[i]);
			if (value)
				p += sprintf(p, "rx_rate[%02d] = %d\n",
					   i, value);
		}
	}

	for (i = 0; i < MWIFIEX_MAX_SNR; i++) {
		value =  atomic_read(&phist_data->snr[i]);
		if (value)
			p += sprintf(p, "snr[%02ddB] = %d\n", i, value);
	}
	for (i = 0; i < MWIFIEX_MAX_NOISE_FLR; i++) {
		value = atomic_read(&phist_data->noise_flr[i]);
		if (value)
			p += sprintf(p, "noise_flr[-%02ddBm] = %d\n",
				(int)(i-128), value);
	}
	for (i = 0; i < MWIFIEX_MAX_SIG_STRENGTH; i++) {
		value = atomic_read(&phist_data->sig_str[i]);
		if (value)
			p += sprintf(p, "sig_strength[-%02ddBm] = %d\n",
				i, value);
	}

	ret = simple_read_from_buffer(ubuf, count, ppos, (char *)page,
				      (unsigned long)p - page);

	return ret;
}

static ssize_t
mwifiex_histogram_write(struct file *file, const char __user *ubuf,
			size_t count, loff_t *ppos)
{
	struct mwifiex_private *priv = (void *)file->private_data;

	if (priv && priv->hist_data)
		mwifiex_hist_data_reset(priv);
	return 0;
}

static struct mwifiex_debug_info info;

/*
 * Proc debug file read handler.
 *
 * This function is called when the 'debug' file is opened for reading
 * It prints the following log information -
 *      - Interrupt count
 *      - WMM AC VO packets count
 *      - WMM AC VI packets count
 *      - WMM AC BE packets count
 *      - WMM AC BK packets count
 *      - Maximum Tx buffer size
 *      - Tx buffer size
 *      - Current Tx buffer size
 *      - Power Save mode
 *      - Power Save state
 *      - Deep Sleep status
 *      - Device wakeup required status
 *      - Number of wakeup tries
 *      - Host Sleep configured status
 *      - Host Sleep activated status
 *      - Number of Tx timeouts
 *      - Number of command timeouts
 *      - Last timed out command ID
 *      - Last timed out command action
 *      - Last command ID
 *      - Last command action
 *      - Last command index
 *      - Last command response ID
 *      - Last command response index
 *      - Last event
 *      - Last event index
 *      - Number of host to card command failures
 *      - Number of sleep confirm command failures
 *      - Number of host to card data failure
 *      - Number of deauthentication events
 *      - Number of disassociation events
 *      - Number of link lost events
 *      - Number of deauthentication commands
 *      - Number of association success commands
 *      - Number of association failure commands
 *      - Number of commands sent
 *      - Number of data packets sent
 *      - Number of command responses received
 *      - Number of events received
 *      - Tx BA stream table (TID, RA)
 *      - Rx reorder table (TID, TA, Start window, Window size, Buffer)
 */
static ssize_t
mwifiex_debug_read(struct file *file, char __user *ubuf,
		   size_t count, loff_t *ppos)
{
	struct mwifiex_private *priv =
		(struct mwifiex_private *) file->private_data;
	unsigned long page = get_zeroed_page(GFP_KERNEL);
	char *p = (char *) page;
	ssize_t ret;

	if (!p)
		return -ENOMEM;

	ret = mwifiex_get_debug_info(priv, &info);
	if (ret)
		goto free_and_exit;

	p += mwifiex_debug_info_to_buffer(priv, p, &info);

	ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
				      (unsigned long) p - page);

free_and_exit:
	free_page(page);
	return ret;
}

static u32 saved_reg_type, saved_reg_offset, saved_reg_value;

/*
 * Proc regrdwr file write handler.
 *
 * This function is called when the 'regrdwr' file is opened for writing
 *
 * This function can be used to write to a register.
 */
static ssize_t
mwifiex_regrdwr_write(struct file *file,
		      const char __user *ubuf, size_t count, loff_t *ppos)
{
	unsigned long addr = get_zeroed_page(GFP_KERNEL);
	char *buf = (char *) addr;
	size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1);
	int ret;
	u32 reg_type = 0, reg_offset = 0, reg_value = UINT_MAX;

	if (!buf)
		return -ENOMEM;


	if (copy_from_user(buf, ubuf, buf_size)) {
		ret = -EFAULT;
		goto done;
	}

	sscanf(buf, "%u %x %x", &reg_type, &reg_offset, &reg_value);

	if (reg_type == 0 || reg_offset == 0) {
		ret = -EINVAL;
		goto done;
	} else {
		saved_reg_type = reg_type;
		saved_reg_offset = reg_offset;
		saved_reg_value = reg_value;
		ret = count;
	}
done:
	free_page(addr);
	return ret;
}

/*
 * Proc regrdwr file read handler.
 *
 * This function is called when the 'regrdwr' file is opened for reading
 *
 * This function can be used to read from a register.
 */
static ssize_t
mwifiex_regrdwr_read(struct file *file, char __user *ubuf,
		     size_t count, loff_t *ppos)
{
	struct mwifiex_private *priv =
		(struct mwifiex_private *) file->private_data;
	unsigned long addr = get_zeroed_page(GFP_KERNEL);
	char *buf = (char *) addr;
	int pos = 0, ret = 0;
	u32 reg_value;

	if (!buf)
		return -ENOMEM;

	if (!saved_reg_type) {
		/* No command has been given */
		pos += snprintf(buf, PAGE_SIZE, "0");
		goto done;
	}
	/* Set command has been given */
	if (saved_reg_value != UINT_MAX) {
		ret = mwifiex_reg_write(priv, saved_reg_type, saved_reg_offset,
					saved_reg_value);

		pos += snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n",
				saved_reg_type, saved_reg_offset,
				saved_reg_value);

		ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);

		goto done;
	}
	/* Get command has been given */
	ret = mwifiex_reg_read(priv, saved_reg_type,
			       saved_reg_offset, &reg_value);
	if (ret) {
		ret = -EINVAL;
		goto done;
	}

	pos += snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n", saved_reg_type,
			saved_reg_offset, reg_value);

	ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);

done:
	free_page(addr);
	return ret;
}

static u32 saved_offset = -1, saved_bytes = -1;

/*
 * Proc rdeeprom file write handler.
 *
 * This function is called when the 'rdeeprom' file is opened for writing
 *
 * This function can be used to write to a RDEEPROM location.
 */
static ssize_t
mwifiex_rdeeprom_write(struct file *file,
		       const char __user *ubuf, size_t count, loff_t *ppos)
{
	unsigned long addr = get_zeroed_page(GFP_KERNEL);
	char *buf = (char *) addr;
	size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1);
	int ret = 0;
	int offset = -1, bytes = -1;

	if (!buf)
		return -ENOMEM;


	if (copy_from_user(buf, ubuf, buf_size)) {
		ret = -EFAULT;
		goto done;
	}

	sscanf(buf, "%d %d", &offset, &bytes);

	if (offset == -1 || bytes == -1) {
		ret = -EINVAL;
		goto done;
	} else {
		saved_offset = offset;
		saved_bytes = bytes;
		ret = count;
	}
done:
	free_page(addr);
	return ret;
}

/*
 * Proc rdeeprom read write handler.
 *
 * This function is called when the 'rdeeprom' file is opened for reading
 *
 * This function can be used to read from a RDEEPROM location.
 */
static ssize_t
mwifiex_rdeeprom_read(struct file *file, char __user *ubuf,
		      size_t count, loff_t *ppos)
{
	struct mwifiex_private *priv =
		(struct mwifiex_private *) file->private_data;
	unsigned long addr = get_zeroed_page(GFP_KERNEL);
	char *buf = (char *) addr;
	int pos = 0, ret = 0, i;
	u8 value[MAX_EEPROM_DATA];

	if (!buf)
		return -ENOMEM;

	if (saved_offset == -1) {
		/* No command has been given */
		pos += snprintf(buf, PAGE_SIZE, "0");
		goto done;
	}

	/* Get command has been given */
	ret = mwifiex_eeprom_read(priv, (u16) saved_offset,
				  (u16) saved_bytes, value);
	if (ret) {
		ret = -EINVAL;
		goto done;
	}

	pos += snprintf(buf, PAGE_SIZE, "%d %d ", saved_offset, saved_bytes);

	for (i = 0; i < saved_bytes; i++)
		pos += snprintf(buf + strlen(buf), PAGE_SIZE, "%d ", value[i]);

	ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);

done:
	free_page(addr);
	return ret;
}

/* Proc hscfg file write handler
 * This function can be used to configure the host sleep parameters.
 */
static ssize_t
mwifiex_hscfg_write(struct file *file, const char __user *ubuf,
		    size_t count, loff_t *ppos)
{
	struct mwifiex_private *priv = (void *)file->private_data;
	unsigned long addr = get_zeroed_page(GFP_KERNEL);
	char *buf = (char *)addr;
	size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1);
	int ret, arg_num;
	struct mwifiex_ds_hs_cfg hscfg;
	int conditions = HS_CFG_COND_DEF;
	u32 gpio = HS_CFG_GPIO_DEF, gap = HS_CFG_GAP_DEF;

	if (!buf)
		return -ENOMEM;

	if (copy_from_user(buf, ubuf, buf_size)) {
		ret = -EFAULT;
		goto done;
	}

	arg_num = sscanf(buf, "%d %x %x", &conditions, &gpio, &gap);

	memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg));

	if (arg_num > 3) {
		dev_err(priv->adapter->dev, "Too many arguments\n");
		ret = -EINVAL;
		goto done;
	}

	if (arg_num >= 1 && arg_num < 3)
		mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_GET,
				      MWIFIEX_SYNC_CMD, &hscfg);

	if (arg_num) {
		if (conditions == HS_CFG_CANCEL) {
			mwifiex_cancel_hs(priv, MWIFIEX_ASYNC_CMD);
			ret = count;
			goto done;
		}
		hscfg.conditions = conditions;
	}
	if (arg_num >= 2)
		hscfg.gpio = gpio;
	if (arg_num == 3)
		hscfg.gap = gap;

	hscfg.is_invoke_hostcmd = false;
	mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET,
			      MWIFIEX_SYNC_CMD, &hscfg);

	mwifiex_enable_hs(priv->adapter);
	priv->adapter->hs_enabling = false;
	ret = count;
done:
	free_page(addr);
	return ret;
}

/* Proc hscfg file read handler
 * This function can be used to read host sleep configuration
 * parameters from driver.
 */
static ssize_t
mwifiex_hscfg_read(struct file *file, char __user *ubuf,
		   size_t count, loff_t *ppos)
{
	struct mwifiex_private *priv = (void *)file->private_data;
	unsigned long addr = get_zeroed_page(GFP_KERNEL);
	char *buf = (char *)addr;
	int pos, ret;
	struct mwifiex_ds_hs_cfg hscfg;

	if (!buf)
		return -ENOMEM;

	mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_GET,
			      MWIFIEX_SYNC_CMD, &hscfg);

	pos = snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n", hscfg.conditions,
		       hscfg.gpio, hscfg.gap);

	ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);

	free_page(addr);
	return ret;
}

/*
 * Proc crash write handler.
 *
 * This function is called when the 'crash' file is opened for writing.
 *
 * Write a '1' to this file to simulate a device disconnect/reconnect.  In
 * the future, other numbers may be used to simulate different kinds of
 * crashes.
 */
static ssize_t
mwifiex_crash_write(struct file *file,
			const char __user *ubuf, size_t count, loff_t *ppos)
{
	struct mwifiex_private *priv =
		(struct mwifiex_private *) file->private_data;
	char buf[16];
	int mode;

	memset(buf, 0, sizeof(buf));
	if (simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count) < 0) {
		return -EFAULT;
	}

	mode = simple_strtol(buf, NULL, 0);
	*ppos += count;
	switch (mode) {
	case 1:
		pr_warn("causing crash: disconnect/reconnect");
		priv->adapter->if_ops.card_reset(priv->adapter);
		break;
	default:
		return -EIO;
	}

	return count;
}

#define MWIFIEX_DFS_ADD_FILE(name) do {                                 \
	if (!debugfs_create_file(#name, 0644, priv->dfs_dev_dir,        \
			priv, &mwifiex_dfs_##name##_fops))              \
		return;                                                 \
} while (0);

#define MWIFIEX_DFS_FILE_OPS(name)                                      \
static const struct file_operations mwifiex_dfs_##name##_fops = {       \
	.read = mwifiex_##name##_read,                                  \
	.write = mwifiex_##name##_write,                                \
	.open = simple_open,                                            \
};

#define MWIFIEX_DFS_FILE_READ_OPS(name)                                 \
static const struct file_operations mwifiex_dfs_##name##_fops = {       \
	.read = mwifiex_##name##_read,                                  \
	.open = simple_open,                                            \
};

#define MWIFIEX_DFS_FILE_WRITE_OPS(name)                                \
static const struct file_operations mwifiex_dfs_##name##_fops = {       \
	.write = mwifiex_##name##_write,                                \
	.open = simple_open,                                            \
};


MWIFIEX_DFS_FILE_READ_OPS(info);
MWIFIEX_DFS_FILE_READ_OPS(debug);
MWIFIEX_DFS_FILE_READ_OPS(getlog);
MWIFIEX_DFS_FILE_READ_OPS(fw_dump);
MWIFIEX_DFS_FILE_OPS(regrdwr);
MWIFIEX_DFS_FILE_OPS(rdeeprom);
MWIFIEX_DFS_FILE_WRITE_OPS(crash);
MWIFIEX_DFS_FILE_OPS(hscfg);
MWIFIEX_DFS_FILE_OPS(histogram);

/*
 * This function creates the debug FS directory structure and the files.
 */
void
mwifiex_dev_debugfs_init(struct mwifiex_private *priv)
{
	if (!mwifiex_dfs_dir || !priv)
		return;

	priv->dfs_dev_dir = debugfs_create_dir(priv->netdev->name,
					       mwifiex_dfs_dir);

	if (!priv->dfs_dev_dir)
		return;

	MWIFIEX_DFS_ADD_FILE(info);
	MWIFIEX_DFS_ADD_FILE(debug);
	MWIFIEX_DFS_ADD_FILE(getlog);
	MWIFIEX_DFS_ADD_FILE(regrdwr);
	MWIFIEX_DFS_ADD_FILE(rdeeprom);
	MWIFIEX_DFS_ADD_FILE(fw_dump);
	MWIFIEX_DFS_ADD_FILE(crash);
	MWIFIEX_DFS_ADD_FILE(hscfg);
	MWIFIEX_DFS_ADD_FILE(histogram);
}

/*
 * This function removes the debug FS directory structure and the files.
 */
void
mwifiex_dev_debugfs_remove(struct mwifiex_private *priv)
{
	if (!priv)
		return;

	debugfs_remove_recursive(priv->dfs_dev_dir);
}

/*
 * This function creates the top level proc directory.
 */
void
mwifiex_debugfs_init(void)
{
	if (!mwifiex_dfs_dir)
		mwifiex_dfs_dir = debugfs_create_dir("mwifiex", NULL);
}

/*
 * This function removes the top level proc directory.
 */
void
mwifiex_debugfs_remove(void)
{
	if (mwifiex_dfs_dir)
		debugfs_remove(mwifiex_dfs_dir);
}
