18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * NXP Wireless LAN device driver: debugfs
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Copyright 2011-2020 NXP
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * This software file (the "File") is distributed by NXP
78c2ecf20Sopenharmony_ci * under the terms of the GNU General Public License Version 2, June 1991
88c2ecf20Sopenharmony_ci * (the "License").  You may use, redistribute and/or modify this File in
98c2ecf20Sopenharmony_ci * accordance with the terms and conditions of the License, a copy of which
108c2ecf20Sopenharmony_ci * is available by writing to the Free Software Foundation, Inc.,
118c2ecf20Sopenharmony_ci * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
128c2ecf20Sopenharmony_ci * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
158c2ecf20Sopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
168c2ecf20Sopenharmony_ci * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
178c2ecf20Sopenharmony_ci * this warranty disclaimer.
188c2ecf20Sopenharmony_ci */
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#include <linux/debugfs.h>
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci#include "main.h"
238c2ecf20Sopenharmony_ci#include "11n.h"
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_cistatic struct dentry *mwifiex_dfs_dir;
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_cistatic char *bss_modes[] = {
298c2ecf20Sopenharmony_ci	"UNSPECIFIED",
308c2ecf20Sopenharmony_ci	"ADHOC",
318c2ecf20Sopenharmony_ci	"STATION",
328c2ecf20Sopenharmony_ci	"AP",
338c2ecf20Sopenharmony_ci	"AP_VLAN",
348c2ecf20Sopenharmony_ci	"WDS",
358c2ecf20Sopenharmony_ci	"MONITOR",
368c2ecf20Sopenharmony_ci	"MESH_POINT",
378c2ecf20Sopenharmony_ci	"P2P_CLIENT",
388c2ecf20Sopenharmony_ci	"P2P_GO",
398c2ecf20Sopenharmony_ci	"P2P_DEVICE",
408c2ecf20Sopenharmony_ci};
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci/*
438c2ecf20Sopenharmony_ci * Proc info file read handler.
448c2ecf20Sopenharmony_ci *
458c2ecf20Sopenharmony_ci * This function is called when the 'info' file is opened for reading.
468c2ecf20Sopenharmony_ci * It prints the following driver related information -
478c2ecf20Sopenharmony_ci *      - Driver name
488c2ecf20Sopenharmony_ci *      - Driver version
498c2ecf20Sopenharmony_ci *      - Driver extended version
508c2ecf20Sopenharmony_ci *      - Interface name
518c2ecf20Sopenharmony_ci *      - BSS mode
528c2ecf20Sopenharmony_ci *      - Media state (connected or disconnected)
538c2ecf20Sopenharmony_ci *      - MAC address
548c2ecf20Sopenharmony_ci *      - Total number of Tx bytes
558c2ecf20Sopenharmony_ci *      - Total number of Rx bytes
568c2ecf20Sopenharmony_ci *      - Total number of Tx packets
578c2ecf20Sopenharmony_ci *      - Total number of Rx packets
588c2ecf20Sopenharmony_ci *      - Total number of dropped Tx packets
598c2ecf20Sopenharmony_ci *      - Total number of dropped Rx packets
608c2ecf20Sopenharmony_ci *      - Total number of corrupted Tx packets
618c2ecf20Sopenharmony_ci *      - Total number of corrupted Rx packets
628c2ecf20Sopenharmony_ci *      - Carrier status (on or off)
638c2ecf20Sopenharmony_ci *      - Tx queue status (started or stopped)
648c2ecf20Sopenharmony_ci *
658c2ecf20Sopenharmony_ci * For STA mode drivers, it also prints the following extra -
668c2ecf20Sopenharmony_ci *      - ESSID
678c2ecf20Sopenharmony_ci *      - BSSID
688c2ecf20Sopenharmony_ci *      - Channel
698c2ecf20Sopenharmony_ci *      - Region code
708c2ecf20Sopenharmony_ci *      - Multicast count
718c2ecf20Sopenharmony_ci *      - Multicast addresses
728c2ecf20Sopenharmony_ci */
738c2ecf20Sopenharmony_cistatic ssize_t
748c2ecf20Sopenharmony_cimwifiex_info_read(struct file *file, char __user *ubuf,
758c2ecf20Sopenharmony_ci		  size_t count, loff_t *ppos)
768c2ecf20Sopenharmony_ci{
778c2ecf20Sopenharmony_ci	struct mwifiex_private *priv =
788c2ecf20Sopenharmony_ci		(struct mwifiex_private *) file->private_data;
798c2ecf20Sopenharmony_ci	struct net_device *netdev = priv->netdev;
808c2ecf20Sopenharmony_ci	struct netdev_hw_addr *ha;
818c2ecf20Sopenharmony_ci	struct netdev_queue *txq;
828c2ecf20Sopenharmony_ci	unsigned long page = get_zeroed_page(GFP_KERNEL);
838c2ecf20Sopenharmony_ci	char *p = (char *) page, fmt[64];
848c2ecf20Sopenharmony_ci	struct mwifiex_bss_info info;
858c2ecf20Sopenharmony_ci	ssize_t ret;
868c2ecf20Sopenharmony_ci	int i = 0;
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci	if (!p)
898c2ecf20Sopenharmony_ci		return -ENOMEM;
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci	memset(&info, 0, sizeof(info));
928c2ecf20Sopenharmony_ci	ret = mwifiex_get_bss_info(priv, &info);
938c2ecf20Sopenharmony_ci	if (ret)
948c2ecf20Sopenharmony_ci		goto free_and_exit;
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci	mwifiex_drv_get_driver_version(priv->adapter, fmt, sizeof(fmt) - 1);
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci	mwifiex_get_ver_ext(priv, 0);
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci	p += sprintf(p, "driver_name = " "\"mwifiex\"\n");
1018c2ecf20Sopenharmony_ci	p += sprintf(p, "driver_version = %s", fmt);
1028c2ecf20Sopenharmony_ci	p += sprintf(p, "\nverext = %s", priv->version_str);
1038c2ecf20Sopenharmony_ci	p += sprintf(p, "\ninterface_name=\"%s\"\n", netdev->name);
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	if (info.bss_mode >= ARRAY_SIZE(bss_modes))
1068c2ecf20Sopenharmony_ci		p += sprintf(p, "bss_mode=\"%d\"\n", info.bss_mode);
1078c2ecf20Sopenharmony_ci	else
1088c2ecf20Sopenharmony_ci		p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]);
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci	p += sprintf(p, "media_state=\"%s\"\n",
1118c2ecf20Sopenharmony_ci		     (!priv->media_connected ? "Disconnected" : "Connected"));
1128c2ecf20Sopenharmony_ci	p += sprintf(p, "mac_address=\"%pM\"\n", netdev->dev_addr);
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) {
1158c2ecf20Sopenharmony_ci		p += sprintf(p, "multicast_count=\"%d\"\n",
1168c2ecf20Sopenharmony_ci			     netdev_mc_count(netdev));
1178c2ecf20Sopenharmony_ci		p += sprintf(p, "essid=\"%.*s\"\n", info.ssid.ssid_len,
1188c2ecf20Sopenharmony_ci			     info.ssid.ssid);
1198c2ecf20Sopenharmony_ci		p += sprintf(p, "bssid=\"%pM\"\n", info.bssid);
1208c2ecf20Sopenharmony_ci		p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan);
1218c2ecf20Sopenharmony_ci		p += sprintf(p, "country_code = \"%s\"\n", info.country_code);
1228c2ecf20Sopenharmony_ci		p += sprintf(p, "region_code=\"0x%x\"\n",
1238c2ecf20Sopenharmony_ci			     priv->adapter->region_code);
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci		netdev_for_each_mc_addr(ha, netdev)
1268c2ecf20Sopenharmony_ci			p += sprintf(p, "multicast_address[%d]=\"%pM\"\n",
1278c2ecf20Sopenharmony_ci					i++, ha->addr);
1288c2ecf20Sopenharmony_ci	}
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci	p += sprintf(p, "num_tx_bytes = %lu\n", priv->stats.tx_bytes);
1318c2ecf20Sopenharmony_ci	p += sprintf(p, "num_rx_bytes = %lu\n", priv->stats.rx_bytes);
1328c2ecf20Sopenharmony_ci	p += sprintf(p, "num_tx_pkts = %lu\n", priv->stats.tx_packets);
1338c2ecf20Sopenharmony_ci	p += sprintf(p, "num_rx_pkts = %lu\n", priv->stats.rx_packets);
1348c2ecf20Sopenharmony_ci	p += sprintf(p, "num_tx_pkts_dropped = %lu\n", priv->stats.tx_dropped);
1358c2ecf20Sopenharmony_ci	p += sprintf(p, "num_rx_pkts_dropped = %lu\n", priv->stats.rx_dropped);
1368c2ecf20Sopenharmony_ci	p += sprintf(p, "num_tx_pkts_err = %lu\n", priv->stats.tx_errors);
1378c2ecf20Sopenharmony_ci	p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors);
1388c2ecf20Sopenharmony_ci	p += sprintf(p, "carrier %s\n", ((netif_carrier_ok(priv->netdev))
1398c2ecf20Sopenharmony_ci					 ? "on" : "off"));
1408c2ecf20Sopenharmony_ci	p += sprintf(p, "tx queue");
1418c2ecf20Sopenharmony_ci	for (i = 0; i < netdev->num_tx_queues; i++) {
1428c2ecf20Sopenharmony_ci		txq = netdev_get_tx_queue(netdev, i);
1438c2ecf20Sopenharmony_ci		p += sprintf(p, " %d:%s", i, netif_tx_queue_stopped(txq) ?
1448c2ecf20Sopenharmony_ci			     "stopped" : "started");
1458c2ecf20Sopenharmony_ci	}
1468c2ecf20Sopenharmony_ci	p += sprintf(p, "\n");
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci	ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
1498c2ecf20Sopenharmony_ci				      (unsigned long) p - page);
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_cifree_and_exit:
1528c2ecf20Sopenharmony_ci	free_page(page);
1538c2ecf20Sopenharmony_ci	return ret;
1548c2ecf20Sopenharmony_ci}
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci/*
1578c2ecf20Sopenharmony_ci * Proc getlog file read handler.
1588c2ecf20Sopenharmony_ci *
1598c2ecf20Sopenharmony_ci * This function is called when the 'getlog' file is opened for reading
1608c2ecf20Sopenharmony_ci * It prints the following log information -
1618c2ecf20Sopenharmony_ci *      - Number of multicast Tx frames
1628c2ecf20Sopenharmony_ci *      - Number of failed packets
1638c2ecf20Sopenharmony_ci *      - Number of Tx retries
1648c2ecf20Sopenharmony_ci *      - Number of multicast Tx retries
1658c2ecf20Sopenharmony_ci *      - Number of duplicate frames
1668c2ecf20Sopenharmony_ci *      - Number of RTS successes
1678c2ecf20Sopenharmony_ci *      - Number of RTS failures
1688c2ecf20Sopenharmony_ci *      - Number of ACK failures
1698c2ecf20Sopenharmony_ci *      - Number of fragmented Rx frames
1708c2ecf20Sopenharmony_ci *      - Number of multicast Rx frames
1718c2ecf20Sopenharmony_ci *      - Number of FCS errors
1728c2ecf20Sopenharmony_ci *      - Number of Tx frames
1738c2ecf20Sopenharmony_ci *      - WEP ICV error counts
1748c2ecf20Sopenharmony_ci *      - Number of received beacons
1758c2ecf20Sopenharmony_ci *      - Number of missed beacons
1768c2ecf20Sopenharmony_ci */
1778c2ecf20Sopenharmony_cistatic ssize_t
1788c2ecf20Sopenharmony_cimwifiex_getlog_read(struct file *file, char __user *ubuf,
1798c2ecf20Sopenharmony_ci		    size_t count, loff_t *ppos)
1808c2ecf20Sopenharmony_ci{
1818c2ecf20Sopenharmony_ci	struct mwifiex_private *priv =
1828c2ecf20Sopenharmony_ci		(struct mwifiex_private *) file->private_data;
1838c2ecf20Sopenharmony_ci	unsigned long page = get_zeroed_page(GFP_KERNEL);
1848c2ecf20Sopenharmony_ci	char *p = (char *) page;
1858c2ecf20Sopenharmony_ci	ssize_t ret;
1868c2ecf20Sopenharmony_ci	struct mwifiex_ds_get_stats stats;
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci	if (!p)
1898c2ecf20Sopenharmony_ci		return -ENOMEM;
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci	memset(&stats, 0, sizeof(stats));
1928c2ecf20Sopenharmony_ci	ret = mwifiex_get_stats_info(priv, &stats);
1938c2ecf20Sopenharmony_ci	if (ret)
1948c2ecf20Sopenharmony_ci		goto free_and_exit;
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci	p += sprintf(p, "\n"
1978c2ecf20Sopenharmony_ci		     "mcasttxframe     %u\n"
1988c2ecf20Sopenharmony_ci		     "failed           %u\n"
1998c2ecf20Sopenharmony_ci		     "retry            %u\n"
2008c2ecf20Sopenharmony_ci		     "multiretry       %u\n"
2018c2ecf20Sopenharmony_ci		     "framedup         %u\n"
2028c2ecf20Sopenharmony_ci		     "rtssuccess       %u\n"
2038c2ecf20Sopenharmony_ci		     "rtsfailure       %u\n"
2048c2ecf20Sopenharmony_ci		     "ackfailure       %u\n"
2058c2ecf20Sopenharmony_ci		     "rxfrag           %u\n"
2068c2ecf20Sopenharmony_ci		     "mcastrxframe     %u\n"
2078c2ecf20Sopenharmony_ci		     "fcserror         %u\n"
2088c2ecf20Sopenharmony_ci		     "txframe          %u\n"
2098c2ecf20Sopenharmony_ci		     "wepicverrcnt-1   %u\n"
2108c2ecf20Sopenharmony_ci		     "wepicverrcnt-2   %u\n"
2118c2ecf20Sopenharmony_ci		     "wepicverrcnt-3   %u\n"
2128c2ecf20Sopenharmony_ci		     "wepicverrcnt-4   %u\n"
2138c2ecf20Sopenharmony_ci		     "bcn_rcv_cnt   %u\n"
2148c2ecf20Sopenharmony_ci		     "bcn_miss_cnt   %u\n",
2158c2ecf20Sopenharmony_ci		     stats.mcast_tx_frame,
2168c2ecf20Sopenharmony_ci		     stats.failed,
2178c2ecf20Sopenharmony_ci		     stats.retry,
2188c2ecf20Sopenharmony_ci		     stats.multi_retry,
2198c2ecf20Sopenharmony_ci		     stats.frame_dup,
2208c2ecf20Sopenharmony_ci		     stats.rts_success,
2218c2ecf20Sopenharmony_ci		     stats.rts_failure,
2228c2ecf20Sopenharmony_ci		     stats.ack_failure,
2238c2ecf20Sopenharmony_ci		     stats.rx_frag,
2248c2ecf20Sopenharmony_ci		     stats.mcast_rx_frame,
2258c2ecf20Sopenharmony_ci		     stats.fcs_error,
2268c2ecf20Sopenharmony_ci		     stats.tx_frame,
2278c2ecf20Sopenharmony_ci		     stats.wep_icv_error[0],
2288c2ecf20Sopenharmony_ci		     stats.wep_icv_error[1],
2298c2ecf20Sopenharmony_ci		     stats.wep_icv_error[2],
2308c2ecf20Sopenharmony_ci		     stats.wep_icv_error[3],
2318c2ecf20Sopenharmony_ci		     stats.bcn_rcv_cnt,
2328c2ecf20Sopenharmony_ci		     stats.bcn_miss_cnt);
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_ci	ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
2368c2ecf20Sopenharmony_ci				      (unsigned long) p - page);
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_cifree_and_exit:
2398c2ecf20Sopenharmony_ci	free_page(page);
2408c2ecf20Sopenharmony_ci	return ret;
2418c2ecf20Sopenharmony_ci}
2428c2ecf20Sopenharmony_ci
2438c2ecf20Sopenharmony_ci/* Sysfs histogram file read handler.
2448c2ecf20Sopenharmony_ci *
2458c2ecf20Sopenharmony_ci * This function is called when the 'histogram' file is opened for reading
2468c2ecf20Sopenharmony_ci * It prints the following histogram information -
2478c2ecf20Sopenharmony_ci *      - Number of histogram samples
2488c2ecf20Sopenharmony_ci *      - Receive packet number of each rx_rate
2498c2ecf20Sopenharmony_ci *      - Receive packet number of each snr
2508c2ecf20Sopenharmony_ci *      - Receive packet number of each nosie_flr
2518c2ecf20Sopenharmony_ci *      - Receive packet number of each signal streath
2528c2ecf20Sopenharmony_ci */
2538c2ecf20Sopenharmony_cistatic ssize_t
2548c2ecf20Sopenharmony_cimwifiex_histogram_read(struct file *file, char __user *ubuf,
2558c2ecf20Sopenharmony_ci		       size_t count, loff_t *ppos)
2568c2ecf20Sopenharmony_ci{
2578c2ecf20Sopenharmony_ci	struct mwifiex_private *priv =
2588c2ecf20Sopenharmony_ci		(struct mwifiex_private *)file->private_data;
2598c2ecf20Sopenharmony_ci	ssize_t ret;
2608c2ecf20Sopenharmony_ci	struct mwifiex_histogram_data *phist_data;
2618c2ecf20Sopenharmony_ci	int i, value;
2628c2ecf20Sopenharmony_ci	unsigned long page = get_zeroed_page(GFP_KERNEL);
2638c2ecf20Sopenharmony_ci	char *p = (char *)page;
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_ci	if (!p)
2668c2ecf20Sopenharmony_ci		return -ENOMEM;
2678c2ecf20Sopenharmony_ci
2688c2ecf20Sopenharmony_ci	if (!priv || !priv->hist_data) {
2698c2ecf20Sopenharmony_ci		ret = -EFAULT;
2708c2ecf20Sopenharmony_ci		goto free_and_exit;
2718c2ecf20Sopenharmony_ci	}
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_ci	phist_data = priv->hist_data;
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_ci	p += sprintf(p, "\n"
2768c2ecf20Sopenharmony_ci		     "total samples = %d\n",
2778c2ecf20Sopenharmony_ci		     atomic_read(&phist_data->num_samples));
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci	p += sprintf(p,
2808c2ecf20Sopenharmony_ci		     "rx rates (in Mbps): 0=1M   1=2M 2=5.5M  3=11M   4=6M   5=9M  6=12M\n"
2818c2ecf20Sopenharmony_ci		     "7=18M  8=24M  9=36M  10=48M  11=54M 12-27=MCS0-15(BW20) 28-43=MCS0-15(BW40)\n");
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci	if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info)) {
2848c2ecf20Sopenharmony_ci		p += sprintf(p,
2858c2ecf20Sopenharmony_ci			     "44-53=MCS0-9(VHT:BW20) 54-63=MCS0-9(VHT:BW40) 64-73=MCS0-9(VHT:BW80)\n\n");
2868c2ecf20Sopenharmony_ci	} else {
2878c2ecf20Sopenharmony_ci		p += sprintf(p, "\n");
2888c2ecf20Sopenharmony_ci	}
2898c2ecf20Sopenharmony_ci
2908c2ecf20Sopenharmony_ci	for (i = 0; i < MWIFIEX_MAX_RX_RATES; i++) {
2918c2ecf20Sopenharmony_ci		value = atomic_read(&phist_data->rx_rate[i]);
2928c2ecf20Sopenharmony_ci		if (value)
2938c2ecf20Sopenharmony_ci			p += sprintf(p, "rx_rate[%02d] = %d\n", i, value);
2948c2ecf20Sopenharmony_ci	}
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_ci	if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info)) {
2978c2ecf20Sopenharmony_ci		for (i = MWIFIEX_MAX_RX_RATES; i < MWIFIEX_MAX_AC_RX_RATES;
2988c2ecf20Sopenharmony_ci		     i++) {
2998c2ecf20Sopenharmony_ci			value = atomic_read(&phist_data->rx_rate[i]);
3008c2ecf20Sopenharmony_ci			if (value)
3018c2ecf20Sopenharmony_ci				p += sprintf(p, "rx_rate[%02d] = %d\n",
3028c2ecf20Sopenharmony_ci					   i, value);
3038c2ecf20Sopenharmony_ci		}
3048c2ecf20Sopenharmony_ci	}
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_ci	for (i = 0; i < MWIFIEX_MAX_SNR; i++) {
3078c2ecf20Sopenharmony_ci		value =  atomic_read(&phist_data->snr[i]);
3088c2ecf20Sopenharmony_ci		if (value)
3098c2ecf20Sopenharmony_ci			p += sprintf(p, "snr[%02ddB] = %d\n", i, value);
3108c2ecf20Sopenharmony_ci	}
3118c2ecf20Sopenharmony_ci	for (i = 0; i < MWIFIEX_MAX_NOISE_FLR; i++) {
3128c2ecf20Sopenharmony_ci		value = atomic_read(&phist_data->noise_flr[i]);
3138c2ecf20Sopenharmony_ci		if (value)
3148c2ecf20Sopenharmony_ci			p += sprintf(p, "noise_flr[%02ddBm] = %d\n",
3158c2ecf20Sopenharmony_ci				(int)(i-128), value);
3168c2ecf20Sopenharmony_ci	}
3178c2ecf20Sopenharmony_ci	for (i = 0; i < MWIFIEX_MAX_SIG_STRENGTH; i++) {
3188c2ecf20Sopenharmony_ci		value = atomic_read(&phist_data->sig_str[i]);
3198c2ecf20Sopenharmony_ci		if (value)
3208c2ecf20Sopenharmony_ci			p += sprintf(p, "sig_strength[-%02ddBm] = %d\n",
3218c2ecf20Sopenharmony_ci				i, value);
3228c2ecf20Sopenharmony_ci	}
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_ci	ret = simple_read_from_buffer(ubuf, count, ppos, (char *)page,
3258c2ecf20Sopenharmony_ci				      (unsigned long)p - page);
3268c2ecf20Sopenharmony_ci
3278c2ecf20Sopenharmony_cifree_and_exit:
3288c2ecf20Sopenharmony_ci	free_page(page);
3298c2ecf20Sopenharmony_ci	return ret;
3308c2ecf20Sopenharmony_ci}
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_cistatic ssize_t
3338c2ecf20Sopenharmony_cimwifiex_histogram_write(struct file *file, const char __user *ubuf,
3348c2ecf20Sopenharmony_ci			size_t count, loff_t *ppos)
3358c2ecf20Sopenharmony_ci{
3368c2ecf20Sopenharmony_ci	struct mwifiex_private *priv = (void *)file->private_data;
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci	if (priv && priv->hist_data)
3398c2ecf20Sopenharmony_ci		mwifiex_hist_data_reset(priv);
3408c2ecf20Sopenharmony_ci	return 0;
3418c2ecf20Sopenharmony_ci}
3428c2ecf20Sopenharmony_ci
3438c2ecf20Sopenharmony_cistatic struct mwifiex_debug_info info;
3448c2ecf20Sopenharmony_ci
3458c2ecf20Sopenharmony_ci/*
3468c2ecf20Sopenharmony_ci * Proc debug file read handler.
3478c2ecf20Sopenharmony_ci *
3488c2ecf20Sopenharmony_ci * This function is called when the 'debug' file is opened for reading
3498c2ecf20Sopenharmony_ci * It prints the following log information -
3508c2ecf20Sopenharmony_ci *      - Interrupt count
3518c2ecf20Sopenharmony_ci *      - WMM AC VO packets count
3528c2ecf20Sopenharmony_ci *      - WMM AC VI packets count
3538c2ecf20Sopenharmony_ci *      - WMM AC BE packets count
3548c2ecf20Sopenharmony_ci *      - WMM AC BK packets count
3558c2ecf20Sopenharmony_ci *      - Maximum Tx buffer size
3568c2ecf20Sopenharmony_ci *      - Tx buffer size
3578c2ecf20Sopenharmony_ci *      - Current Tx buffer size
3588c2ecf20Sopenharmony_ci *      - Power Save mode
3598c2ecf20Sopenharmony_ci *      - Power Save state
3608c2ecf20Sopenharmony_ci *      - Deep Sleep status
3618c2ecf20Sopenharmony_ci *      - Device wakeup required status
3628c2ecf20Sopenharmony_ci *      - Number of wakeup tries
3638c2ecf20Sopenharmony_ci *      - Host Sleep configured status
3648c2ecf20Sopenharmony_ci *      - Host Sleep activated status
3658c2ecf20Sopenharmony_ci *      - Number of Tx timeouts
3668c2ecf20Sopenharmony_ci *      - Number of command timeouts
3678c2ecf20Sopenharmony_ci *      - Last timed out command ID
3688c2ecf20Sopenharmony_ci *      - Last timed out command action
3698c2ecf20Sopenharmony_ci *      - Last command ID
3708c2ecf20Sopenharmony_ci *      - Last command action
3718c2ecf20Sopenharmony_ci *      - Last command index
3728c2ecf20Sopenharmony_ci *      - Last command response ID
3738c2ecf20Sopenharmony_ci *      - Last command response index
3748c2ecf20Sopenharmony_ci *      - Last event
3758c2ecf20Sopenharmony_ci *      - Last event index
3768c2ecf20Sopenharmony_ci *      - Number of host to card command failures
3778c2ecf20Sopenharmony_ci *      - Number of sleep confirm command failures
3788c2ecf20Sopenharmony_ci *      - Number of host to card data failure
3798c2ecf20Sopenharmony_ci *      - Number of deauthentication events
3808c2ecf20Sopenharmony_ci *      - Number of disassociation events
3818c2ecf20Sopenharmony_ci *      - Number of link lost events
3828c2ecf20Sopenharmony_ci *      - Number of deauthentication commands
3838c2ecf20Sopenharmony_ci *      - Number of association success commands
3848c2ecf20Sopenharmony_ci *      - Number of association failure commands
3858c2ecf20Sopenharmony_ci *      - Number of commands sent
3868c2ecf20Sopenharmony_ci *      - Number of data packets sent
3878c2ecf20Sopenharmony_ci *      - Number of command responses received
3888c2ecf20Sopenharmony_ci *      - Number of events received
3898c2ecf20Sopenharmony_ci *      - Tx BA stream table (TID, RA)
3908c2ecf20Sopenharmony_ci *      - Rx reorder table (TID, TA, Start window, Window size, Buffer)
3918c2ecf20Sopenharmony_ci */
3928c2ecf20Sopenharmony_cistatic ssize_t
3938c2ecf20Sopenharmony_cimwifiex_debug_read(struct file *file, char __user *ubuf,
3948c2ecf20Sopenharmony_ci		   size_t count, loff_t *ppos)
3958c2ecf20Sopenharmony_ci{
3968c2ecf20Sopenharmony_ci	struct mwifiex_private *priv =
3978c2ecf20Sopenharmony_ci		(struct mwifiex_private *) file->private_data;
3988c2ecf20Sopenharmony_ci	unsigned long page = get_zeroed_page(GFP_KERNEL);
3998c2ecf20Sopenharmony_ci	char *p = (char *) page;
4008c2ecf20Sopenharmony_ci	ssize_t ret;
4018c2ecf20Sopenharmony_ci
4028c2ecf20Sopenharmony_ci	if (!p)
4038c2ecf20Sopenharmony_ci		return -ENOMEM;
4048c2ecf20Sopenharmony_ci
4058c2ecf20Sopenharmony_ci	ret = mwifiex_get_debug_info(priv, &info);
4068c2ecf20Sopenharmony_ci	if (ret)
4078c2ecf20Sopenharmony_ci		goto free_and_exit;
4088c2ecf20Sopenharmony_ci
4098c2ecf20Sopenharmony_ci	p += mwifiex_debug_info_to_buffer(priv, p, &info);
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci	ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
4128c2ecf20Sopenharmony_ci				      (unsigned long) p - page);
4138c2ecf20Sopenharmony_ci
4148c2ecf20Sopenharmony_cifree_and_exit:
4158c2ecf20Sopenharmony_ci	free_page(page);
4168c2ecf20Sopenharmony_ci	return ret;
4178c2ecf20Sopenharmony_ci}
4188c2ecf20Sopenharmony_ci
4198c2ecf20Sopenharmony_cistatic u32 saved_reg_type, saved_reg_offset, saved_reg_value;
4208c2ecf20Sopenharmony_ci
4218c2ecf20Sopenharmony_ci/*
4228c2ecf20Sopenharmony_ci * Proc regrdwr file write handler.
4238c2ecf20Sopenharmony_ci *
4248c2ecf20Sopenharmony_ci * This function is called when the 'regrdwr' file is opened for writing
4258c2ecf20Sopenharmony_ci *
4268c2ecf20Sopenharmony_ci * This function can be used to write to a register.
4278c2ecf20Sopenharmony_ci */
4288c2ecf20Sopenharmony_cistatic ssize_t
4298c2ecf20Sopenharmony_cimwifiex_regrdwr_write(struct file *file,
4308c2ecf20Sopenharmony_ci		      const char __user *ubuf, size_t count, loff_t *ppos)
4318c2ecf20Sopenharmony_ci{
4328c2ecf20Sopenharmony_ci	char *buf;
4338c2ecf20Sopenharmony_ci	int ret;
4348c2ecf20Sopenharmony_ci	u32 reg_type = 0, reg_offset = 0, reg_value = UINT_MAX;
4358c2ecf20Sopenharmony_ci
4368c2ecf20Sopenharmony_ci	buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1)));
4378c2ecf20Sopenharmony_ci	if (IS_ERR(buf))
4388c2ecf20Sopenharmony_ci		return PTR_ERR(buf);
4398c2ecf20Sopenharmony_ci
4408c2ecf20Sopenharmony_ci	sscanf(buf, "%u %x %x", &reg_type, &reg_offset, &reg_value);
4418c2ecf20Sopenharmony_ci
4428c2ecf20Sopenharmony_ci	if (reg_type == 0 || reg_offset == 0) {
4438c2ecf20Sopenharmony_ci		ret = -EINVAL;
4448c2ecf20Sopenharmony_ci		goto done;
4458c2ecf20Sopenharmony_ci	} else {
4468c2ecf20Sopenharmony_ci		saved_reg_type = reg_type;
4478c2ecf20Sopenharmony_ci		saved_reg_offset = reg_offset;
4488c2ecf20Sopenharmony_ci		saved_reg_value = reg_value;
4498c2ecf20Sopenharmony_ci		ret = count;
4508c2ecf20Sopenharmony_ci	}
4518c2ecf20Sopenharmony_cidone:
4528c2ecf20Sopenharmony_ci	kfree(buf);
4538c2ecf20Sopenharmony_ci	return ret;
4548c2ecf20Sopenharmony_ci}
4558c2ecf20Sopenharmony_ci
4568c2ecf20Sopenharmony_ci/*
4578c2ecf20Sopenharmony_ci * Proc regrdwr file read handler.
4588c2ecf20Sopenharmony_ci *
4598c2ecf20Sopenharmony_ci * This function is called when the 'regrdwr' file is opened for reading
4608c2ecf20Sopenharmony_ci *
4618c2ecf20Sopenharmony_ci * This function can be used to read from a register.
4628c2ecf20Sopenharmony_ci */
4638c2ecf20Sopenharmony_cistatic ssize_t
4648c2ecf20Sopenharmony_cimwifiex_regrdwr_read(struct file *file, char __user *ubuf,
4658c2ecf20Sopenharmony_ci		     size_t count, loff_t *ppos)
4668c2ecf20Sopenharmony_ci{
4678c2ecf20Sopenharmony_ci	struct mwifiex_private *priv =
4688c2ecf20Sopenharmony_ci		(struct mwifiex_private *) file->private_data;
4698c2ecf20Sopenharmony_ci	unsigned long addr = get_zeroed_page(GFP_KERNEL);
4708c2ecf20Sopenharmony_ci	char *buf = (char *) addr;
4718c2ecf20Sopenharmony_ci	int pos = 0, ret = 0;
4728c2ecf20Sopenharmony_ci	u32 reg_value;
4738c2ecf20Sopenharmony_ci
4748c2ecf20Sopenharmony_ci	if (!buf)
4758c2ecf20Sopenharmony_ci		return -ENOMEM;
4768c2ecf20Sopenharmony_ci
4778c2ecf20Sopenharmony_ci	if (!saved_reg_type) {
4788c2ecf20Sopenharmony_ci		/* No command has been given */
4798c2ecf20Sopenharmony_ci		pos += snprintf(buf, PAGE_SIZE, "0");
4808c2ecf20Sopenharmony_ci		goto done;
4818c2ecf20Sopenharmony_ci	}
4828c2ecf20Sopenharmony_ci	/* Set command has been given */
4838c2ecf20Sopenharmony_ci	if (saved_reg_value != UINT_MAX) {
4848c2ecf20Sopenharmony_ci		ret = mwifiex_reg_write(priv, saved_reg_type, saved_reg_offset,
4858c2ecf20Sopenharmony_ci					saved_reg_value);
4868c2ecf20Sopenharmony_ci
4878c2ecf20Sopenharmony_ci		pos += snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n",
4888c2ecf20Sopenharmony_ci				saved_reg_type, saved_reg_offset,
4898c2ecf20Sopenharmony_ci				saved_reg_value);
4908c2ecf20Sopenharmony_ci
4918c2ecf20Sopenharmony_ci		ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
4928c2ecf20Sopenharmony_ci
4938c2ecf20Sopenharmony_ci		goto done;
4948c2ecf20Sopenharmony_ci	}
4958c2ecf20Sopenharmony_ci	/* Get command has been given */
4968c2ecf20Sopenharmony_ci	ret = mwifiex_reg_read(priv, saved_reg_type,
4978c2ecf20Sopenharmony_ci			       saved_reg_offset, &reg_value);
4988c2ecf20Sopenharmony_ci	if (ret) {
4998c2ecf20Sopenharmony_ci		ret = -EINVAL;
5008c2ecf20Sopenharmony_ci		goto done;
5018c2ecf20Sopenharmony_ci	}
5028c2ecf20Sopenharmony_ci
5038c2ecf20Sopenharmony_ci	pos += snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n", saved_reg_type,
5048c2ecf20Sopenharmony_ci			saved_reg_offset, reg_value);
5058c2ecf20Sopenharmony_ci
5068c2ecf20Sopenharmony_ci	ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
5078c2ecf20Sopenharmony_ci
5088c2ecf20Sopenharmony_cidone:
5098c2ecf20Sopenharmony_ci	free_page(addr);
5108c2ecf20Sopenharmony_ci	return ret;
5118c2ecf20Sopenharmony_ci}
5128c2ecf20Sopenharmony_ci
5138c2ecf20Sopenharmony_ci/* Proc debug_mask file read handler.
5148c2ecf20Sopenharmony_ci * This function is called when the 'debug_mask' file is opened for reading
5158c2ecf20Sopenharmony_ci * This function can be used read driver debugging mask value.
5168c2ecf20Sopenharmony_ci */
5178c2ecf20Sopenharmony_cistatic ssize_t
5188c2ecf20Sopenharmony_cimwifiex_debug_mask_read(struct file *file, char __user *ubuf,
5198c2ecf20Sopenharmony_ci			size_t count, loff_t *ppos)
5208c2ecf20Sopenharmony_ci{
5218c2ecf20Sopenharmony_ci	struct mwifiex_private *priv =
5228c2ecf20Sopenharmony_ci		(struct mwifiex_private *)file->private_data;
5238c2ecf20Sopenharmony_ci	unsigned long page = get_zeroed_page(GFP_KERNEL);
5248c2ecf20Sopenharmony_ci	char *buf = (char *)page;
5258c2ecf20Sopenharmony_ci	size_t ret = 0;
5268c2ecf20Sopenharmony_ci	int pos = 0;
5278c2ecf20Sopenharmony_ci
5288c2ecf20Sopenharmony_ci	if (!buf)
5298c2ecf20Sopenharmony_ci		return -ENOMEM;
5308c2ecf20Sopenharmony_ci
5318c2ecf20Sopenharmony_ci	pos += snprintf(buf, PAGE_SIZE, "debug mask=0x%08x\n",
5328c2ecf20Sopenharmony_ci			priv->adapter->debug_mask);
5338c2ecf20Sopenharmony_ci	ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
5348c2ecf20Sopenharmony_ci
5358c2ecf20Sopenharmony_ci	free_page(page);
5368c2ecf20Sopenharmony_ci	return ret;
5378c2ecf20Sopenharmony_ci}
5388c2ecf20Sopenharmony_ci
5398c2ecf20Sopenharmony_ci/* Proc debug_mask file read handler.
5408c2ecf20Sopenharmony_ci * This function is called when the 'debug_mask' file is opened for reading
5418c2ecf20Sopenharmony_ci * This function can be used read driver debugging mask value.
5428c2ecf20Sopenharmony_ci */
5438c2ecf20Sopenharmony_cistatic ssize_t
5448c2ecf20Sopenharmony_cimwifiex_debug_mask_write(struct file *file, const char __user *ubuf,
5458c2ecf20Sopenharmony_ci			 size_t count, loff_t *ppos)
5468c2ecf20Sopenharmony_ci{
5478c2ecf20Sopenharmony_ci	int ret;
5488c2ecf20Sopenharmony_ci	unsigned long debug_mask;
5498c2ecf20Sopenharmony_ci	struct mwifiex_private *priv = (void *)file->private_data;
5508c2ecf20Sopenharmony_ci	char *buf;
5518c2ecf20Sopenharmony_ci
5528c2ecf20Sopenharmony_ci	buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1)));
5538c2ecf20Sopenharmony_ci	if (IS_ERR(buf))
5548c2ecf20Sopenharmony_ci		return PTR_ERR(buf);
5558c2ecf20Sopenharmony_ci
5568c2ecf20Sopenharmony_ci	if (kstrtoul(buf, 0, &debug_mask)) {
5578c2ecf20Sopenharmony_ci		ret = -EINVAL;
5588c2ecf20Sopenharmony_ci		goto done;
5598c2ecf20Sopenharmony_ci	}
5608c2ecf20Sopenharmony_ci
5618c2ecf20Sopenharmony_ci	priv->adapter->debug_mask = debug_mask;
5628c2ecf20Sopenharmony_ci	ret = count;
5638c2ecf20Sopenharmony_cidone:
5648c2ecf20Sopenharmony_ci	kfree(buf);
5658c2ecf20Sopenharmony_ci	return ret;
5668c2ecf20Sopenharmony_ci}
5678c2ecf20Sopenharmony_ci
5688c2ecf20Sopenharmony_ci/* debugfs verext file write handler.
5698c2ecf20Sopenharmony_ci * This function is called when the 'verext' file is opened for write
5708c2ecf20Sopenharmony_ci */
5718c2ecf20Sopenharmony_cistatic ssize_t
5728c2ecf20Sopenharmony_cimwifiex_verext_write(struct file *file, const char __user *ubuf,
5738c2ecf20Sopenharmony_ci		     size_t count, loff_t *ppos)
5748c2ecf20Sopenharmony_ci{
5758c2ecf20Sopenharmony_ci	int ret;
5768c2ecf20Sopenharmony_ci	u32 versionstrsel;
5778c2ecf20Sopenharmony_ci	struct mwifiex_private *priv = (void *)file->private_data;
5788c2ecf20Sopenharmony_ci	char buf[16];
5798c2ecf20Sopenharmony_ci
5808c2ecf20Sopenharmony_ci	memset(buf, 0, sizeof(buf));
5818c2ecf20Sopenharmony_ci
5828c2ecf20Sopenharmony_ci	if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
5838c2ecf20Sopenharmony_ci		return -EFAULT;
5848c2ecf20Sopenharmony_ci
5858c2ecf20Sopenharmony_ci	ret = kstrtou32(buf, 10, &versionstrsel);
5868c2ecf20Sopenharmony_ci	if (ret)
5878c2ecf20Sopenharmony_ci		return ret;
5888c2ecf20Sopenharmony_ci
5898c2ecf20Sopenharmony_ci	priv->versionstrsel = versionstrsel;
5908c2ecf20Sopenharmony_ci
5918c2ecf20Sopenharmony_ci	return count;
5928c2ecf20Sopenharmony_ci}
5938c2ecf20Sopenharmony_ci
5948c2ecf20Sopenharmony_ci/* Proc verext file read handler.
5958c2ecf20Sopenharmony_ci * This function is called when the 'verext' file is opened for reading
5968c2ecf20Sopenharmony_ci * This function can be used read driver exteneed verion string.
5978c2ecf20Sopenharmony_ci */
5988c2ecf20Sopenharmony_cistatic ssize_t
5998c2ecf20Sopenharmony_cimwifiex_verext_read(struct file *file, char __user *ubuf,
6008c2ecf20Sopenharmony_ci		    size_t count, loff_t *ppos)
6018c2ecf20Sopenharmony_ci{
6028c2ecf20Sopenharmony_ci	struct mwifiex_private *priv =
6038c2ecf20Sopenharmony_ci		(struct mwifiex_private *)file->private_data;
6048c2ecf20Sopenharmony_ci	char buf[256];
6058c2ecf20Sopenharmony_ci	int ret;
6068c2ecf20Sopenharmony_ci
6078c2ecf20Sopenharmony_ci	mwifiex_get_ver_ext(priv, priv->versionstrsel);
6088c2ecf20Sopenharmony_ci	ret = snprintf(buf, sizeof(buf), "version string: %s\n",
6098c2ecf20Sopenharmony_ci		       priv->version_str);
6108c2ecf20Sopenharmony_ci
6118c2ecf20Sopenharmony_ci	return simple_read_from_buffer(ubuf, count, ppos, buf, ret);
6128c2ecf20Sopenharmony_ci}
6138c2ecf20Sopenharmony_ci
6148c2ecf20Sopenharmony_ci/* Proc memrw file write handler.
6158c2ecf20Sopenharmony_ci * This function is called when the 'memrw' file is opened for writing
6168c2ecf20Sopenharmony_ci * This function can be used to write to a memory location.
6178c2ecf20Sopenharmony_ci */
6188c2ecf20Sopenharmony_cistatic ssize_t
6198c2ecf20Sopenharmony_cimwifiex_memrw_write(struct file *file, const char __user *ubuf, size_t count,
6208c2ecf20Sopenharmony_ci		    loff_t *ppos)
6218c2ecf20Sopenharmony_ci{
6228c2ecf20Sopenharmony_ci	int ret;
6238c2ecf20Sopenharmony_ci	char cmd;
6248c2ecf20Sopenharmony_ci	struct mwifiex_ds_mem_rw mem_rw;
6258c2ecf20Sopenharmony_ci	u16 cmd_action;
6268c2ecf20Sopenharmony_ci	struct mwifiex_private *priv = (void *)file->private_data;
6278c2ecf20Sopenharmony_ci	char *buf;
6288c2ecf20Sopenharmony_ci
6298c2ecf20Sopenharmony_ci	buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1)));
6308c2ecf20Sopenharmony_ci	if (IS_ERR(buf))
6318c2ecf20Sopenharmony_ci		return PTR_ERR(buf);
6328c2ecf20Sopenharmony_ci
6338c2ecf20Sopenharmony_ci	ret = sscanf(buf, "%c %x %x", &cmd, &mem_rw.addr, &mem_rw.value);
6348c2ecf20Sopenharmony_ci	if (ret != 3) {
6358c2ecf20Sopenharmony_ci		ret = -EINVAL;
6368c2ecf20Sopenharmony_ci		goto done;
6378c2ecf20Sopenharmony_ci	}
6388c2ecf20Sopenharmony_ci
6398c2ecf20Sopenharmony_ci	if ((cmd == 'r') || (cmd == 'R')) {
6408c2ecf20Sopenharmony_ci		cmd_action = HostCmd_ACT_GEN_GET;
6418c2ecf20Sopenharmony_ci		mem_rw.value = 0;
6428c2ecf20Sopenharmony_ci	} else if ((cmd == 'w') || (cmd == 'W')) {
6438c2ecf20Sopenharmony_ci		cmd_action = HostCmd_ACT_GEN_SET;
6448c2ecf20Sopenharmony_ci	} else {
6458c2ecf20Sopenharmony_ci		ret = -EINVAL;
6468c2ecf20Sopenharmony_ci		goto done;
6478c2ecf20Sopenharmony_ci	}
6488c2ecf20Sopenharmony_ci
6498c2ecf20Sopenharmony_ci	memcpy(&priv->mem_rw, &mem_rw, sizeof(mem_rw));
6508c2ecf20Sopenharmony_ci	if (mwifiex_send_cmd(priv, HostCmd_CMD_MEM_ACCESS, cmd_action, 0,
6518c2ecf20Sopenharmony_ci			     &mem_rw, true))
6528c2ecf20Sopenharmony_ci		ret = -1;
6538c2ecf20Sopenharmony_ci	else
6548c2ecf20Sopenharmony_ci		ret = count;
6558c2ecf20Sopenharmony_ci
6568c2ecf20Sopenharmony_cidone:
6578c2ecf20Sopenharmony_ci	kfree(buf);
6588c2ecf20Sopenharmony_ci	return ret;
6598c2ecf20Sopenharmony_ci}
6608c2ecf20Sopenharmony_ci
6618c2ecf20Sopenharmony_ci/* Proc memrw file read handler.
6628c2ecf20Sopenharmony_ci * This function is called when the 'memrw' file is opened for reading
6638c2ecf20Sopenharmony_ci * This function can be used to read from a memory location.
6648c2ecf20Sopenharmony_ci */
6658c2ecf20Sopenharmony_cistatic ssize_t
6668c2ecf20Sopenharmony_cimwifiex_memrw_read(struct file *file, char __user *ubuf,
6678c2ecf20Sopenharmony_ci		   size_t count, loff_t *ppos)
6688c2ecf20Sopenharmony_ci{
6698c2ecf20Sopenharmony_ci	struct mwifiex_private *priv = (void *)file->private_data;
6708c2ecf20Sopenharmony_ci	unsigned long addr = get_zeroed_page(GFP_KERNEL);
6718c2ecf20Sopenharmony_ci	char *buf = (char *)addr;
6728c2ecf20Sopenharmony_ci	int ret, pos = 0;
6738c2ecf20Sopenharmony_ci
6748c2ecf20Sopenharmony_ci	if (!buf)
6758c2ecf20Sopenharmony_ci		return -ENOMEM;
6768c2ecf20Sopenharmony_ci
6778c2ecf20Sopenharmony_ci	pos += snprintf(buf, PAGE_SIZE, "0x%x 0x%x\n", priv->mem_rw.addr,
6788c2ecf20Sopenharmony_ci			priv->mem_rw.value);
6798c2ecf20Sopenharmony_ci	ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
6808c2ecf20Sopenharmony_ci
6818c2ecf20Sopenharmony_ci	free_page(addr);
6828c2ecf20Sopenharmony_ci	return ret;
6838c2ecf20Sopenharmony_ci}
6848c2ecf20Sopenharmony_ci
6858c2ecf20Sopenharmony_cistatic u32 saved_offset = -1, saved_bytes = -1;
6868c2ecf20Sopenharmony_ci
6878c2ecf20Sopenharmony_ci/*
6888c2ecf20Sopenharmony_ci * Proc rdeeprom file write handler.
6898c2ecf20Sopenharmony_ci *
6908c2ecf20Sopenharmony_ci * This function is called when the 'rdeeprom' file is opened for writing
6918c2ecf20Sopenharmony_ci *
6928c2ecf20Sopenharmony_ci * This function can be used to write to a RDEEPROM location.
6938c2ecf20Sopenharmony_ci */
6948c2ecf20Sopenharmony_cistatic ssize_t
6958c2ecf20Sopenharmony_cimwifiex_rdeeprom_write(struct file *file,
6968c2ecf20Sopenharmony_ci		       const char __user *ubuf, size_t count, loff_t *ppos)
6978c2ecf20Sopenharmony_ci{
6988c2ecf20Sopenharmony_ci	char *buf;
6998c2ecf20Sopenharmony_ci	int ret = 0;
7008c2ecf20Sopenharmony_ci	int offset = -1, bytes = -1;
7018c2ecf20Sopenharmony_ci
7028c2ecf20Sopenharmony_ci	buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1)));
7038c2ecf20Sopenharmony_ci	if (IS_ERR(buf))
7048c2ecf20Sopenharmony_ci		return PTR_ERR(buf);
7058c2ecf20Sopenharmony_ci
7068c2ecf20Sopenharmony_ci	sscanf(buf, "%d %d", &offset, &bytes);
7078c2ecf20Sopenharmony_ci
7088c2ecf20Sopenharmony_ci	if (offset == -1 || bytes == -1) {
7098c2ecf20Sopenharmony_ci		ret = -EINVAL;
7108c2ecf20Sopenharmony_ci		goto done;
7118c2ecf20Sopenharmony_ci	} else {
7128c2ecf20Sopenharmony_ci		saved_offset = offset;
7138c2ecf20Sopenharmony_ci		saved_bytes = bytes;
7148c2ecf20Sopenharmony_ci		ret = count;
7158c2ecf20Sopenharmony_ci	}
7168c2ecf20Sopenharmony_cidone:
7178c2ecf20Sopenharmony_ci	kfree(buf);
7188c2ecf20Sopenharmony_ci	return ret;
7198c2ecf20Sopenharmony_ci}
7208c2ecf20Sopenharmony_ci
7218c2ecf20Sopenharmony_ci/*
7228c2ecf20Sopenharmony_ci * Proc rdeeprom read write handler.
7238c2ecf20Sopenharmony_ci *
7248c2ecf20Sopenharmony_ci * This function is called when the 'rdeeprom' file is opened for reading
7258c2ecf20Sopenharmony_ci *
7268c2ecf20Sopenharmony_ci * This function can be used to read from a RDEEPROM location.
7278c2ecf20Sopenharmony_ci */
7288c2ecf20Sopenharmony_cistatic ssize_t
7298c2ecf20Sopenharmony_cimwifiex_rdeeprom_read(struct file *file, char __user *ubuf,
7308c2ecf20Sopenharmony_ci		      size_t count, loff_t *ppos)
7318c2ecf20Sopenharmony_ci{
7328c2ecf20Sopenharmony_ci	struct mwifiex_private *priv =
7338c2ecf20Sopenharmony_ci		(struct mwifiex_private *) file->private_data;
7348c2ecf20Sopenharmony_ci	unsigned long addr = get_zeroed_page(GFP_KERNEL);
7358c2ecf20Sopenharmony_ci	char *buf = (char *) addr;
7368c2ecf20Sopenharmony_ci	int pos, ret, i;
7378c2ecf20Sopenharmony_ci	u8 value[MAX_EEPROM_DATA];
7388c2ecf20Sopenharmony_ci
7398c2ecf20Sopenharmony_ci	if (!buf)
7408c2ecf20Sopenharmony_ci		return -ENOMEM;
7418c2ecf20Sopenharmony_ci
7428c2ecf20Sopenharmony_ci	if (saved_offset == -1) {
7438c2ecf20Sopenharmony_ci		/* No command has been given */
7448c2ecf20Sopenharmony_ci		pos = snprintf(buf, PAGE_SIZE, "0");
7458c2ecf20Sopenharmony_ci		goto done;
7468c2ecf20Sopenharmony_ci	}
7478c2ecf20Sopenharmony_ci
7488c2ecf20Sopenharmony_ci	/* Get command has been given */
7498c2ecf20Sopenharmony_ci	ret = mwifiex_eeprom_read(priv, (u16) saved_offset,
7508c2ecf20Sopenharmony_ci				  (u16) saved_bytes, value);
7518c2ecf20Sopenharmony_ci	if (ret) {
7528c2ecf20Sopenharmony_ci		ret = -EINVAL;
7538c2ecf20Sopenharmony_ci		goto out_free;
7548c2ecf20Sopenharmony_ci	}
7558c2ecf20Sopenharmony_ci
7568c2ecf20Sopenharmony_ci	pos = snprintf(buf, PAGE_SIZE, "%d %d ", saved_offset, saved_bytes);
7578c2ecf20Sopenharmony_ci
7588c2ecf20Sopenharmony_ci	for (i = 0; i < saved_bytes; i++)
7598c2ecf20Sopenharmony_ci		pos += scnprintf(buf + pos, PAGE_SIZE - pos, "%d ", value[i]);
7608c2ecf20Sopenharmony_ci
7618c2ecf20Sopenharmony_cidone:
7628c2ecf20Sopenharmony_ci	ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
7638c2ecf20Sopenharmony_ciout_free:
7648c2ecf20Sopenharmony_ci	free_page(addr);
7658c2ecf20Sopenharmony_ci	return ret;
7668c2ecf20Sopenharmony_ci}
7678c2ecf20Sopenharmony_ci
7688c2ecf20Sopenharmony_ci/* Proc hscfg file write handler
7698c2ecf20Sopenharmony_ci * This function can be used to configure the host sleep parameters.
7708c2ecf20Sopenharmony_ci */
7718c2ecf20Sopenharmony_cistatic ssize_t
7728c2ecf20Sopenharmony_cimwifiex_hscfg_write(struct file *file, const char __user *ubuf,
7738c2ecf20Sopenharmony_ci		    size_t count, loff_t *ppos)
7748c2ecf20Sopenharmony_ci{
7758c2ecf20Sopenharmony_ci	struct mwifiex_private *priv = (void *)file->private_data;
7768c2ecf20Sopenharmony_ci	char *buf;
7778c2ecf20Sopenharmony_ci	int ret, arg_num;
7788c2ecf20Sopenharmony_ci	struct mwifiex_ds_hs_cfg hscfg;
7798c2ecf20Sopenharmony_ci	int conditions = HS_CFG_COND_DEF;
7808c2ecf20Sopenharmony_ci	u32 gpio = HS_CFG_GPIO_DEF, gap = HS_CFG_GAP_DEF;
7818c2ecf20Sopenharmony_ci
7828c2ecf20Sopenharmony_ci	buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1)));
7838c2ecf20Sopenharmony_ci	if (IS_ERR(buf))
7848c2ecf20Sopenharmony_ci		return PTR_ERR(buf);
7858c2ecf20Sopenharmony_ci
7868c2ecf20Sopenharmony_ci	arg_num = sscanf(buf, "%d %x %x", &conditions, &gpio, &gap);
7878c2ecf20Sopenharmony_ci
7888c2ecf20Sopenharmony_ci	memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg));
7898c2ecf20Sopenharmony_ci
7908c2ecf20Sopenharmony_ci	if (arg_num > 3) {
7918c2ecf20Sopenharmony_ci		mwifiex_dbg(priv->adapter, ERROR,
7928c2ecf20Sopenharmony_ci			    "Too many arguments\n");
7938c2ecf20Sopenharmony_ci		ret = -EINVAL;
7948c2ecf20Sopenharmony_ci		goto done;
7958c2ecf20Sopenharmony_ci	}
7968c2ecf20Sopenharmony_ci
7978c2ecf20Sopenharmony_ci	if (arg_num >= 1 && arg_num < 3)
7988c2ecf20Sopenharmony_ci		mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_GET,
7998c2ecf20Sopenharmony_ci				      MWIFIEX_SYNC_CMD, &hscfg);
8008c2ecf20Sopenharmony_ci
8018c2ecf20Sopenharmony_ci	if (arg_num) {
8028c2ecf20Sopenharmony_ci		if (conditions == HS_CFG_CANCEL) {
8038c2ecf20Sopenharmony_ci			mwifiex_cancel_hs(priv, MWIFIEX_ASYNC_CMD);
8048c2ecf20Sopenharmony_ci			ret = count;
8058c2ecf20Sopenharmony_ci			goto done;
8068c2ecf20Sopenharmony_ci		}
8078c2ecf20Sopenharmony_ci		hscfg.conditions = conditions;
8088c2ecf20Sopenharmony_ci	}
8098c2ecf20Sopenharmony_ci	if (arg_num >= 2)
8108c2ecf20Sopenharmony_ci		hscfg.gpio = gpio;
8118c2ecf20Sopenharmony_ci	if (arg_num == 3)
8128c2ecf20Sopenharmony_ci		hscfg.gap = gap;
8138c2ecf20Sopenharmony_ci
8148c2ecf20Sopenharmony_ci	hscfg.is_invoke_hostcmd = false;
8158c2ecf20Sopenharmony_ci	mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET,
8168c2ecf20Sopenharmony_ci			      MWIFIEX_SYNC_CMD, &hscfg);
8178c2ecf20Sopenharmony_ci
8188c2ecf20Sopenharmony_ci	mwifiex_enable_hs(priv->adapter);
8198c2ecf20Sopenharmony_ci	clear_bit(MWIFIEX_IS_HS_ENABLING, &priv->adapter->work_flags);
8208c2ecf20Sopenharmony_ci	ret = count;
8218c2ecf20Sopenharmony_cidone:
8228c2ecf20Sopenharmony_ci	kfree(buf);
8238c2ecf20Sopenharmony_ci	return ret;
8248c2ecf20Sopenharmony_ci}
8258c2ecf20Sopenharmony_ci
8268c2ecf20Sopenharmony_ci/* Proc hscfg file read handler
8278c2ecf20Sopenharmony_ci * This function can be used to read host sleep configuration
8288c2ecf20Sopenharmony_ci * parameters from driver.
8298c2ecf20Sopenharmony_ci */
8308c2ecf20Sopenharmony_cistatic ssize_t
8318c2ecf20Sopenharmony_cimwifiex_hscfg_read(struct file *file, char __user *ubuf,
8328c2ecf20Sopenharmony_ci		   size_t count, loff_t *ppos)
8338c2ecf20Sopenharmony_ci{
8348c2ecf20Sopenharmony_ci	struct mwifiex_private *priv = (void *)file->private_data;
8358c2ecf20Sopenharmony_ci	unsigned long addr = get_zeroed_page(GFP_KERNEL);
8368c2ecf20Sopenharmony_ci	char *buf = (char *)addr;
8378c2ecf20Sopenharmony_ci	int pos, ret;
8388c2ecf20Sopenharmony_ci	struct mwifiex_ds_hs_cfg hscfg;
8398c2ecf20Sopenharmony_ci
8408c2ecf20Sopenharmony_ci	if (!buf)
8418c2ecf20Sopenharmony_ci		return -ENOMEM;
8428c2ecf20Sopenharmony_ci
8438c2ecf20Sopenharmony_ci	mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_GET,
8448c2ecf20Sopenharmony_ci			      MWIFIEX_SYNC_CMD, &hscfg);
8458c2ecf20Sopenharmony_ci
8468c2ecf20Sopenharmony_ci	pos = snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n", hscfg.conditions,
8478c2ecf20Sopenharmony_ci		       hscfg.gpio, hscfg.gap);
8488c2ecf20Sopenharmony_ci
8498c2ecf20Sopenharmony_ci	ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
8508c2ecf20Sopenharmony_ci
8518c2ecf20Sopenharmony_ci	free_page(addr);
8528c2ecf20Sopenharmony_ci	return ret;
8538c2ecf20Sopenharmony_ci}
8548c2ecf20Sopenharmony_ci
8558c2ecf20Sopenharmony_cistatic ssize_t
8568c2ecf20Sopenharmony_cimwifiex_timeshare_coex_read(struct file *file, char __user *ubuf,
8578c2ecf20Sopenharmony_ci			    size_t count, loff_t *ppos)
8588c2ecf20Sopenharmony_ci{
8598c2ecf20Sopenharmony_ci	struct mwifiex_private *priv = file->private_data;
8608c2ecf20Sopenharmony_ci	char buf[3];
8618c2ecf20Sopenharmony_ci	bool timeshare_coex;
8628c2ecf20Sopenharmony_ci	int ret;
8638c2ecf20Sopenharmony_ci	unsigned int len;
8648c2ecf20Sopenharmony_ci
8658c2ecf20Sopenharmony_ci	if (priv->adapter->fw_api_ver != MWIFIEX_FW_V15)
8668c2ecf20Sopenharmony_ci		return -EOPNOTSUPP;
8678c2ecf20Sopenharmony_ci
8688c2ecf20Sopenharmony_ci	ret = mwifiex_send_cmd(priv, HostCmd_CMD_ROBUST_COEX,
8698c2ecf20Sopenharmony_ci			       HostCmd_ACT_GEN_GET, 0, &timeshare_coex, true);
8708c2ecf20Sopenharmony_ci	if (ret)
8718c2ecf20Sopenharmony_ci		return ret;
8728c2ecf20Sopenharmony_ci
8738c2ecf20Sopenharmony_ci	len = sprintf(buf, "%d\n", timeshare_coex);
8748c2ecf20Sopenharmony_ci	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
8758c2ecf20Sopenharmony_ci}
8768c2ecf20Sopenharmony_ci
8778c2ecf20Sopenharmony_cistatic ssize_t
8788c2ecf20Sopenharmony_cimwifiex_timeshare_coex_write(struct file *file, const char __user *ubuf,
8798c2ecf20Sopenharmony_ci			     size_t count, loff_t *ppos)
8808c2ecf20Sopenharmony_ci{
8818c2ecf20Sopenharmony_ci	bool timeshare_coex;
8828c2ecf20Sopenharmony_ci	struct mwifiex_private *priv = file->private_data;
8838c2ecf20Sopenharmony_ci	char kbuf[16];
8848c2ecf20Sopenharmony_ci	int ret;
8858c2ecf20Sopenharmony_ci
8868c2ecf20Sopenharmony_ci	if (priv->adapter->fw_api_ver != MWIFIEX_FW_V15)
8878c2ecf20Sopenharmony_ci		return -EOPNOTSUPP;
8888c2ecf20Sopenharmony_ci
8898c2ecf20Sopenharmony_ci	memset(kbuf, 0, sizeof(kbuf));
8908c2ecf20Sopenharmony_ci
8918c2ecf20Sopenharmony_ci	if (copy_from_user(&kbuf, ubuf, min_t(size_t, sizeof(kbuf) - 1, count)))
8928c2ecf20Sopenharmony_ci		return -EFAULT;
8938c2ecf20Sopenharmony_ci
8948c2ecf20Sopenharmony_ci	if (strtobool(kbuf, &timeshare_coex))
8958c2ecf20Sopenharmony_ci		return -EINVAL;
8968c2ecf20Sopenharmony_ci
8978c2ecf20Sopenharmony_ci	ret = mwifiex_send_cmd(priv, HostCmd_CMD_ROBUST_COEX,
8988c2ecf20Sopenharmony_ci			       HostCmd_ACT_GEN_SET, 0, &timeshare_coex, true);
8998c2ecf20Sopenharmony_ci	if (ret)
9008c2ecf20Sopenharmony_ci		return ret;
9018c2ecf20Sopenharmony_ci	else
9028c2ecf20Sopenharmony_ci		return count;
9038c2ecf20Sopenharmony_ci}
9048c2ecf20Sopenharmony_ci
9058c2ecf20Sopenharmony_cistatic ssize_t
9068c2ecf20Sopenharmony_cimwifiex_reset_write(struct file *file,
9078c2ecf20Sopenharmony_ci		    const char __user *ubuf, size_t count, loff_t *ppos)
9088c2ecf20Sopenharmony_ci{
9098c2ecf20Sopenharmony_ci	struct mwifiex_private *priv = file->private_data;
9108c2ecf20Sopenharmony_ci	struct mwifiex_adapter *adapter = priv->adapter;
9118c2ecf20Sopenharmony_ci	bool result;
9128c2ecf20Sopenharmony_ci	int rc;
9138c2ecf20Sopenharmony_ci
9148c2ecf20Sopenharmony_ci	rc = kstrtobool_from_user(ubuf, count, &result);
9158c2ecf20Sopenharmony_ci	if (rc)
9168c2ecf20Sopenharmony_ci		return rc;
9178c2ecf20Sopenharmony_ci
9188c2ecf20Sopenharmony_ci	if (!result)
9198c2ecf20Sopenharmony_ci		return -EINVAL;
9208c2ecf20Sopenharmony_ci
9218c2ecf20Sopenharmony_ci	if (adapter->if_ops.card_reset) {
9228c2ecf20Sopenharmony_ci		dev_info(adapter->dev, "Resetting per request\n");
9238c2ecf20Sopenharmony_ci		adapter->if_ops.card_reset(adapter);
9248c2ecf20Sopenharmony_ci	}
9258c2ecf20Sopenharmony_ci
9268c2ecf20Sopenharmony_ci	return count;
9278c2ecf20Sopenharmony_ci}
9288c2ecf20Sopenharmony_ci
9298c2ecf20Sopenharmony_ci#define MWIFIEX_DFS_ADD_FILE(name) do {                                 \
9308c2ecf20Sopenharmony_ci	debugfs_create_file(#name, 0644, priv->dfs_dev_dir, priv,       \
9318c2ecf20Sopenharmony_ci			    &mwifiex_dfs_##name##_fops);                \
9328c2ecf20Sopenharmony_ci} while (0);
9338c2ecf20Sopenharmony_ci
9348c2ecf20Sopenharmony_ci#define MWIFIEX_DFS_FILE_OPS(name)                                      \
9358c2ecf20Sopenharmony_cistatic const struct file_operations mwifiex_dfs_##name##_fops = {       \
9368c2ecf20Sopenharmony_ci	.read = mwifiex_##name##_read,                                  \
9378c2ecf20Sopenharmony_ci	.write = mwifiex_##name##_write,                                \
9388c2ecf20Sopenharmony_ci	.open = simple_open,                                            \
9398c2ecf20Sopenharmony_ci};
9408c2ecf20Sopenharmony_ci
9418c2ecf20Sopenharmony_ci#define MWIFIEX_DFS_FILE_READ_OPS(name)                                 \
9428c2ecf20Sopenharmony_cistatic const struct file_operations mwifiex_dfs_##name##_fops = {       \
9438c2ecf20Sopenharmony_ci	.read = mwifiex_##name##_read,                                  \
9448c2ecf20Sopenharmony_ci	.open = simple_open,                                            \
9458c2ecf20Sopenharmony_ci};
9468c2ecf20Sopenharmony_ci
9478c2ecf20Sopenharmony_ci#define MWIFIEX_DFS_FILE_WRITE_OPS(name)                                \
9488c2ecf20Sopenharmony_cistatic const struct file_operations mwifiex_dfs_##name##_fops = {       \
9498c2ecf20Sopenharmony_ci	.write = mwifiex_##name##_write,                                \
9508c2ecf20Sopenharmony_ci	.open = simple_open,                                            \
9518c2ecf20Sopenharmony_ci};
9528c2ecf20Sopenharmony_ci
9538c2ecf20Sopenharmony_ci
9548c2ecf20Sopenharmony_ciMWIFIEX_DFS_FILE_READ_OPS(info);
9558c2ecf20Sopenharmony_ciMWIFIEX_DFS_FILE_READ_OPS(debug);
9568c2ecf20Sopenharmony_ciMWIFIEX_DFS_FILE_READ_OPS(getlog);
9578c2ecf20Sopenharmony_ciMWIFIEX_DFS_FILE_OPS(regrdwr);
9588c2ecf20Sopenharmony_ciMWIFIEX_DFS_FILE_OPS(rdeeprom);
9598c2ecf20Sopenharmony_ciMWIFIEX_DFS_FILE_OPS(memrw);
9608c2ecf20Sopenharmony_ciMWIFIEX_DFS_FILE_OPS(hscfg);
9618c2ecf20Sopenharmony_ciMWIFIEX_DFS_FILE_OPS(histogram);
9628c2ecf20Sopenharmony_ciMWIFIEX_DFS_FILE_OPS(debug_mask);
9638c2ecf20Sopenharmony_ciMWIFIEX_DFS_FILE_OPS(timeshare_coex);
9648c2ecf20Sopenharmony_ciMWIFIEX_DFS_FILE_WRITE_OPS(reset);
9658c2ecf20Sopenharmony_ciMWIFIEX_DFS_FILE_OPS(verext);
9668c2ecf20Sopenharmony_ci
9678c2ecf20Sopenharmony_ci/*
9688c2ecf20Sopenharmony_ci * This function creates the debug FS directory structure and the files.
9698c2ecf20Sopenharmony_ci */
9708c2ecf20Sopenharmony_civoid
9718c2ecf20Sopenharmony_cimwifiex_dev_debugfs_init(struct mwifiex_private *priv)
9728c2ecf20Sopenharmony_ci{
9738c2ecf20Sopenharmony_ci	if (!mwifiex_dfs_dir || !priv)
9748c2ecf20Sopenharmony_ci		return;
9758c2ecf20Sopenharmony_ci
9768c2ecf20Sopenharmony_ci	priv->dfs_dev_dir = debugfs_create_dir(priv->netdev->name,
9778c2ecf20Sopenharmony_ci					       mwifiex_dfs_dir);
9788c2ecf20Sopenharmony_ci
9798c2ecf20Sopenharmony_ci	if (!priv->dfs_dev_dir)
9808c2ecf20Sopenharmony_ci		return;
9818c2ecf20Sopenharmony_ci
9828c2ecf20Sopenharmony_ci	MWIFIEX_DFS_ADD_FILE(info);
9838c2ecf20Sopenharmony_ci	MWIFIEX_DFS_ADD_FILE(debug);
9848c2ecf20Sopenharmony_ci	MWIFIEX_DFS_ADD_FILE(getlog);
9858c2ecf20Sopenharmony_ci	MWIFIEX_DFS_ADD_FILE(regrdwr);
9868c2ecf20Sopenharmony_ci	MWIFIEX_DFS_ADD_FILE(rdeeprom);
9878c2ecf20Sopenharmony_ci
9888c2ecf20Sopenharmony_ci	MWIFIEX_DFS_ADD_FILE(memrw);
9898c2ecf20Sopenharmony_ci	MWIFIEX_DFS_ADD_FILE(hscfg);
9908c2ecf20Sopenharmony_ci	MWIFIEX_DFS_ADD_FILE(histogram);
9918c2ecf20Sopenharmony_ci	MWIFIEX_DFS_ADD_FILE(debug_mask);
9928c2ecf20Sopenharmony_ci	MWIFIEX_DFS_ADD_FILE(timeshare_coex);
9938c2ecf20Sopenharmony_ci	MWIFIEX_DFS_ADD_FILE(reset);
9948c2ecf20Sopenharmony_ci	MWIFIEX_DFS_ADD_FILE(verext);
9958c2ecf20Sopenharmony_ci}
9968c2ecf20Sopenharmony_ci
9978c2ecf20Sopenharmony_ci/*
9988c2ecf20Sopenharmony_ci * This function removes the debug FS directory structure and the files.
9998c2ecf20Sopenharmony_ci */
10008c2ecf20Sopenharmony_civoid
10018c2ecf20Sopenharmony_cimwifiex_dev_debugfs_remove(struct mwifiex_private *priv)
10028c2ecf20Sopenharmony_ci{
10038c2ecf20Sopenharmony_ci	if (!priv)
10048c2ecf20Sopenharmony_ci		return;
10058c2ecf20Sopenharmony_ci
10068c2ecf20Sopenharmony_ci	debugfs_remove_recursive(priv->dfs_dev_dir);
10078c2ecf20Sopenharmony_ci}
10088c2ecf20Sopenharmony_ci
10098c2ecf20Sopenharmony_ci/*
10108c2ecf20Sopenharmony_ci * This function creates the top level proc directory.
10118c2ecf20Sopenharmony_ci */
10128c2ecf20Sopenharmony_civoid
10138c2ecf20Sopenharmony_cimwifiex_debugfs_init(void)
10148c2ecf20Sopenharmony_ci{
10158c2ecf20Sopenharmony_ci	if (!mwifiex_dfs_dir)
10168c2ecf20Sopenharmony_ci		mwifiex_dfs_dir = debugfs_create_dir("mwifiex", NULL);
10178c2ecf20Sopenharmony_ci}
10188c2ecf20Sopenharmony_ci
10198c2ecf20Sopenharmony_ci/*
10208c2ecf20Sopenharmony_ci * This function removes the top level proc directory.
10218c2ecf20Sopenharmony_ci */
10228c2ecf20Sopenharmony_civoid
10238c2ecf20Sopenharmony_cimwifiex_debugfs_remove(void)
10248c2ecf20Sopenharmony_ci{
10258c2ecf20Sopenharmony_ci	debugfs_remove(mwifiex_dfs_dir);
10268c2ecf20Sopenharmony_ci}
1027